namjaejeon / ksmbd

ksmbd kernel server(SMB/CIFS server)
https://github.com/cifsd-team/ksmbd
270 stars 62 forks source link

MacOS can not access by GCM256 or CCM256 cipher type, and the volume's format not present correctly #418

Closed MiaoLiHua closed 1 year ago

MiaoLiHua commented 1 year ago

I have a MacBookPro17,1 with Apple M1 CPU, macOS 12.6 (21G115) and Darwin 21.6.0 kernel. By it do "Connect to Server..." command to a ubuntu which running KSMBD, always can not login. I have dig deeper into KSMBD source code and log, know the client(macOS) prefers GCM256 and CCM256 cipher type, so KSMBD smb2pdu.c picked GCM256 as result cipher type by source code lines 908-918. I experimentally change the cipher type picking policy to enforced CCM256 as negotiated cipher type result, the problem still exists as before. By check KSMBD output log, I known that KSMBD successfully finished smb2_negotiate_request and smb2_sess_setup and replied successful responses, then received a logoff request weirdly from the mac client, of course KSMBD lead to smb2_session_logoff.

If enforce KSMBD picking GCM128 or CCM128, everything is back to normal except one little fault: the volume's format show "Unknown". While mac opened a KSMBD's share and listed all files in it's Finder, right clicked and choose "Get Info", you could get the fs info about this share. Following is I got:     Kind: Volume    Server: smb://192.168.0.134/MyShare      .......    Format: SMB (Unknown) I think it should be SMB (NTFS) because smb2pdu.c line 5072 set NTFS as the fs name. We have one piece of observational evidence on it by connecting a windows 11 SMB server with the same mac client, got correct SMB (NTFS) volume format. On the other hand, connecting the KSMBD with a windows 11 client, the windows client also got correct SMB (NTFS) volume format.

namjaejeon commented 1 year ago

@lihua-theone Thanks for your report! I have old Macbook, OS version isMojave (10.14). There is no issue with old MacOS. I think that the latest MacOS upgrade supported SMB version to SMB3.1.1 from SMB3.0.2. I need to buy or borrow the latest Macbook to fix this issue fast. It's hard with my salary... or Although it will take a lot of time, you can help me fixing this issue.

Can you give me two tcpdump(or wireshark dump) to compare packet ? Don't update ksmbd codes. you can dump it on original one.

  1. while connecting between MacOS client and ksmbd, dump packets.
  2. while connecting between MacOS client and windows server, dump packets.
MiaoLiHua commented 1 year ago

I have more messages: my another MacBook run Big Sur macOS 11.6.7 (20G630), all functions perform good except volume's format not present correctly. The old macOS taken the 128 as cipher type. I guess, macOS client and windows server maybe also forcefully negotiated 128 GCM/CCM cipher type. Surely, I will dump the network packet as soon as possible. Also, I have downloaded macOS smbclient from https://opensource.apple.com/releases and try run it, attempt checking what is the smbclient doing.

MiaoLiHua commented 1 year ago

I read the source codes of the macOS smbclient, and known if you want show SMB (NTFS) volume format, MUST set the FILE_NAMED_STREAMS flag while it get filesystem attributes, e.g. at smb2pdu.c line 5067 insert following sentence: info->Attributes |= FILE_NAMED_STREAMS;

namjaejeon commented 1 year ago

I guess, macOS client and windows server maybe also forcefully negotiated 128 GCM/CCM cipher type.

Maybe, But we need to check it on real, not guessing.

known if you want show SMB (NTFS) volume format, MUST set the FILE_NAMED_STREAMS flag while it get filesystem attributes,

Oh, Great! Have you ever sent the patch to the mailing list(linux-cifs@vger.kernel.org) ? It would be great if you send it to mailing list.

MacBookPro17,1 with Apple M1 CPU, macOS 12.6 (21G115)

I am wondering why the latest Mac client can not connect with ksmbd, and why it can connect windows server... anyway nice work.

MiaoLiHua commented 1 year ago

Here zip archive contains four files:

  1. mac_to_KSMBD.pcapng is Wireshark dump packets while connecting between MacOS client and ksmbd.
  2. mac_to_Win11.pcapng is Wireshark dump packets while connecting between MacOS client and windows server.
  3. mac_to_KSMBD.log is ksmbd debug log while connecting between MacOS client and ksmbd.
  4. win11_to_KSMBD.log is ksmbd debug log while connecting between Win11 client and ksmbd. I do an auxiliary test connecting between Win11 client and ksmbd. Because selected CCM128 as cipher type, so all functions are perfect.

archive.zip

MiaoLiHua commented 1 year ago

As mentioned in last comment, while connecting between Win11 client and ksmbd, selected CCM128 as cipher type. But if modified ksmbd enforced the GCM256 as selected cipher type, the Win11 can not login to ksmbd either, almost same as MacOS. So, maybe could fix the issue with win11 client.

MiaoLiHua commented 1 year ago

