From f3d820826d86548e0f6aa948066896f117ebcbf2 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Thu, 8 Jul 2010 15:49:16 +0000 Subject: [PATCH] Improve SSH and VirtualBox support git-svn-id: https://svn.argeo.org/slc/trunk@3654 4cfe0d0a-d680-48aa-b62c-e0a02a3f76cc --- .../org/argeo/slc/jsch/SimpleUserInfo.java | 8 +- .../java/org/argeo/slc/jsch/UiUserInfo.java | 134 ++++++++++++++++++ .../org/argeo/slc/lib/vbox/VBoxManager.java | 56 ++++++-- .../java/org/argeo/slc/lib/vbox/VBoxNat.java | 11 +- .../argeo/slc/lib/vbox/VBoxPortMapping.java | 22 +-- 5 files changed, 205 insertions(+), 26 deletions(-) create mode 100644 runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/UiUserInfo.java diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/SimpleUserInfo.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/SimpleUserInfo.java index bbd9e106b..6b23422a8 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/SimpleUserInfo.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/SimpleUserInfo.java @@ -33,10 +33,10 @@ public class SimpleUserInfo implements UserInfo { private final static Log log = LogFactory.getLog(SimpleUserInfo.class); - private String password; - private char[] passwordSafe; - private String passphrase; - private char[] passphraseSafe; + protected String password; + protected char[] passwordSafe; + protected String passphrase; + protected char[] passphraseSafe; public void setPassword(String password) { this.password = password; diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/UiUserInfo.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/UiUserInfo.java new file mode 100644 index 000000000..a19c0db43 --- /dev/null +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/jsch/UiUserInfo.java @@ -0,0 +1,134 @@ +package org.argeo.slc.jsch; + +import java.awt.Container; +import java.awt.GridLayout; +import java.awt.Panel; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Arrays; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JPasswordField; + +public class UiUserInfo extends SimpleUserInfo { + + private Boolean alwaysPrompt = false; + + public boolean promptPassphrase(String message) { + if (passphrase != null) + return true; + + if (!alwaysPrompt && passphraseSafe != null) + return true; + + PasswordDialog dialog = new PasswordDialog(message) { + private static final long serialVersionUID = 3266299327166418364L; + + @Override + protected void useCredentials(char[] password) { + passphraseSafe = Arrays.copyOf(password, password.length); + } + }; + dialog.setVisible(true); + return dialog.getWasProvided(); + } + + public boolean promptPassword(String message) { + if (password != null) + return true; + + if (!alwaysPrompt && passwordSafe != null) + return true; + + PasswordDialog dialog = new PasswordDialog(message) { + private static final long serialVersionUID = 3266299327166418364L; + + @Override + protected void useCredentials(char[] password) { + passwordSafe = Arrays.copyOf(password, password.length); + } + }; + dialog.setVisible(true); + return dialog.getWasProvided(); + } + + public void setAlwaysPrompt(Boolean alwaysPrompt) { + this.alwaysPrompt = alwaysPrompt; + } + + protected static class PasswordDialog extends JDialog implements + ActionListener { + private static final long serialVersionUID = 3399155607980846207L; + + private static final String OK = "ok"; + + private JPasswordField password = new JPasswordField("", 10); + + private JButton okButton; + private JButton cancelButton; + + private Boolean wasProvided = false; + + public PasswordDialog(String title) { + setTitle(title); + setModal(true); + setLocationRelativeTo(null); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + + JPanel p1 = new JPanel(new GridLayout(1, 2, 3, 3)); + p1.add(new JLabel("Password")); + password.setActionCommand(OK); + password.addActionListener(this); + p1.add(password); + add("Center", p1); + + Panel p2 = new Panel(); + okButton = addButton(p2, "OK"); + okButton.setActionCommand(OK); + cancelButton = addButton(p2, "Cancel"); + add("South", p2); + setSize(240, 120); + + pack(); + } + + /** To be overridden */ + protected void useCredentials(char[] password) { + // does nothing + } + + private JButton addButton(Container c, String name) { + JButton button = new JButton(name); + button.addActionListener(this); + c.add(button); + return button; + } + + public final void actionPerformed(ActionEvent evt) { + Object source = evt.getSource(); + if (source == okButton || evt.getActionCommand().equals(OK)) { + char[] p = password.getPassword(); + useCredentials(p); + wasProvided = true; + Arrays.fill(p, '0'); + cleanUp(); + } else if (source == cancelButton) + cleanUp(); + } + + private void cleanUp() { + password.setText(""); + dispose(); + } + + public Boolean getWasProvided() { + return wasProvided; + } + + } + +} diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxManager.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxManager.java index 189abb73d..4713c9d76 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxManager.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxManager.java @@ -55,6 +55,10 @@ public class VBoxManager { startVm("gui"); } + public void startVmHeadless() { + startVm("vrdp"); + } + public void startVm(String type) { List cmd = new ArrayList(); cmd.add(executable); @@ -70,16 +74,48 @@ public class VBoxManager { for (VBoxNat vBoxNat : nats) { for (String id : vBoxNat.getMappings().keySet()) { VBoxPortMapping mapping = vBoxNat.getMappings().get(id); - new SystemCall(createNatCommand(id, vBoxNat.getDevice(), - "Protocol", mapping.getProtocol(), script)).run(); - script.append('\n'); - new SystemCall(createNatCommand(id, vBoxNat.getDevice(), - "GuestPort", mapping.getGuest(), script)).run(); - script.append('\n'); - new SystemCall(createNatCommand(id, vBoxNat.getDevice(), - "HostPort", mapping.getHost(), script)).run(); - script.append('\n'); - script.append('\n'); + + // Try to delete rule first + try { + StringBuffer delCmd = new StringBuffer( + "VBoxManage modifyvm"); + delCmd.append(" \"").append(vm.getName()).append("\""); + delCmd.append(" --natpf").append(vBoxNat.getDevice()) + .append(" "); + delCmd.append(" delete "); + delCmd.append("\"").append(id).append("\""); + new SystemCall(delCmd.toString()).run(); + script.append(delCmd).append("\n"); + } catch (Exception e) { + // silent + } + + StringBuffer cmd = new StringBuffer("VBoxManage modifyvm"); + cmd.append(" \"").append(vm.getName()).append("\""); + cmd.append(" --natpf").append(vBoxNat.getDevice()).append(" "); + cmd.append("\""); + cmd.append(id).append(","); + cmd.append(mapping.getProtocol()).append(","); + cmd.append(","); + cmd.append(mapping.getHostPort()).append(","); + cmd.append(vBoxNat.getGuestIp()).append(","); + cmd.append(mapping.getGuestPort()); + cmd.append("\""); + + new SystemCall(cmd.toString()).run(); + script.append(cmd).append("\n"); + + // Older VirtualBox + // new SystemCall(createNatCommand(id, vBoxNat.getDevice(), + // "Protocol", mapping.getProtocol(), script)).run(); + // script.append('\n'); + // new SystemCall(createNatCommand(id, vBoxNat.getDevice(), + // "GuestPort", mapping.getGuest(), script)).run(); + // script.append('\n'); + // new SystemCall(createNatCommand(id, vBoxNat.getDevice(), + // "HostPort", mapping.getHost(), script)).run(); + // script.append('\n'); + // script.append('\n'); } script.append('\n'); } diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxNat.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxNat.java index b0ba966f8..16e5961e7 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxNat.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxNat.java @@ -20,7 +20,8 @@ import java.util.Map; /** The NAT mapping table */ public class VBoxNat { - private String device = "pcnet"; + private String device = "1"; + private String guestIp = ""; private Map mappings; public String getDevice() { @@ -39,4 +40,12 @@ public class VBoxNat { this.mappings = mappings; } + public String getGuestIp() { + return guestIp; + } + + public void setGuestIp(String guestIp) { + this.guestIp = guestIp; + } + } diff --git a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxPortMapping.java b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxPortMapping.java index 11879d569..4e839b200 100644 --- a/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxPortMapping.java +++ b/runtime/org.argeo.slc.support.simple/src/main/java/org/argeo/slc/lib/vbox/VBoxPortMapping.java @@ -16,11 +16,11 @@ package org.argeo.slc.lib.vbox; -/** The mapping of one port.*/ +/** The mapping of one port. */ public class VBoxPortMapping { private String protocol = "TCP"; - private String guest; - private String host; + private String guestPort; + private String hostPort; public String getProtocol() { return protocol; @@ -30,20 +30,20 @@ public class VBoxPortMapping { this.protocol = type; } - public String getGuest() { - return guest; + public String getGuestPort() { + return guestPort; } - public void setGuest(String guest) { - this.guest = guest; + public void setGuestPort(String guestPort) { + this.guestPort = guestPort; } - public String getHost() { - return host; + public String getHostPort() { + return hostPort; } - public void setHost(String host) { - this.host = host; + public void setHostPort(String hostPort) { + this.hostPort = hostPort; } } -- 2.39.2