2010-06-19 15 views
32

क्या कोई जावा लाइब्रेरी है जिसका उपयोग SFTP सर्वर को लागू करने के लिए किया जा सकता है?जावा एसएफटीपी सर्वर पुस्तकालय?

मैं एसएफटीपी के माध्यम से फाइलें प्राप्त करने की कोशिश कर रहा हूं, लेकिन मुझे एसएफटीपी सर्वर के किसी भी कार्यान्वयन को प्रतीत नहीं होता है। मुझे एफ़टीपी/एसएफटीपी/एफटीपीएस क्लाइंट पुस्तकालय, और एफ़टीपी/एफटीपीएस सर्वर पुस्तकालय मिला है, लेकिन एसएफटीपी के लिए सर्वर के लिए कोई भी नहीं मिला है।

स्पष्टीकरण के लिए, मैं को फ़ाइलों को SFTP के माध्यम से प्राप्त करने का प्रयास कर रहा हूं। मेरे आवेदन से अन्य मौजूदा सर्वर पर फ़ाइलों को "प्राप्त करें" या "डालें" नहीं।

अभी मेरा एप्लिकेशन उपयोगकर्ताओं को स्थानीय लिनक्स एसएफटीपी सर्वर से कनेक्ट करने देता है, फ़ाइलों को छोड़ देता है, और फिर मेरा आवेदन निर्देशिका को छोड़ देता है, लेकिन मुझे लगता है कि यह एक खराब कार्यान्वयन है; मुझे "मतदान" निर्देशिकाओं के विचार से नफरत है, लेकिन दुर्भाग्यवश उन्हें एसएफटीपी का उपयोग करना है। कोई सुझाव?

उत्तर

40

कैसे सेटअप Apache Mina SSHD का उपयोग कर एक SFTP सर्वर करने के लिए:

