📄 accoutserverforremote.java
字号:
/**
*
*/
package org.apache.ftpserver;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;
import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ftpserver.ftplet.Component;
import org.apache.ftpserver.ftplet.Configuration;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.User;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.interfaces.IFtpConfig;
import org.apache.ftpserver.usermanager.BaseUser;
import org.apache.ftpserver.util.SocketChannelHelper;
import org.apache.ftpserver.util.XmlUtils;
import org.jdom.Document;
import org.jdom.Element;
/**
* 2006-7-7 10:52:37
*
* @author xudz 为远程机器建立和删除帐号的线程, 此操作为非标准FTP操作
*/
public class AccoutServerForRemote extends Thread {
private IFtpConfig ftpConfig;
private int port = 21210;
private Log m_log;
ServerSocketChannel channelServer;
private boolean isClosed = false;
private final static Random PASS_GEN = new Random(System
.currentTimeMillis());
/**
*
*/
public AccoutServerForRemote(IFtpConfig config) {
super();
this.ftpConfig = config;
}
public void run() {
this.m_log.info("accout thread started!");
try {
channelServer = ServerSocketChannel.open();
ServerSocket socketServer = channelServer.socket();
SocketAddress address = new InetSocketAddress(port);
socketServer.bind(address);
} catch (IOException e) {
m_log.error(e.getMessage());
return;
}
while (true) {
if (isClosed == true)
return;
SocketChannel sock = null;
try {
sock = channelServer.accept();
} catch (IOException e) {
m_log.error(e.getMessage());
}
if (sock != null)
processRequest(sock);
}
}
private void processRequest(SocketChannel sock) {
Document rcvDoc = null;
try {
rcvDoc = this.rcvReqDoc(sock);
} catch (Exception e) {
m_log.error(e.getMessage());
this.closeSockChannel(sock);
return;
}
String busi = rcvDoc.getRootElement().getChildText("busi");
String action = rcvDoc.getRootElement().getChildText("action");
Document sendDoc = null;
try {
XmlUtils.printDocument(rcvDoc,System.out);
if ("ftp.addition".equals(busi) && "add.account".equals(action)) {
sendDoc = this.dealAddAccountReq(rcvDoc);
} else if ("ftp.addition".equals(busi)
&& "delete.account".equals(action)) {
sendDoc = this.dealDeleteAccountReq(rcvDoc);
} else {
m_log.error("busi or action do not recognize!");
this.closeSockChannel(sock);
return;
}
} catch (Exception e2) {
e2.printStackTrace();
this.m_log.error(e2.getMessage());
sendDoc = this.createErrorDoc(e2.getMessage());
}
this.sendBackDoc(sock, sendDoc);
}
private Document dealAddAccountReq(Document rcvDoc) throws FtpException {
UserManager userMan = this.ftpConfig.getUserManager();
Element root = rcvDoc.getRootElement();
Element parEle = root.getChild("parentAccount");
String parName = parEle.getChildText("name");
String parPass = parEle.getChildText("pass");
boolean isAuth = false;
if (!"anonymous".equals(parName) && userMan.doesExist(parName))
isAuth = userMan.authenticate(parName, parPass);
if (isAuth == false)
return this.createErrorDoc("authenticate error!");
Element newAccEle = root.getChild("newAccount");
String newAccName = newAccEle.getChildText("name");
String newAccDir = newAccEle.getChildText("rootDirName");
if (userMan.doesExist(newAccName))
return this
.createErrorDoc("Already exist login name:" + newAccName);
User parUser = userMan.getUserByName(parName);
File uploadFile = new File(parUser.getHomeDirectory(), "upload");
File newUserHomeDir = new File(uploadFile, newAccDir);
if (!newUserHomeDir.exists())
newUserHomeDir.mkdirs();
String password = this.generatePassword();
BaseUser newUser = new BaseUser();
newUser.setName(newAccName);
newUser.setHomeDirectory(newUserHomeDir.getAbsolutePath());
newUser.setPassword(password);
newUser.setEnabled(parUser.getEnabled());
newUser.setMaxDownloadRate(parUser.getMaxDownloadRate());
newUser.setMaxIdleTime(parUser.getMaxIdleTime());
newUser.setMaxUploadRate(parUser.getMaxUploadRate());
newUser.setWritePermission(parUser.getWritePermission());
userMan.save(newUser);
Document rtnDoc = this.createSuccDoc("add new Account successfully!");
Element rtnAccountEle = new Element("account");
rtnAccountEle.getChildren()
.add(new Element("name").setText(newAccName));
rtnAccountEle.getChildren().add(new Element("pass").setText(password));
rtnDoc.getRootElement().getChildren().add(rtnAccountEle);
StringBuffer sb = new StringBuffer("new Accout Created,name:");
sb.append(newAccName);
sb.append(",pass:");
sb.append(password);
m_log.info(sb.toString());
return rtnDoc;
}
private Document dealDeleteAccountReq(Document rcvDoc) throws FtpException{
UserManager userMan = this.ftpConfig.getUserManager();
Element root = rcvDoc.getRootElement();
Element parEle = root.getChild("parentAccount");
String parName = parEle.getChildText("name");
String parPass = parEle.getChildText("pass");
boolean isAuth = false;
if (!"anonymous".equals(parName) && userMan.doesExist(parName))
isAuth = userMan.authenticate(parName, parPass);
if (isAuth == false)
return this.createErrorDoc("authenticate error!");
Element discardEle = root.getChild("discardAccount");
String discardAccName = discardEle.getChildText("name");
if (!userMan.doesExist(discardAccName))
return this
.createErrorDoc("no login name exist:" + discardAccName);
userMan.delete(discardAccName);
Document rtnDoc = this.createSuccDoc("delete Account successfully!");
Element rtnAccountEle = new Element("account");
rtnAccountEle.getChildren()
.add(new Element("name").setText(discardAccName));
rtnDoc.getRootElement().getChildren().add(rtnAccountEle);
m_log.info("succeed to delete accout,name :" + discardAccName);
return rtnDoc;
}
private void sendBackDoc(SocketChannel sock, Document doc) {
SocketChannelHelper sockHelper = SocketChannelHelper.getInstance();
ByteBuffer buff = null;
try {
buff = this.getSendBuffer(doc);
sockHelper.sendData(sock, buff, 6000);
} catch (Exception e) {
e.printStackTrace();
this.m_log.error(e.getMessage());
} finally {
this.closeSockChannel(sock);
}
}
private ByteBuffer getSendBuffer(Document doc) throws IOException {
byte[] xmlByte = null;
try {
xmlByte = XmlUtils.transferDocToByte(doc);
} catch (IOException e) {
throw new IOException("xml转换成Byte失败");
}
byte[] head = getHeadByte(xmlByte.length, 6);
String headStr = "rt" + new String(head);
byte[] headByte = headStr.getBytes();
ByteBuffer buff = ByteBuffer.allocate(xmlByte.length + headByte.length);
buff.clear();
buff.put(headByte);
buff.put(xmlByte);
buff.flip();
return buff;
}
/**
* 根据传递的参数生成固定包头的byte
*
* @param dataLen
* byte数组的长度
* @param size
* 固定包头长度
* @return 以十六进制表示的dataLen的byte数组
*/
private byte[] getHeadByte(int dataLen, int size) {
byte[] buffer = new byte[size];
Arrays.fill(buffer, 0, buffer.length, (byte) '0');
byte[] lenByte = (Integer.toString(dataLen, 16)).getBytes();
System.arraycopy(lenByte, 0, buffer, size - lenByte.length,
lenByte.length);
return buffer;
}
private Document createErrorDoc(String errMsg) {
Element root = new Element("result");
Document doc = new Document(root);
root.getChildren().add(new Element("success").setText("false"));
root.getChildren().add(new Element("msg").setText(errMsg));
return doc;
}
private Document createSuccDoc(String msg) {
Element root = new Element("result");
Document doc = new Document(root);
root.getChildren().add(new Element("success").setText("true"));
root.getChildren().add(new Element("msg").setText(msg));
return doc;
}
/**
*
* @param sock
* @return
* @throws Exception
*/
private Document rcvReqDoc(SocketChannel sock) throws Exception {
SocketChannelHelper sockHelper = SocketChannelHelper.getInstance();
ByteBuffer buffer = ByteBuffer.allocate(8);
buffer = sockHelper.readFixPackage(sock, 8, 4000, buffer);
byte[] head = new byte[8];
buffer.get(head);
int xmlLen = this.getRcvXmlLen(head);
ByteBuffer xmlBuffer = ByteBuffer.allocate(xmlLen);
xmlBuffer = sockHelper.readFixPackage(sock, xmlLen, 5000, xmlBuffer);
byte[] xml = new byte[xmlLen];
xmlBuffer.get(xml);
Document rcvDoc = XmlUtils.getDocFromByte(xml);
return rcvDoc;
}
/**
* 根据接收到head字节串,计算出即将接收的xml的字节串长度
*
* @param head
* @return 返回接收到的xml数据的长度
*/
private int getRcvXmlLen(byte[] head) {
int size = 0;
String str = new String(head).substring(2);
size = Integer.parseInt(str, 16);
return size;
}
/**
* Generate random password.
*/
private String generatePassword() {
StringBuffer sb = new StringBuffer(8);
for (int i = 0; i < 8; i++) {
int charType = PASS_GEN.nextInt(3);
switch (charType) {
// number
case 0:
sb.append((char) ('0' + PASS_GEN.nextInt(10)));
break;
// uppercase character
case 1:
sb.append((char) ('A' + PASS_GEN.nextInt(26)));
break;
// lowercase character
case 2:
sb.append((char) ('a' + PASS_GEN.nextInt(26)));
break;
}
}
String password = sb.toString();
return password;
}
private void closeSockChannel(SocketChannel sockChan) {
try {
sockChan.close();
} catch (IOException e) {
this.m_log.error(e.getMessage());
}
}
/**
*
* @override
*/
public void setLogFactory(LogFactory logFact) {
m_log = logFact.getInstance(getClass());
}
/**
*
* @override
*/
public void configure(Configuration config) throws FtpException {
}
/**
*
* @override
*/
public void closeSocket() {
this.isClosed = true;
try {
this.channelServer.close();
} catch (IOException e) {
this.m_log.error(e.getMessage());
}
this.m_log.info("account thread stoped!");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -