从java访问SMB2.1或SMB3共享?

时间:2017-01-05 20:43:41

标签: java smb

由于Windows 2012R2不再支持SMB1协议而没有一些注册表黑客,在Java中只支持SMB2.1或SMB3的SMB共享中是否有任何成功? JCIFS库显然只是SMB1,所以它出来了。我看到微软有一个用于Azure的Java库,但这似乎是利用服务而不是SMB。

5 个答案:

答案 0 :(得分:9)

我发现这个包可以用于SMB2和SMB3,名为smbj 看看这个:https://github.com/hierynomus/smbj

答案 1 :(得分:4)

扩展@Breakidi答案,我刚刚在Android上使用hierynomus/smbj v0.2.0并添加了SMB2支持。它声称支持SMB2和SMB3,虽然类仅参考SMB2版本,但不确定,可能它是无关紧要的。

测试

我在一个案例中测试了运行SMB2的盒子,然后在另一个案例中打开了SMB2和SMB3。我无法单独禁用SMB2并测试SMB3。

BouncyCastle的/ Spongycastle

在我的情况下需要使用Spongycastle(很可能是因为Android),因为类路径中缺少必需的MD4依赖。我在班级中使用它连接到SMB:

import org.spongycastle.jce.provider.BouncyCastleProvider;
import java.security.Security;
<...>
static {
    Security.addProvider(new BouncyCastleProvider());
}

上传文件

确保在openFile上调用DiskShare时设置正确的标记(通过查看源代码偏离课程):

// 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();
}

答案 2 :(得分:2)

Visuality Systems目前正在开发JNQ,它是基于Java的SMB,支持3.1.1。由于该要求包含对Java 1.4的向后支持,因此开发进展缓慢。 SMB客户端将在即将到来的夏天的某个地方推出,服务器将在稍后推出。

答案 3 :(得分:0)

当使用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);

答案 4 :(得分:0)

还有一个支持 SMB2 的库:https://github.com/AgNO3/jcifs-ng