web-dev-qa-db-ja.com

JavaからSMB2.1またはSMB3共有にアクセスしますか?

Windows 2012R2はレジストリハックなしでSMB1プロトコルをサポートしなくなったため、SMB Javaの共有)での作業は成功しました。SMB2.1またはSMB3のみがサポートされていますか?JCIFSライブラリは明らかにSMB1のみであるため、リリースされています。MicrosoftにはAzure用のJavaライブラリがありますが、これはSMBではなくサービスを利用しているようです。

5
Moth

Smbjという名前のSMB2およびSMB3で動作するこのパッケージを見つけました。これを見てください: https://github.com/hierynomus/smbj

9

@Breakidiの回答を拡張して、使用したばかりです hierynomus/smbj v0.2. on AndroidそしてSMB2サポートを追加しました。クラスはSMB2バージョンのみを参照しますが、SMB2とSMB3の両方のサポートを主張します。確かではありませんが、おそらく無関係です。

テスト

あるケースではSMB2を開いてから、別のケースではSMB2とSMB3の両方を開いているボックスに対してテストしました。ただし、SMB2を無効にしてSMB3だけをテストすることはできませんでした。

Bouncycastle/Spongycastle

私の場合(おそらくAndroidが原因)、必要なMD4依存関係がクラスパスにないため、Spongycastleを使用する必要がありました。 SMBに接続するクラス内で使用しました。

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

ファイルのアップロード

openFileDiskShareを呼び出すときは、(コース外のソースコードを調べて)正しいフラグを設定してください。

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

Visuality Systemsは現在、JavaベースのJNQを開発していますSMB 3.1.1までサポートしています。要件にはJava 1.4、開発はゆっくりと進みます。SMBクライアントは来年の夏のどこかで利用可能になり、サーバーは後で利用可能になります。

3
Mark Rabinovich

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);
0
Vasil