├── .gitignore ├── src └── main │ ├── java │ └── com │ │ ├── mxgraph │ │ └── examples │ │ │ └── swing │ │ │ ├── bell.png │ │ │ ├── FixedPoints.java │ │ │ ├── editor │ │ │ ├── EditorKeyboardHandler.java │ │ │ ├── EditorPopupMenu.java │ │ │ ├── ShadowBorder.java │ │ │ ├── DefaultFileFilter.java │ │ │ └── EditorAboutFrame.java │ │ │ ├── CustomCanvas.java │ │ │ ├── Validation.java │ │ │ └── shapes.xml │ │ └── sensepost │ │ └── mallet │ │ ├── graph │ │ ├── Vertex.java │ │ ├── IndeterminateChannelHandler.java │ │ ├── GraphLookup.java │ │ ├── ConnectionNumberChannelHandler.java │ │ ├── GraphNode.java │ │ ├── Listener.java │ │ └── TargetSpecificChannelHandler.java │ │ ├── ChannelAttributes.java │ │ ├── ConnectRequest.java │ │ ├── SocksInitializer.java │ │ ├── ConnectTargetHandler.java │ │ ├── swing │ │ ├── editors │ │ │ ├── ObjectEditor.java │ │ │ ├── EditorController.java │ │ │ ├── ToStringEditor.java │ │ │ ├── ByteBufEditor.java │ │ │ ├── StringEditor.java │ │ │ ├── HttpMessageEditor.java │ │ │ └── ByteArrayEditor.java │ │ ├── DateRenderer.java │ │ ├── ConnectionData.java │ │ ├── CustomCellEditor.java │ │ ├── AutoEditor.java │ │ ├── InterceptFrame.java │ │ └── ConnectionPanel.java │ │ ├── ssl │ │ ├── SingleX509KeyManager.java │ │ ├── KeystoreUtils.java │ │ └── CertificateUtils.java │ │ ├── ScriptHandler.java │ │ ├── InterceptController.java │ │ ├── SocksServerHandler.java │ │ ├── RelayHandler.java │ │ ├── Main.java │ │ └── SocksServerConnectHandler.java │ └── resources │ └── com │ ├── mxgraph │ └── examples │ │ └── swing │ │ ├── images │ │ ├── box.png │ │ ├── cut.gif │ │ ├── fit.gif │ │ ├── new.gif │ │ ├── pan.gif │ │ ├── top.gif │ │ ├── up.gif │ │ ├── actor.png │ │ ├── arrow.gif │ │ ├── arrow.png │ │ ├── bell.png │ │ ├── bold.gif │ │ ├── cloud.png │ │ ├── copy.gif │ │ ├── down.gif │ │ ├── dude3.png │ │ ├── earth.png │ │ ├── error.png │ │ ├── event.png │ │ ├── font.gif │ │ ├── fork.png │ │ ├── gear.png │ │ ├── group.gif │ │ ├── hline.png │ │ ├── house.gif │ │ ├── house.png │ │ ├── image.gif │ │ ├── left.gif │ │ ├── link.png │ │ ├── merge.png │ │ ├── open.gif │ │ ├── paste.gif │ │ ├── plain.gif │ │ ├── print.gif │ │ ├── redo.gif │ │ ├── right.gif │ │ ├── rule.png │ │ ├── save.gif │ │ ├── timer.png │ │ ├── tree.gif │ │ ├── undo.gif │ │ ├── zoom.gif │ │ ├── aligntop.gif │ │ ├── bottom.gif │ │ ├── center.gif │ │ ├── collapse.gif │ │ ├── connect.gif │ │ ├── connect.png │ │ ├── cylinder.png │ │ ├── delete.gif │ │ ├── diagram.gif │ │ ├── ellipse.png │ │ ├── entity.gif │ │ ├── entity.png │ │ ├── expand.gif │ │ ├── hexagon.png │ │ ├── italic.gif │ │ ├── maximize.gif │ │ ├── message.png │ │ ├── middle.gif │ │ ├── minimize.gif │ │ ├── multiple.png │ │ ├── open_end.gif │ │ ├── outline.gif │ │ ├── oval_end.gif │ │ ├── package.png │ │ ├── preview.gif │ │ ├── printer.png │ │ ├── resize.gif │ │ ├── rhombus.png │ │ ├── rounded.png │ │ ├── saveas.gif │ │ ├── select.gif │ │ ├── server.png │ │ ├── straight.gif │ │ ├── straight.png │ │ ├── swimlane.png │ │ ├── toback.gif │ │ ├── tofront.gif │ │ ├── triangle.png │ │ ├── ungroup.gif │ │ ├── vertical.gif │ │ ├── vertical.png │ │ ├── wrench.png │ │ ├── zoomin.gif │ │ ├── zoomout.gif │ │ ├── alignleft.gif │ │ ├── alignright.gif │ │ ├── block_end.gif │ │ ├── cancel_end.png │ │ ├── connector.gif │ │ ├── cube_green.png │ │ ├── event_end.png │ │ ├── fillcolor.gif │ │ ├── fontcolor.gif │ │ ├── inclusive.png │ │ ├── linecolor.gif │ │ ├── open_start.gif │ │ ├── oval_start.gif │ │ ├── pagesetup.gif │ │ ├── rectangle.png │ │ ├── terminate.png │ │ ├── workplace.png │ │ ├── zoomactual.gif │ │ ├── alignbottom.gif │ │ ├── aligncenter.gif │ │ ├── alignmiddle.gif │ │ ├── block_start.gif │ │ ├── classic_end.gif │ │ ├── classic_start.gif │ │ ├── diamond_end.gif │ │ ├── diamond_start.gif │ │ ├── doubleellipse.png │ │ ├── message_end.png │ │ ├── preferences.gif │ │ ├── doublerectangle.png │ │ ├── event_intermediate.png │ │ ├── cancel_intermediate.png │ │ └── message_intermediate.png │ │ └── resources │ │ ├── editor_de.properties │ │ ├── editor_es.properties │ │ ├── editor_fr.properties │ │ ├── editor_it.properties │ │ ├── editor_nl.properties │ │ ├── editor_pt.properties │ │ ├── editor_zh-CN.properties │ │ ├── editor_ja.properties │ │ ├── basic-style.xml │ │ ├── default-style.xml │ │ ├── editor.properties │ │ └── editor_ru.properties │ └── sensepost │ └── mallet │ └── script.groovy ├── http.mxe ├── graph.mxe └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | /target/ 3 | ca.p12 4 | ca.pem 5 | keystore.jks 6 | -------------------------------------------------------------------------------- /src/main/java/com/mxgraph/examples/swing/bell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/java/com/mxgraph/examples/swing/bell.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/box.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/cut.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/cut.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/fit.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/fit.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/new.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/new.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/pan.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/pan.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/top.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/top.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/up.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/up.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/actor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/actor.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/arrow.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/arrow.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/arrow.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/bell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/bell.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/bold.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/bold.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/cloud.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/copy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/copy.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/down.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/down.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/dude3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/dude3.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/earth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/earth.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/error.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/event.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/event.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/font.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/font.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/fork.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/gear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/gear.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/group.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/group.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/hline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/hline.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/house.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/house.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/house.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/house.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/image.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/image.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/left.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/left.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/link.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/merge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/merge.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/open.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/open.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/paste.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/paste.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/plain.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/plain.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/print.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/print.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/redo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/redo.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/right.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/right.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/rule.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/save.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/save.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/timer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/timer.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/tree.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/tree.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/undo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/undo.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/zoom.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/zoom.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/aligntop.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/aligntop.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/bottom.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/bottom.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/center.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/center.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/collapse.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/collapse.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/connect.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/connect.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/connect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/connect.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/cylinder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/cylinder.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/delete.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/delete.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/diagram.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/diagram.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/ellipse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/ellipse.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/entity.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/entity.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/entity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/entity.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/expand.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/expand.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/hexagon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/hexagon.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/italic.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/italic.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/maximize.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/maximize.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/message.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/middle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/middle.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/minimize.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/minimize.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/multiple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/multiple.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/open_end.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/open_end.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/outline.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/outline.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/oval_end.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/oval_end.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/package.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/preview.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/printer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/printer.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/resize.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/resize.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/rhombus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/rhombus.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/rounded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/rounded.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/saveas.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/saveas.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/select.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/select.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/server.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/straight.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/straight.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/straight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/straight.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/swimlane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/swimlane.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/toback.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/toback.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/tofront.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/tofront.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/triangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/triangle.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/ungroup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/ungroup.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/vertical.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/vertical.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/vertical.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/wrench.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/wrench.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/zoomin.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/zoomin.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/zoomout.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/zoomout.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/alignleft.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/alignleft.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/alignright.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/alignright.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/block_end.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/block_end.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/cancel_end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/cancel_end.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/connector.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/connector.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/cube_green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/cube_green.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/event_end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/event_end.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/fillcolor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/fillcolor.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/fontcolor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/fontcolor.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/inclusive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/inclusive.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/linecolor.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/linecolor.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/open_start.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/open_start.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/oval_start.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/oval_start.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/pagesetup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/pagesetup.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/rectangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/rectangle.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/terminate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/terminate.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/workplace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/workplace.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/zoomactual.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/zoomactual.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/alignbottom.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/alignbottom.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/aligncenter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/aligncenter.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/alignmiddle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/alignmiddle.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/block_start.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/block_start.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/classic_end.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/classic_end.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/classic_start.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/classic_start.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/diamond_end.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/diamond_end.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/diamond_start.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/diamond_start.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/doubleellipse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/doubleellipse.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/message_end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/message_end.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/preferences.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/preferences.gif -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/doublerectangle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/doublerectangle.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/event_intermediate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/event_intermediate.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/cancel_intermediate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/cancel_intermediate.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/images/message_intermediate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/images/message_intermediate.png -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/resources/editor_de.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/resources/editor_de.properties -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/resources/editor_es.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/resources/editor_es.properties -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/resources/editor_fr.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/resources/editor_fr.properties -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/resources/editor_it.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/resources/editor_it.properties -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/resources/editor_nl.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/resources/editor_nl.properties -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/resources/editor_pt.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RoganDawes/mallet/HEAD/src/main/resources/com/mxgraph/examples/swing/resources/editor_pt.properties -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/graph/Vertex.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.graph; 2 | 3 | import io.netty.channel.ChannelHandler; 4 | 5 | public interface Vertex { 6 | 7 | String getVertexDescription(); 8 | 9 | ChannelHandler[] getChannelHandlers(); 10 | 11 | int getOutboundEdgeCount(); 12 | 13 | String getOutboundEdgeDescription(int n); 14 | 15 | Vertex getOutboundVertex(int n); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/graph/IndeterminateChannelHandler.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.graph; 2 | 3 | import io.netty.channel.ChannelHandler; 4 | import io.netty.channel.ChannelHandlerContext; 5 | 6 | public interface IndeterminateChannelHandler extends ChannelHandler { 7 | 8 | void setOutboundOptions(String[] options); 9 | 10 | String[] getOutboundOptions(); 11 | 12 | void optionSelected(ChannelHandlerContext ctx, String option) throws Exception; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/graph/GraphLookup.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.graph; 2 | 3 | import java.net.SocketAddress; 4 | 5 | import io.netty.channel.ChannelHandler; 6 | 7 | public interface GraphLookup { 8 | 9 | void startServers() throws Exception; 10 | 11 | ChannelHandler[] getNextHandlers(ChannelHandler handler, String option); 12 | 13 | ChannelHandler[] getClientChannelInitializer(ChannelHandler handler); 14 | 15 | ChannelHandler[] getProxyInitializer(ChannelHandler handler, SocketAddress target); 16 | 17 | void shutdownServers() throws Exception; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/ChannelAttributes.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet; 2 | 3 | import com.sensepost.mallet.graph.GraphLookup; 4 | 5 | import io.netty.channel.Channel; 6 | import io.netty.util.AttributeKey; 7 | 8 | public class ChannelAttributes { 9 | 10 | public static final AttributeKey CHANNEL = AttributeKey.valueOf("channel"); 11 | 12 | public static final AttributeKey TARGET = AttributeKey.valueOf("target"); 13 | 14 | public static final AttributeKey GRAPH = AttributeKey.valueOf("graph"); 15 | 16 | public static final AttributeKey CONNECTION_IDENTIFIER = AttributeKey.valueOf("connection_identifier"); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/graph/ConnectionNumberChannelHandler.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.graph; 2 | 3 | import java.util.concurrent.atomic.AtomicInteger; 4 | 5 | import com.sensepost.mallet.ChannelAttributes; 6 | 7 | import io.netty.channel.ChannelHandlerAdapter; 8 | import io.netty.channel.ChannelHandlerContext; 9 | 10 | public class ConnectionNumberChannelHandler extends ChannelHandlerAdapter { 11 | 12 | private static AtomicInteger counter = new AtomicInteger(0); 13 | 14 | @Override 15 | public void handlerAdded(ChannelHandlerContext ctx) throws Exception { 16 | ctx.channel().attr(ChannelAttributes.CONNECTION_IDENTIFIER).set(counter.incrementAndGet()); 17 | ctx.pipeline().remove(this); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/graph/GraphNode.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.graph; 2 | 3 | import java.io.Serializable; 4 | import java.util.Arrays; 5 | 6 | public class GraphNode implements Serializable { 7 | 8 | private String className; 9 | private String[] arguments; 10 | public String getClassName() { 11 | return className; 12 | } 13 | public void setClassName(String className) { 14 | this.className = className; 15 | } 16 | public String[] getArguments() { 17 | return arguments; 18 | } 19 | public void setArguments(String[] arguments) { 20 | this.arguments = arguments; 21 | } 22 | 23 | @Override 24 | public String toString() { 25 | return className; // + (arguments == null ? "" : "\n" + Arrays.asList(arguments)); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/ConnectRequest.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet; 2 | 3 | import java.net.SocketAddress; 4 | 5 | import io.netty.channel.Channel; 6 | import io.netty.util.concurrent.Promise; 7 | 8 | public class ConnectRequest { 9 | 10 | private SocketAddress target; 11 | 12 | private Promise connectPromise; 13 | 14 | public ConnectRequest(SocketAddress target, Promise connectPromise) { 15 | this.target = target; 16 | this.connectPromise = connectPromise; 17 | } 18 | 19 | public SocketAddress getTarget() { 20 | return target; 21 | } 22 | 23 | public Promise getConnectPromise() { 24 | return connectPromise; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return "Connect " + target; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/SocksInitializer.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet; 2 | 3 | import io.netty.channel.Channel; 4 | import io.netty.channel.ChannelInitializer; 5 | import io.netty.channel.ChannelPipeline; 6 | import io.netty.handler.codec.socksx.SocksPortUnificationServerHandler; 7 | 8 | public class SocksInitializer extends ChannelInitializer { 9 | 10 | @Override 11 | protected void initChannel(Channel ch) throws Exception { 12 | ChannelPipeline p = ch.pipeline(); 13 | String baseName = p.context(this).name(); 14 | p.addAfter(baseName, null, new ConnectTargetHandler()); 15 | p.addAfter(baseName, null, new SocksServerConnectHandler()); 16 | p.addAfter(baseName, null, new SocksServerHandler()); 17 | p.addAfter(baseName, null, new SocksPortUnificationServerHandler()); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/graph/Listener.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.graph; 2 | 3 | import io.netty.channel.EventLoopGroup; 4 | import io.netty.channel.ServerChannel; 5 | 6 | public class Listener { 7 | 8 | private EventLoopGroup boss, workerGroup; 9 | private Class serverClass; 10 | private String inetHost; 11 | private int inetPort; 12 | 13 | public Listener(EventLoopGroup boss, EventLoopGroup workerGroup, Class serverClass, String inetHost, int inetPort) { 14 | this.boss = boss; 15 | this.workerGroup = workerGroup; 16 | this.serverClass = serverClass; 17 | this.inetHost = inetHost; 18 | this.inetPort = inetPort; 19 | } 20 | 21 | public EventLoopGroup getBoss() { 22 | return boss; 23 | } 24 | 25 | public EventLoopGroup getWorkerGroup() { 26 | return workerGroup; 27 | } 28 | 29 | public Class getServerClass() { 30 | return serverClass; 31 | } 32 | 33 | public String getInetHost() { 34 | return inetHost; 35 | } 36 | 37 | public int getInetPort() { 38 | return inetPort; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/ConnectTargetHandler.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | import io.netty.channel.ChannelInboundHandlerAdapter; 5 | 6 | /** 7 | * Handler to receive a Socks ConnectRequest, and save the requested address as 8 | * a Channel Attribute. 9 | * 10 | * It confirms that the connection has been successfully made, even though no 11 | * such thing has happened. This is done in order to allow data to be read from 12 | * the client. Care should be taken to address the case where the client waits 13 | * for the server to write data first, though. 14 | * 15 | * Subsequent handlers must retrieve the TARGET Channel Attribute, and make the 16 | * outbound connection accordingly, before any data can be written. 17 | * 18 | * @author rogan 19 | * 20 | */ 21 | public class ConnectTargetHandler extends ChannelInboundHandlerAdapter { 22 | 23 | @Override 24 | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { 25 | if (evt instanceof ConnectRequest) { 26 | ConnectRequest cr = (ConnectRequest) evt; 27 | ctx.channel().attr(ChannelAttributes.TARGET).set(cr); 28 | if (!cr.getConnectPromise().isDone()) 29 | cr.getConnectPromise().setSuccess(ctx.channel()); 30 | ctx.pipeline().remove(this); 31 | } 32 | super.userEventTriggered(ctx, evt); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/swing/editors/ObjectEditor.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.swing.editors; 2 | 3 | import javax.swing.JComponent; 4 | 5 | public interface ObjectEditor { 6 | 7 | /** 8 | * returns the user interface component of this editor; 9 | * 10 | * @return 11 | */ 12 | JComponent getEditorComponent(); 13 | 14 | /** 15 | * the description of this editor, when added to the user interface 16 | * 17 | * @return 18 | */ 19 | String getEditorName(); 20 | 21 | /** 22 | * the list of classes that this editor is capable of editing 23 | * 24 | * It is probably best to list only concrete classes here, rather than 25 | * interfaces, as the editor will be expected to replace the original object 26 | * with one of the same type in the event of any changes. That is, unless 27 | * the editor is read-only 28 | * 29 | * @return 30 | */ 31 | Class[] getSupportedClasses(); 32 | 33 | /** 34 | * Sets the editor controller for this editor. The controller supports 35 | * PropertyChange events when the object being edited changes. Editors 36 | * should add a propertychange listener to receive these events, and update 37 | * itself accordingly. 38 | * 39 | * Editors are encouraged to update their state lazily, i.e. only if the 40 | * editor component is visible, in order to minimize any performance impact 41 | * 42 | * @param controller 43 | */ 44 | void setEditorController(EditorController controller); 45 | } 46 | -------------------------------------------------------------------------------- /src/main/resources/com/sensepost/mallet/script.groovy: -------------------------------------------------------------------------------- 1 | import java.awt.*; 2 | import java.awt.image.*; 3 | import java.awt.geom.*; 4 | import javax.imageio.ImageIO; 5 | import io.netty.handler.codec.http.*; 6 | import io.netty.buffer.*; 7 | import io.netty.channel.*; 8 | 9 | return new ChannelDuplexHandler() { 10 | public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception { 11 | if (FullHttpRequest.class.isAssignableFrom(msg.getClass())) { 12 | msg.headers().set("if-modified-since", "-1"); 13 | msg.headers().get("if-range"); 14 | msg.headers().get("range"); 15 | } else if (FullHttpResponse.class.isAssignableFrom(object.getClass())) { 16 | ct = msg.headers().get(HttpHeaderNames.CONTENT_TYPE); 17 | if ("image/jpeg".equals(ct)) { 18 | msg = msg.copy(); 19 | bb = msg.content(); 20 | if (bb != null && bb.readableBytes() > 0) { 21 | bytes = new byte[bb.readableBytes()]; 22 | bb.readBytes(bytes); 23 | bais = new ByteArrayInputStream(bytes); 24 | bi = ImageIO.read(bais); 25 | 26 | flipped = new BufferedImage(bi.getWidth(),bi.getHeight(),bi.getType()); 27 | tran = AffineTransform.getTranslateInstance(0, bi.getHeight()); 28 | flip = AffineTransform.getScaleInstance(1d, -1d); 29 | tran.concatenate(flip); 30 | g = flipped.createGraphics(); 31 | g.setTransform(tran); 32 | g.drawImage(bi, 0, 0, null); 33 | g.dispose(); 34 | 35 | baos = new ByteArrayOutputStream(); 36 | ImageIO.write(flipped, "jpg", baos); 37 | newcontent = Unpooled.wrappedBuffer(baos.toByteArray()); 38 | msg.replace(newcontent); 39 | msg.headers().setHeader("Content-Length", newContent.readableBytes()); 40 | } 41 | } 42 | } 43 | ctx.fireChannelRead(msg); 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/swing/editors/EditorController.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.swing.editors; 2 | 3 | import java.beans.PropertyChangeListener; 4 | import java.beans.PropertyChangeSupport; 5 | 6 | public class EditorController { 7 | 8 | public static final String OBJECT = "object"; 9 | public static final String READ_ONLY = "readOnly"; 10 | 11 | private PropertyChangeSupport pcs = new PropertyChangeSupport(this); 12 | private Object object; 13 | private boolean readOnly; 14 | 15 | public void addPropertyChangeListener(PropertyChangeListener listener) { 16 | pcs.addPropertyChangeListener(listener); 17 | } 18 | 19 | public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { 20 | pcs.addPropertyChangeListener(propertyName, listener); 21 | } 22 | 23 | public void removePropertyChangeListener(PropertyChangeListener listener) { 24 | pcs.removePropertyChangeListener(listener); 25 | } 26 | 27 | public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { 28 | pcs.removePropertyChangeListener(propertyName, listener); 29 | } 30 | 31 | public Object getObject() { 32 | return object; 33 | } 34 | 35 | public void setObject(Object object) { 36 | Object old = this.getObject(); 37 | this.object = object; 38 | pcs.firePropertyChange(OBJECT, old, this.object); 39 | } 40 | 41 | public boolean isReadOnly() { 42 | return readOnly; 43 | } 44 | 45 | public void setReadOnly(boolean readOnly) { 46 | boolean old = this.readOnly; 47 | this.readOnly = readOnly; 48 | pcs.firePropertyChange(READ_ONLY, old, this.readOnly); 49 | } 50 | 51 | protected void dispose() { 52 | PropertyChangeListener[] listeners = pcs.getPropertyChangeListeners(); 53 | for (PropertyChangeListener l : listeners) { 54 | pcs.removePropertyChangeListener(l); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/mxgraph/examples/swing/FixedPoints.java: -------------------------------------------------------------------------------- 1 | package com.mxgraph.examples.swing; 2 | 3 | import javax.swing.JFrame; 4 | 5 | import com.mxgraph.swing.mxGraphComponent; 6 | import com.mxgraph.view.mxGraph; 7 | 8 | public class FixedPoints extends JFrame 9 | { 10 | 11 | /** 12 | * 13 | */ 14 | private static final long serialVersionUID = -2707712944901661771L; 15 | 16 | @SuppressWarnings("unused") 17 | public FixedPoints() 18 | { 19 | super("Hello, World!"); 20 | 21 | mxGraph graph = new mxGraph(); 22 | Object parent = graph.getDefaultParent(); 23 | 24 | graph.getModel().beginUpdate(); 25 | try 26 | { 27 | Object v1 = graph.insertVertex(parent, null, "Hello,", 20, 20, 80, 28 | 60, "shape=triangle;perimeter=trianglePerimeter"); 29 | Object v2 = graph.insertVertex(parent, null, "World!", 200, 150, 30 | 80, 60, "shape=ellipse;perimeter=ellipsePerimeter"); 31 | Object v3 = graph.insertVertex(parent, null, "Hello,", 200, 20, 80, 32 | 30); 33 | Object e1 = graph 34 | .insertEdge( 35 | parent, 36 | null, 37 | "", 38 | v1, 39 | v2, 40 | "edgeStyle=elbowEdgeStyle;elbow=horizontal;" 41 | + "exitX=0.5;exitY=1;exitPerimeter=1;entryX=0;entryY=0;entryPerimeter=1;"); 42 | Object e2 = graph.insertEdge(parent, null, "", v3, v2, 43 | "edgeStyle=elbowEdgeStyle;elbow=horizontal;orthogonal=0;" 44 | + "entryX=0;entryY=0;entryPerimeter=1;"); 45 | } 46 | finally 47 | { 48 | graph.getModel().endUpdate(); 49 | } 50 | 51 | mxGraphComponent graphComponent = new mxGraphComponent(graph); 52 | getContentPane().add(graphComponent); 53 | } 54 | 55 | public static void main(String[] args) 56 | { 57 | FixedPoints frame = new FixedPoints(); 58 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 59 | frame.setSize(400, 320); 60 | frame.setVisible(true); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/swing/DateRenderer.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.swing; 2 | 3 | import java.awt.Component; 4 | import java.awt.FontMetrics; 5 | import java.text.SimpleDateFormat; 6 | import java.util.Date; 7 | 8 | import javax.swing.JTable; 9 | import javax.swing.table.DefaultTableCellRenderer; 10 | 11 | public class DateRenderer extends DefaultTableCellRenderer { 12 | 13 | private static final long serialVersionUID = 4146923038862167831L; 14 | private static SimpleDateFormat[] formats = new SimpleDateFormat[] { new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.S"), 15 | new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"), new SimpleDateFormat("MM/dd HH:mm:ss"), 16 | new SimpleDateFormat("HH:mm:ss"), new SimpleDateFormat(":mm:ss") }; 17 | 18 | private boolean relative = false; 19 | 20 | public DateRenderer() { 21 | this(true); 22 | } 23 | 24 | public DateRenderer(boolean relative) { 25 | this.relative = relative; 26 | } 27 | 28 | public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, 29 | int row, int column) { 30 | super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 31 | if (value instanceof Date) { 32 | Date date = (Date) value; 33 | FontMetrics fm = getFontMetrics(getFont()); 34 | int i = 0; 35 | String text; 36 | int textWidth; 37 | int targetWidth = table.getColumnModel().getColumn(column).getWidth() - 4; 38 | if (!relative || row == 0) { 39 | do { 40 | text = formats[i++].format(date); 41 | textWidth = fm.stringWidth(text); 42 | } while (textWidth > targetWidth && i < formats.length); 43 | } else { 44 | Date base = (Date) table.getValueAt(0, column); 45 | float r = date.getTime() - base.getTime(); 46 | text = String.format("+%.3f", r/1000) + "s"; 47 | } 48 | setText(text); 49 | } 50 | return this; 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/ssl/SingleX509KeyManager.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.ssl; 2 | 3 | import java.net.Socket; 4 | import java.security.Principal; 5 | import java.security.PrivateKey; 6 | import java.security.cert.X509Certificate; 7 | 8 | import javax.net.ssl.SSLEngine; 9 | import javax.net.ssl.X509ExtendedKeyManager; 10 | 11 | public class SingleX509KeyManager extends X509ExtendedKeyManager { 12 | 13 | private String alias; 14 | 15 | private PrivateKey pk; 16 | 17 | private X509Certificate[] certs; 18 | 19 | public SingleX509KeyManager(String alias, PrivateKey pk, 20 | X509Certificate[] certs) { 21 | this.alias = alias; 22 | this.pk = pk; 23 | this.certs = copy(certs); 24 | } 25 | 26 | 27 | @Override 28 | public String chooseEngineClientAlias(String[] paramArrayOfString, 29 | Principal[] paramArrayOfPrincipal, SSLEngine paramSSLEngine) { 30 | return alias; 31 | } 32 | 33 | 34 | @Override 35 | public String chooseEngineServerAlias(String paramString, 36 | Principal[] paramArrayOfPrincipal, SSLEngine paramSSLEngine) { 37 | return alias; 38 | } 39 | 40 | 41 | public String chooseClientAlias(String[] keyType, Principal[] issuers, 42 | Socket socket) { 43 | return alias; 44 | } 45 | 46 | public String chooseServerAlias(String keyType, Principal[] issuers, 47 | Socket socket) { 48 | return alias; 49 | } 50 | 51 | public X509Certificate[] getCertificateChain(String alias) { 52 | return copy(certs); 53 | } 54 | 55 | public String[] getClientAliases(String keyType, Principal[] issuers) { 56 | return new String[] {alias}; 57 | } 58 | 59 | public PrivateKey getPrivateKey(String alias) { 60 | return pk; 61 | } 62 | 63 | public String[] getServerAliases(String keyType, Principal[] issuers) { 64 | return new String[] { alias }; 65 | } 66 | 67 | private X509Certificate[] copy(X509Certificate[] certs) { 68 | if (certs == null) 69 | return null; 70 | X509Certificate[] copy = new X509Certificate[certs.length]; 71 | System.arraycopy(certs, 0, copy, 0, certs.length); 72 | return copy; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/resources/editor_zh-CN.properties: -------------------------------------------------------------------------------- 1 | file=\u6587\u4ef6 2 | new=\u65b0\u5efa 3 | openFile=\u6253\u5f00\u6587\u4ef6 4 | save=\u4fdd\u5b58 5 | saveAs=\u53e6\u5b58\u4e3a 6 | print=\u6253\u5370 7 | edit=\u7f16\u8f91 8 | undo=\u53d6\u6d88\u64cd\u4f5c 9 | redo=\u91cd\u505a 10 | cut=\u526a\u5207 11 | copy=\u590d\u5236 12 | paste=\u7c98\u8d34 13 | delete=\u5220\u9664 14 | selectAll=\u5168\u9009 15 | pageLayout=\u9875\u9762\u5e03\u5c40 16 | grid=\u683c\u5b50 17 | zoom=\u7f29\u653e 18 | custom=\u81ea\u5b9a\u4e49 19 | zoomIn=\u653e\u5927 20 | zoomOut=\u7f29\u5c0f 21 | width=\u5bbd 22 | actualSize=\u5b9e\u9645\u5c3a\u5bf8 23 | format=\u683c\u5f0f 24 | left=\u5de6 25 | center=\u4e2d 26 | right=\u53f3 27 | top=\u9876 28 | middle=\u4e2d 29 | bottom=\u5e95 30 | label=\u6807\u7b7e 31 | position=\u4f4d\u7f6e 32 | shadow=\u9634\u5f71 33 | opacity=\u900f\u660e\u5ea6 34 | hide=\u9690\u85cf 35 | line=\u7ebf 36 | straight=\u76f4 37 | horizontal=\u6c34\u5e73 38 | vertical=\u5782\u76f4 39 | entityRelation=\u4f4d\u7f6e\u5173\u7cfb 40 | arrow=\u7bad\u5934 41 | plain=\u5e73 42 | rounded=\u5706\u865a\u7ebf 43 | dashed=\u865a\u7ebf 44 | linewidth=\u7ebf\u5bbd 45 | linestart=\u7ebf\u59cb\u7aef 46 | open=\u6253\u5f00 47 | classic=\u9ad8\u7ea7 48 | block=\u6846 49 | diamond=\u94bb\u77f3\u5f62 50 | oval=\u692d\u5706\u5f62 51 | none=\u65e0 52 | size=\u5927\u5c0f 53 | lineend=\u7ebf\u672b\u7aef 54 | spacing=\u95f4\u8ddd 55 | perimeter=\u5468\u957f 56 | global=\u5168\u7403 57 | direction=\u65b9\u5411 58 | north=\u5317 59 | east=\u4e1c 60 | south=\u5357 61 | west=\u897f 62 | rotation=\u65cb\u8f6c 63 | style=\u98ce\u683c 64 | shape=\u5f62\u72b6 65 | group=\u7ec4\u5408 66 | ungroup=\u53d6\u6d88\u7ec4\u5408 67 | removeFromGroup=Remove from group 68 | updateGroupBounds=Update group bounds 69 | toBack=\u8f6c\u5230\u540e\u9762 70 | toFront=\u8f6c\u5230\u524d\u9762 71 | align=\u5bf9\u9f50 72 | autosize=\u81ea\u52a8\u8c03\u6574\u5927\u5c0f 73 | outline=\u6982\u51b5 74 | background=\u80cc\u666f 75 | line=\u7ebf 76 | help=\u5e2e\u52a9 77 | selectVertices=\u9009\u62e9\u9876\u70b9 78 | selectEdges=\u9009\u62e9\u8fb9 79 | file=\u6587\u4ef6 80 | error=\u9519\u8bef -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/swing/editors/ToStringEditor.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.swing.editors; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.Color; 5 | import java.beans.PropertyChangeEvent; 6 | import java.beans.PropertyChangeListener; 7 | 8 | import javax.swing.JComponent; 9 | import javax.swing.JPanel; 10 | import javax.swing.JScrollPane; 11 | import javax.swing.JTextArea; 12 | import javax.swing.UIManager; 13 | 14 | public class ToStringEditor extends JPanel implements ObjectEditor { 15 | 16 | private JTextArea textArea; 17 | 18 | private EditorController controller = null; 19 | 20 | private PropertyChangeListener listener = new PropertyChangeListener() { 21 | 22 | @Override 23 | public void propertyChange(PropertyChangeEvent evt) { 24 | if (EditorController.OBJECT.equals(evt.getPropertyName())) { 25 | Object o = evt.getNewValue(); 26 | updateString(o); 27 | } 28 | } 29 | 30 | }; 31 | 32 | public ToStringEditor() { 33 | setLayout(new BorderLayout(0, 0)); 34 | 35 | JScrollPane scrollPane = new JScrollPane(); 36 | add(scrollPane); 37 | 38 | textArea = new JTextArea(); 39 | textArea.setEditable(false); 40 | scrollPane.setViewportView(textArea); 41 | } 42 | 43 | private void updateString(Object o) { 44 | if (o != null) { 45 | textArea.setText(o.toString()); 46 | textArea.setToolTipText(o.getClass().getName()); 47 | textArea.setCaretPosition(0); 48 | } else { 49 | textArea.setText(""); 50 | textArea.setToolTipText(""); 51 | } 52 | } 53 | 54 | @Override 55 | public JComponent getEditorComponent() { 56 | return this; 57 | } 58 | 59 | @Override 60 | public Class[] getSupportedClasses() { 61 | return new Class[] { Object.class }; 62 | } 63 | 64 | @Override 65 | public String getEditorName() { 66 | return "toString()"; 67 | } 68 | 69 | @Override 70 | public void setEditorController(EditorController controller) { 71 | if (this.controller != null) 72 | controller.removePropertyChangeListener(listener); 73 | this.controller = controller; 74 | if (this.controller != null) { 75 | controller.addPropertyChangeListener(listener); 76 | updateString(controller.getObject()); 77 | } else { 78 | updateString(null); 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/mxgraph/examples/swing/editor/EditorKeyboardHandler.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2008, Gaudenz Alder 3 | */ 4 | package com.mxgraph.examples.swing.editor; 5 | 6 | import javax.swing.ActionMap; 7 | import javax.swing.InputMap; 8 | import javax.swing.JComponent; 9 | import javax.swing.KeyStroke; 10 | 11 | import com.mxgraph.swing.mxGraphComponent; 12 | import com.mxgraph.swing.handler.mxKeyboardHandler; 13 | import com.mxgraph.swing.util.mxGraphActions; 14 | 15 | /** 16 | * @author Administrator 17 | * 18 | */ 19 | public class EditorKeyboardHandler extends mxKeyboardHandler 20 | { 21 | 22 | /** 23 | * 24 | * @param graphComponent 25 | */ 26 | public EditorKeyboardHandler(mxGraphComponent graphComponent) 27 | { 28 | super(graphComponent); 29 | } 30 | 31 | /** 32 | * Return JTree's input map. 33 | */ 34 | protected InputMap getInputMap(int condition) 35 | { 36 | InputMap map = super.getInputMap(condition); 37 | 38 | if (condition == JComponent.WHEN_FOCUSED && map != null) 39 | { 40 | map.put(KeyStroke.getKeyStroke("control S"), "save"); 41 | map.put(KeyStroke.getKeyStroke("control shift S"), "saveAs"); 42 | map.put(KeyStroke.getKeyStroke("control N"), "new"); 43 | map.put(KeyStroke.getKeyStroke("control O"), "open"); 44 | 45 | map.put(KeyStroke.getKeyStroke("control Z"), "undo"); 46 | map.put(KeyStroke.getKeyStroke("control Y"), "redo"); 47 | map 48 | .put(KeyStroke.getKeyStroke("control shift V"), 49 | "selectVertices"); 50 | map.put(KeyStroke.getKeyStroke("control shift E"), "selectEdges"); 51 | } 52 | 53 | return map; 54 | } 55 | 56 | /** 57 | * Return the mapping between JTree's input map and JGraph's actions. 58 | */ 59 | protected ActionMap createActionMap() 60 | { 61 | ActionMap map = super.createActionMap(); 62 | 63 | map.put("save", new EditorActions.SaveAction(false)); 64 | map.put("saveAs", new EditorActions.SaveAction(true)); 65 | map.put("new", new EditorActions.NewAction()); 66 | map.put("open", new EditorActions.OpenAction()); 67 | map.put("undo", new EditorActions.HistoryAction(true)); 68 | map.put("redo", new EditorActions.HistoryAction(false)); 69 | map.put("selectVertices", mxGraphActions.getSelectVerticesAction()); 70 | map.put("selectEdges", mxGraphActions.getSelectEdgesAction()); 71 | 72 | return map; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/graph/TargetSpecificChannelHandler.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.graph; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import com.sensepost.mallet.ChannelAttributes; 6 | import com.sensepost.mallet.ConnectRequest; 7 | 8 | import io.netty.channel.Channel; 9 | import io.netty.channel.ChannelHandler; 10 | import io.netty.channel.ChannelHandlerContext; 11 | import io.netty.channel.ChannelInboundHandlerAdapter; 12 | 13 | public class TargetSpecificChannelHandler extends ChannelInboundHandlerAdapter implements IndeterminateChannelHandler { 14 | 15 | public TargetSpecificChannelHandler() { 16 | } 17 | 18 | private String[] options = new String[0]; 19 | 20 | public void setOutboundOptions(String[] options) { 21 | this.options = options; 22 | } 23 | 24 | @Override 25 | public String[] getOutboundOptions() { 26 | return options; 27 | } 28 | 29 | @Override 30 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 31 | super.channelActive(ctx); 32 | ConnectRequest target = ctx.channel().attr(ChannelAttributes.TARGET).get(); 33 | if (target != null) 34 | this.userEventTriggered(ctx, target); 35 | } 36 | 37 | 38 | @Override 39 | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { 40 | if (evt instanceof ConnectRequest) { 41 | ConnectRequest cr = (ConnectRequest) evt; 42 | InetSocketAddress target = (InetSocketAddress) cr.getTarget(); 43 | String hs = target.getHostString() + ":" + target.getPort(); 44 | 45 | for (String option : options) { 46 | if (hs.matches(option)) { 47 | optionSelected(ctx, option); 48 | break; 49 | } 50 | } 51 | } 52 | super.userEventTriggered(ctx, evt); 53 | } 54 | 55 | @Override 56 | public void optionSelected(ChannelHandlerContext ctx, String option) throws Exception { 57 | GraphLookup gl = ctx.channel().attr(ChannelAttributes.GRAPH).get(); 58 | if (gl == null) 59 | throw new NullPointerException("gl"); 60 | ChannelHandler[] handlers = gl.getNextHandlers(this, option); 61 | String name = ctx.name(); 62 | for (int i = handlers.length - 1; i >= 0; i--) { 63 | try { 64 | ctx.pipeline().addAfter(name, null, handlers[i]); 65 | } catch (Exception e) { 66 | Channel ch = ctx.channel().attr(ChannelAttributes.CHANNEL).get(); 67 | ctx.close(); 68 | if (ch != null && ch.isOpen()) 69 | ch.close(); 70 | } 71 | } 72 | ctx.pipeline().remove(name); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/mxgraph/examples/swing/editor/EditorPopupMenu.java: -------------------------------------------------------------------------------- 1 | package com.mxgraph.examples.swing.editor; 2 | 3 | import javax.swing.JMenu; 4 | import javax.swing.JPopupMenu; 5 | import javax.swing.TransferHandler; 6 | 7 | import com.mxgraph.examples.swing.editor.EditorActions.HistoryAction; 8 | import com.mxgraph.swing.util.mxGraphActions; 9 | import com.mxgraph.util.mxResources; 10 | 11 | public class EditorPopupMenu extends JPopupMenu 12 | { 13 | 14 | /** 15 | * 16 | */ 17 | private static final long serialVersionUID = -3132749140550242191L; 18 | 19 | public EditorPopupMenu(BasicGraphEditor editor) 20 | { 21 | boolean selected = !editor.getGraphComponent().getGraph() 22 | .isSelectionEmpty(); 23 | 24 | add(editor.bind(mxResources.get("undo"), new HistoryAction(true), 25 | "/com/mxgraph/examples/swing/images/undo.gif")); 26 | 27 | addSeparator(); 28 | 29 | add( 30 | editor.bind(mxResources.get("cut"), TransferHandler 31 | .getCutAction(), 32 | "/com/mxgraph/examples/swing/images/cut.gif")) 33 | .setEnabled(selected); 34 | add( 35 | editor.bind(mxResources.get("copy"), TransferHandler 36 | .getCopyAction(), 37 | "/com/mxgraph/examples/swing/images/copy.gif")) 38 | .setEnabled(selected); 39 | add(editor.bind(mxResources.get("paste"), TransferHandler 40 | .getPasteAction(), 41 | "/com/mxgraph/examples/swing/images/paste.gif")); 42 | 43 | addSeparator(); 44 | 45 | add( 46 | editor.bind(mxResources.get("delete"), mxGraphActions 47 | .getDeleteAction(), 48 | "/com/mxgraph/examples/swing/images/delete.gif")) 49 | .setEnabled(selected); 50 | 51 | addSeparator(); 52 | 53 | // Creates the format menu 54 | JMenu menu = (JMenu) add(new JMenu(mxResources.get("format"))); 55 | 56 | EditorMenuBar.populateFormatMenu(menu, editor); 57 | 58 | // Creates the shape menu 59 | menu = (JMenu) add(new JMenu(mxResources.get("shape"))); 60 | 61 | EditorMenuBar.populateShapeMenu(menu, editor); 62 | 63 | addSeparator(); 64 | 65 | add( 66 | editor.bind(mxResources.get("edit"), mxGraphActions 67 | .getEditAction())).setEnabled(selected); 68 | 69 | addSeparator(); 70 | 71 | add(editor.bind(mxResources.get("selectVertices"), mxGraphActions 72 | .getSelectVerticesAction())); 73 | add(editor.bind(mxResources.get("selectEdges"), mxGraphActions 74 | .getSelectEdgesAction())); 75 | 76 | addSeparator(); 77 | 78 | add(editor.bind(mxResources.get("selectAll"), mxGraphActions 79 | .getSelectAllAction())); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/mxgraph/examples/swing/editor/ShadowBorder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2001-2005, Gaudenz Alder 3 | * 4 | * All rights reserved. 5 | * 6 | * This file is licensed under the JGraph software license, a copy of which 7 | * will have been provided to you in the file LICENSE at the root of your 8 | * installation directory. If you are unable to locate this file please 9 | * contact JGraph sales for another copy. 10 | */ 11 | package com.mxgraph.examples.swing.editor; 12 | 13 | import java.awt.Color; 14 | import java.awt.Component; 15 | import java.awt.Graphics; 16 | import java.awt.Insets; 17 | import java.io.Serializable; 18 | 19 | import javax.swing.border.Border; 20 | 21 | /** 22 | * Border with a drop shadow. 23 | */ 24 | public class ShadowBorder implements Border, Serializable 25 | { 26 | /** 27 | * 28 | */ 29 | private static final long serialVersionUID = 6854989457150641240L; 30 | 31 | private Insets insets; 32 | 33 | public static ShadowBorder sharedInstance = new ShadowBorder(); 34 | 35 | private ShadowBorder() 36 | { 37 | insets = new Insets(0, 0, 2, 2); 38 | } 39 | 40 | public Insets getBorderInsets(Component c) 41 | { 42 | return insets; 43 | } 44 | 45 | public boolean isBorderOpaque() 46 | { 47 | return false; 48 | } 49 | 50 | public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) 51 | { 52 | // choose which colors we want to use 53 | Color bg = c.getBackground(); 54 | 55 | if (c.getParent() != null) 56 | { 57 | bg = c.getParent().getBackground(); 58 | } 59 | 60 | if (bg != null) 61 | { 62 | Color mid = bg.darker(); 63 | Color edge = average(mid, bg); 64 | 65 | g.setColor(bg); 66 | g.drawLine(0, h - 2, w, h - 2); 67 | g.drawLine(0, h - 1, w, h - 1); 68 | g.drawLine(w - 2, 0, w - 2, h); 69 | g.drawLine(w - 1, 0, w - 1, h); 70 | 71 | // draw the drop-shadow 72 | g.setColor(mid); 73 | g.drawLine(1, h - 2, w - 2, h - 2); 74 | g.drawLine(w - 2, 1, w - 2, h - 2); 75 | 76 | g.setColor(edge); 77 | g.drawLine(2, h - 1, w - 2, h - 1); 78 | g.drawLine(w - 1, 2, w - 1, h - 2); 79 | } 80 | } 81 | 82 | private static Color average(Color c1, Color c2) 83 | { 84 | int red = c1.getRed() + (c2.getRed() - c1.getRed()) / 2; 85 | int green = c1.getGreen() + (c2.getGreen() - c1.getGreen()) / 2; 86 | int blue = c1.getBlue() + (c2.getBlue() - c1.getBlue()) / 2; 87 | return new Color(red, green, blue); 88 | } 89 | 90 | public static ShadowBorder getSharedInstance() 91 | { 92 | return sharedInstance; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/swing/editors/ByteBufEditor.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.swing.editors; 2 | 3 | import java.beans.PropertyChangeEvent; 4 | import java.beans.PropertyChangeListener; 5 | 6 | import javax.swing.JComponent; 7 | 8 | import io.netty.buffer.ByteBuf; 9 | import io.netty.buffer.Unpooled; 10 | 11 | public class ByteBufEditor implements ObjectEditor { 12 | 13 | private ByteArrayEditor bae = new ByteArrayEditor(); 14 | private EditorController adapter = new EditorController(); 15 | private EditorController controller = null; 16 | 17 | private boolean updating = false; 18 | 19 | private PropertyChangeListener listener = new PropertyChangeListener() { 20 | 21 | @Override 22 | public void propertyChange(PropertyChangeEvent evt) { 23 | if (EditorController.OBJECT.equals(evt.getPropertyName())) { 24 | if (evt.getSource() == controller) { 25 | updateAdapter(evt.getNewValue()); 26 | } else if (evt.getSource() == adapter) { 27 | if (!updating) { 28 | if (controller != null) 29 | controller.setObject(Unpooled.wrappedBuffer((byte[])evt.getNewValue())); 30 | } 31 | } 32 | } else if (EditorController.READ_ONLY.equals(evt.getPropertyName())) { 33 | if (evt.getSource() == controller) { 34 | adapter.setReadOnly(controller.isReadOnly()); 35 | } 36 | } 37 | } 38 | }; 39 | 40 | public ByteBufEditor() { 41 | bae.setEditorController(adapter); 42 | adapter.addPropertyChangeListener(listener); 43 | } 44 | 45 | @Override 46 | public JComponent getEditorComponent() { 47 | return bae; 48 | } 49 | 50 | @Override 51 | public String getEditorName() { 52 | return "ByteBuf"; 53 | } 54 | 55 | @Override 56 | public Class[] getSupportedClasses() { 57 | return new Class[] { ByteBuf.class }; 58 | } 59 | 60 | @Override 61 | public void setEditorController(EditorController controller) { 62 | if (this.controller != null) 63 | controller.removePropertyChangeListener(listener); 64 | this.controller = controller; 65 | if (this.controller != null) { 66 | controller.addPropertyChangeListener(listener); 67 | updateAdapter(controller.getObject()); 68 | } else { 69 | updateAdapter(null); 70 | } 71 | } 72 | 73 | private void updateAdapter(Object o) { 74 | updating = true; 75 | if (o != null && ByteBuf.class.isAssignableFrom(o.getClass())) { 76 | ByteBuf bb = (ByteBuf) o; 77 | bb.retain(); 78 | byte[] data = new byte[bb.readableBytes()]; 79 | bb.getBytes(bb.readerIndex(), data); 80 | adapter.setObject(data); 81 | } else { 82 | adapter.setObject(null); 83 | } 84 | updating = false; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/resources/editor_ja.properties: -------------------------------------------------------------------------------- 1 | file=\u30d5\u30a1\u30a4\u30eb 2 | new=\u65b0\u898f\u4f5c\u6210 3 | openFile=\u30d5\u30a1\u30a4\u30eb\u3092\u958b\u304f 4 | save=\u4fdd\u5b58 5 | saveAs=\u3068\u3057\u3066\u4fdd\u5b58\u3059\u308b 6 | print=\u5370\u5237 7 | edit=\u7de8\u96c6 8 | undo=\u5143\u306b\u623b\u3059 9 | redo=\u3084\u308a\u76f4\u3057 10 | cut=\u5207\u308a\u53d6\u308a 11 | copy=\u30b3\u30d4\u30fc 12 | paste=\u8cbc\u308a\u4ed8\u3051 13 | delete=\u524a\u9664 14 | selectAll=\u3059\u3079\u3066\u9078\u629e 15 | pageLayout=\u30da\u30fc\u30b8\u306e\u30ec\u30a4\u30a2\u30a6\u30c8 16 | grid=\u30b0\u30ea\u30c3\u30c9 17 | zoom=\u62e1\u5927 18 | custom=\u30ab\u30b9\u30bf\u30e0 19 | zoomIn=\u30ba\u30fc\u30e0\u30a4\u30f3 20 | zoomOut=\u30ba\u30fc\u30e0\u30a2\u30a6\u30c8 21 | width=\u6a2a\u5e45 22 | actualSize=\u5b9f\u5bf8 23 | format=\u5f62\u5f0f 24 | left=\u5de6\u7aef 25 | center=\u4e2d\u592e 26 | right=\u53f3\u7aef 27 | top=\u4e0a\u4ed8\u304d 28 | middle=\u4e2d\u592e 29 | bottom=\u4e0b\u4ed8\u304d 30 | label=\u30e9\u30d9\u30eb 31 | position=\u4f4d\u7f6e 32 | shadow=\u5f71\u4ed8\u304d 33 | opacity=\u4e0d\u900f\u660e\u5ea6 34 | hide=\u975e\u8868\u793a 35 | line=\u7dda 36 | straight=\u76f4\u7dda 37 | horizontal=\u6c34\u5e73 38 | vertical=\u5782\u76f4 39 | entityRelation=ER 40 | arrow=\u77e2\u5370 41 | plain=\u30d7\u30ec\u30fc\u30f3 42 | rounded=\u89d2\u4e38 43 | dashed=\u7834\u7dda 44 | linewidth=\u7dda\u5e45 45 | linestart=\u884c\u306e\u958b\u59cb 46 | open=\u958b\u304f 47 | classic=\u30af\u30e9\u30b7\u30c3\u30af 48 | block=\u30d6\u30ed\u30c3\u30af 49 | diamond=\u30c0\u30a4\u30e4\u30e2\u30f3\u30c9 50 | oval=\u6955\u5186 51 | none=\u306a\u3057 52 | size=\u30b5\u30a4\u30ba 53 | lineend=\u884c\u306e\u7d42\u4e86 54 | spacing=\u30b9\u30da\u30fc\u30b9 55 | perimeter=\u5883\u754c 56 | global=\u30b0\u30ed\u30fc\u30d0\u30eb 57 | direction=\u65b9\u5411 58 | north=\u5317 59 | east=\u6771 60 | south=\u5357 61 | west=\u897f 62 | rotation=\u56de\u8ee2 63 | style=\u30b9\u30bf\u30a4\u30eb 64 | shape=\u56f3\u5f62 65 | group=\u30b0\u30eb\u30fc\u30d7\u5316 66 | ungroup=\u30b0\u30eb\u30fc\u30d7\u89e3\u9664 67 | removeFromGroup=\u30b0\u30eb\u30fc\u30d7\u304b\u3089\u524a\u9664 68 | updateGroupBounds=\u30b0\u30eb\u30fc\u30d7\u7bc4\u56f2\u306e\u66f4\u65b0 69 | toBack=\u5f8c\u308d\u3078 70 | toFront=\u524d\u3078 71 | align=\u6574\u5217 72 | autosize=\u81ea\u52d5\u30b5\u30a4\u30ba 73 | outline=\u30a2\u30a6\u30c8\u30e9\u30a4\u30f3 74 | background=\u80cc\u666f 75 | line=\u7dda 76 | help=\u30d8\u30eb\u30d7 77 | selectVertices=\u9802\u70b9\u3092\u9078\u629e 78 | selectEdges=\u30a8\u30c3\u30b8\u3092\u9078\u629e 79 | file=\u30d5\u30a1\u30a4\u30eb 80 | error=\u30a8\u30e9\u30fc -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/resources/basic-style.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/swing/ConnectionData.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.swing; 2 | 3 | import java.util.BitSet; 4 | 5 | import javax.swing.DefaultListModel; 6 | import javax.swing.ListModel; 7 | 8 | import com.sensepost.mallet.InterceptController.ChannelActiveEvent; 9 | import com.sensepost.mallet.InterceptController.ChannelEvent; 10 | import com.sensepost.mallet.InterceptController.ChannelInactiveEvent; 11 | 12 | public class ConnectionData { 13 | 14 | private DefaultListModel events = new DefaultListModel<>(); 15 | private BitSet pending = new BitSet(); 16 | private int closed = 0; 17 | 18 | public ConnectionData() { 19 | } 20 | 21 | public void addChannelEvent(ChannelEvent e) throws Exception { 22 | events.addElement(e); 23 | int n = events.size() - 1; 24 | pending.set(n); 25 | if ((e instanceof ChannelActiveEvent) && pending.nextSetBit(0) == n) { 26 | e.execute(); 27 | pending.clear(events.size()); 28 | } 29 | if (e instanceof ChannelInactiveEvent) { 30 | closed++; 31 | } 32 | } 33 | 34 | public int getEventCount() { 35 | return events.size(); 36 | } 37 | 38 | public int getPendingEventCount() { 39 | return pending.cardinality(); 40 | } 41 | 42 | public boolean isClosed() { 43 | return closed == 2; 44 | } 45 | 46 | public void executeNextEvents(int p) throws Exception { 47 | while (pending.nextSetBit(0) <= p && pending.nextSetBit(0) >= 0) 48 | doNextEvent(true); 49 | } 50 | 51 | public void dropNextEvents(int p) throws Exception { 52 | while (pending.nextSetBit(0) <= p && pending.nextSetBit(0) >= 0) 53 | doNextEvent(false); 54 | } 55 | 56 | public void executeNextEvent() throws Exception { 57 | doNextEvent(true); 58 | } 59 | 60 | public void dropNextEvent() throws Exception { 61 | doNextEvent(false); 62 | } 63 | 64 | private void doNextEvent(boolean execute) throws Exception { 65 | int n = pending.nextSetBit(0); 66 | if (n >= 0) { 67 | ChannelEvent e = events.elementAt(n); 68 | try { 69 | pending.clear(n); 70 | if (execute) 71 | e.execute(); 72 | events.set(n, events.get(n)); // trigger an update event 73 | } catch (Exception ex) { 74 | ex.printStackTrace(); 75 | } 76 | } 77 | 78 | } 79 | 80 | public int getNextPendingEvent() { 81 | return pending.nextSetBit(0); 82 | } 83 | 84 | public void executeAllEvents() throws Exception { 85 | while (pending.nextSetBit(0) >= 0) 86 | doNextEvent(true); 87 | } 88 | 89 | public void dropAllEvents() throws Exception { 90 | while (pending.nextSetBit(0) >= 0) 91 | doNextEvent(false); 92 | } 93 | 94 | public ListModel getEvents() { 95 | return events; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/ScriptHandler.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.FileNotFoundException; 6 | import java.io.FileReader; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.io.InputStreamReader; 10 | 11 | import javax.script.Bindings; 12 | import javax.script.Invocable; 13 | import javax.script.ScriptEngine; 14 | import javax.script.ScriptEngineManager; 15 | import javax.script.ScriptException; 16 | 17 | import io.netty.channel.Channel; 18 | import io.netty.channel.ChannelDuplexHandler; 19 | import io.netty.channel.ChannelHandler; 20 | import io.netty.channel.ChannelHandler.Sharable; 21 | import io.netty.channel.ChannelInitializer; 22 | 23 | @Sharable 24 | public class ScriptHandler extends ChannelInitializer { 25 | 26 | private ScriptEngineManager sem = new ScriptEngineManager(); 27 | private ScriptEngine engine; 28 | 29 | private ChannelHandler handler; 30 | 31 | private static String SCRIPT = null; 32 | 33 | static { 34 | try { 35 | InputStream is = ScriptHandler.class.getResourceAsStream("script.groovy"); 36 | BufferedReader r = new BufferedReader(new InputStreamReader(is)); 37 | StringBuilder b = new StringBuilder(); 38 | String line; 39 | while ((line = r.readLine()) != null) { 40 | b.append(line); 41 | } 42 | SCRIPT = b.toString(); 43 | } catch (IOException ioe) { 44 | ioe.printStackTrace(); 45 | SCRIPT = null; 46 | } 47 | } 48 | 49 | public ScriptHandler() throws Exception { 50 | this(SCRIPT, "groovy"); 51 | } 52 | 53 | public ScriptHandler(String script, String language) throws Exception { 54 | this.engine = sem.getEngineByName(language); 55 | try { 56 | Object scriptResult = engine.eval(script); 57 | handler = getScriptHandler(engine, scriptResult); 58 | } catch (Exception e) { 59 | e.printStackTrace(); 60 | throw e; 61 | } 62 | } 63 | 64 | public ScriptHandler(String filename) throws FileNotFoundException, ScriptException { 65 | String extension = filename.substring(filename.lastIndexOf('.')); 66 | this.engine = sem.getEngineByExtension(extension); 67 | handler = getScriptHandler(engine, engine.eval(new FileReader(filename))); 68 | } 69 | 70 | private ChannelHandler getScriptHandler(ScriptEngine engine, Object script) { 71 | if (script == null) 72 | throw new NullPointerException("script result is null"); 73 | 74 | if (!Invocable.class.isAssignableFrom(engine.getClass())) 75 | throw new RuntimeException("Script engine cannot implement objects"); 76 | 77 | if (script instanceof ChannelDuplexHandler) 78 | return (ChannelDuplexHandler) script; 79 | if (script instanceof ChannelHandler) { 80 | return (ChannelHandler) script; 81 | } else 82 | throw new ClassCastException("Script does not implement ChannelHandler"); 83 | } 84 | 85 | @Override 86 | protected void initChannel(Channel ch) throws Exception { 87 | String name = ch.pipeline().context(this).name(); 88 | ch.pipeline().addAfter(name, null, handler); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/InterceptController.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet; 2 | 3 | import java.net.SocketAddress; 4 | 5 | public interface InterceptController { 6 | 7 | void addChannelEvent(ChannelEvent evt) throws Exception; 8 | 9 | public enum Direction { 10 | Client_Server, Server_Client 11 | } 12 | 13 | public class ChannelEvent { 14 | 15 | private long eventTime, executionTime = -1; 16 | private int connection_number; 17 | private Direction direction; 18 | private boolean executed = false; 19 | 20 | public ChannelEvent(int connection, Direction direction) { 21 | this.connection_number = connection; 22 | this.direction = direction; 23 | this.eventTime = System.currentTimeMillis(); 24 | } 25 | 26 | public int getConnectionIdentifier() { 27 | return connection_number; 28 | } 29 | 30 | public long getEventTime() { 31 | return eventTime; 32 | } 33 | 34 | public Direction getDirection() { 35 | return direction; 36 | } 37 | 38 | public void execute() throws Exception { 39 | executed = true; 40 | executionTime = System.currentTimeMillis(); 41 | } 42 | 43 | public boolean isExecuted() { 44 | return executed; 45 | } 46 | 47 | public long getExecutionTime() { 48 | return executionTime; 49 | } 50 | } 51 | 52 | public abstract class ChannelActiveEvent extends ChannelEvent { 53 | 54 | private SocketAddress src, dst; 55 | 56 | public ChannelActiveEvent(int connection, Direction direction, SocketAddress src, SocketAddress dst) { 57 | super(connection, direction); 58 | this.src = src; 59 | this.dst = dst; 60 | } 61 | 62 | public SocketAddress getSourceAddress() { 63 | return src; 64 | } 65 | 66 | public SocketAddress getDestinationAddress() { 67 | return dst; 68 | } 69 | } 70 | 71 | public abstract class ChannelInactiveEvent extends ChannelEvent { 72 | public ChannelInactiveEvent(int connection, Direction direction) { 73 | super(connection, direction); 74 | } 75 | } 76 | 77 | public abstract class ChannelExceptionEvent extends ChannelEvent { 78 | 79 | private Throwable cause; 80 | 81 | public ChannelExceptionEvent(int connection, Direction direction, Throwable cause) { 82 | super(connection, direction); 83 | this.cause = cause; 84 | } 85 | 86 | public Throwable getCause() { 87 | return cause; 88 | } 89 | 90 | } 91 | 92 | public abstract class ChannelReadEvent extends ChannelEvent { 93 | 94 | private Object msg; 95 | 96 | public ChannelReadEvent(int connection, Direction direction, Object msg) { 97 | super(connection, direction); 98 | this.msg = msg; 99 | } 100 | 101 | public Object getMessage() { 102 | return msg; 103 | } 104 | 105 | public void setMessage(Object msg) { 106 | this.msg = msg; 107 | } 108 | } 109 | 110 | public abstract class ChannelUserEvent extends ChannelEvent { 111 | 112 | private Object evt; 113 | 114 | public ChannelUserEvent(int connection, Direction direction, Object evt) { 115 | super(connection, direction); 116 | this.evt = evt; 117 | } 118 | 119 | public Object getUserEvent() { 120 | return evt; 121 | } 122 | 123 | } 124 | 125 | } 126 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/swing/editors/StringEditor.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.swing.editors; 2 | 3 | import java.awt.BorderLayout; 4 | import java.beans.PropertyChangeEvent; 5 | import java.beans.PropertyChangeListener; 6 | 7 | import javax.swing.JComponent; 8 | import javax.swing.JPanel; 9 | import javax.swing.JScrollPane; 10 | import javax.swing.JTextArea; 11 | import javax.swing.event.DocumentEvent; 12 | import javax.swing.event.DocumentListener; 13 | 14 | public class StringEditor extends JPanel implements ObjectEditor { 15 | 16 | private JTextArea textArea; 17 | 18 | private EditorController controller = null; 19 | 20 | private boolean updating = false; 21 | 22 | private PropertyChangeListener listener = new PropertyChangeListener() { 23 | 24 | @Override 25 | public void propertyChange(PropertyChangeEvent evt) { 26 | System.out.println(evt); 27 | if (evt.getSource().equals(controller) && (EditorController.OBJECT.equals(evt.getPropertyName()) 28 | || EditorController.READ_ONLY.equals(evt.getPropertyName()))) { 29 | updateEditor(); 30 | } 31 | } 32 | 33 | }; 34 | 35 | private DocumentListener docListener = new DocumentListener() { 36 | 37 | @Override 38 | public void removeUpdate(DocumentEvent e) { 39 | updateController(); 40 | } 41 | 42 | @Override 43 | public void insertUpdate(DocumentEvent e) { 44 | updateController(); 45 | } 46 | 47 | @Override 48 | public void changedUpdate(DocumentEvent e) { 49 | updateController(); 50 | } 51 | 52 | private void updateController() { 53 | if (updating) 54 | return; 55 | updating = true; 56 | String o = textArea.getText(); 57 | if (controller != null) 58 | controller.setObject(o); 59 | updating = false; 60 | } 61 | }; 62 | 63 | public StringEditor() { 64 | setLayout(new BorderLayout(0, 0)); 65 | 66 | JScrollPane scrollPane = new JScrollPane(); 67 | add(scrollPane); 68 | 69 | textArea = new JTextArea(); 70 | textArea.getDocument().addDocumentListener(docListener); 71 | scrollPane.setViewportView(textArea); 72 | } 73 | 74 | private void updateEditor() { 75 | if (updating) 76 | return; 77 | updating = true; 78 | Object o = controller != null ? controller.getObject() : null; 79 | if (o instanceof String) { 80 | textArea.setText((String) o); 81 | textArea.setCaretPosition(0); 82 | textArea.setEditable(!controller.isReadOnly()); 83 | } else { 84 | textArea.setText(""); 85 | textArea.setToolTipText(""); 86 | textArea.setEditable(false); 87 | } 88 | updating = false; 89 | } 90 | 91 | @Override 92 | public JComponent getEditorComponent() { 93 | return this; 94 | } 95 | 96 | @Override 97 | public Class[] getSupportedClasses() { 98 | return new Class[] { String.class }; 99 | } 100 | 101 | @Override 102 | public String getEditorName() { 103 | return "String"; 104 | } 105 | 106 | @Override 107 | public void setEditorController(EditorController controller) { 108 | if (this.controller != null) 109 | controller.removePropertyChangeListener(listener); 110 | this.controller = controller; 111 | if (this.controller != null) { 112 | controller.addPropertyChangeListener(listener); 113 | } 114 | updateEditor(); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/swing/CustomCellEditor.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.swing; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.event.ActionEvent; 5 | import java.awt.event.WindowAdapter; 6 | import java.awt.event.WindowEvent; 7 | import java.util.EventObject; 8 | 9 | import javax.swing.AbstractAction; 10 | import javax.swing.Action; 11 | import javax.swing.JDialog; 12 | import javax.swing.JFrame; 13 | import javax.swing.JPanel; 14 | import javax.swing.SwingUtilities; 15 | 16 | import org.w3c.dom.Element; 17 | 18 | import com.mxgraph.layout.mxIGraphLayout; 19 | import com.mxgraph.layout.hierarchical.mxHierarchicalLayout; 20 | import com.mxgraph.swing.mxGraphComponent; 21 | import com.mxgraph.swing.view.mxICellEditor; 22 | import com.mxgraph.view.mxGraph; 23 | import com.sensepost.mallet.graph.GraphNode; 24 | 25 | public class CustomCellEditor implements mxICellEditor { 26 | 27 | private mxGraphComponent graphComponent; 28 | 29 | private JPanel graphNodePanel = new JPanel(new BorderLayout()); 30 | 31 | private Object editingCell = null; 32 | 33 | private GraphNodeEditor editor = new GraphNodeEditor(); 34 | private JDialog dialog; 35 | 36 | public CustomCellEditor(mxGraphComponent graphComponent) { 37 | this.graphComponent = graphComponent; 38 | dialog = new JDialog((JFrame) SwingUtilities.getAncestorOfClass(JFrame.class, graphComponent)); 39 | dialog.setModal(true); 40 | dialog.getRootPane().setLayout(new BorderLayout()); 41 | dialog.getRootPane().add(editor, BorderLayout.CENTER); 42 | Action cancelAction = new AbstractAction("Cancel") { 43 | 44 | @Override 45 | public void actionPerformed(ActionEvent e) { 46 | dialog.setVisible(false); 47 | stopEditing(true); 48 | } 49 | 50 | }; 51 | Action okAction = new AbstractAction("Ok") { 52 | 53 | @Override 54 | public void actionPerformed(ActionEvent e) { 55 | dialog.setVisible(false); 56 | stopEditing(false); 57 | } 58 | 59 | }; 60 | editor.setActions(cancelAction, okAction); 61 | dialog.addWindowListener(new WindowAdapter() { 62 | 63 | @Override 64 | public void windowClosed(WindowEvent e) { 65 | dialog.setVisible(false); 66 | stopEditing(true); 67 | } 68 | 69 | }); 70 | dialog.pack(); 71 | } 72 | 73 | @Override 74 | public Object getEditingCell() { 75 | return editingCell; 76 | } 77 | 78 | @Override 79 | public void startEditing(Object cell, EventObject trigger) { 80 | if (editingCell != null) { 81 | stopEditing(true); 82 | } 83 | 84 | editingCell = cell; 85 | Object value = graphComponent.getGraph().getModel().getValue(cell); 86 | if (value instanceof Element) { 87 | editor.setGraphNode((Element) value); 88 | dialog.pack(); 89 | dialog.setLocationRelativeTo(graphComponent); 90 | dialog.setVisible(true); 91 | } 92 | } 93 | 94 | @Override 95 | public void stopEditing(boolean cancel) { 96 | if (editingCell == null) 97 | return; 98 | 99 | if (!cancel) 100 | graphComponent.getGraph().getModel().setValue(editingCell, editor.getGraphNode()); 101 | editingCell = null; 102 | editor.setGraphNode(null); 103 | layoutGraph(graphComponent.getGraph()); 104 | } 105 | 106 | private void layoutGraph(mxGraph graph) { 107 | mxIGraphLayout layout = new mxHierarchicalLayout(graph); 108 | graph.getModel().beginUpdate(); 109 | try { 110 | Object[] cells = graph.getChildCells(graph.getDefaultParent()); 111 | for (int i = 0; i < cells.length; i++) { 112 | graph.updateCellSize(cells[i]); 113 | } 114 | 115 | layout.execute(graph.getDefaultParent()); 116 | } finally { 117 | graph.getModel().endUpdate(); 118 | } 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/SocksServerHandler.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet; 2 | 3 | import io.netty.channel.ChannelHandler; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.channel.SimpleChannelInboundHandler; 6 | import io.netty.handler.codec.socksx.SocksMessage; 7 | import io.netty.handler.codec.socksx.v4.Socks4CommandRequest; 8 | import io.netty.handler.codec.socksx.v4.Socks4CommandType; 9 | import io.netty.handler.codec.socksx.v5.DefaultSocks5InitialResponse; 10 | import io.netty.handler.codec.socksx.v5.DefaultSocks5PasswordAuthResponse; 11 | import io.netty.handler.codec.socksx.v5.Socks5AuthMethod; 12 | import io.netty.handler.codec.socksx.v5.Socks5CommandRequest; 13 | import io.netty.handler.codec.socksx.v5.Socks5CommandRequestDecoder; 14 | import io.netty.handler.codec.socksx.v5.Socks5CommandType; 15 | import io.netty.handler.codec.socksx.v5.Socks5InitialRequest; 16 | import io.netty.handler.codec.socksx.v5.Socks5PasswordAuthRequest; 17 | import io.netty.handler.codec.socksx.v5.Socks5PasswordAuthStatus; 18 | import io.netty.util.internal.logging.InternalLogger; 19 | import io.netty.util.internal.logging.InternalLoggerFactory; 20 | 21 | @ChannelHandler.Sharable 22 | public final class SocksServerHandler extends SimpleChannelInboundHandler { 23 | 24 | private static final InternalLogger logger = InternalLoggerFactory.getInstance(SocksServerHandler.class); 25 | 26 | public SocksServerHandler() { 27 | } 28 | 29 | @Override 30 | public void channelRead0(ChannelHandlerContext ctx, SocksMessage socksRequest) throws Exception { 31 | switch (socksRequest.version()) { 32 | case SOCKS4a: 33 | Socks4CommandRequest socks4CmdRequest = (Socks4CommandRequest) socksRequest; 34 | if (socks4CmdRequest.type() == Socks4CommandType.CONNECT) { 35 | ctx.pipeline().remove(this); 36 | ctx.fireChannelRead(socks4CmdRequest); 37 | } else { 38 | logger.info("Unsupported Socks4a request type : " + socks4CmdRequest.type()); 39 | ctx.close(); 40 | } 41 | break; 42 | case SOCKS5: 43 | if (socksRequest instanceof Socks5InitialRequest) { 44 | /* 45 | * auth support example 46 | * 47 | * ctx.pipeline().addFirst(new 48 | * Socks5PasswordAuthRequestDecoder()); ctx.write(new 49 | * DefaultSocks5AuthMethodResponse(Socks5AuthMethod.PASSWORD)); 50 | */ 51 | ctx.pipeline().addBefore(ctx.name(), "socks5commandrequestdecoder", new Socks5CommandRequestDecoder()); 52 | ctx.write(new DefaultSocks5InitialResponse(Socks5AuthMethod.NO_AUTH)); 53 | } else if (socksRequest instanceof Socks5PasswordAuthRequest) { 54 | ctx.pipeline().addBefore(ctx.name(), "socks5commandrequestdecoder", new Socks5CommandRequestDecoder()); 55 | ctx.write(new DefaultSocks5PasswordAuthResponse(Socks5PasswordAuthStatus.SUCCESS)); 56 | } else if (socksRequest instanceof Socks5CommandRequest) { 57 | Socks5CommandRequest socks5CmdRequest = (Socks5CommandRequest) socksRequest; 58 | if (socks5CmdRequest.type() == Socks5CommandType.CONNECT) { 59 | ctx.pipeline().remove(this); 60 | ctx.fireChannelRead(socks5CmdRequest); 61 | } else { 62 | logger.info("Unsupported Socks5 Command Request type : " + socks5CmdRequest.type()); 63 | ctx.close(); 64 | } 65 | } else { 66 | logger.info("Unsupported Socks5 Request type : " + socksRequest.toString()); 67 | ctx.close(); 68 | } 69 | break; 70 | case UNKNOWN: 71 | logger.info("Unsupported Socks version : " + socksRequest.version()); 72 | ctx.close(); 73 | break; 74 | } 75 | } 76 | 77 | @Override 78 | public void channelReadComplete(ChannelHandlerContext ctx) { 79 | ctx.flush(); 80 | } 81 | 82 | @Override 83 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable throwable) { 84 | logger.debug("Exception caught", throwable); 85 | throwable.printStackTrace(); 86 | ctx.channel().close(); 87 | } 88 | } -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/resources/default-style.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/swing/AutoEditor.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.swing; 2 | 3 | import java.awt.BorderLayout; 4 | import java.beans.PropertyChangeEvent; 5 | import java.beans.PropertyChangeListener; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import javax.swing.JComponent; 10 | import javax.swing.JPanel; 11 | import javax.swing.JTabbedPane; 12 | 13 | import com.sensepost.mallet.swing.editors.ByteArrayEditor; 14 | import com.sensepost.mallet.swing.editors.ByteBufEditor; 15 | import com.sensepost.mallet.swing.editors.EditorController; 16 | import com.sensepost.mallet.swing.editors.HttpMessageEditor; 17 | import com.sensepost.mallet.swing.editors.ObjectEditor; 18 | import com.sensepost.mallet.swing.editors.ReflectionEditor; 19 | import com.sensepost.mallet.swing.editors.StringEditor; 20 | import com.sensepost.mallet.swing.editors.ToStringEditor; 21 | 22 | public class AutoEditor extends JPanel implements ObjectEditor { 23 | 24 | private List editors = new ArrayList<>(); 25 | private JTabbedPane tabbedPane; 26 | private EditorController controller = null; 27 | 28 | public AutoEditor() { 29 | setLayout(new BorderLayout(0, 0)); 30 | 31 | tabbedPane = new JTabbedPane(JTabbedPane.TOP); 32 | add(tabbedPane); 33 | addEditors(); 34 | } 35 | 36 | private void addEditor(ObjectEditor e) { 37 | editors.add(e); 38 | tabbedPane.addTab(e.getEditorName(), e.getEditorComponent()); 39 | } 40 | 41 | private void addEditors() { 42 | addEditor(new StringEditor()); 43 | addEditor(new HttpMessageEditor()); 44 | addEditor(new ByteArrayEditor()); 45 | addEditor(new ByteBufEditor()); 46 | addEditor(new ReflectionEditor()); 47 | addEditor(new ToStringEditor()); 48 | } 49 | 50 | public void setEditorController(EditorController controller) { 51 | if (this.controller != null) 52 | this.controller.removePropertyChangeListener(listener); 53 | this.controller = controller; 54 | if (this.controller != null) { 55 | this.controller.addPropertyChangeListener(listener); 56 | Object o = this.controller.getObject(); 57 | if (o == null) 58 | updateVisibleEditors(null); 59 | else 60 | updateVisibleEditors(o.getClass()); 61 | } 62 | for (ObjectEditor e : editors) { 63 | e.setEditorController(controller); 64 | } 65 | } 66 | 67 | @Override 68 | public JComponent getEditorComponent() { 69 | return this; 70 | } 71 | 72 | @Override 73 | public String getEditorName() { 74 | return "Automatic"; 75 | } 76 | 77 | private void updateVisibleEditors(Class clazz) { 78 | for (int i = tabbedPane.getTabCount(); i > 0; i--) { 79 | tabbedPane.removeTabAt(i - 1); 80 | } 81 | if (clazz != null) { 82 | for (ObjectEditor e : editors) { 83 | Class[] classes = e.getSupportedClasses(); 84 | for (Class c : classes) { 85 | if (c.isAssignableFrom(clazz)) { 86 | tabbedPane.addTab(e.getEditorName(), e.getEditorComponent()); 87 | break; 88 | } 89 | } 90 | } 91 | } 92 | } 93 | 94 | @Override 95 | public Class[] getSupportedClasses() { 96 | List> classList = new ArrayList<>(); 97 | for (ObjectEditor e : editors) { 98 | Class[] classes = e.getSupportedClasses(); 99 | for (int i = 0; i < classes.length; i++) 100 | classList.add(classes[i]); 101 | } 102 | return classList.toArray(new Class[0]); 103 | } 104 | 105 | private PropertyChangeListener listener = new PropertyChangeListener() { 106 | 107 | @Override 108 | public void propertyChange(PropertyChangeEvent evt) { 109 | if (EditorController.OBJECT.equals(evt.getPropertyName())) { 110 | Class n = evt.getNewValue() == null ? null : evt.getNewValue().getClass(); 111 | Class o = evt.getOldValue() == null ? null : evt.getOldValue().getClass(); 112 | if (o != n) { 113 | updateVisibleEditors(n); 114 | } 115 | } 116 | } 117 | 118 | }; 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/com/mxgraph/examples/swing/CustomCanvas.java: -------------------------------------------------------------------------------- 1 | package com.mxgraph.examples.swing; 2 | 3 | import javax.swing.BorderFactory; 4 | import javax.swing.CellRendererPane; 5 | import javax.swing.JFrame; 6 | import javax.swing.JLabel; 7 | import javax.swing.border.BevelBorder; 8 | 9 | import com.mxgraph.canvas.mxICanvas; 10 | import com.mxgraph.canvas.mxImageCanvas; 11 | import com.mxgraph.swing.mxGraphComponent; 12 | import com.mxgraph.swing.handler.mxRubberband; 13 | import com.mxgraph.swing.view.mxInteractiveCanvas; 14 | import com.mxgraph.view.mxCellState; 15 | import com.mxgraph.view.mxGraph; 16 | 17 | public class CustomCanvas extends JFrame 18 | { 19 | 20 | /** 21 | * 22 | */ 23 | private static final long serialVersionUID = -844106998814982739L; 24 | 25 | public CustomCanvas() 26 | { 27 | super("Custom Canvas"); 28 | 29 | // Demonstrates the use of a Swing component for rendering vertices. 30 | // Note: Use the heavyweight feature to allow for event handling in 31 | // the Swing component that is used for rendering the vertex. 32 | 33 | mxGraph graph = new mxGraph() 34 | { 35 | public void drawState(mxICanvas canvas, mxCellState state, 36 | boolean drawLabel) 37 | { 38 | String label = (drawLabel) ? state.getLabel() : ""; 39 | 40 | // Indirection for wrapped swing canvas inside image canvas (used for creating 41 | // the preview image when cells are dragged) 42 | if (getModel().isVertex(state.getCell()) 43 | && canvas instanceof mxImageCanvas 44 | && ((mxImageCanvas) canvas) 45 | .getGraphicsCanvas() instanceof SwingCanvas) 46 | { 47 | ((SwingCanvas) ((mxImageCanvas) canvas).getGraphicsCanvas()) 48 | .drawVertex(state, label); 49 | } 50 | // Redirection of drawing vertices in SwingCanvas 51 | else if (getModel().isVertex(state.getCell()) 52 | && canvas instanceof SwingCanvas) 53 | { 54 | ((SwingCanvas) canvas).drawVertex(state, label); 55 | } 56 | else 57 | { 58 | super.drawState(canvas, state, drawLabel); 59 | } 60 | } 61 | }; 62 | 63 | Object parent = graph.getDefaultParent(); 64 | 65 | graph.getModel().beginUpdate(); 66 | try 67 | { 68 | 69 | Object v1 = graph.insertVertex(parent, null, "Hello", 20, 20, 80, 70 | 30); 71 | Object v2 = graph.insertVertex(parent, null, "World!", 240, 150, 80, 72 | 30); 73 | graph.insertEdge(parent, null, "Edge", v1, v2); 74 | } 75 | finally 76 | { 77 | graph.getModel().endUpdate(); 78 | } 79 | 80 | mxGraphComponent graphComponent = new mxGraphComponent(graph) 81 | { 82 | /** 83 | * 84 | */ 85 | private static final long serialVersionUID = 4683716829748931448L; 86 | 87 | public mxInteractiveCanvas createCanvas() 88 | { 89 | return new SwingCanvas(this); 90 | } 91 | }; 92 | 93 | getContentPane().add(graphComponent); 94 | 95 | // Adds rubberband selection 96 | new mxRubberband(graphComponent); 97 | } 98 | 99 | public class SwingCanvas extends mxInteractiveCanvas 100 | { 101 | protected CellRendererPane rendererPane = new CellRendererPane(); 102 | 103 | protected JLabel vertexRenderer = new JLabel(); 104 | 105 | protected mxGraphComponent graphComponent; 106 | 107 | public SwingCanvas(mxGraphComponent graphComponent) 108 | { 109 | this.graphComponent = graphComponent; 110 | 111 | vertexRenderer.setBorder( 112 | BorderFactory.createBevelBorder(BevelBorder.RAISED)); 113 | vertexRenderer.setHorizontalAlignment(JLabel.CENTER); 114 | vertexRenderer 115 | .setBackground(graphComponent.getBackground().darker()); 116 | vertexRenderer.setOpaque(true); 117 | } 118 | 119 | public void drawVertex(mxCellState state, String label) 120 | { 121 | vertexRenderer.setText(label); 122 | // TODO: Configure other properties... 123 | 124 | rendererPane.paintComponent(g, vertexRenderer, graphComponent, 125 | (int) (state.getX() + translate.getX()), 126 | (int) (state.getY() + translate.getY()), 127 | (int) state.getWidth(), (int) state.getHeight(), true); 128 | } 129 | 130 | } 131 | 132 | public static void main(String[] args) 133 | { 134 | CustomCanvas frame = new CustomCanvas(); 135 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 136 | frame.setSize(400, 320); 137 | frame.setVisible(true); 138 | } 139 | 140 | } 141 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/RelayHandler.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet; 2 | 3 | import java.net.SocketAddress; 4 | 5 | import com.sensepost.mallet.graph.GraphLookup; 6 | 7 | import io.netty.bootstrap.Bootstrap; 8 | import io.netty.channel.Channel; 9 | import io.netty.channel.ChannelFuture; 10 | import io.netty.channel.ChannelFutureListener; 11 | import io.netty.channel.ChannelHandler; 12 | import io.netty.channel.ChannelHandler.Sharable; 13 | import io.netty.channel.ChannelHandlerContext; 14 | import io.netty.channel.ChannelInboundHandlerAdapter; 15 | import io.netty.channel.ChannelInitializer; 16 | import io.netty.channel.ChannelOption; 17 | import io.netty.channel.EventLoopGroup; 18 | import io.netty.channel.socket.ChannelInputShutdownEvent; 19 | import io.netty.channel.socket.SocketChannel; 20 | import io.netty.channel.socket.nio.NioSocketChannel; 21 | import io.netty.util.internal.logging.InternalLogger; 22 | import io.netty.util.internal.logging.InternalLoggerFactory; 23 | 24 | @Sharable 25 | public class RelayHandler extends ChannelInboundHandlerAdapter { 26 | 27 | private static final InternalLogger logger = InternalLoggerFactory.getInstance(RelayHandler.class); 28 | 29 | private volatile boolean added = false; 30 | 31 | private Bootstrap bootstrap; 32 | 33 | public RelayHandler() { 34 | bootstrap = new Bootstrap().channel(NioSocketChannel.class).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000) 35 | .option(ChannelOption.SO_KEEPALIVE, true); 36 | } 37 | 38 | @Override 39 | public void handlerAdded(final ChannelHandlerContext ctx) throws Exception { 40 | if (!added && ctx.channel().attr(ChannelAttributes.TARGET).get() != null) { 41 | added = true; 42 | setupOutboundChannel(ctx); 43 | } 44 | } 45 | 46 | private void setupOutboundChannel(final ChannelHandlerContext ctx) throws Exception { 47 | final GraphLookup gl = ctx.channel().attr(ChannelAttributes.GRAPH).get(); 48 | final ConnectRequest target = ctx.channel().attr(ChannelAttributes.TARGET).get(); 49 | 50 | logger.info("Connecting " + ctx.channel().remoteAddress() + " -> " + target); 51 | ChannelInitializer initializer = new ChannelInitializer() { 52 | 53 | @Override 54 | protected void initChannel(SocketChannel ch) throws Exception { 55 | ch.attr(ChannelAttributes.GRAPH).set(gl); 56 | ch.attr(ChannelAttributes.CHANNEL).set(ctx.channel()); 57 | ctx.channel().attr(ChannelAttributes.CHANNEL).set(ch); 58 | target.getConnectPromise().setSuccess(ch); 59 | 60 | ChannelHandler[] handlers = gl.getClientChannelInitializer(RelayHandler.this); 61 | ch.pipeline().addLast(handlers); 62 | } 63 | }; 64 | 65 | try { 66 | bootstrap.group(ctx.channel().eventLoop()).handler(initializer).connect(target.getTarget()).sync(); 67 | } catch (Exception e) { 68 | ctx.close(); 69 | } 70 | } 71 | 72 | @Override 73 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 74 | Channel other = ctx.channel().attr(ChannelAttributes.CHANNEL).get(); 75 | if (other != null && other.isOpen()) { 76 | other.close(); 77 | } 78 | super.channelInactive(ctx); 79 | } 80 | 81 | @Override 82 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 83 | Channel other = ctx.channel().attr(ChannelAttributes.CHANNEL).get(); 84 | if (other != null && other.isOpen()) { 85 | other.close(); 86 | } 87 | ctx.channel().close(); 88 | cause.printStackTrace(); 89 | } 90 | 91 | @Override 92 | public void channelRead(final ChannelHandlerContext ctx, Object msg) throws Exception { 93 | Channel channel = ctx.channel().attr(ChannelAttributes.CHANNEL).get(); 94 | if (channel == null) { 95 | throw new NullPointerException("Channel is null!"); 96 | } 97 | ChannelFuture cf = channel.writeAndFlush(msg); 98 | cf.addListener(new ChannelFutureListener() { 99 | @Override 100 | public void operationComplete(ChannelFuture future) { 101 | if (!future.isSuccess()) { 102 | future.channel().close(); 103 | } 104 | } 105 | }); 106 | } 107 | 108 | @Override 109 | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { 110 | if (evt instanceof ChannelInputShutdownEvent) { 111 | ((SocketChannel) ctx.channel().attr(ChannelAttributes.CHANNEL).get()).shutdownOutput(); 112 | } else if (evt instanceof ConnectRequest) { 113 | added = true; 114 | setupOutboundChannel(ctx); 115 | } 116 | super.userEventTriggered(ctx, evt); 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/ssl/KeystoreUtils.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.ssl; 2 | 3 | import java.io.ByteArrayInputStream; 4 | import java.io.File; 5 | import java.io.FileNotFoundException; 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | import java.io.OutputStream; 9 | import java.lang.reflect.Constructor; 10 | import java.lang.reflect.InvocationTargetException; 11 | import java.security.GeneralSecurityException; 12 | import java.security.InvalidKeyException; 13 | import java.security.Key; 14 | import java.security.KeyStore; 15 | import java.security.KeyStoreException; 16 | import java.security.PrivateKey; 17 | import java.security.Provider; 18 | import java.security.Security; 19 | import java.security.cert.Certificate; 20 | import java.security.cert.X509Certificate; 21 | import java.util.Enumeration; 22 | import java.util.LinkedHashMap; 23 | import java.util.Map; 24 | 25 | import javax.net.ssl.X509KeyManager; 26 | 27 | public class KeystoreUtils { 28 | 29 | public static X509KeyManager getKeyManagerForAlias(KeyStore keyStore, 30 | String alias, char[] password) throws GeneralSecurityException { 31 | Key key = keyStore.getKey(alias, password); 32 | Certificate[] chain = keyStore.getCertificateChain(alias); 33 | if (key instanceof PrivateKey) { 34 | X509Certificate[] certChain = new X509Certificate[chain.length]; 35 | for (int i = 0; i < chain.length; i++) { 36 | if (chain[i] instanceof X509Certificate) { 37 | certChain[i] = (X509Certificate) chain[i]; 38 | } else { 39 | throw new InvalidKeyException("CA cert[" + i 40 | + "] is not an X509Certificate: " + chain[i]); 41 | } 42 | } 43 | return new SingleX509KeyManager(alias, (PrivateKey) key, certChain); 44 | } else { 45 | throw new InvalidKeyException( 46 | "The private key should implement PrivateKey, but is a " + key); 47 | } 48 | } 49 | 50 | public static X509KeyManager loadFromKeyStore(InputStream in, String type, 51 | String alias, char[] password) throws GeneralSecurityException, 52 | IOException { 53 | KeyStore ks = KeyStore.getInstance(type); 54 | ks.load(in, password); 55 | return getKeyManagerForAlias(ks, alias, password); 56 | } 57 | 58 | public static void addToKeyStore(KeyStore keyStore, X509KeyManager km, 59 | String alias, char[] password) throws GeneralSecurityException { 60 | keyStore.setKeyEntry(alias, km.getPrivateKey(alias), password, 61 | km.getCertificateChain(alias)); 62 | } 63 | 64 | public static void saveToKeyStore(OutputStream out, X509KeyManager km, 65 | String alias, String type, char[] password) 66 | throws GeneralSecurityException, IOException { 67 | KeyStore ks = KeyStore.getInstance(type); 68 | ks.load(null, password); 69 | addToKeyStore(ks, km, alias, password); 70 | ks.store(out, password); 71 | } 72 | 73 | public static KeyStore getPKCS11Keystore(String name, File library, 74 | int slot, char[] password) throws ClassNotFoundException, 75 | NoSuchMethodException, InvocationTargetException, 76 | IllegalAccessException, InstantiationException, 77 | GeneralSecurityException, IOException { 78 | // Set up a virtual config file 79 | if (!library.exists()) 80 | throw new FileNotFoundException(library + " could not be found"); 81 | StringBuffer cardConfig = new StringBuffer(); 82 | cardConfig.append("name = ").append(name).append("\n"); 83 | cardConfig.append("library = ").append(library.getAbsolutePath()).append("\n"); 84 | cardConfig.append("slotListIndex = ").append(Integer.toString(slot)) 85 | .append("\n"); 86 | InputStream is = new ByteArrayInputStream(cardConfig.toString() 87 | .getBytes()); 88 | 89 | // create the provider 90 | Class pkcs11Class = Class.forName("sun.security.pkcs11.SunPKCS11"); 91 | Constructor c = pkcs11Class 92 | .getConstructor(new Class[] { InputStream.class }); 93 | Provider pkcs11 = (Provider) c.newInstance(new Object[] { is }); 94 | Security.addProvider(pkcs11); 95 | 96 | // init the key store 97 | KeyStore ks = KeyStore.getInstance("PKCS11"); 98 | ks.load(null, password); 99 | return ks; 100 | } 101 | 102 | public static Map getAliases(KeyStore keyStore) throws KeyStoreException { 103 | Enumeration aliases = keyStore.aliases(); 104 | Map all = new LinkedHashMap(); 105 | while (aliases.hasMoreElements()) { 106 | String alias = aliases.nextElement(); 107 | all.put(alias, splitDN(getName(keyStore, alias))[0]); 108 | } 109 | return all; 110 | } 111 | 112 | public static String getName(KeyStore ks, String alias) throws KeyStoreException { 113 | Certificate cert = ks.getCertificate(alias); 114 | if (cert instanceof X509Certificate) { 115 | X509Certificate xcert = (X509Certificate) cert; 116 | return xcert.getSubjectX500Principal().getName(); 117 | } 118 | return "Unknown"; 119 | } 120 | 121 | public static String[] splitDN(String name) { 122 | return name.split(", *"); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/swing/InterceptFrame.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.swing; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.event.ActionEvent; 5 | import java.awt.event.ActionListener; 6 | import java.io.File; 7 | import java.io.IOException; 8 | 9 | import javax.swing.JCheckBoxMenuItem; 10 | import javax.swing.JFileChooser; 11 | import javax.swing.JFrame; 12 | import javax.swing.JMenu; 13 | import javax.swing.JMenuBar; 14 | import javax.swing.JMenuItem; 15 | import javax.swing.JOptionPane; 16 | import javax.swing.JTabbedPane; 17 | import javax.swing.SwingUtilities; 18 | import javax.swing.filechooser.FileNameExtensionFilter; 19 | 20 | import com.mxgraph.swing.mxGraphComponent; 21 | import com.mxgraph.swing.view.mxICellEditor; 22 | import com.mxgraph.view.mxGraph; 23 | import com.sensepost.mallet.InterceptController; 24 | import com.sensepost.mallet.graph.Graph; 25 | 26 | import io.netty.util.ReferenceCountUtil; 27 | 28 | public class InterceptFrame extends JFrame implements InterceptController { 29 | 30 | private JCheckBoxMenuItem interceptMenuItem; 31 | private ConnectionPanel connectionPanel; 32 | private JTabbedPane tabbedPane; 33 | 34 | private GraphEditor editor; 35 | 36 | private mxGraphComponent graphComponent; 37 | 38 | private Graph graph; 39 | private JMenuItem loadMenuItem; 40 | private File currentDir = new File("."); 41 | 42 | public InterceptFrame(mxGraphComponent graphComponent) { 43 | setTitle("Mallet"); 44 | setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 45 | 46 | this.graphComponent = graphComponent; 47 | 48 | tabbedPane = new JTabbedPane(JTabbedPane.TOP); 49 | getContentPane().add(tabbedPane, BorderLayout.CENTER); 50 | 51 | editor = new GraphEditor("", graphComponent); 52 | 53 | tabbedPane.addTab("Graph Editor", editor); 54 | 55 | connectionPanel = new ConnectionPanel(); 56 | tabbedPane.addTab("Connections", connectionPanel); 57 | 58 | JMenuBar menuBar = new JMenuBar(); 59 | setJMenuBar(menuBar); 60 | 61 | JMenu mnFile = new JMenu("File"); 62 | menuBar.add(mnFile); 63 | 64 | JMenuItem mntmExit = new JMenuItem("Exit"); 65 | mntmExit.addActionListener(new ActionListener() { 66 | public void actionPerformed(ActionEvent e) { 67 | if (graph != null) 68 | try { 69 | graph.shutdownServers(); 70 | } catch (Exception ex) { 71 | JOptionPane.showMessageDialog(InterceptFrame.this, ex.getLocalizedMessage(), "Error", 72 | JOptionPane.ERROR_MESSAGE); 73 | } 74 | System.exit(0); 75 | } 76 | }); 77 | 78 | loadMenuItem = new JMenuItem("Load"); 79 | loadMenuItem.addActionListener(new ActionListener() { 80 | public void actionPerformed(ActionEvent e) { 81 | try { 82 | JFileChooser jfc = new JFileChooser(currentDir); 83 | FileNameExtensionFilter filter = new FileNameExtensionFilter("Graph files", "mxe"); 84 | jfc.setFileFilter(filter); 85 | int r = jfc.showOpenDialog(InterceptFrame.this); 86 | if (r != JFileChooser.APPROVE_OPTION) 87 | return; 88 | File f = jfc.getSelectedFile(); 89 | if (f == null) 90 | return; 91 | currentDir = jfc.getCurrentDirectory(); 92 | graph.loadGraph(f); 93 | InterceptFrame.this.graphComponent.setEnabled(true); 94 | try { 95 | graph.startServers(); 96 | } catch (Exception ex) { 97 | ex.printStackTrace(); 98 | JOptionPane.showMessageDialog(InterceptFrame.this, ex.getLocalizedMessage(), "Error", 99 | JOptionPane.ERROR_MESSAGE); 100 | } 101 | 102 | } catch (IOException ex) { 103 | JOptionPane.showMessageDialog(InterceptFrame.this, ex.getLocalizedMessage(), "Error", 104 | JOptionPane.ERROR_MESSAGE); 105 | } 106 | } 107 | }); 108 | mnFile.add(loadMenuItem); 109 | mnFile.add(mntmExit); 110 | 111 | interceptMenuItem = new JCheckBoxMenuItem("Intercept"); 112 | interceptMenuItem.addActionListener(new ActionListener() { 113 | public void actionPerformed(ActionEvent e) { 114 | connectionPanel.setIntercept(interceptMenuItem.isSelected()); 115 | } 116 | }); 117 | menuBar.add(interceptMenuItem); 118 | 119 | } 120 | 121 | public void setGraph(final Graph graph) { 122 | if (graph == null) 123 | throw new NullPointerException("graph"); 124 | this.graph = graph; 125 | graph.setInterceptController(this); 126 | this.graphComponent.setGraph(graph.getGraph()); 127 | } 128 | 129 | @Override 130 | public void addChannelEvent(final ChannelEvent evt) throws Exception { 131 | if (evt instanceof ChannelReadEvent) { 132 | Object o = ((ChannelReadEvent) evt).getMessage(); 133 | ReferenceCountUtil.retain(o); 134 | } 135 | SwingUtilities.invokeAndWait(new Runnable() { 136 | public void run() { 137 | try { 138 | connectionPanel.addChannelEvent(evt); 139 | } catch (Exception e) { 140 | e.printStackTrace(); 141 | } 142 | } 143 | }); 144 | } 145 | 146 | protected JCheckBoxMenuItem getInterceptMenuItem() { 147 | return interceptMenuItem; 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/resources/editor.properties: -------------------------------------------------------------------------------- 1 | shapes=Shapes 2 | basic=Basic 3 | protocolHandlers=Protocols 4 | images=Images 5 | symbols=Symbols 6 | file=File 7 | new=New 8 | openFile=Open File 9 | importStencil=Import Stencil 10 | stencilImported=Stencil imported as {1} 11 | allSupportedFormats=All supported formats 12 | imageContainsNoDiagramData=Image contains no diagram data 13 | save=Save 14 | saveAs=Save As 15 | pageSetup=Page Setup 16 | print=Print 17 | exit=Exit 18 | edit=Edit 19 | undo=Undo 20 | redo=Redo 21 | cut=Cut 22 | copy=Copy 23 | paste=Paste 24 | delete=Delete 25 | selectAll=Select All 26 | selectNone=Select None 27 | warning=Warning 28 | view=View 29 | pageLayout=Page Layout 30 | antialias=Antialias 31 | grid=Grid 32 | rulers=Rulers 33 | zoom=Zoom 34 | custom=Custom 35 | zoomIn=Zoom In 36 | zoomOut=Zoom Out 37 | page=Page 38 | width=Width 39 | actualSize=Actual Size 40 | format=Format 41 | alignment=Alignment 42 | left=Left 43 | center=Center 44 | right=Right 45 | top=Top 46 | middle=Middle 47 | bottom=Bottom 48 | wordWrap=Word wrap 49 | noWordWrap=No word wrap 50 | fontcolor=Fontcolor 51 | linecolor=Linecolor 52 | fillcolor=Fillcolor 53 | gradient=Gradient 54 | label=Label 55 | labelFill=Label Fill 56 | labelBorder=Label Border 57 | position=Position 58 | shadow=Shadow 59 | opacity=Opacity 60 | textOpacity=Text opacity 61 | hide=Hide 62 | connector=Connector 63 | line=Line 64 | straight=Straight 65 | horizontal=Horizontal 66 | vertical=Vertical 67 | curved=Curved 68 | entityRelation=Entity Relation 69 | arrow=Arrow 70 | plain=Plain 71 | rounded=Rounded 72 | orthogonal=Orthogonal 73 | dashed=Dashed 74 | linewidth=Linewidth 75 | linestart=Linestart 76 | open=Open 77 | classic=Classic 78 | block=Block 79 | diamond=Diamond 80 | oval=Oval 81 | none=None 82 | size=Size 83 | lineend=Lineend 84 | spacing=Spacing 85 | sourceSpacing=Source spacing 86 | targetSpacing=target spacing 87 | perimeter=Perimeter 88 | global=Global 89 | direction=Direction 90 | north=North 91 | east=East 92 | south=South 93 | west=West 94 | rotateLabel=Rotate Label 95 | rotation=Rotation 96 | image=Image 97 | style=Style 98 | shape=Shape 99 | home=Home 100 | enterGroup=Enter group 101 | exitGroup=Exit group 102 | group=Group 103 | ungroup=Ungroup 104 | removeFromGroup=Remove from group 105 | updateGroupBounds=Update group bounds 106 | collapse=Collapse 107 | expand=Expand 108 | toBack=To Back 109 | toFront=To Front 110 | align=Align 111 | autosize=Autosize 112 | diagram=Diagram 113 | outline=Outline 114 | background=Background 115 | backgroundColor=Background Color 116 | backgroundImage=Background Image 117 | pageBackground=Page background 118 | layout=Layout 119 | verticalHierarchical=Vertical Hierarchical 120 | horizontalHierarchical=Horizontal Hierarchical 121 | verticalPartition=Vertical Partition 122 | horizontalPartition=Horizontal Partition 123 | verticalStack=Vertical Stack 124 | horizontalStack=Horizontal Stack 125 | verticalTree=Vertical Tree 126 | horizontalTree=Horizontal Tree 127 | parallelEdges=Parallel Edges 128 | placeEdgeLabels=Edge Labels 129 | organicLayout=Organic 130 | circleLayout=Circle 131 | selection=Selection 132 | selectPath=Select Path 133 | selectDirectedPath=Select Directed Path 134 | selectTree=Select Tree 135 | selectDirectedTree=Select Directed Tree 136 | stylesheet=Stylesheet 137 | basicStyle=Basic Style 138 | defaultStyle=Default Style 139 | options=Options 140 | display=Display 141 | buffering=Buffering 142 | dirty=Dirty 143 | centerPage=Center Page 144 | centerZoom=Center Zoom 145 | zoomToSelection=Zoom to Selection 146 | preferPageSize=Prefer Pagesize 147 | pageBreaks=Page Breaks 148 | tolerance=Tolerance 149 | gridSize=Grid Size 150 | gridColor=Grid Color 151 | dot=Dot 152 | line=Line 153 | cross=Cross 154 | dragAndDrop=Drag and Drop 155 | dragEnabled=Drag Enabled 156 | dropEnabled=Drop Enabled 157 | imagePreview=Image Preview 158 | labels=Labels 159 | htmlLabels=HTML Labels 160 | showLabels=Show Labels 161 | moveEdgeLabels=Move Edge Labels 162 | moveVertexLabels=Move Vertex Labels 163 | handleReturn=Handle Return 164 | connections=Connections 165 | connectable=Connectable 166 | connectableEdges=Connectable Edges 167 | createTarget=Create Target 168 | connectMode=Connect Mode 169 | validation=Validation 170 | allowDanglingEdges=Allow Dangling Edges 171 | cloneInvalidEdges=Clone Invalid Edges 172 | allowLoops=Allow Loops 173 | multigraph=Multigraph 174 | disconnectOnMove=Disconnect on Move 175 | window=Window 176 | help=Help 177 | aboutGraphEditor=About mxGraph Editor 178 | magnifyPage=Magnify Page 179 | selectVertices=Select Vertices 180 | selectEdges=Select Edges 181 | newDiagram=New Diagram 182 | ready=Ready. 183 | scale=Scale 184 | value=Value 185 | file=File 186 | allImages=All Images 187 | overwriteExistingFile=Overwrite existing file? 188 | transparentBackground=Transparent Background? 189 | noImageData=No Image Data 190 | noSourceAndTargetSelected=No source and target selected. 191 | enterWarningMessage=Enter warning message 192 | noCellSelected=No cell selected. 193 | loseChanges=Lose Changes? 194 | noLayout=Layout unavailable 195 | error=Error 196 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/Main.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet; 2 | 3 | import java.awt.event.WindowEvent; 4 | import java.awt.event.WindowStateListener; 5 | import java.io.File; 6 | import java.io.FileInputStream; 7 | import java.io.FileOutputStream; 8 | import java.io.FileWriter; 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.io.OutputStream; 12 | import java.security.GeneralSecurityException; 13 | import java.security.Key; 14 | import java.security.KeyStore; 15 | import java.security.cert.Certificate; 16 | 17 | import javax.security.auth.x500.X500Principal; 18 | 19 | import com.mxgraph.swing.mxGraphComponent; 20 | import com.sensepost.mallet.graph.Graph; 21 | import com.sensepost.mallet.ssl.AutoGeneratingContextSelector; 22 | import com.sensepost.mallet.swing.GraphEditor.CustomGraph; 23 | import com.sensepost.mallet.swing.GraphEditor.CustomGraphComponent; 24 | import com.sensepost.mallet.swing.InterceptFrame; 25 | 26 | import io.netty.handler.ssl.SslContext; 27 | import io.netty.handler.ssl.SslContextBuilder; 28 | import io.netty.handler.ssl.util.InsecureTrustManagerFactory; 29 | 30 | public class Main { 31 | 32 | private static boolean initFromP12(KeyStore keyStore, File ca, char[] password, char[] keyPassword) { 33 | if (!ca.exists()) 34 | return false; 35 | try { 36 | KeyStore p12 = KeyStore.getInstance("PKCS12"); 37 | InputStream in = new FileInputStream(ca); 38 | try { 39 | p12.load(in, password); 40 | } finally { 41 | try { 42 | in.close(); 43 | } catch (IOException ioe) { 44 | } 45 | } 46 | Key caKey = p12.getKey("cacert", password); 47 | Certificate[] caCerts = p12.getCertificateChain("cacert"); 48 | if (caKey == null || caCerts == null) 49 | return false; 50 | keyStore.load(null, password); 51 | keyStore.setKeyEntry(AutoGeneratingContextSelector.CA_ALIAS, caKey, password, caCerts); 52 | return true; 53 | } catch (IOException ioe) { 54 | return false; 55 | } catch (GeneralSecurityException gse) { 56 | return false; 57 | } 58 | } 59 | 60 | private static AutoGeneratingContextSelector getServerSslContextSelector() 61 | throws GeneralSecurityException, IOException { 62 | File ks = new File("keystore.jks"); 63 | char[] password = "password".toCharArray(); 64 | KeyStore keyStore = KeyStore.getInstance("JKS"); 65 | if (!ks.exists()) { 66 | AutoGeneratingContextSelector selector = null; 67 | if (!initFromP12(keyStore, new File("ca.p12"), password, password)) { 68 | keyStore.load(null, password); 69 | System.err.println("Generating a new CA"); 70 | X500Principal ca = new X500Principal( 71 | "cn=OWASP Custom CA for " + java.net.InetAddress.getLocalHost().getHostName() 72 | + ",ou=OWASP Custom CA,o=OWASP,l=OWASP,st=OWASP,c=OWASP"); 73 | selector = new AutoGeneratingContextSelector(ca, keyStore, password); 74 | } else { 75 | selector = new AutoGeneratingContextSelector(keyStore, password); 76 | } 77 | OutputStream out = new FileOutputStream(ks); 78 | try { 79 | keyStore.store(out, password); 80 | } finally { 81 | out.close(); 82 | } 83 | File pem = new File("ca.pem"); 84 | if (!pem.exists()) { 85 | FileWriter w = null; 86 | try { 87 | w = new FileWriter(pem); 88 | w.write(selector.getCACert()); 89 | } catch (IOException e) { 90 | System.err.println("Error exporting CA cert : " + e.getLocalizedMessage()); 91 | } finally { 92 | if (w != null) 93 | w.close(); 94 | } 95 | } 96 | return selector; 97 | } 98 | if (ks.exists()) { 99 | try { 100 | InputStream in = new FileInputStream(ks); 101 | keyStore.load(in, password); 102 | return new AutoGeneratingContextSelector(keyStore, password); 103 | } catch (GeneralSecurityException e) { 104 | System.err.println("Error loading keystore: " + e.getLocalizedMessage()); 105 | } catch (IOException e) { 106 | System.err.println("Error loading keystore: " + e.getLocalizedMessage()); 107 | } 108 | } 109 | throw new GeneralSecurityException("Could not initialise Server SSL ContextSelector"); 110 | } 111 | 112 | public static void main(String[] args) throws Exception { 113 | mxGraphComponent graphComponent = new CustomGraphComponent(new CustomGraph()); 114 | InterceptFrame ui = new InterceptFrame(graphComponent); 115 | ui.setSize(800, 600); 116 | 117 | final SslContext clientContext = SslContextBuilder.forClient() 118 | .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); 119 | 120 | final AutoGeneratingContextSelector serverCertMapping = getServerSslContextSelector(); 121 | 122 | ui.addWindowStateListener(new WindowStateListener() { 123 | @Override 124 | public void windowStateChanged(WindowEvent arg0) { 125 | try { 126 | serverCertMapping.save(new File("keystore.jks"), "password".toCharArray()); 127 | } catch (Exception e) { 128 | e.printStackTrace(); 129 | } 130 | } 131 | }); 132 | Graph graph = new Graph(graphComponent.getGraph(), serverCertMapping, clientContext); 133 | ui.setGraph(graph); 134 | ui.setVisible(true); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/ssl/CertificateUtils.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.ssl; 2 | 3 | import java.io.ByteArrayInputStream; 4 | import java.io.IOException; 5 | import java.math.BigInteger; 6 | import java.security.GeneralSecurityException; 7 | import java.security.PrivateKey; 8 | import java.security.PublicKey; 9 | import java.security.cert.CertificateFactory; 10 | import java.security.cert.X509Certificate; 11 | import java.util.Date; 12 | 13 | import javax.security.auth.x500.X500Principal; 14 | 15 | import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; 16 | import org.bouncycastle.asn1.misc.NetscapeCertType; 17 | import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier; 18 | import org.bouncycastle.asn1.x509.BasicConstraints; 19 | import org.bouncycastle.asn1.x509.ExtendedKeyUsage; 20 | import org.bouncycastle.asn1.x509.Extension; 21 | import org.bouncycastle.asn1.x509.KeyPurposeId; 22 | import org.bouncycastle.asn1.x509.KeyUsage; 23 | import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; 24 | import org.bouncycastle.cert.CertIOException; 25 | import org.bouncycastle.cert.X509CertificateHolder; 26 | import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; 27 | import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; 28 | import org.bouncycastle.operator.OperatorCreationException; 29 | import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; 30 | 31 | public class CertificateUtils { 32 | 33 | private static final String SIGALG = "SHA1withRSA"; 34 | 35 | public static X509Certificate sign(X500Principal subject, PublicKey pubKey, 36 | X500Principal issuer, PublicKey caPubKey, PrivateKey caKey, 37 | Date begin, Date ends, BigInteger serialNo, 38 | X509Certificate baseCrt) 39 | throws GeneralSecurityException, CertIOException, OperatorCreationException, IOException { 40 | 41 | if (baseCrt != null) { 42 | subject = baseCrt.getSubjectX500Principal(); 43 | } 44 | 45 | JcaX509v3CertificateBuilder certificateBuilder; 46 | certificateBuilder = new JcaX509v3CertificateBuilder(issuer, serialNo, 47 | begin, ends, subject, pubKey); 48 | 49 | if (subject.equals(issuer)) { 50 | certificateBuilder.addExtension( 51 | Extension.basicConstraints, true, 52 | new BasicConstraints(5)); 53 | } else { 54 | JcaX509ExtensionUtils jxeu = new JcaX509ExtensionUtils(); 55 | 56 | if (baseCrt != null) { 57 | byte[] sans = baseCrt.getExtensionValue(Extension.subjectAlternativeName.getId()); 58 | if (sans != null) { 59 | certificateBuilder.copyAndAddExtension(Extension.subjectAlternativeName, true, baseCrt); 60 | } 61 | } 62 | 63 | SubjectKeyIdentifier subjectKeyIdentifier = jxeu.createSubjectKeyIdentifier(pubKey); 64 | certificateBuilder.addExtension( 65 | Extension.subjectKeyIdentifier, false, subjectKeyIdentifier); 66 | 67 | AuthorityKeyIdentifier authorityKeyIdentifier = jxeu.createAuthorityKeyIdentifier(caPubKey); 68 | certificateBuilder.addExtension( 69 | Extension.authorityKeyIdentifier, false, 70 | authorityKeyIdentifier); 71 | 72 | certificateBuilder.addExtension( 73 | Extension.basicConstraints, true, 74 | new BasicConstraints(false)); 75 | 76 | NetscapeCertType netscapeCertType = new NetscapeCertType(NetscapeCertType.sslClient | NetscapeCertType.sslServer); 77 | certificateBuilder.addExtension( 78 | MiscObjectIdentifiers.netscapeCertType, false, 79 | netscapeCertType); 80 | 81 | KeyUsage keyUsage = new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment); 82 | certificateBuilder.addExtension(Extension.keyUsage, true, 83 | keyUsage); 84 | 85 | ExtendedKeyUsage extendedKeyUsage = new ExtendedKeyUsage(new KeyPurposeId[]{ 86 | KeyPurposeId.id_kp_clientAuth, 87 | KeyPurposeId.id_kp_serverAuth 88 | }); 89 | certificateBuilder.addExtension(Extension.extendedKeyUsage, false, 90 | extendedKeyUsage); 91 | } 92 | 93 | JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(SIGALG); 94 | X509CertificateHolder holder = certificateBuilder.build(signerBuilder.build(caKey)); 95 | 96 | /* 97 | * Next certificate factory trick is needed to make sure that the 98 | * certificate delivered to the caller is provided by the default 99 | * security provider instead of BouncyCastle. If we don't do this trick 100 | * we might run into trouble when trying to use the CertPath validator. 101 | */ 102 | CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); 103 | X509Certificate certificate; 104 | certificate = (X509Certificate) certificateFactory.generateCertificate(new ByteArrayInputStream(holder.getEncoded())); 105 | return certificate; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/com/mxgraph/examples/swing/editor/DefaultFileFilter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2001-2005, Gaudenz Alder 3 | * 4 | * All rights reserved. 5 | * 6 | * See LICENSE file for license details. If you are unable to locate 7 | * this file please contact info (at) jgraph (dot) com. 8 | */ 9 | package com.mxgraph.examples.swing.editor; 10 | 11 | import java.io.File; 12 | 13 | import javax.imageio.ImageIO; 14 | import javax.swing.JFileChooser; 15 | import javax.swing.filechooser.FileFilter; 16 | 17 | /** 18 | * Filter for use in a {@link JFileChooser}. 19 | */ 20 | public class DefaultFileFilter extends FileFilter 21 | { 22 | 23 | /** 24 | * Extension of accepted files. 25 | */ 26 | protected String ext; 27 | 28 | /** 29 | * Description of accepted files. 30 | */ 31 | protected String desc; 32 | 33 | /** 34 | * Constructs a new filter for the specified extension and descpription. 35 | * 36 | * @param extension 37 | * The extension to accept files with. 38 | * @param description 39 | * The description of the file format. 40 | */ 41 | public DefaultFileFilter(String extension, String description) 42 | { 43 | ext = extension.toLowerCase(); 44 | desc = description; 45 | } 46 | 47 | /** 48 | * Returns true if file is a directory or ends with 49 | * {@link #ext}. 50 | * 51 | * @param file 52 | * The file to be checked. 53 | * @return Returns true if the file is accepted. 54 | */ 55 | public boolean accept(File file) 56 | { 57 | return file.isDirectory() || file.getName().toLowerCase().endsWith(ext); 58 | } 59 | 60 | /** 61 | * Returns the description for accepted files. 62 | * 63 | * @return Returns the description. 64 | */ 65 | public String getDescription() 66 | { 67 | return desc; 68 | } 69 | 70 | /** 71 | * Returns the extension for accepted files. 72 | * 73 | * @return Returns the extension. 74 | */ 75 | public String getExtension() 76 | { 77 | return ext; 78 | } 79 | 80 | /** 81 | * Sets the extension for accepted files. 82 | * 83 | * @param extension 84 | * The extension to set. 85 | */ 86 | public void setExtension(String extension) 87 | { 88 | this.ext = extension; 89 | } 90 | 91 | /** 92 | * Utility file filter to accept all image formats supported by image io. 93 | * 94 | * @see ImageIO#getReaderFormatNames() 95 | */ 96 | public static class ImageFileFilter extends FileFilter 97 | { 98 | 99 | /** 100 | * Holds the accepted file format extensions for images. 101 | */ 102 | protected static String[] imageFormats = ImageIO.getReaderFormatNames(); 103 | 104 | /** 105 | * Description of the filter. 106 | */ 107 | protected String desc; 108 | 109 | /** 110 | * Constructs a new file filter for all supported image formats using 111 | * the specified description. 112 | * 113 | * @param description 114 | * The description to use for the file filter. 115 | */ 116 | public ImageFileFilter(String description) 117 | { 118 | desc = description; 119 | } 120 | 121 | /** 122 | * Returns true if the file is a directory or ends with a known image 123 | * extension. 124 | * 125 | * @param file 126 | * The file to be checked. 127 | * @return Returns true if the file is accepted. 128 | */ 129 | public boolean accept(File file) 130 | { 131 | if (file.isDirectory()) 132 | { 133 | return true; 134 | } 135 | 136 | String filename = file.toString().toLowerCase(); 137 | 138 | for (int j = 0; j < imageFormats.length; j++) 139 | { 140 | if (filename.endsWith("." + imageFormats[j].toLowerCase())) 141 | { 142 | return true; 143 | } 144 | } 145 | 146 | return false; 147 | } 148 | 149 | /** 150 | * Returns the description. 151 | * 152 | * @return Returns the description. 153 | */ 154 | public String getDescription() 155 | { 156 | return desc; 157 | } 158 | 159 | } 160 | 161 | /** 162 | * Utility file filter to accept editor files, namely .xml and .xml.gz 163 | * extensions. 164 | * 165 | * @see ImageIO#getReaderFormatNames() 166 | */ 167 | public static class EditorFileFilter extends FileFilter 168 | { 169 | 170 | /** 171 | * Description of the File format 172 | */ 173 | protected String desc; 174 | 175 | /** 176 | * Constructs a new editor file filter using the specified description. 177 | * 178 | * @param description 179 | * The description to use for the filter. 180 | */ 181 | public EditorFileFilter(String description) 182 | { 183 | desc = description; 184 | } 185 | 186 | /** 187 | * Returns true if the file is a directory or has a .xml or .xml.gz 188 | * extension. 189 | * 190 | * @return Returns true if the file is accepted. 191 | */ 192 | public boolean accept(File file) 193 | { 194 | if (file.isDirectory()) 195 | { 196 | return true; 197 | } 198 | 199 | String filename = file.getName().toLowerCase(); 200 | 201 | return filename.endsWith(".xml") || filename.endsWith(".xml.gz"); 202 | } 203 | 204 | /** 205 | * Returns the description. 206 | * 207 | * @return Returns the description. 208 | */ 209 | public String getDescription() 210 | { 211 | return desc; 212 | } 213 | 214 | } 215 | } 216 | -------------------------------------------------------------------------------- /src/main/resources/com/mxgraph/examples/swing/resources/editor_ru.properties: -------------------------------------------------------------------------------- 1 | file=\u0424\u0430\u0439\u043b 2 | new=\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 3 | openFile=\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0444\u0430\u0439\u043b 4 | save=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c 5 | saveAs=\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0430\u043a 6 | print=\u041f\u0435\u0447\u0430\u0442\u044c 7 | edit=\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c 8 | undo=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c 9 | redo=\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c 10 | cut=\u0412\u044b\u0440\u0435\u0437\u0430\u0442\u044c 11 | copy=\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c 12 | paste=\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u044c 13 | delete=\u0423\u0434\u0430\u043b\u0438\u0442\u044c 14 | selectAll=\u0412\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u0432\u0441\u0435 15 | pageLayout=\u0420\u0430\u0437\u043c\u0435\u0442\u043a\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b 16 | grid=\u0421\u0435\u0442\u043a\u0430 17 | zoom=\u041c\u0430\u0441\u0448\u0442\u0430\u0431 18 | custom=\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c 19 | zoomIn=\u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0442\u044c 20 | zoomOut=\u0423\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c 21 | width=\u0428\u0438\u0440\u0438\u043d\u0430 22 | actualSize=\u0420\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 23 | format=\u0424\u043e\u0440\u043c\u0430\u0442 24 | left=\u0421\u043b\u0435\u0432\u0430 25 | center=\u041f\u043e \u0446\u0435\u043d\u0442\u0440\u0443 26 | right=\u0421\u043f\u0440\u0430\u0432\u0430 27 | top=\u0421\u0432\u0435\u0440\u0445\u0443 28 | middle=\u041f\u043e \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 29 | bottom=\u0421\u043d\u0438\u0437\u0443 30 | label=\u041d\u0430\u0434\u043f\u0438\u0441\u044c 31 | position=\u041f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 32 | shadow=\u0422\u0435\u043d\u044c 33 | opacity=\u041d\u0435\u043f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u044c 34 | hide=\u0421\u043a\u0440\u044b\u0442\u044c 35 | line=\u041b\u0438\u043d\u0438\u044f 36 | straight=\u041f\u0440\u044f\u043c\u043e\u0435 37 | horizontal=\u0413\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435 38 | vertical=\u0412\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 39 | entityRelation=\u0421\u0432\u044f\u0437\u044c \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0435\u0439 40 | arrow=\u0421\u0442\u0440\u0435\u043b\u043a\u0430 41 | plain=\u041f\u0440\u043e\u0441\u0442\u043e\u0435 42 | rounded=\u0421\u043a\u0440\u0443\u0433\u043b\u0438\u0442\u044c 43 | dashed=\u041f\u0443\u043d\u043a\u0442\u0438\u0440 44 | linewidth=\u0422\u043e\u043b\u0449\u0438\u043d\u0430 \u043b\u0438\u043d\u0438\u0438 45 | linestart=\u041d\u0430\u0447\u0430\u043b\u043e \u0441\u0442\u0440\u0435\u043b\u043a\u0438 46 | open=\u041e\u0442\u043a\u0440\u044b\u0442\u044c 47 | classic=\u041a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0430\u044f 48 | block=\u0422\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0430\u044f 49 | diamond=\u0420\u043e\u043c\u0431\u043e\u0432\u0438\u0434\u043d\u0430\u044f 50 | oval=\u0428\u0430\u0440\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u0430\u044f 51 | none=\u041d\u0435\u0442 \u0441\u0442\u0440\u0435\u043b\u043a\u0438 52 | size=\u0420\u0430\u0437\u043c\u0435\u0440 53 | lineend=\u041a\u043e\u043d\u0435\u0446 \u0441\u0442\u0440\u0435\u043b\u043a\u0438 54 | spacing=\u041e\u0442\u0441\u0442\u0443\u043f\u044b 55 | perimeter=\u041f\u043e \u043f\u0435\u0440\u0438\u043c\u0435\u0442\u0440\u0443 56 | global=\u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 57 | direction=\u041d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 58 | north=\u0421\u0435\u0432\u0435\u0440 59 | east=\u0412\u043e\u0441\u0442\u043e\u043a 60 | south=\u042e\u0433 61 | west=\u0417\u0430\u043f\u0430\u0434 62 | rotation=\u041f\u043e\u0432\u043e\u0440\u043e\u0442 63 | style=\u0421\u0442\u0438\u043b\u044c 64 | shape=\u0424\u0438\u0433\u0443\u0440\u0430 65 | group=\u0421\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c 66 | ungroup=\u0420\u0430\u0437\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c 67 | removeFromGroup=\u0423\u0431\u0440\u0430\u0442\u044c \u0438\u0437 \u0433\u0440\u0443\u043f\u043f\u044b 68 | updateGroupBounds=\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u0433\u0440\u0443\u043f\u043f\u044b 69 | toBack=\u041d\u0430 \u0437\u0430\u0434\u043d\u0438\u0439 \u043f\u043b\u0430\u043d 70 | toFront=\u041d\u0430 \u043f\u0435\u0440\u0435\u0434\u043d\u0438\u0439 \u043f\u043b\u0430\u043d 71 | align=\u0412\u044b\u0440\u043e\u0432\u043d\u044f\u0442\u044c 72 | autosize=\u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 73 | outline=\u041e\u0431\u0449\u0430\u044f \u043f\u0435\u0440\u0441\u043f\u0435\u043a\u0442\u0438\u0432\u0430 74 | background=\u0424\u043e\u043d 75 | line=\u041b\u0438\u043d\u0438\u044f 76 | help=\u041f\u043e\u043c\u043e\u0449\u044c 77 | selectVertices=\u0412\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u0432\u0435\u0440\u0448\u0438\u043d\u044b 78 | selectEdges=\u0412\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u0441\u0442\u043e\u0440\u043e\u043d\u044b 79 | file=\u0424\u0430\u0439\u043b 80 | error=\u041e\u0448\u0438\u0431\u043a\u0430 -------------------------------------------------------------------------------- /src/main/java/com/mxgraph/examples/swing/Validation.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2007-2012, JGraph Ltd 3 | */ 4 | package com.mxgraph.examples.swing; 5 | 6 | import java.io.IOException; 7 | import java.util.Arrays; 8 | 9 | import javax.swing.JFrame; 10 | 11 | import org.w3c.dom.Document; 12 | import org.w3c.dom.Element; 13 | 14 | import com.mxgraph.io.mxCodec; 15 | import com.mxgraph.swing.mxGraphComponent; 16 | import com.mxgraph.swing.handler.mxKeyboardHandler; 17 | import com.mxgraph.swing.handler.mxRubberband; 18 | import com.mxgraph.util.mxDomUtils; 19 | import com.mxgraph.util.mxEvent; 20 | import com.mxgraph.util.mxEventObject; 21 | import com.mxgraph.util.mxEventSource.mxIEventListener; 22 | import com.mxgraph.util.mxUtils; 23 | import com.mxgraph.util.mxXmlUtils; 24 | import com.mxgraph.view.mxGraph; 25 | import com.mxgraph.view.mxMultiplicity; 26 | 27 | public class Validation extends JFrame { 28 | 29 | /** 30 | * 31 | */ 32 | private static final long serialVersionUID = -8928982366041695471L; 33 | 34 | public Validation() { 35 | super("Hello, World!"); 36 | 37 | Document xmlDocument = mxDomUtils.createDocument(); 38 | Element listener = xmlDocument.createElement("Listener"); 39 | listener.setAttribute("classname", "io.netty.channel.socket.nio.NioServerSocketChannel"); 40 | listener.setAttribute("socketaddress", "localhost:1080"); 41 | 42 | Element socks = xmlDocument.createElement("ChannelHandler"); 43 | socks.setAttribute("classname", "com.sensepost.mallet.SocksInitializer"); 44 | 45 | Element logger = xmlDocument.createElement("ChannelHandler"); 46 | logger.setAttribute("classname", "io.netty.handler.logging.LoggingHandler"); 47 | 48 | Element relay = xmlDocument.createElement("Relay"); 49 | relay.setAttribute("classname", "com.sensepost.mallet.InterceptHandler"); 50 | relay.appendChild(xmlDocument.createElement("Parameter")) 51 | .appendChild(xmlDocument.createCDATASection("{InterceptController}\r\nFoo\r\nBar\r\n< > & ]]> foobar\r\n")); 52 | 53 | Element sink = xmlDocument.createElement("Sink"); 54 | 55 | mxGraph graph = new mxGraph(); 56 | Object parent = graph.getDefaultParent(); 57 | 58 | graph.getModel().beginUpdate(); 59 | try { 60 | Object v1 = graph.insertVertex(parent, null, listener, 20, 20, 80, 30); 61 | Object v2 = graph.insertVertex(parent, null, socks, 120, 20, 80, 30); 62 | Object v2_5 = graph.insertVertex(parent, null, logger, 170, 20, 80, 30); 63 | Object v3 = graph.insertVertex(parent, null, relay, 220, 20, 80, 30); 64 | Object v3_5 = graph.insertVertex(parent, null, logger.cloneNode(true), 270, 20, 80, 30); 65 | Object v4 = graph.insertVertex(parent, null, sink, 320, 20, 80, 30); 66 | 67 | graph.insertEdge(parent, null, "", v1, v2); 68 | graph.insertEdge(parent, null, "", v2, v2_5); 69 | graph.insertEdge(parent, null, "", v2_5, v3); 70 | graph.insertEdge(parent, null, "", v3, v3_5); 71 | graph.insertEdge(parent, null, "", v3_5, v4); 72 | // Object e4 = graph.insertEdge(parent, null, "", v1, v4); 73 | } finally { 74 | graph.getModel().endUpdate(); 75 | } 76 | 77 | mxMultiplicity[] multiplicities = new mxMultiplicity[3]; 78 | 79 | multiplicities[0] = new mxMultiplicity(true, "Listener", null, null, 1, "1", 80 | Arrays.asList(new String[] { "ChannelHandler", "Relay" }), 81 | "Listener must have only 1 ChannelHandler or Relay", "Listener must connect to handler", true); 82 | 83 | // Source node does not want any incoming connections 84 | multiplicities[1] = new mxMultiplicity(false, "Listener", null, null, 0, "0", null, 85 | "Listener must have no incoming edge", null, true); // Type does 86 | // not 87 | // matter 88 | 89 | // Target needs exactly one incoming connection from Source 90 | multiplicities[2] = new mxMultiplicity(false, "ChannelHandler", null, null, 1, "1", 91 | Arrays.asList(new String[] { "Listener", "ChannelHandler" }), 92 | "ChannelHandler can only accept connections from a Listener or a previous Handler", 93 | "Handler must connect from Listener or Handler", true); 94 | 95 | graph.setMultiplicities(multiplicities); 96 | 97 | mxCodec codec = new mxCodec(); 98 | String xml = mxXmlUtils.getXml(codec.encode(graph.getModel())); 99 | 100 | try { 101 | mxUtils.writeFile(xml, "validation2.mxe"); 102 | } catch (IOException ioe) { 103 | ioe.printStackTrace(); 104 | } 105 | 106 | final mxGraphComponent graphComponent = new mxGraphComponent(graph); 107 | graph.setMultigraph(false); 108 | graph.setAllowDanglingEdges(false); 109 | graphComponent.setConnectable(true); 110 | graphComponent.setToolTips(true); 111 | 112 | // Enables rubberband selection 113 | new mxRubberband(graphComponent); 114 | new mxKeyboardHandler(graphComponent); 115 | 116 | // Installs automatic validation (use editor.validation = true 117 | // if you are using an mxEditor instance) 118 | graph.getModel().addListener(mxEvent.CHANGE, new mxIEventListener() { 119 | public void invoke(Object sender, mxEventObject evt) { 120 | graphComponent.validateGraph(); 121 | } 122 | }); 123 | 124 | // Initial validation 125 | graphComponent.validateGraph(); 126 | 127 | getContentPane().add(graphComponent); 128 | } 129 | 130 | public static void main(String[] args) { 131 | Validation frame = new Validation(); 132 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 133 | frame.setSize(400, 320); 134 | frame.setVisible(true); 135 | } 136 | 137 | } 138 | -------------------------------------------------------------------------------- /src/main/java/com/mxgraph/examples/swing/editor/EditorAboutFrame.java: -------------------------------------------------------------------------------- 1 | package com.mxgraph.examples.swing.editor; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.Color; 5 | import java.awt.FlowLayout; 6 | import java.awt.Font; 7 | import java.awt.Frame; 8 | import java.awt.GradientPaint; 9 | import java.awt.Graphics; 10 | import java.awt.Graphics2D; 11 | import java.awt.event.ActionEvent; 12 | import java.awt.event.ActionListener; 13 | import java.awt.event.KeyEvent; 14 | 15 | import javax.swing.BorderFactory; 16 | import javax.swing.BoxLayout; 17 | import javax.swing.JButton; 18 | import javax.swing.JComponent; 19 | import javax.swing.JDialog; 20 | import javax.swing.JLabel; 21 | import javax.swing.JPanel; 22 | import javax.swing.JRootPane; 23 | import javax.swing.KeyStroke; 24 | 25 | import com.mxgraph.util.mxResources; 26 | import com.mxgraph.view.mxGraph; 27 | 28 | public class EditorAboutFrame extends JDialog 29 | { 30 | 31 | /** 32 | * 33 | */ 34 | private static final long serialVersionUID = -3378029138434324390L; 35 | 36 | /** 37 | * 38 | */ 39 | public EditorAboutFrame(Frame owner) 40 | { 41 | super(owner); 42 | setTitle(mxResources.get("aboutGraphEditor")); 43 | setLayout(new BorderLayout()); 44 | 45 | // Creates the gradient panel 46 | JPanel panel = new JPanel(new BorderLayout()) 47 | { 48 | 49 | /** 50 | * 51 | */ 52 | private static final long serialVersionUID = -5062895855016210947L; 53 | 54 | /** 55 | * 56 | */ 57 | public void paintComponent(Graphics g) 58 | { 59 | super.paintComponent(g); 60 | 61 | // Paint gradient background 62 | Graphics2D g2d = (Graphics2D) g; 63 | g2d.setPaint(new GradientPaint(0, 0, Color.WHITE, getWidth(), 64 | 0, getBackground())); 65 | g2d.fillRect(0, 0, getWidth(), getHeight()); 66 | } 67 | 68 | }; 69 | 70 | panel.setBorder(BorderFactory.createCompoundBorder(BorderFactory 71 | .createMatteBorder(0, 0, 1, 0, Color.GRAY), BorderFactory 72 | .createEmptyBorder(8, 8, 12, 8))); 73 | 74 | // Adds title 75 | JLabel titleLabel = new JLabel(mxResources.get("aboutGraphEditor")); 76 | titleLabel.setFont(titleLabel.getFont().deriveFont(Font.BOLD)); 77 | titleLabel.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0)); 78 | titleLabel.setOpaque(false); 79 | panel.add(titleLabel, BorderLayout.NORTH); 80 | 81 | // Adds optional subtitle 82 | JLabel subtitleLabel = new JLabel( 83 | "For more information visit http://www.mxgraph.com/"); 84 | subtitleLabel.setBorder(BorderFactory.createEmptyBorder(4, 18, 0, 0)); 85 | subtitleLabel.setOpaque(false); 86 | panel.add(subtitleLabel, BorderLayout.CENTER); 87 | 88 | getContentPane().add(panel, BorderLayout.NORTH); 89 | 90 | JPanel content = new JPanel(); 91 | content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS)); 92 | content.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12)); 93 | 94 | content.add(new JLabel("JGraph X - The Swing Portion of mxGraph")); 95 | content.add(new JLabel(" ")); 96 | 97 | content.add(new JLabel("mxGraph Version " + mxGraph.VERSION)); 98 | content.add(new JLabel("Copyright (C) 2009 by JGraph Ltd.")); 99 | content.add(new JLabel("All rights reserved.")); 100 | content.add(new JLabel(" ")); 101 | 102 | try 103 | { 104 | content.add(new JLabel("Operating System Name: " 105 | + System.getProperty("os.name"))); 106 | content.add(new JLabel("Operating System Version: " 107 | + System.getProperty("os.version"))); 108 | content.add(new JLabel(" ")); 109 | 110 | content.add(new JLabel("Java Vendor: " 111 | + System.getProperty("java.vendor", "undefined"))); 112 | content.add(new JLabel("Java Version: " 113 | + System.getProperty("java.version", "undefined"))); 114 | content.add(new JLabel(" ")); 115 | 116 | content.add(new JLabel("Total Memory: " 117 | + Runtime.getRuntime().totalMemory())); 118 | content.add(new JLabel("Free Memory: " 119 | + Runtime.getRuntime().freeMemory())); 120 | } 121 | catch (Exception e) 122 | { 123 | // ignore 124 | } 125 | 126 | getContentPane().add(content, BorderLayout.CENTER); 127 | 128 | JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); 129 | buttonPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory 130 | .createMatteBorder(1, 0, 0, 0, Color.GRAY), BorderFactory 131 | .createEmptyBorder(16, 8, 8, 8))); 132 | getContentPane().add(buttonPanel, BorderLayout.SOUTH); 133 | 134 | // Adds OK button to close window 135 | JButton closeButton = new JButton("Close"); 136 | closeButton.addActionListener(new ActionListener() 137 | { 138 | public void actionPerformed(ActionEvent e) 139 | { 140 | setVisible(false); 141 | } 142 | }); 143 | 144 | buttonPanel.add(closeButton); 145 | 146 | // Sets default button for enter key 147 | getRootPane().setDefaultButton(closeButton); 148 | 149 | setResizable(false); 150 | setSize(400, 400); 151 | } 152 | 153 | /** 154 | * Overrides {@link JDialog#createRootPane()} to return a root pane that 155 | * hides the window when the user presses the ESCAPE key.O 156 | */ 157 | protected JRootPane createRootPane() 158 | { 159 | KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); 160 | JRootPane rootPane = new JRootPane(); 161 | rootPane.registerKeyboardAction(new ActionListener() 162 | { 163 | public void actionPerformed(ActionEvent actionEvent) 164 | { 165 | setVisible(false); 166 | } 167 | }, stroke, JComponent.WHEN_IN_FOCUSED_WINDOW); 168 | return rootPane; 169 | } 170 | 171 | } 172 | -------------------------------------------------------------------------------- /http.mxe: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /graph.mxe: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.sensepost 6 | mallet 7 | jar 8 | 9 | http://maven.apache.org 10 | 11 | 1.0-SNAPSHOT 12 | mallet 13 | 14 | 1.7 15 | 1.7 16 | 1.7 17 | 1.7 18 | UTF-8 19 | 20 | 21 | 22 | jitpack.io 23 | https://jitpack.io 24 | 25 | 26 | 27 | 28 | io.netty 29 | netty-all 30 | 4.1.11.Final 31 | 32 | 33 | org.bouncycastle 34 | bcprov-jdk15on 35 | 1.52 36 | 37 | 38 | org.bouncycastle 39 | bcpkix-jdk15on 40 | 1.52 41 | 42 | 43 | org.springframework 44 | spring-jdbc 45 | 4.2.5.RELEASE 46 | compile 47 | 48 | 49 | aopalliance 50 | aopalliance 51 | 52 | 53 | spring-context 54 | org.springframework 55 | 56 | 57 | true 58 | 59 | 60 | com.h2database 61 | h2 62 | 1.4.191 63 | 64 | 65 | commons-cli 66 | commons-cli 67 | 1.2 68 | 69 | 70 | com.github.jgraph 71 | jgraphx 72 | v3.7.1 73 | 74 | 75 | 76 | org.swinglabs.swingx 77 | swingx-all 78 | 1.6.5-1 79 | 80 | 81 | 82 | org.codehaus.groovy 83 | groovy-all 84 | 2.4.10 85 | 86 | 87 | 88 | org.luaj 89 | luaj-jse 90 | 3.0.1 91 | 92 | 93 | 94 | com.fasterxml.jackson.core 95 | jackson-databind 96 | 2.8.9 97 | 98 | 99 | 100 | junit 101 | junit 102 | 4.12 103 | 104 | 105 | com.jolira 106 | onejar-maven-plugin 107 | 1.4.4 108 | 109 | 110 | 111 | 112 | 113 | 114 | org.apache.maven.plugins 115 | maven-jar-plugin 116 | 2.4 117 | 118 | 119 | 120 | true 121 | com.sensepost.mallet.Main 122 | 123 | 124 | 125 | 126 | 127 | 128 | org.apache.maven.plugins 129 | maven-dependency-plugin 130 | 2.5.1 131 | 132 | 133 | copy-dependencies 134 | package 135 | 136 | copy-dependencies 137 | 138 | 139 | 140 | ${project.build.directory}/ 141 | 142 | 143 | 144 | 145 | 146 | 147 | com.jolira 148 | onejar-maven-plugin 149 | 1.4.4 150 | 151 | 152 | 153 | 0.97 154 | 155 | 156 | one-jar 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/swing/ConnectionPanel.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.swing; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.Color; 5 | import java.awt.Component; 6 | import java.net.SocketAddress; 7 | import java.util.HashMap; 8 | import java.util.LinkedHashMap; 9 | import java.util.Map; 10 | 11 | import javax.swing.DefaultListCellRenderer; 12 | import javax.swing.DefaultListModel; 13 | import javax.swing.JLabel; 14 | import javax.swing.JList; 15 | import javax.swing.JPanel; 16 | import javax.swing.JScrollPane; 17 | import javax.swing.JSplitPane; 18 | import javax.swing.ListCellRenderer; 19 | import javax.swing.ListSelectionModel; 20 | import javax.swing.event.ListSelectionEvent; 21 | import javax.swing.event.ListSelectionListener; 22 | 23 | import com.sensepost.mallet.InterceptController.ChannelActiveEvent; 24 | import com.sensepost.mallet.InterceptController.ChannelEvent; 25 | 26 | public class ConnectionPanel extends JPanel { 27 | 28 | private ConnectionDataPanel cdp; 29 | 30 | private JList list; 31 | private DefaultListModel listModel = new DefaultListModel<>(); 32 | 33 | private Map connAddrMap = new HashMap<>(); 34 | private Map channelEventMap = new LinkedHashMap<>(); 35 | 36 | private boolean intercept = false; 37 | 38 | public ConnectionPanel() { 39 | setLayout(new BorderLayout(0, 0)); 40 | JSplitPane splitPane = new JSplitPane(); 41 | splitPane.setResizeWeight(0.5); 42 | add(splitPane); 43 | 44 | JScrollPane scrollPane = new JScrollPane(); 45 | splitPane.setLeftComponent(scrollPane); 46 | 47 | list = new JList<>(listModel); 48 | list.addListSelectionListener(new ListSelectionListener() { 49 | public void valueChanged(ListSelectionEvent e) { 50 | if (e.getValueIsAdjusting()) 51 | return; 52 | ConnectionData cd = null; 53 | if (list.getSelectedValue() != null) { 54 | synchronized (channelEventMap) { 55 | cd = channelEventMap.get(list.getSelectedValue()); 56 | } 57 | } 58 | cdp.setConnectionData(cd); 59 | } 60 | }); 61 | list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 62 | list.setCellRenderer(new ChannelPairCellRenderer()); 63 | scrollPane.setViewportView(list); 64 | 65 | cdp = new ConnectionDataPanel(); 66 | splitPane.setRightComponent(cdp); 67 | 68 | 69 | } 70 | 71 | public boolean isIntercept() { 72 | return intercept; 73 | } 74 | 75 | public void setIntercept(boolean intercept) { 76 | this.intercept = intercept; 77 | if (!intercept) { 78 | sendAllPendingEvents(); 79 | } 80 | } 81 | 82 | public void addChannelEvent(ChannelEvent evt) throws Exception { 83 | Integer cp = evt.getConnectionIdentifier(); 84 | 85 | if (evt instanceof ChannelActiveEvent) { 86 | ChannelActiveEvent cae = (ChannelActiveEvent) evt; 87 | SocketAddress src = cae.getSourceAddress(); 88 | SocketAddress dst = cae.getDestinationAddress(); 89 | AddrPair ap = new AddrPair(src, dst); 90 | synchronized (connAddrMap) { 91 | if (connAddrMap.get(cp) == null) 92 | connAddrMap.put(cp, ap); 93 | else 94 | connAddrMap.get(cp).dst = cae.getSourceAddress(); 95 | } 96 | } 97 | 98 | synchronized (channelEventMap) { 99 | ConnectionData eventList; 100 | if (!channelEventMap.containsKey(cp)) { 101 | eventList = new ConnectionData(); 102 | channelEventMap.put(cp, eventList); 103 | listModel.addElement(cp); 104 | } else { 105 | eventList = channelEventMap.get(cp); 106 | } 107 | eventList.addChannelEvent(evt); 108 | 109 | // force redraw of the element in the list 110 | int index = listModel.indexOf(cp); 111 | listModel.setElementAt(listModel.getElementAt(index), index); 112 | 113 | if (!intercept) { 114 | try { 115 | eventList.executeAllEvents(); 116 | } catch (Exception e) { 117 | e.printStackTrace(); 118 | } 119 | } 120 | } 121 | } 122 | 123 | private void sendAllPendingEvents() { 124 | synchronized (channelEventMap) { 125 | for (Integer conn : channelEventMap.keySet()) { 126 | try { 127 | channelEventMap.get(conn).executeAllEvents(); 128 | } catch (Exception e) { 129 | e.printStackTrace(); 130 | } 131 | } 132 | } 133 | } 134 | 135 | 136 | protected JList getConnectionList() { 137 | return list; 138 | } 139 | 140 | protected static class AddrPair { 141 | private SocketAddress src, dst; 142 | 143 | public AddrPair(SocketAddress src, SocketAddress dst) { 144 | if (src == null) 145 | throw new NullPointerException("src"); 146 | if (dst == null) 147 | throw new NullPointerException("dst"); 148 | this.src = src; 149 | this.dst = dst; 150 | } 151 | 152 | public int hashCode() { 153 | return src.hashCode() ^ dst.hashCode(); 154 | } 155 | 156 | public boolean equals(Object obj) { 157 | if (!(obj instanceof AddrPair)) 158 | return false; 159 | AddrPair that = (AddrPair) obj; 160 | return (this.src == that.src && this.dst == that.dst) || (this.src == that.dst && this.dst == that.src); 161 | } 162 | } 163 | 164 | private class ChannelPairCellRenderer implements ListCellRenderer { 165 | protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer(); 166 | 167 | @Override 168 | public Component getListCellRendererComponent(JList list, Integer value, int index, 169 | boolean isSelected, boolean cellHasFocus) { 170 | 171 | AddrPair ap = connAddrMap.get(value); 172 | String text = value + " : " + ap.src + " -> " + ap.dst; 173 | ConnectionData cd = channelEventMap.get(value); 174 | text += " (" + cd.getPendingEventCount() + "/" + cd.getEventCount() + ")"; 175 | if (cd.isClosed()) 176 | text += " CLOSED"; 177 | JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, text, index, isSelected, 178 | cellHasFocus); 179 | if (cd.isClosed()) 180 | renderer.setBackground(Color.LIGHT_GRAY); 181 | 182 | return renderer; 183 | } 184 | 185 | } 186 | 187 | 188 | } 189 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/SocksServerConnectHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | package com.sensepost.mallet; 17 | 18 | import java.net.InetSocketAddress; 19 | 20 | import io.netty.channel.Channel; 21 | import io.netty.channel.ChannelFuture; 22 | import io.netty.channel.ChannelFutureListener; 23 | import io.netty.channel.ChannelHandler; 24 | import io.netty.channel.ChannelHandlerContext; 25 | import io.netty.channel.SimpleChannelInboundHandler; 26 | import io.netty.handler.codec.socksx.AbstractSocksMessage; 27 | import io.netty.handler.codec.socksx.SocksMessage; 28 | import io.netty.handler.codec.socksx.v4.DefaultSocks4CommandResponse; 29 | import io.netty.handler.codec.socksx.v4.Socks4CommandRequest; 30 | import io.netty.handler.codec.socksx.v4.Socks4CommandStatus; 31 | import io.netty.handler.codec.socksx.v4.Socks4ServerDecoder; 32 | import io.netty.handler.codec.socksx.v4.Socks4ServerEncoder; 33 | import io.netty.handler.codec.socksx.v5.DefaultSocks5CommandResponse; 34 | import io.netty.handler.codec.socksx.v5.Socks5CommandRequest; 35 | import io.netty.handler.codec.socksx.v5.Socks5CommandRequestDecoder; 36 | import io.netty.handler.codec.socksx.v5.Socks5CommandStatus; 37 | import io.netty.handler.codec.socksx.v5.Socks5ServerEncoder; 38 | import io.netty.util.concurrent.Future; 39 | import io.netty.util.concurrent.FutureListener; 40 | import io.netty.util.concurrent.Promise; 41 | import io.netty.util.internal.logging.InternalLogger; 42 | import io.netty.util.internal.logging.InternalLoggerFactory; 43 | 44 | @ChannelHandler.Sharable 45 | public final class SocksServerConnectHandler extends SimpleChannelInboundHandler { 46 | 47 | private static final InternalLogger logger = InternalLoggerFactory.getInstance(SocksServerConnectHandler.class); 48 | 49 | private final DefaultSocks4CommandResponse socks4Success = new DefaultSocks4CommandResponse( 50 | Socks4CommandStatus.SUCCESS); 51 | private final DefaultSocks4CommandResponse socks4Failure = new DefaultSocks4CommandResponse( 52 | Socks4CommandStatus.REJECTED_OR_FAILED); 53 | 54 | @Override 55 | public void channelRead0(final ChannelHandlerContext ctx, final SocksMessage message) throws Exception { 56 | final AbstractSocksMessage success, failure; 57 | 58 | String host = null; 59 | int port = 0; 60 | Class socksEncoder = null; 61 | 62 | if (message instanceof Socks4CommandRequest) { 63 | Socks4CommandRequest request = (Socks4CommandRequest) message; 64 | 65 | success = socks4Success; 66 | failure = socks4Failure; 67 | 68 | host = request.dstAddr(); 69 | port = request.dstPort(); 70 | 71 | // we're not going to need this anymore 72 | ctx.pipeline().remove(Socks4ServerDecoder.class); 73 | // and we can remove this once the response message has been written 74 | socksEncoder = Socks4ServerEncoder.class; 75 | 76 | } else if (message instanceof Socks5CommandRequest) { 77 | Socks5CommandRequest request = (Socks5CommandRequest) message; 78 | 79 | success = new DefaultSocks5CommandResponse(Socks5CommandStatus.SUCCESS, request.dstAddrType()); 80 | failure = new DefaultSocks5CommandResponse(Socks5CommandStatus.FAILURE, request.dstAddrType()); 81 | 82 | host = request.dstAddr(); 83 | port = request.dstPort(); 84 | 85 | // we're not going to need this anymore 86 | ctx.pipeline().remove(Socks5CommandRequestDecoder.class); 87 | // and we can remove this once the response message has been written 88 | socksEncoder = Socks5ServerEncoder.class; 89 | 90 | } else { 91 | logger.info("Unknown SOCKS message received: " + message); 92 | ctx.close(); 93 | return; 94 | } 95 | 96 | final Promise connectPromise = ctx.executor().newPromise(); 97 | // set up a method to notify the inbound channel if/when the outbound 98 | // channel is connected, or if the connection should be closed. 99 | connectPromise.addListener(new SocksConnectionResponseSender(ctx, success, failure, socksEncoder)); 100 | 101 | ConnectRequest tp = new ConnectRequest(InetSocketAddress.createUnresolved(host, port), connectPromise); 102 | ctx.fireUserEventTriggered(tp); 103 | 104 | ctx.pipeline().remove(this); 105 | } 106 | 107 | @Override 108 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 109 | logger.info(cause); 110 | ctx.close(); 111 | } 112 | 113 | private class SocksConnectionResponseSender implements FutureListener { 114 | 115 | private ChannelHandlerContext ctx; 116 | private AbstractSocksMessage success, failure; 117 | private Class socksEncoder; 118 | 119 | public SocksConnectionResponseSender(ChannelHandlerContext ctx, AbstractSocksMessage success, 120 | AbstractSocksMessage failure, Class socksEncoder) { 121 | this.ctx = ctx; 122 | this.success = success; 123 | this.failure = failure; 124 | this.socksEncoder = socksEncoder; 125 | } 126 | 127 | @Override 128 | public void operationComplete(final Future future) throws Exception { 129 | // we have been told by upstream that the connection is open 130 | if (future.isSuccess()) { 131 | // send the socks client a message to confirm that the connect 132 | // was successful 133 | ctx.writeAndFlush(success).addListener(new ChannelFutureListener() { 134 | @Override 135 | public void operationComplete(ChannelFuture future) { 136 | // once the success message is written, remove the 137 | // encoder 138 | if (future.isSuccess()) { 139 | ctx.pipeline().remove(socksEncoder); 140 | } else { 141 | SocksServerConnectHandler.logger.error("Error writing SOCKS success message", 142 | future.cause()); 143 | ctx.channel().close(); 144 | } 145 | } 146 | }); 147 | } else { 148 | // send a failure message, and close the connection 149 | ctx.writeAndFlush(failure).addListener(ChannelFutureListener.CLOSE); 150 | logger.error("Failed to connect to server", future.cause()); 151 | } 152 | } 153 | } 154 | 155 | } -------------------------------------------------------------------------------- /src/main/java/com/mxgraph/examples/swing/shapes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/swing/editors/HttpMessageEditor.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.swing.editors; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.FlowLayout; 5 | import java.awt.GridLayout; 6 | import java.beans.PropertyChangeEvent; 7 | import java.beans.PropertyChangeListener; 8 | import java.util.Collections; 9 | import java.util.List; 10 | import java.util.Map.Entry; 11 | 12 | import javax.swing.JComponent; 13 | import javax.swing.JLabel; 14 | import javax.swing.JPanel; 15 | import javax.swing.JScrollPane; 16 | import javax.swing.JSplitPane; 17 | import javax.swing.JTable; 18 | import javax.swing.JTextField; 19 | import javax.swing.table.AbstractTableModel; 20 | 21 | import io.netty.handler.codec.http.FullHttpMessage; 22 | import io.netty.handler.codec.http.HttpContent; 23 | import io.netty.handler.codec.http.HttpHeaders; 24 | import io.netty.handler.codec.http.HttpMessage; 25 | import io.netty.handler.codec.http.HttpRequest; 26 | import io.netty.handler.codec.http.HttpResponse; 27 | import io.netty.handler.codec.http.HttpVersion; 28 | import io.netty.handler.codec.http.LastHttpContent; 29 | 30 | public class HttpMessageEditor extends JPanel implements ObjectEditor { 31 | 32 | private PropertyChangeListener listener = new PropertyChangeListener() { 33 | 34 | @Override 35 | public void propertyChange(PropertyChangeEvent evt) { 36 | if (EditorController.OBJECT.equals(evt.getPropertyName())) { 37 | Object o = evt.getNewValue(); 38 | if (o instanceof HttpMessage) { 39 | updateMessage((HttpMessage) o); 40 | } else { 41 | updateMessage(null); 42 | } 43 | } else if (EditorController.READ_ONLY.equals(evt.getPropertyName())) { 44 | boolean editable = Boolean.FALSE.equals(evt.getNewValue()); 45 | updateEditable(editable); 46 | } 47 | } 48 | 49 | }; 50 | 51 | private EditorController controller = null; 52 | private JTextField methodField, urlField, versionField, statusField, messageField; 53 | private JPanel methodPanel, urlPanel, versionPanel, statusPanel, messagePanel; 54 | private HeaderTableModel headerModel = new HeaderTableModel(); 55 | private ByteBufEditor contentEditor; 56 | private EditorController contentController = new EditorController(); 57 | 58 | public HttpMessageEditor() { 59 | setLayout(new BorderLayout(0, 0)); 60 | 61 | JSplitPane splitPane = new JSplitPane(); 62 | splitPane.setResizeWeight(0.5); 63 | splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT); 64 | add(splitPane); 65 | 66 | JPanel panel = new JPanel(); 67 | splitPane.setLeftComponent(panel); 68 | panel.setLayout(new BorderLayout(0, 0)); 69 | 70 | JPanel statusLinePanel = new JPanel(); 71 | statusLinePanel.setLayout(new FlowLayout(FlowLayout.LEFT)); 72 | panel.add(statusLinePanel, BorderLayout.NORTH); 73 | 74 | methodField = new JTextField(); 75 | methodField.setColumns(7); 76 | methodPanel = createPanel("Method", methodField); 77 | statusLinePanel.add(methodPanel); 78 | 79 | urlField = new JTextField(); 80 | urlField.setColumns(10); 81 | urlPanel = createPanel("URL", urlField); 82 | statusLinePanel.add(urlPanel); 83 | 84 | versionField = new JTextField(); 85 | versionField.setColumns(10); 86 | versionPanel = createPanel("Version", versionField); 87 | statusLinePanel.add(versionPanel); 88 | 89 | statusField = new JTextField(); 90 | statusField.setColumns(3); 91 | statusPanel = createPanel("Status", statusField); 92 | statusLinePanel.add(statusPanel); 93 | 94 | messageField = new JTextField(); 95 | messageField.setColumns(10); 96 | messagePanel = createPanel("Message", messageField); 97 | statusLinePanel.add(messagePanel); 98 | 99 | JScrollPane scrollPane = new JScrollPane(); 100 | panel.add(scrollPane, BorderLayout.CENTER); 101 | 102 | JTable headerTable = new JTable(headerModel); 103 | scrollPane.setViewportView(headerTable); 104 | 105 | JPanel panel_1 = new JPanel(); 106 | splitPane.setRightComponent(panel_1); 107 | panel_1.setLayout(new BorderLayout(0, 0)); 108 | 109 | contentEditor = new ByteBufEditor(); 110 | contentEditor.setEditorController(contentController); 111 | panel_1.add(contentEditor.getEditorComponent(), BorderLayout.CENTER); 112 | } 113 | 114 | private JPanel createPanel(String label, JTextField field) { 115 | JPanel p = new JPanel(); 116 | p.setLayout(new GridLayout(0, 1, 0, 0)); 117 | 118 | JLabel l = new JLabel(label); 119 | p.add(l); 120 | p.add(field); 121 | return p; 122 | } 123 | 124 | @Override 125 | public JComponent getEditorComponent() { 126 | return this; 127 | } 128 | 129 | @Override 130 | public Class[] getSupportedClasses() { 131 | return new Class[] { HttpRequest.class, HttpResponse.class, HttpMessage.class, HttpContent.class, 132 | LastHttpContent.class }; 133 | } 134 | 135 | private void updateEditable(boolean editable) { 136 | methodField.setEditable(editable); 137 | urlField.setEditable(editable); 138 | versionField.setEditable(editable); 139 | statusField.setEditable(editable); 140 | messageField.setEditable(editable); 141 | headerModel.setEditable(editable); 142 | contentController.setReadOnly(!editable); 143 | } 144 | 145 | private void updateMessage(HttpMessage message) { 146 | if (message == null) { 147 | headerModel.setHeaders(null); 148 | contentController.setObject(null); 149 | this.setVisible(false); 150 | this.repaint(); 151 | } else { 152 | methodPanel.setVisible(message instanceof HttpRequest); 153 | urlPanel.setVisible(message instanceof HttpRequest); 154 | if (message instanceof HttpRequest) { 155 | HttpRequest req = (HttpRequest) message; 156 | methodField.setText(req.method().name()); 157 | urlField.setText(req.uri()); 158 | } 159 | HttpVersion version = message.protocolVersion(); 160 | versionField.setText(version.text()); 161 | statusPanel.setVisible(message instanceof HttpResponse); 162 | messagePanel.setVisible(message instanceof HttpResponse); 163 | if (message instanceof HttpResponse) { 164 | HttpResponse resp = (HttpResponse) message; 165 | statusField.setText(resp.status().codeAsText().toString()); 166 | messageField.setText(resp.status().reasonPhrase()); 167 | } 168 | headerModel.setHeaders(message.headers()); 169 | if (message instanceof HttpContent) { 170 | HttpContent hc = (HttpContent) message; 171 | contentController.setObject(hc.content()); 172 | } else { 173 | contentController.setObject(null); 174 | } 175 | } 176 | 177 | } 178 | 179 | @Override 180 | public void setEditorController(EditorController controller) { 181 | if (this.controller != null) 182 | controller.removePropertyChangeListener(listener); 183 | this.controller = controller; 184 | if (this.controller != null) { 185 | controller.addPropertyChangeListener(listener); 186 | updateMessage((HttpMessage) controller.getObject()); 187 | updateEditable(!controller.isReadOnly()); 188 | } else { 189 | updateMessage(null); 190 | updateEditable(false); 191 | } 192 | } 193 | 194 | @Override 195 | public String getEditorName() { 196 | return "HTTP Message"; 197 | } 198 | 199 | private static class HeaderTableModel extends AbstractTableModel { 200 | 201 | private static String[] names = new String[] { "Name", "Value" }; 202 | 203 | private HttpHeaders headers = null; 204 | private List> entries = null; 205 | private boolean editable = false; 206 | 207 | public void setHeaders(HttpHeaders headers) { 208 | this.headers = headers; 209 | if (headers != null) 210 | this.entries = headers.entries(); 211 | else 212 | this.entries = Collections.>emptyList(); 213 | fireTableDataChanged(); 214 | } 215 | 216 | public void setEditable(boolean editable) { 217 | this.editable = editable; 218 | } 219 | 220 | @Override 221 | public String getColumnName(int column) { 222 | return names[column]; 223 | } 224 | 225 | @Override 226 | public Class getColumnClass(int column) { 227 | return String.class; 228 | } 229 | 230 | @Override 231 | public int getColumnCount() { 232 | return 2; 233 | } 234 | 235 | @Override 236 | public int getRowCount() { 237 | int ret = headers == null ? 0 : entries.size(); 238 | return ret; 239 | } 240 | 241 | @Override 242 | public Object getValueAt(int row, int column) { 243 | Entry e = entries.get(row); 244 | switch (column) { 245 | case 0: 246 | return e.getKey(); 247 | case 1: 248 | return e.getValue(); 249 | } 250 | return null; 251 | } 252 | 253 | @Override 254 | public boolean isCellEditable(int row, int column) { 255 | return editable; 256 | } 257 | 258 | } 259 | } 260 | -------------------------------------------------------------------------------- /src/main/java/com/sensepost/mallet/swing/editors/ByteArrayEditor.java: -------------------------------------------------------------------------------- 1 | package com.sensepost.mallet.swing.editors; 2 | 3 | import java.awt.BorderLayout; 4 | import java.awt.Event; 5 | import java.awt.event.ActionEvent; 6 | import java.awt.event.KeyEvent; 7 | import java.beans.PropertyChangeEvent; 8 | import java.beans.PropertyChangeListener; 9 | import java.io.ByteArrayOutputStream; 10 | import java.io.FileInputStream; 11 | import java.io.FileOutputStream; 12 | import java.io.IOException; 13 | 14 | import javax.swing.AbstractAction; 15 | import javax.swing.InputMap; 16 | import javax.swing.JComponent; 17 | import javax.swing.JFileChooser; 18 | import javax.swing.JOptionPane; 19 | import javax.swing.JPanel; 20 | import javax.swing.JScrollPane; 21 | import javax.swing.JTable; 22 | import javax.swing.KeyStroke; 23 | import javax.swing.event.TableModelEvent; 24 | import javax.swing.event.TableModelListener; 25 | import javax.swing.table.AbstractTableModel; 26 | 27 | public class ByteArrayEditor extends JPanel implements ObjectEditor { 28 | 29 | private EditorController controller = null; 30 | 31 | private boolean tableUpdating = false; 32 | 33 | private PropertyChangeListener listener = new PropertyChangeListener() { 34 | 35 | @Override 36 | public void propertyChange(PropertyChangeEvent evt) { 37 | if (evt.getSource() != controller) 38 | return; 39 | if (EditorController.OBJECT.equals(evt.getPropertyName())) { 40 | Object o = controller.getObject(); 41 | tableUpdating = true; 42 | if (o instanceof byte[]) { 43 | htm.setData((byte[]) o); 44 | } else { 45 | htm.setData(null); 46 | } 47 | tableUpdating = false; 48 | } else if (EditorController.READ_ONLY.equals(evt.getPropertyName())) { 49 | htm.setEditable(!controller.isReadOnly()); 50 | } 51 | } 52 | 53 | }; 54 | 55 | private TableModelListener tl = new TableModelListener() { 56 | 57 | @Override 58 | public void tableChanged(TableModelEvent e) { 59 | if (tableUpdating) 60 | return; 61 | controller.setObject(htm.getData()); 62 | } 63 | 64 | }; 65 | 66 | private HexTableModel htm = new HexTableModel(8); 67 | private JTable table; 68 | 69 | public ByteArrayEditor() { 70 | setLayout(new BorderLayout(0, 0)); 71 | 72 | JScrollPane scrollPane = new JScrollPane(); 73 | add(scrollPane); 74 | 75 | table = new JTable(); 76 | table.setModel(htm); 77 | scrollPane.setViewportView(table); 78 | htm.addTableModelListener(tl); 79 | 80 | InputMap im = getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 81 | im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, Event.CTRL_MASK), "Save"); 82 | im.put(KeyStroke.getKeyStroke(KeyEvent.VK_O, Event.CTRL_MASK), "Open"); 83 | getActionMap().put("Save", new AbstractAction() { 84 | public void actionPerformed(ActionEvent evt) { 85 | JFileChooser jfc = new JFileChooser(); 86 | jfc.setDialogTitle("Select a file to write the message content to"); 87 | int returnVal = jfc.showSaveDialog(ByteArrayEditor.this); 88 | if (returnVal == JFileChooser.APPROVE_OPTION) { 89 | try { 90 | FileOutputStream fos = new FileOutputStream(jfc.getSelectedFile()); 91 | fos.write(htm.getData()); 92 | fos.close(); 93 | } catch (IOException ioe) { 94 | JOptionPane.showMessageDialog(ByteArrayEditor.this, "Error writing file: " + ioe.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); 95 | } 96 | } 97 | } 98 | }); 99 | getActionMap().put("Open", new AbstractAction() { 100 | public void actionPerformed(ActionEvent evt) { 101 | if (controller.isReadOnly()) 102 | return; 103 | JFileChooser jfc = new JFileChooser(); 104 | jfc.setDialogTitle("Select a file to read the message content from"); 105 | int returnVal = jfc.showOpenDialog(ByteArrayEditor.this); 106 | if (returnVal == JFileChooser.APPROVE_OPTION) { 107 | try { 108 | FileInputStream fis = new FileInputStream(jfc.getSelectedFile()); 109 | ByteArrayOutputStream baos = new ByteArrayOutputStream(); 110 | byte[] buff = new byte[2048]; 111 | int got; 112 | while ((got = fis.read(buff))>0) { 113 | baos.write(buff,0,got); 114 | } 115 | fis.close(); 116 | baos.close(); 117 | htm.setData(baos.toByteArray()); 118 | } catch (IOException ioe) { 119 | JOptionPane.showMessageDialog(ByteArrayEditor.this, "Error writing file: " + ioe.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); 120 | } 121 | } 122 | } 123 | }); 124 | 125 | } 126 | 127 | @Override 128 | public JComponent getEditorComponent() { 129 | return this; 130 | } 131 | 132 | @Override 133 | public Class[] getSupportedClasses() { 134 | return new Class[] { byte[].class }; 135 | } 136 | 137 | @Override 138 | public void setEditorController(EditorController controller) { 139 | if (this.controller != null) 140 | controller.removePropertyChangeListener(listener); 141 | this.controller = controller; 142 | tableUpdating = true; 143 | if (this.controller != null) { 144 | controller.addPropertyChangeListener(listener); 145 | Object o = controller.getObject(); 146 | if (o instanceof byte[]) { 147 | htm.setData((byte[]) o); 148 | } else { 149 | htm.setData(null); 150 | } 151 | } else { 152 | htm.setData(null); 153 | } 154 | tableUpdating = false; 155 | } 156 | 157 | public String getEditorName() { 158 | return "Byte[]"; 159 | } 160 | 161 | private class HexTableModel extends AbstractTableModel { 162 | 163 | private byte[] data; 164 | private boolean editable = true; 165 | 166 | private int columns = 8; 167 | 168 | public HexTableModel() { 169 | } 170 | 171 | public HexTableModel(int columns) { 172 | this.columns = columns; 173 | } 174 | 175 | public void setData(byte[] data) { 176 | this.data = data; 177 | fireTableDataChanged(); 178 | } 179 | 180 | public byte[] getData() { 181 | if (data == null) 182 | return null; 183 | 184 | byte[] copy = new byte[data.length]; 185 | System.arraycopy(data, 0, copy, 0, data.length); 186 | return copy; 187 | } 188 | 189 | public void setEditable(boolean editable) { 190 | this.editable = editable; 191 | } 192 | 193 | public String getColumnName(int columnIndex) { 194 | if (columnIndex == 0) { 195 | return "Position"; 196 | } else if (columnIndex - 1 < columns) { 197 | return Integer.toHexString(columnIndex - 1).toUpperCase(); 198 | } else { 199 | return "String"; 200 | } 201 | } 202 | 203 | public int getColumnCount() { 204 | return columns + 2; 205 | } 206 | 207 | public int getRowCount() { 208 | if (data == null || data.length == 0) { 209 | return 0; 210 | } 211 | if (data.length % columns == 0) { 212 | return (data.length / columns); 213 | } else { 214 | return (data.length / columns) + 1; 215 | } 216 | } 217 | 218 | public Object getValueAt(int rowIndex, int columnIndex) { 219 | if (columnIndex == 0) { 220 | return String.format("%08X", rowIndex * columns); 221 | } else if (columnIndex - 1 < columns) { 222 | int position = rowIndex * columns + columnIndex - 1; 223 | if (position < data.length) { 224 | int i = data[position]; 225 | if (i < 0) { 226 | i = i + 256; 227 | } 228 | return String.format("%02X", i); 229 | } else { 230 | return ""; 231 | } 232 | } else { 233 | int start = rowIndex * columns; 234 | StringBuffer buff = new StringBuffer(); 235 | for (int i = 0; i < columns; i++) { 236 | int pos = start + i; 237 | if (pos >= data.length) { 238 | return buff.toString(); 239 | } 240 | if (data[pos] < 32 || data[pos] > 126) { 241 | buff.append("."); 242 | } else { 243 | buff.append((char) data[pos]); 244 | } 245 | } 246 | return buff.toString(); 247 | } 248 | } 249 | 250 | public boolean isCellEditable(int rowIndex, int columnIndex) { 251 | if (columnIndex == 0 || columnIndex > columns) { 252 | return false; 253 | } 254 | int position = rowIndex * columns + columnIndex - 1; 255 | if (position < data.length) { 256 | return editable; 257 | } 258 | return false; 259 | } 260 | 261 | public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 262 | int position = rowIndex * columns + columnIndex - 1; 263 | if (position >= data.length) { 264 | System.out.println("Out of range"); 265 | return; 266 | } 267 | if (aValue instanceof String) { 268 | try { 269 | String s = (String) aValue; 270 | data[position] = new Integer(Integer.parseInt(s.trim(), 16)).byteValue(); 271 | fireTableCellUpdated(rowIndex, columns + 1); 272 | } catch (NumberFormatException nfe) { 273 | System.out.println("Number format error : " + nfe); 274 | } 275 | } else { 276 | System.out.println("Value is a " + aValue.getClass().getName()); 277 | } 278 | } 279 | } 280 | 281 | } 282 | --------------------------------------------------------------------------------