【发布时间】:2017-05-20 13:07:09
【问题描述】:
由于 Windows 2012R2 不再支持 SMB 1 协议而没有一些注册表黑客攻击,是否有人在仅支持 SMB 2.1 或 SMB 3 的 Java 中使用 SMB 共享成功?
JCIFS 库显然只是 SMB 1,所以它已经过时了。我看到微软有一个用于 Azure 的 Java 库,但这似乎是利用服务而不是 SMB。
【问题讨论】:
由于 Windows 2012R2 不再支持 SMB 1 协议而没有一些注册表黑客攻击,是否有人在仅支持 SMB 2.1 或 SMB 3 的 Java 中使用 SMB 共享成功?
JCIFS 库显然只是 SMB 1,所以它已经过时了。我看到微软有一个用于 Azure 的 Java 库,但这似乎是利用服务而不是 SMB。
【问题讨论】:
我发现这个包可以与 SMB2 和 SMB3 一起使用,名为 smbj 看看这个:https://github.com/hierynomus/smbj
【讨论】:
扩展@Breakidi 答案,我刚刚在Android 上使用hierynomus/smbj v0.2.0 并添加了SMB2 支持。它声称支持 SMB2 和 SMB3,尽管类仅引用 SMB2 版本,不确定,也许它无关紧要。
我已经针对在一种情况下打开 SMB2 并在另一种情况下同时打开 SMB2 和 SMB3 的盒子进行了测试。不过,我无法禁用 SMB2 并单独测试 SMB3。
在我的情况下需要使用 Spongycastle(很可能是因为 Android),因为类路径中缺少所需的 MD4 依赖项。我已经在连接到 SMB 的班级中使用它:
import org.spongycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;
<...>
static {
Security.addProvider(new BouncyCastleProvider());
}
确保在DiskShare 上调用openFile 时设置正确的标志(通过查看源代码偏离课程):
// required imports
import com.hierynomus.msdtyp.AccessMask;
import com.hierynomus.msfscc.FileAttributes;
import com.hierynomus.mssmb2.SMB2CreateDisposition;
import com.hierynomus.mssmb2.SMB2CreateOptions;
import com.hierynomus.mssmb2.SMB2ShareAccess;
import com.hierynomus.smbj.SMBClient;
import com.hierynomus.smbj.SmbConfig;
import com.hierynomus.smbj.auth.AuthenticationContext;
import com.hierynomus.smbj.common.SMBApiException;
import com.hierynomus.smbj.connection.Connection;
import com.hierynomus.smbj.session.Session;
import com.hierynomus.smbj.share.DiskShare;
import com.hierynomus.smbj.share.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.HashSet;
...
// connection params
String sambaDomain = null; // can be null
String sambaUsername = "iamuploader";
String sambaPass = "mysecret";
String sambaIP = "192.168.1.236";
String sambaSharedPath = "sharedfolder";
...
// upload method
// usage: upload("file/whithin/folder.txt", fileBytes);
public void upload(String filename, byte[] bytes) throws IOException {
SmbConfig cfg = SmbConfig.builder().build();
SMBClient client = new SMBClient(cfg);
Connection connection = client.connect(sambaIP);
Session session = connection.authenticate(new AuthenticationContext(sambaUsername, sambaPass.toCharArray(), sambaDomain));
DiskShare share = (DiskShare) session.connectShare(sambaSharedPath);
// this is com.hierynomus.smbj.share.File !
File f = null;
int idx = filename.lastIndexOf("/");
// if file is in folder(s), create them first
if(idx > -1) {
String folder = filename.substring(0, idx);
try {
if(!share.folderExists(folder)) share.mkdir(folder);
} catch (SMBApiException ex) {
throw new IOException(ex);
}
}
// I am creating file with flag FILE_CREATE, which will throw if file exists already
if(!share.fileExists(filename)){
f = share.openFile(filename,
new HashSet<>(Arrays.asList(AccessMask.GENERIC_ALL)),
new HashSet<>(Arrays.asList(FileAttributes.FILE_ATTRIBUTE_NORMAL)),
SMB2ShareAccess.ALL,
SMB2CreateDisposition.FILE_CREATE,
new HashSet<>(Arrays.asList(SMB2CreateOptions.FILE_DIRECTORY_FILE))
);
}
if(f == null) return null;
OutputStream os = f.getOutputStream();
os.write(bytes);
os.close();
}
【讨论】:
Visuality Systems 目前正在开发 JNQ,它是基于 Java 的 SMB,支持 3.1.1。由于该需求包含对 Java 1.4 的向后支持,因此开发进展缓慢。 SMB客户端将在即将到来的夏天的某个地方可用,服务器将在稍后出现。
【讨论】:
当使用hierynomus/smbj v0.3.0时,我得到了类似“ClassNotFoundException: sun.security.provider.MD4”的异常,然后我使用下面的代码来解决问题。
SmbConfig cfg = SmbConfig.builder().
withMultiProtocolNegotiate(true).
withSecurityProvider(new JceSecurityProvider(new BouncyCastleProvider())).
build();
SMBClient client = new SMBClient(cfg);
【讨论】:
BCSecurityProvider。
还有一个支持 SMB2 的库:https://github.com/AgNO3/jcifs-ng
【讨论】: