-
Notifications
You must be signed in to change notification settings - Fork 186
Description
SMBJ 0.11.x introduced SMB 3.x support with (optionally enabled) encryption feature, configurable via SmbConfig.Builder.withEncryptData(boolean).
When using 3.0
dialect, the encryption is negotiated properly with the server:
- if
withEncryptData
is set totrue
, the library sendsSMB2_GLOBAL_CAP_ENCRYPTION
capability in the negotiate request to the server, and if the server also supports encryption (answers with the same capability), the client will use encryption - if
withEncryptData
is set tofalse
(default), the library does not send the encryption capability and will not use encryption (regardless of the server's response)
So the library uses encryption only if both sides claimed that they support encryption during the protocol negotiation, which I believe the proper behaviour.
In case of 3.1.1
dialect, the library decides based on the servers response only and does not take into account whether the encryption was set via withEncryptData(true)
and the capability was sent to the server, or not.
It works for the withEncryptData(true)
case but leads to inconsistent behaviour with some servers when withEncryptData(false)
(and therefore no encryption capability was sent from the client side):
- Samba running on Ubuntu 20.04 does not send back encryption info in this case and
smbj
will not use encryption - Windows Server 2002 sends back the encryption info, and based on this
smbj
will turn on encryption (and the communication will be successful) - NetApp Files sends back the encryption info, and based on this
smbj
will turn on encryption but the communication will fail (it seems NetApp Files does not tolerate that the client does not claim encryption capability but then tries to use encryption, which sounds reasonable from the server's perspective)
The first 2 cases are just inconsistent but the 3rd one is a concrete failure in the communication between the client and the server.
For these reasons, I would suggest taking into account also the client side encryption setting (not just the server's response) when encryption is determined in case of 3.1.1 (similar to 3.0):
ConnectionContext. supportsEncryption()
public boolean supportsEncryption() {
SMB2Dialect dialect = negotiatedProtocol.getDialect();
if (dialect == SMB2Dialect.SMB_3_1_1) {
return cipherId != null; // clientCapabilities.contains(SMB2GlobalCapability.SMB2_GLOBAL_CAP_ENCRYPTION) should be checked here too
} else {
return clientCapabilities.contains(SMB2GlobalCapability.SMB2_GLOBAL_CAP_ENCRYPTION)
&& supports(SMB2GlobalCapability.SMB2_GLOBAL_CAP_ENCRYPTION);
}
}
Error stack trace (no useful info related to the root cause though):
12:02:09.704 [main] DEBUG com.hierynomus.smbj.connection.Connection - Granted 1 (out of 128) credits to Encrypted[SMB2_CREATE with message id << 4 >>]
12:02:09.704 [main] DEBUG com.hierynomus.smbj.transport.tcp.direct.DirectTcpTransport - Writing packet Encrypted[SMB2_CREATE with message id << 4 >>]
12:02:09.705 [main] DEBUG com.hierynomus.protocol.commons.concurrent.Promise - Awaiting << 4 >>
12:02:09.813 [Packet Reader for localhost] DEBUG com.hierynomus.smbj.transport.tcp.direct.DirectTcpPacketReader - Received packet Encrypted for session id << -7976719365003134876 >>
12:02:09.813 [Packet Reader for localhost] DEBUG com.hierynomus.smbj.connection.packet.SMB3DecryptingPacketHandler - Decrypting packet Encrypted for session id << -7976719365003134876 >>
12:02:09.814 [Packet Reader for localhost] DEBUG com.hierynomus.smbj.connection.packet.SMB3DecryptingPacketHandler - Decrypted packet Encrypted for session id << -7976719365003134876 >> is packet SMB2_CREATE with message id << 4 >>.
12:02:09.814 [Packet Reader for localhost] DEBUG com.hierynomus.smbj.connection.packet.SMB2SignatureVerificationPacketHandler - Passthrough Signature Verification as packet is decrypted
12:02:09.814 [Packet Reader for localhost] DEBUG com.hierynomus.smbj.connection.packet.SMB2CreditGrantingPacketHandler - Server granted us 1 credits for SMB2_CREATE with message id << 4 >>, now available: 128 credits
12:02:09.814 [Packet Reader for localhost] DEBUG com.hierynomus.protocol.commons.concurrent.Promise - Setting << 4 >> to `SMB2_CREATE with message id << 4 >>`
Exception in thread "main" com.hierynomus.mssmb2.SMBApiException: STATUS_ACCESS_DENIED (0xc0000022): Create failed for \\localhost\netapp-vol2
at com.hierynomus.smbj.share.Share.receive(Share.java:380)
at com.hierynomus.smbj.share.Share.sendReceive(Share.java:359)
at com.hierynomus.smbj.share.Share.createFile(Share.java:156)
at com.hierynomus.smbj.share.DiskShare.createFileAndResolve(DiskShare.java:75)
at com.hierynomus.smbj.share.DiskShare.access$100(DiskShare.java:55)
at com.hierynomus.smbj.share.DiskShare$2.apply(DiskShare.java:109)
at com.hierynomus.smbj.share.DiskShare$2.apply(DiskShare.java:105)
at com.hierynomus.smbj.paths.PathResolver$1.resolve(PathResolver.java:32)
at com.hierynomus.smbj.paths.SymlinkPathResolver.resolve(SymlinkPathResolver.java:62)
at com.hierynomus.smbj.share.DiskShare.resolveAndCreateFile(DiskShare.java:105)
at com.hierynomus.smbj.share.DiskShare.open(DiskShare.java:65)
at com.hierynomus.smbj.share.DiskShare.openDirectory(DiskShare.java:151)
at ...