public void setupSftpServer(){ 
    SshServer sshd = SshServer.setUpDefaultServer(); 
    sshd.setPort(22); 
    sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider("hostkey.ser")); 

    List<NamedFactory<UserAuth>> userAuthFactories = new ArrayList<NamedFactory<UserAuth>>(); 
    userAuthFactories.add(new UserAuthNone.Factory()); 
    sshd.setUserAuthFactories(userAuthFactories); 

    sshd.setCommandFactory(new ScpCommandFactory()); 

    List<NamedFactory<Command>> namedFactoryList = new ArrayList<NamedFactory<Command>>(); 
    namedFactoryList.add(new SftpSubsystem.Factory()); 
    sshd.setSubsystemFactories(namedFactoryList); 

    try { 
     sshd.start(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

और इतना ही है।

+0

यह एक एसएसएच सर्वर बनाता है जो अधिकतर आधुनिक ग्राहक कनेक्ट करने से इनकार कर देंगे :-(http://stackoverflow.com/questions/33690689/no-matching-host-key-type-found-apache-mina-sftp-server देखें – Rich

0
+0

लिंक आपके द्वारा दी गई नहीं है एक जावा पुस्तकालय, यह एक स्टैंडअलोन उत्पाद है। साथ ही, यह एसएफटीपी का उपयोग नहीं करता है, बल्कि इसके बजाय एफटीपीएस। क्या आपने इस उत्पाद के बारे में कुछ भी पढ़ा था, या जब आपने "जावा सुरक्षित एफटीपी" गुगल किया था तो क्या आपने दूसरा लिंक चुना था? –

+5

मेरी माफ़ी, मैं एक लिंक के माध्यम से चला गया जिसमें कहा गया था कि javasecureftpd एसएफटीपी लागू कर रहा था और मैंने सोचा कि यह किया था। वैसे भी, आपको मतलब नहीं होना चाहिए, मैं बस आपकी मदद करने की कोशिश कर रहा था। – pakore

-1

मेरा सुझाव है कि आप Apache Camel पर एक नज़र डालें। यह एफ़टीपी, एफटीपीएस दोनों के साथ-साथ एसएफटीपी

+1

यहां आपके द्वारा लिंक किए गए अपाचे कैमल वेबसाइट से सीधा उद्धरण दिया गया है: "यह घटक एफ़टीपी और एसएफटीपी प्रोटोकॉल पर रिमोट फाइल सिस्टम तक पहुंच प्रदान करता है।" कुंजी बिंदु "दूरस्थ फ़ाइल सिस्टम तक पहुंच" होने के कारण, यह आपको अपने स्वयं के SFTP सर्वर को होस्ट करने की अनुमति नहीं देता है। –

4

कृपया ध्यान दें कि एसएफटीपी एसएसएल पर एफ़टीपी नहीं है, न ही एसएसएच पर एफ़टीपी है। एसएफटीपी सर्वर समर्थन जावा में एसएसएचडी के कार्यान्वयन की आवश्यकता है। आपका सबसे अच्छा शर्त, अपाचे SSHD है

http://mina.apache.org/sshd-project/

मैं SFTP इस्तेमाल कभी नहीं किया है, लेकिन मैंने सुना है यह बुनियादी लेकिन कार्यात्मक है।

+0

अच्छा बिंदु। शब्दावली सीधे भ्रमित है। इतने सारे लोग सोचते हैं कि एसएफटीपी "सुरक्षित एफ़टीपी" या एफ़टीपी का संस्करण है जो एसएसएल या एसएसएच पर चलता है, या कुछ (और यह नहीं है)। काश वे इसे पूरी तरह से अलग कहा जाएगा। – hotshot309

+0

लिंक मृत बीटीडब्ल्यू – Tommy

1

SSHTools (j2ssh) पर एक नज़र डालें। इसमें एक ग्राहक और सर्वर शामिल है।

हालांकि एक निर्देशिका को मतदान करना एक बुरा विचार नहीं है - यह शायद j2ssh का उपयोग करके अपना स्वयं का एसएफटीपी सर्वर स्थापित करने से कहीं अधिक विश्वसनीय है। मैंने जिन अनुप्रयोगों का सामना किया है, उनकी संख्या की गिनती खो गई है जो इस तरह के मतदान करते हैं, और यह आमतौर पर काफी अच्छी तरह से काम करता है।

+0

है, मुझे नहीं पता कि यह अतीत में हुआ था, लेकिन ऐसा लगता है कि अब यह एक (एन ओपन सोर्स) सर्वर पेश नहीं करता है। शायद यह उनकी वाणिज्यिक पेशकश में ले जाया गया है। –

0

मैं jftp से http://j-ftp.sourceforge.net/ निकालने jftp.jar jftp उपयोग कर रहा हूँ -। * Tgz/jftp/जिले केवल समस्या - वे वहाँ जार के अंदर अपाचे वर्गों डाल (तो मैं उन्हें हटाने के लिए आम-httpclient, log4j संकुल मैन्युअल परस्पर विरोधी निर्भरता से बचने के लिए)

+0

नीचे वोट क्यों? –

+1

शायद क्योंकि सवाल एक एसएफटीपी सर्वर के बारे में था, ग्राहक नहीं। – FelixM

1

बस पूर्णता के लिए - हमारे SecureBlackbox (जावा संस्करण) लाइब्रेरी जावा (एंड्रॉइड समेत) में अपना स्वयं का एसएसएच/एसएफटीपी सर्वर बनाने के लिए कक्षाएं प्रदान करता है।

+3

यह वाणिज्यिक है। – Alvins

2

मैं ऊपर के साथ Windows पर MINA 0.10.1 कर की कोशिश की और कुछ मुद्दों पर तय हो गई है, साथ ही मैं बेहतर प्रमाणीकरण और पी के समर्थन (अभी भी उत्पादन प्रयोग के लिए अनुशंसित नहीं) की जरूरत है:

import java.io.File; 
import java.io.ByteArrayOutputStream; 
import java.io.DataOutputStream; 
import java.io.PrintWriter; 

import java.util.Arrays; 
import java.util.Map; 
import java.util.HashMap; 
import java.util.Scanner; 

import java.math.BigInteger; 

import java.security.PublicKey; 
import java.security.interfaces.RSAPublicKey; 
import java.security.interfaces.DSAPublicKey; 

import java.security.KeyFactory; 

import java.security.spec.KeySpec; 
import java.security.spec.DSAPublicKeySpec; 
import java.security.spec.RSAPublicKeySpec; 

import org.apache.sshd.common.NamedFactory; 

import org.apache.sshd.SshServer; 
import org.apache.sshd.server.Command; 
import org.apache.sshd.server.command.ScpCommandFactory; 
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; 
import org.apache.sshd.server.PasswordAuthenticator; 
import org.apache.sshd.server.PublickeyAuthenticator; 
import org.apache.sshd.server.session.ServerSession; 
import org.apache.sshd.server.sftp.SftpSubsystem; 
import org.apache.sshd.server.shell.ProcessShellFactory; 
import org.apache.sshd.server.UserAuth; 
import org.apache.sshd.server.auth.UserAuthPassword; 
import org.apache.sshd.server.auth.UserAuthPublicKey; 

import org.apache.sshd.common.KeyExchange; 
//import org.apache.sshd.server.kex.DHGEX; 
//import org.apache.sshd.server.kex.DHGEX256; 
import org.apache.sshd.server.kex.ECDHP256; 
import org.apache.sshd.server.kex.ECDHP384; 
import org.apache.sshd.server.kex.ECDHP521; 
import org.apache.sshd.server.kex.DHG1; 

import org.apache.mina.util.Base64; 
/* 
javac -classpath .;lib/sshd-core-0.10.1.jar;lib/mina-core-2.0.7.jar;lib/waffle-jna.jar;lib/guava-13.0.1.jar;lib/jna-platform-4.0.0.jar;lib/jna-4.0.0.jar SFTPServer.java 
java -classpath .;lib/sshd-core-0.10.1.jar;lib/slf4j-simple-1.7.6.jar;lib/slf4j-api-1.6.6.jar;lib/mina-core-2.0.7.jar;lib/waffle-jna.jar;lib/guava-13.0.1.jar;lib/jna-platform-4.0.0.jar;lib/jna-4.0.0.jar SFTPServer 
*/ 
public class SFTPServer { 
    public void setupSftpServer() throws Exception { 

    class AuthorizedKeyEntry { 
     private String keyType; 
     private String pubKey; 

     private byte[] bytes; 
     private int pos; 
     private PublicKey key = null; 

     private int decodeInt() { 
     return ((bytes[pos++] & 0xFF) << 24) | ((bytes[pos++] & 0xFF) << 16) 
       | ((bytes[pos++] & 0xFF) << 8) | (bytes[pos++] & 0xFF); 
     } 

     private BigInteger decodeBigInt() { 
     int len = decodeInt(); 
     byte[] bigIntBytes = new byte[len]; 
     System.arraycopy(bytes, pos, bigIntBytes, 0, len); 
     pos += len; 
     return new BigInteger(bigIntBytes); 
     } 

     private void decodeType() { 
     int len = decodeInt(); 
     keyType = new String(bytes, pos, len); 
     pos += len; 
     } 

     public PublicKey getPubKey() { 
     return key; 
     } 

     public void setPubKey(PublicKey key) throws Exception { 
     this.key = key; 
     ByteArrayOutputStream byteOs = new ByteArrayOutputStream(); 
     DataOutputStream dos = new DataOutputStream(byteOs); 
     if (key instanceof RSAPublicKey) { 
      keyType = "ssh-rsa"; 
      dos.writeInt(keyType.getBytes().length); 
      dos.write(keyType.getBytes()); 

      RSAPublicKey rsakey = (RSAPublicKey)key; 
      BigInteger e = rsakey.getPublicExponent(); 
      dos.writeInt(e.toByteArray().length); 
      dos.write(e.toByteArray()); 
      BigInteger m = rsakey.getModulus(); 
      dos.writeInt(m.toByteArray().length); 
      dos.write(m.toByteArray()); 
     } else if (key instanceof DSAPublicKey) { 
      keyType = "ssh-dss"; 
      dos.writeInt(keyType.getBytes().length); 
      dos.write(keyType.getBytes()); 

      DSAPublicKey dsskey = (DSAPublicKey)key; 
      BigInteger p = dsskey.getParams().getP(); 
      dos.writeInt(p.toByteArray().length); 
      dos.write(p.toByteArray()); 
      BigInteger q = dsskey.getParams().getQ(); 
      dos.writeInt(q.toByteArray().length); 
      dos.write(q.toByteArray()); 
      BigInteger g = dsskey.getParams().getG(); 
      dos.writeInt(g.toByteArray().length); 
      dos.write(g.toByteArray()); 
      BigInteger y = dsskey.getY(); 
      dos.writeInt(y.toByteArray().length); 
      dos.write(y.toByteArray()); 
     } else { 
      throw new IllegalArgumentException("unknown key encoding " + key.getAlgorithm()); 
     } 
     bytes = byteOs.toByteArray(); 
     this.pubKey = new String(Base64.encodeBase64(bytes)); 
     } 

     public void setPubKey(String pubKey) throws Exception { 
     this.pubKey = pubKey; 
     bytes = Base64.decodeBase64(pubKey.getBytes()); 
     if (bytes == null) 
      return; 
     decodeType(); 
     if (keyType.equals("ssh-rsa")) { 
      BigInteger e = decodeBigInt(); 
      BigInteger m = decodeBigInt(); 
      KeySpec spec = new RSAPublicKeySpec(m, e); 
      key = KeyFactory.getInstance("RSA").generatePublic(spec); 
     } else if (keyType.equals("ssh-dss")) { 
      BigInteger p = decodeBigInt(); 
      BigInteger q = decodeBigInt(); 
      BigInteger g = decodeBigInt(); 
      BigInteger y = decodeBigInt(); 
      KeySpec spec = new DSAPublicKeySpec(y, p, q, g); 
      key = KeyFactory.getInstance("DSA").generatePublic(spec); 
     } else { 
      throw new IllegalArgumentException("unknown type " + keyType); 
     } 
     } 
    } 

    final SshServer sshd = SshServer.setUpDefaultServer(); 
    final Map<ServerSession, PublicKey> sessionKeys = new HashMap(); 

    class AuthorizedKeys extends HashMap<String,AuthorizedKeyEntry> { 
     private File file; 


     public void load(File file) throws Exception { 
     this.file = file; 
     Scanner scanner = new Scanner(file).useDelimiter("\n"); 
     while (scanner.hasNext()) 
      decodePublicKey(scanner.next()); 
     scanner.close(); 
     } 

     public void save() throws Exception { 
     PrintWriter w = new PrintWriter(file); 
     for (String username : keySet()) { 
      AuthorizedKeyEntry entry = get(username); 
      w.print(entry.keyType + " " + entry.pubKey + " " + username + "\n"); 
     } 
     w.close(); 
     } 

     public void put(String username, PublicKey key) { 
     AuthorizedKeyEntry entry = new AuthorizedKeyEntry(); 
     try { 
      entry.setPubKey(key); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     super.put(username,entry); 
     } 

     private void decodePublicKey(String keyLine) throws Exception { 
     AuthorizedKeyEntry entry = new AuthorizedKeyEntry(); 
     String[] toks = keyLine.split(" "); 
     String username = toks[toks.length-1]; 
     for (String part : toks) { 
      if (part.startsWith("AAAA")) { 
      entry.setPubKey(part); 
      //bytes = Base64.decodeBase64(part.getBytes()); 
      break; 
      } 
     } 
     super.put(username,entry); 
     } 
    }; 

    final AuthorizedKeys authenticUserKeys = new AuthorizedKeys(); // load authorized_keys 
    File file = new File("authorized_keys"); 
    file.createNewFile(); // create if not exists 
    authenticUserKeys.load(file); 


    sshd.setPort(22); 
    sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider("key.ser")); 

    sshd.setShellFactory(new ProcessShellFactory(new String[] { "cmd.exe "})); 

    sshd.setPasswordAuthenticator(new PasswordAuthenticator() { 
     public boolean authenticate(String username, String password, ServerSession session) { 
     boolean authentic = false; 
     try { 
      new waffle.windows.auth.impl.WindowsAuthProviderImpl().logonUser(username,password); 
      authentic = true; 
      //authentic = username != null && username.equals(password+password); // obsecurity :) 
      if (authentic) { 
      PublicKey sessionKey = sessionKeys.get(session); 
      if (sessionKey != null) 
       authenticUserKeys.put(username, sessionKey); //save entry to authorized_keys 
      } 
     } catch (Exception e) { 
      System.err.println(e); 
     } 
     return authentic; 
     } 
    }); 

    sshd.setPublickeyAuthenticator(new PublickeyAuthenticator() { 
     public boolean authenticate(String username, PublicKey key, ServerSession session) { 
     sessionKeys.put(session,key); 
     return key.equals(authenticUserKeys.get(username).getPubKey()); 
     } 
    }); 

    sshd.setUserAuthFactories(Arrays.<NamedFactory<UserAuth>>asList(
     new UserAuthPublicKey.Factory() 
     ,new UserAuthPassword.Factory())); 

    sshd.setCommandFactory(new ScpCommandFactory()); 

    sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(
     new SftpSubsystem.Factory())); 

    //workaround for apache sshd 10.0+ (putty) 
    sshd.setKeyExchangeFactories(Arrays.<NamedFactory<KeyExchange>>asList(
     //new DHGEX256.Factory() 
     //,new DHGEX.Factory() 
     new ECDHP256.Factory() 
     ,new ECDHP384.Factory() 
     ,new ECDHP521.Factory() 
     ,new DHG1.Factory())); 

    Runtime.getRuntime().addShutdownHook(new Thread() { 
     public void run() { 
     try { 
      authenticUserKeys.save(); 
      System.out.println("Stopping"); 
      sshd.stop(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     } 
    }); 

    System.out.println("Starting");  
    try { 
     sshd.start(); 
     Thread.sleep(Long.MAX_VALUE); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    } 

    static public void main(String[] args) throws Exception { 
    new SFTPServer().setupSftpServer(); 
    } 
} 
संबंधित मुद्दे