woff 發表於 2020-7-20 23:01:23

JCIFS 介紹

介紹JCIFS是java-based存取網路芳鄰通訊協定的API。

之所以接觸這個API,是因為好奇Windows管理工具psexec,能將Local程式放到Remote並執行的做法。後來看到類似工具paexec程式碼,與經過自己的測試,發現原理是將程式複製到遠端的管理共享資料夾,再透過WMI呼叫外部程式。

接下來將說明我有使用的API。
如何做?首先至link下載library。接下來就是寫寫寫。
建立檔案(Create File)大部分的操作都可以透過SmbFile類別完成。而與遠端的機器認證,是透過NTLM通訊協定。private static NtlmPasswordAuthentication createAuth(String aUser, String aPasswd){
                StringBuffer sb = new StringBuffer(aUser);
                sb.append(':').append(aPasswd);
                return new NtlmPasswordAuthentication(sb.toString());
        }

        public static SmbFile createSmbFile(String aUser, String aPasswd, String aTarget) throws IOException {
                NtlmPasswordAuthentication auth = createAuth(aUser, aPasswd);
                return new SmbFile(aTarget, auth);
        }
如果有網域,可以使用new NtlmPasswordAuthentication(domain, user, passwd);
在建立完SmbFile物件後,剩下其實就和操作一般檔案無異。public static void createFile(String aUser, String aPasswd, String aTarget, String aContent) throws IOException {
                SmbFile sFile = createSmbFile(aUser, aPasswd, aTarget);
                SmbFileOutputStream sfos = null;
                try {
                        sfos = new SmbFileOutputStream(sFile);
                        sfos.write(aContent.getBytes());
                } finally {
                        close(sfos);
                }
        }

Delete File刪除檔案:public static void deleteFile(String aUser, String aPasswd, String aTarget) throws IOException {
                SmbFile sFile = createSmbFile(aUser, aPasswd, aTarget);
                sFile.delete();
        }
Exist確認檔案是否存在:public static boolean exists(String aUser, String aPasswd, String aTarget) throws IOException {
                SmbFile sFile = createSmbFile(aUser, aPasswd, aTarget);
                return sFile.exists();
        }
Copy File複製本地檔案到遠端:public static void copyFileTo(String aUser, String aPasswd, String aSource, String aTarget) throws IOException {
                SmbFile sFile = createSmbFile(aUser, aPasswd, aTarget);
                SmbFileOutputStream sfos = null;
                FileInputStream fis = null;
                try {
                        sfos = new SmbFileOutputStream(sFile);
                        fis = new FileInputStream(new File(aSource));

                        byte[] buf = new byte;
                        int len;
                        while(( len = fis.read(buf) )> 0 ){
                                sfos.write(buf, 0, len);
                        }
                } finally {
                        close(sfos);
                        close(fis);
                }
        }
複製遠端檔案到本地:public static void copyFileFrom(String aUser, String aPasswd, String aSource, String aTarget) throws IOException {
                SmbFile sFile = createSmbFile(aUser, aPasswd, aSource);
                SmbFileInputStream sfis = null;
                FileOutputStream fos = null;
                try {
                        sfis = new SmbFileInputStream(sFile);
                        fos = new FileOutputStream(new File(aTarget));

                        byte[] buf = new byte;
                        int len;
                        while(( len = sfis.read(buf) )> 0 ){
                                fos.write(buf, 0, len);
                        }
                } finally {
                        close(sfis);
                        close(fos);
                }
        }
Test簡單的寫了對檔案建立與複製的單元測試,這是對某台Win7機器的管理共享做存取。
public class SmbFileUtilTest {

        private String targetFolder = "smb://192.168.1.25/admin$/";
        private String user = "administrator";
        private String passwd = "123456";

        private String remoteTmpFile = null;
        private String localTmpFile = null;

        @After
        public void tearDown() throws IOException{
                if( remoteTmpFile != null ){
                        SmbFileUtil.deleteFile(user, passwd, remoteTmpFile);
                        assertFalse(SmbFileUtil.exists(user, passwd, remoteTmpFile));
                }
                if( localTmpFile != null ){
                        new File(localTmpFile).delete();
                }
        }

        @Test
        public void copyFile() throws IOException{
                remoteTmpFile = targetFolder+"temp.txt";
                localTmpFile = "temp.tmp";
                SmbFileUtil.copyFileTo(user, passwd, "libs/jcifs-1.3.18.jar", remoteTmpFile);
                assertTrue(SmbFileUtil.exists(user, passwd, remoteTmpFile));

                SmbFileUtil.copyFileFrom(user, passwd, remoteTmpFile,localTmpFile);
                File localFile = new File(localTmpFile);
                assertTrue(localFile.exists());

                assertEquals(new File("libs/jcifs-1.3.18.jar").length(), localFile.length());
        }

        @Test
        public void createFile() throws IOException{
                remoteTmpFile = targetFolder+"temp.txt";
                SmbFileUtil.createFile(user, passwd , remoteTmpFile, "test");
                assertTrue(SmbFileUtil.exists(user, passwd, remoteTmpFile));
        }
}
Summary要將檔案複製到遠端,也可以透過
[*]在本地建立網芳或Samba Server,讓遠端由本地複製檔案。

[*]使用echo在遠端建立wget的VB Script,從本地的http server去wget檔案。


不管是以上兩種方法,或是透過管理共享,都是有可能因為使用者權限與安全性設定而失敗。只能見招拆招了。
Reference
[*]JCIFS official site

[*]Copy File

[*]JCIFS with domain

[*]JCIFS


頁: [1]
查看完整版本: JCIFS 介紹