Sorry, I have not sent that patch to the mailing list(linux-cifs@vger.kernel.org) because I have not config patch mail previously. Maybe I do the config recently. For this little patch, would you like submit it substitute for me?

namjaejeon commented 1 year ago

For this little patch, would you like submit it substitute for me?

Okay, Let me know your mail address and full name like this. I would like to add your sign-off and report-by tag in patch.

Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
MiaoLiHua commented 1 year ago

Thanks!

MiaoLihua <441884205@qq.com>

MiaoLiHua commented 1 year ago

I have learnt the macOS smbclient source codes about session's encryption_key and decryption_key algorithm. Found if cipher type is GCM256 or CCM 256, the session's full_session_key and it's length used.

As MS-SMB2 3.3.5.5.3 mentioned:

So, I presume that the Session.SessionKey and Session.FullSessionKey very different. And ksmbd's ksmbd_session only has one sess_key, and the function "ksmbd_gen_sess_key" generated it. Then using sess_key's SMB2_NTLMV2_SESSKEY_SIZE bytes in function "generate_key" to generate smb3signingkey, smb3encryptionkey and smb3decryptionkey.

I think that we need to upgrade function "ksmbd_gen_sess_key", let sess_key hold the full bytes of the cryptographic key for this authenticated context. But, I do not know how calculate the cryptographic key at all.

namjaejeon commented 1 year ago

Thanks for your check:) I will take a look.

namjaejeon commented 1 year ago

I read the source codes of the macOS smbclient, and known if you want show SMB (NTFS) volume format, MUST set the FILE_NAMED_STREAMS flag while it get filesystem attributes

Can you show me the related codes of MacOS smbclient ? I would like to add it to the patch description.

MiaoLiHua commented 1 year ago

Please check function "smbfs_smb_qfsattr", and line 7766 set the ss_fstype to SMB_FS_NTFS_UNKNOWN(ss_fstype default value is SMB_FS_FAT). Then line 7792 check FILE_NAMED_STREAMS more and alter ss_fstype to SMB_FS_NTFS.

Following is MacOS smbclient's ss_fstype enum.

/* File system types ss_fstype */ enum smb_fs_types { SMB_FS_FAT = 0, /* Fat file system */ SMB_FS_CDFS = 1, /* CD file system */ SMB_FS_UDF = 2, /* DVD file system */ SMB_FS_NTFS_UNKNOWN = 3, /* NTFS file system, sometimes faked by server no streams support */ SMB_FS_NTFS = 4, /* Real NTFS or fully pretending, NTFS share that also supports STREAMS. */ SMB_FS_NTFS_UNIX = 5, /* Pretending to be NTFS file system, no streams, but it is a UNIX system */ SMB_FS_MAC_OS_X = 6 /* Mac OS X Server, SMB 2/3 or greater */ };

smbfs_smb_2.zip

namjaejeon commented 1 year ago

Here zip archive contains four files:

Sorry, I have checked wireshark dump, But there is only packets from client. There is no packets from server(ksmbd and windows server). Can you give the packet dump included both client and server packets to me... ?

MiaoLiHua commented 1 year ago

So sorry, I have made mistake while filter the dump packets. Here given a new archive which contains four files:

  1. toKSMBD.pcapng: originally captured all packet at MacBook(ip:192.168.0.11) while it communicating with ksmbd
  2. toKSMBD_filtered.pcapng: filtered packets between MacBook(ip:192.168.0.11) and ksmbd(ip:192.168.0.134)
  3. toWin11.pcapng: originally captured all packet at MacBook(ip:192.168.0.11) while it communicating with win11
  4. toWin11_filtered.pcapng: filtered packets between MacBook(ip:192.168.0.11) and win11(ip:192.168.0.17) If here still has some fault, please tell me :).

archive.zip

namjaejeon commented 1 year ago

Thanks, I will check them:)

namjaejeon commented 1 year ago

@lihua-theone Hm.. I don't have win11 PC yet. only having win10. So Can you give the dump between windows 11 client and ksmbd ? I would like to check why windows 11 client select CCM128 type.

namjaejeon commented 1 year ago

@lihua-theone windows 10 client doesn't support GCM/CCM 256 type when I check packets...

MiaoLiHua commented 1 year ago

@namjaejeon Surely, I will capture the packets between win11 and ksmbd very soon. But I needs install the Wireshark on my ubuntu firstly. I know why windows 11 client select CCM128 type. In ksmbd function "decode_encrypt_ctxt", following code block determine conn->cipher_type to be set which value: for (i = 0; i < cph_cnt; i++) { if (pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES128_GCM || pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES128_CCM || pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES256_CCM || pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES256_GCM) { ksmbd_debug(SMB, "Cipher ID = 0x%x\n", pneg_ctxt->Ciphers[i]); conn->cipher_type = pneg_ctxt->Ciphers[i]; break; } } Win11's pneg_ctxt->Ciphers put 128 cipher types at first, and macOS put 256 cipher types at first.

