web-dev-qa-db-fra.com

Accéder au partage SMB2.1 ou SMB3 à partir de Java?

Étant donné que Windows 2012R2 ne prend plus en charge le protocole SMB1 sans que quelques piratages de registre aient réussi à fonctionner avec les partages SMB en Java où seuls les processus SMB2.1 ou SMB3 sont pris en charge? la bibliothèque JCIFS est apparemment SMB1 seulement alors elle est sortie. Je vois que Microsoft a une bibliothèque Java pour Azure mais celle-ci semble utiliser des services plutôt que SMB.

5
Moth

J'ai trouvé ce paquet qui fonctionne avec SMB2 et SMB3, nommé smbj Jetez un coup d'œil à ceci: https://github.com/hierynomus/smbj

9
Breakidi

En développant la réponse @Breakidi, je viens d’utiliser hierynomus/smbj v0.2.0 sur Android et d’ajouter le support SMB2. Il réclame le support pour SMB2 et SMB3 bien que les classes ne se réfèrent qu'aux versions SMB2, pas sûr, peut-être que ce n'est pas pertinent.

Essai

Je l'ai testé contre une boîte exécutant SMB2 ouverte dans un cas, puis ouverte entre SMB2 et SMB3 dans un autre. Je ne pouvais pas désactiver SMB2 et tester SMB3 seul.

Bouncycastle/Spongycastle

Il était nécessaire d'utiliser Spongycastle dans mon cas (probablement à cause d'Android), car la dépendance MD4 requise était absente du classpath. Je l'ai utilisé dans ma classe qui se connecte à SMB:

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

Téléchargement du fichier

Assurez-vous de définir les indicateurs corrects lorsque vous appelez openFile sur une DiskShare (en examinant le code source en dehors du parcours):

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

Visuality Systems développe actuellement JNQ qui est basé sur Java SMB avec un support 3.1.1. Étant donné que l'exigence contient un support en amont pour Java 1.4, le développement se fait lentement. Le client SMB sera disponible quelque part cet été, le serveur viendra plus tard. 

2
Mark Rabinovich

lorsque vous utilisez hierynomus/smbj v0.3.0, je reçois une exception comme "ClassNotFoundException: Sun.security.provider.MD4", puis j’utilise le code suivant pour résoudre le problème.

SmbConfig cfg = SmbConfig.builder().
                withMultiProtocolNegotiate(true).
                withSecurityProvider(new JceSecurityProvider(new BouncyCastleProvider())).
                build();
SMBClient client = new SMBClient(cfg);
0
Vasil