namjaejeon commented 1 year ago

Win11's pneg_ctxt->Ciphers put 128 cipher types at first, and macOS put 256 cipher types at first.

Okay, got it. If so, no need to dump it. thanks:) maybe, I need to buy win11 OS first.

namjaejeon commented 1 year ago

in case of win10, there is no gcm256 or ccm 256 in encryption array of encryption context. so I can't check this issue with win10...

MiaoLiHua commented 1 year ago

in case of win10, there is no gcm256 or ccm 256 in encryption array of encryption context. so I can't check this issue with win10...

Yes, in older macOS, the situation is same, the array only contains 128 ones.

MiaoLiHua commented 1 year ago

Here have two files in this archive: win11_to_ksmbd.pcapng is dump packets and win11_to_ksmbd.log is ksmbd's debug log while win11 as client connecting to ksmbd.

archive.zip

MiaoLiHua commented 1 year ago

@namjaejeon I try connect to ksmbd with ubuntu client(64bit Ubuntu 22.04.1 LTS, kernel version 5.15.0-60-generic, GNOME version 42.5), the ubuntu's smb encryption array of encryption context contains four elements: GCM128, CCM128, GCM256 and CCM256 in order. I use following code block to enforce ksmbd to select gcm256, ubuntu can not login the ksmbd either. So, maybe could check the issue by ubuntu client firstly. By the way, read ubuntu's smbclient source codes maybe helpful.

for (i = 0; i < cph_cnt; i++) { if (pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES256_GCM) { ksmbd_debug(SMB, "Negotiated Cipher ID = 0x%xd\n", pneg_ctxt->Ciphers[i]); conn->cipher_type = pneg_ctxt->Ciphers[i]; break; } }

if (conn->cipher_type==0) { for (i = 0; i < cph_cnt; i++) { if (pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES128_GCM || pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES128_CCM || pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES256_CCM || pneg_ctxt->Ciphers[i] == SMB2_ENCRYPTION_AES256_GCM) { ksmbd_debug(SMB, "Negotiated Cipher ID = 0x%xd\n", pneg_ctxt->Ciphers[i]); conn->cipher_type = pneg_ctxt->Ciphers[i]; break; } } }

namjaejeon commented 1 year ago

maybe could check the issue by ubuntu client firstly. By the way, read ubuntu's smbclient source codes maybe helpful.

What is ubuntu client ? Nautilus ?

MiaoLiHua commented 1 year ago

My ubuntu client is Ubuntu Desktop version. And I try connect to ksmbd by application "Files" of the ubuntu GUI(GNOME version 42.5) and "Other Locations" -> "Connect to server" as the attached screenshot illustrating. I am not clear what the ubuntu used as smbclient actually. How do some checks to find the final actor?

Screenshot

namjaejeon commented 1 year ago

How do some checks to find the final actor?

I don't know, This is Nautilus app. I guess that this app may use libsmbclient of samba. not sure... Anyway, I can check this issue using Nautilus app as you inform me. Thanks!

MiaoLiHua commented 1 year ago

I don't know, This is Nautilus app. I guess that this app may use libsmbclient of samba. not sure...

I presume that you are right. Nautilus likely use gio->gvfs, and the gvfs support the SMB scheme by libsmbclient.

namjaejeon commented 1 year ago

@lihua-theone Could you please check if problem is fixed on MacOS and windows 11 ? I have checked problem is fixed with Nautilus.

Please use the code below. git clone --branch=fix-aes256bug https://github.com/namjaejeon/ksmbd

namjaejeon commented 1 year ago

@lihua-theone Ping?

MiaoLiHua commented 1 year ago

@namjaejeon sorry, I'm temporarily absent from work. I will try it just at this evening.

namjaejeon commented 1 year ago

@lihua-theone Thank you! And I pushed the patch to the master branch. Please check this.

git clone https://github.com/namjaejeon/ksmbd

MiaoLiHua commented 1 year ago

@namjaejeon Great!!! I tested the branch=fix-aes256bug codes on MacOS and windows 11. All good! For GCM256 and CCM256, client connected the ksmbd very smoothly!!! Thank you very much, I will checkout the master branch:)

namjaejeon commented 1 year ago

@lihua-theone Thanks for your check! I will apply this patch to the mainline also. Please Close THE ISSUE.

namjaejeon commented 1 year ago

@lihua-theone And I have fixed smb unknown issue also. Can you check this also ?

git clone https://github.com/namjaejeon/ksmbd

And you need to add "vfs objects = streams_xattr" parameter in ksmbd.conf to turn streams support on like the following.

       vfs objects (S)
              List of the VFS modules to overload I/O operations with.  Available  VFS  mod‐
              ules are acl_xattr and streams_xattr.

              Default: vfs objects =
MiaoLiHua commented 1 year ago

@namjaejeon I have added the line to the ksmbd conf file, all right!