mirror of
https://github.com/arduino/Arduino.git
synced 2025-02-26 20:54:22 +01:00
introducing jsch. now network monitor uses SSH to trigger a telnet session at yun side
This commit is contained in:
parent
4392938f6a
commit
21203cbe1b
BIN
app/lib/jsch-0.1.50.jar
Normal file
BIN
app/lib/jsch-0.1.50.jar
Normal file
Binary file not shown.
@ -51,7 +51,7 @@ public class HttpUploader extends Uploader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getAuthorizationKey() {
|
public String getAuthorizationKey() {
|
||||||
return "pwd." + ipAddress;
|
return "runtime.pwd." + ipAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -11,7 +11,6 @@ import java.awt.event.ActionEvent;
|
|||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import static processing.app.I18n._;
|
import static processing.app.I18n._;
|
||||||
|
|
||||||
@ -32,7 +31,7 @@ public abstract class AbstractMonitor extends JFrame implements MessageConsumer
|
|||||||
public void windowClosing(WindowEvent event) {
|
public void windowClosing(WindowEvent event) {
|
||||||
try {
|
try {
|
||||||
close();
|
close();
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,7 +44,7 @@ public abstract class AbstractMonitor extends JFrame implements MessageConsumer
|
|||||||
public void actionPerformed(ActionEvent event) {
|
public void actionPerformed(ActionEvent event) {
|
||||||
try {
|
try {
|
||||||
close();
|
close();
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
@ -174,7 +173,15 @@ public abstract class AbstractMonitor extends JFrame implements MessageConsumer
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void open() throws IOException;
|
public boolean requiresAuthorization() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public abstract void close() throws IOException;
|
public String getAuthorizationKey() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void open() throws Exception;
|
||||||
|
|
||||||
|
public abstract void close() throws Exception;
|
||||||
}
|
}
|
||||||
|
@ -924,7 +924,7 @@ public class Base {
|
|||||||
editors.remove(editor);
|
editors.remove(editor);
|
||||||
try {
|
try {
|
||||||
Editor.serialMonitor.close();
|
Editor.serialMonitor.close();
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
//ignore
|
//ignore
|
||||||
}
|
}
|
||||||
storeSketches();
|
storeSketches();
|
||||||
@ -966,7 +966,7 @@ public class Base {
|
|||||||
storeSketches();
|
storeSketches();
|
||||||
try {
|
try {
|
||||||
Editor.serialMonitor.close();
|
Editor.serialMonitor.close();
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,9 @@
|
|||||||
|
|
||||||
package processing.app;
|
package processing.app;
|
||||||
|
|
||||||
|
import com.jcraft.jsch.JSchException;
|
||||||
import processing.app.debug.*;
|
import processing.app.debug.*;
|
||||||
|
import processing.app.forms.PasswordAuthorizationDialog;
|
||||||
import processing.app.syntax.*;
|
import processing.app.syntax.*;
|
||||||
import processing.app.tools.*;
|
import processing.app.tools.*;
|
||||||
import processing.core.*;
|
import processing.core.*;
|
||||||
@ -704,7 +706,7 @@ public class Editor extends JFrame implements RunnerListener {
|
|||||||
JMenu boardsMenu = new JMenu(_("Board"));
|
JMenu boardsMenu = new JMenu(_("Board"));
|
||||||
Editor.boardsMenus.add(boardsMenu);
|
Editor.boardsMenus.add(boardsMenu);
|
||||||
toolsMenu.add(boardsMenu);
|
toolsMenu.add(boardsMenu);
|
||||||
|
|
||||||
base.rebuildBoardsMenu(toolsMenu, this);
|
base.rebuildBoardsMenu(toolsMenu, this);
|
||||||
//Debug: rebuild imports
|
//Debug: rebuild imports
|
||||||
importMenu.removeAll();
|
importMenu.removeAll();
|
||||||
@ -969,7 +971,7 @@ public class Editor extends JFrame implements RunnerListener {
|
|||||||
Preferences.set("serial.port.file", name);
|
Preferences.set("serial.port.file", name);
|
||||||
try {
|
try {
|
||||||
serialMonitor.close();
|
serialMonitor.close();
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
serialMonitor.setVisible(false);
|
serialMonitor.setVisible(false);
|
||||||
@ -983,14 +985,14 @@ public class Editor extends JFrame implements RunnerListener {
|
|||||||
|
|
||||||
protected void populatePortMenu() {
|
protected void populatePortMenu() {
|
||||||
serialMenu.removeAll();
|
serialMenu.removeAll();
|
||||||
|
|
||||||
String selectedPort = Preferences.get("serial.port");
|
String selectedPort = Preferences.get("serial.port");
|
||||||
|
|
||||||
List<BoardPort> ports = Base.getDiscoveryManager().discovery();
|
List<BoardPort> ports = Base.getDiscoveryManager().discovery();
|
||||||
for (BoardPort port : ports) {
|
for (BoardPort port : ports) {
|
||||||
String address = port.getAddress();
|
String address = port.getAddress();
|
||||||
String label = port.getLabel();
|
String label = port.getLabel();
|
||||||
|
|
||||||
JCheckBoxMenuItem item = new JCheckBoxMenuItem(label, address.equals(selectedPort));
|
JCheckBoxMenuItem item = new JCheckBoxMenuItem(label, address.equals(selectedPort));
|
||||||
item.addActionListener(new SerialMenuListener(address));
|
item.addActionListener(new SerialMenuListener(address));
|
||||||
serialMenu.add(item);
|
serialMenu.add(item);
|
||||||
@ -2490,14 +2492,39 @@ public class Editor extends JFrame implements RunnerListener {
|
|||||||
public void handleSerial() {
|
public void handleSerial() {
|
||||||
if (uploading) return;
|
if (uploading) return;
|
||||||
|
|
||||||
try {
|
boolean success = false;
|
||||||
serialMonitor.open();
|
do {
|
||||||
serialMonitor.setVisible(true);
|
if (serialMonitor.requiresAuthorization() && !Preferences.has(serialMonitor.getAuthorizationKey())) {
|
||||||
} catch (ConnectException e) {
|
PasswordAuthorizationDialog dialog = new PasswordAuthorizationDialog(this, _("Type board password to access its console"));
|
||||||
statusError(_("Unable to connect: is the sketch using the bridge?"));
|
dialog.setLocationRelativeTo(this);
|
||||||
} catch (IOException e) {
|
dialog.setVisible(true);
|
||||||
statusError(e);
|
|
||||||
}
|
if (dialog.isCancelled()) {
|
||||||
|
statusNotice(_("Unable to open serial monitor"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Preferences.set(serialMonitor.getAuthorizationKey(), dialog.getPassword());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
serialMonitor.open();
|
||||||
|
serialMonitor.setVisible(true);
|
||||||
|
success = true;
|
||||||
|
} catch (ConnectException e) {
|
||||||
|
statusError(_("Unable to connect: is the sketch using the bridge?"));
|
||||||
|
} catch (JSchException e) {
|
||||||
|
statusError(_("Unable to connect: wrong password?"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
statusError(e);
|
||||||
|
} finally {
|
||||||
|
if (serialMonitor.requiresAuthorization() && !success) {
|
||||||
|
Preferences.remove(serialMonitor.getAuthorizationKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (serialMonitor.requiresAuthorization() && !success);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2522,7 +2549,8 @@ public class Editor extends JFrame implements RunnerListener {
|
|||||||
statusError(_("Error while burning bootloader."));
|
statusError(_("Error while burning bootloader."));
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}});
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,22 +1,26 @@
|
|||||||
package processing.app;
|
package processing.app;
|
||||||
|
|
||||||
|
import com.jcraft.jsch.*;
|
||||||
import processing.app.debug.MessageSiphon;
|
import processing.app.debug.MessageSiphon;
|
||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
import static processing.app.I18n._;
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class NetworkMonitor extends AbstractMonitor {
|
public class NetworkMonitor extends AbstractMonitor {
|
||||||
|
|
||||||
private final String ipAddress;
|
private final String ipAddress;
|
||||||
|
|
||||||
private Socket socket;
|
private MessageSiphon inputConsumer;
|
||||||
private MessageSiphon consumer;
|
private Session session;
|
||||||
|
private Channel channel;
|
||||||
|
private MessageSiphon errorConsumer;
|
||||||
|
|
||||||
public NetworkMonitor(String port, Base base) {
|
public NetworkMonitor(String port, Base base) {
|
||||||
super(port);
|
super(port);
|
||||||
@ -28,7 +32,7 @@ public class NetworkMonitor extends AbstractMonitor {
|
|||||||
onSendCommand(new ActionListener() {
|
onSendCommand(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent event) {
|
public void actionPerformed(ActionEvent event) {
|
||||||
try {
|
try {
|
||||||
OutputStream out = socket.getOutputStream();
|
OutputStream out = channel.getOutputStream();
|
||||||
out.write(textField.getText().getBytes());
|
out.write(textField.getText().getBytes());
|
||||||
out.write('\n');
|
out.write('\n');
|
||||||
out.flush();
|
out.flush();
|
||||||
@ -41,24 +45,81 @@ public class NetworkMonitor extends AbstractMonitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void open() throws IOException {
|
public boolean requiresAuthorization() {
|
||||||
try {
|
return true;
|
||||||
socket = new Socket();
|
|
||||||
socket.connect(new InetSocketAddress(ipAddress, 6571), 5000);
|
|
||||||
consumer = new MessageSiphon(socket.getInputStream(), this);
|
|
||||||
return;
|
|
||||||
} catch (IOException e) {
|
|
||||||
socket = null;
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public String getAuthorizationKey() {
|
||||||
if (socket != null) {
|
return "runtime.pwd." + ipAddress;
|
||||||
consumer.stop();
|
}
|
||||||
socket.close();
|
|
||||||
|
@Override
|
||||||
|
public void open() throws Exception {
|
||||||
|
JSch jSch = new JSch();
|
||||||
|
session = jSch.getSession("root", ipAddress, 22);
|
||||||
|
session.setPassword(Preferences.get(getAuthorizationKey()));
|
||||||
|
|
||||||
|
session.setUserInfo(new NoInteractionUserInfo());
|
||||||
|
session.connect(30000);
|
||||||
|
|
||||||
|
channel = session.openChannel("exec");
|
||||||
|
((ChannelExec) channel).setCommand("telnet localhost 6571");
|
||||||
|
|
||||||
|
InputStream inputStream = channel.getInputStream();
|
||||||
|
InputStream errStream = ((ChannelExec) channel).getErrStream();
|
||||||
|
|
||||||
|
channel.connect();
|
||||||
|
|
||||||
|
inputConsumer = new MessageSiphon(inputStream, this);
|
||||||
|
errorConsumer = new MessageSiphon(errStream, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void message(String s) {
|
||||||
|
if (s.contains("can't connect")) {
|
||||||
|
s = _("Unable to connect: is the sketch using the bridge?");
|
||||||
|
}
|
||||||
|
super.message(s); //To change body of overridden methods use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() throws Exception {
|
||||||
|
if (channel != null) {
|
||||||
|
inputConsumer.stop();
|
||||||
|
channel.disconnect();
|
||||||
textArea.setText("");
|
textArea.setText("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (session != null) {
|
||||||
|
session.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class NoInteractionUserInfo implements UserInfo {
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean promptYesNo(String str) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassphrase() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean promptPassphrase(String message) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean promptPassword(String message) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showMessage(String message) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@ import processing.core.PApplet;
|
|||||||
|
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import static processing.app.I18n._;
|
import static processing.app.I18n._;
|
||||||
|
|
||||||
@ -49,10 +48,10 @@ public class SerialMonitor extends AbstractMonitor {
|
|||||||
close();
|
close();
|
||||||
Thread.sleep(100); // Wait for serial port to properly close
|
Thread.sleep(100); // Wait for serial port to properly close
|
||||||
open();
|
open();
|
||||||
} catch (IOException e) {
|
|
||||||
System.err.println(e);
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
e.printStackTrace();
|
// noop
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.err.println(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -82,14 +81,14 @@ public class SerialMonitor extends AbstractMonitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void open() throws IOException {
|
public void open() throws Exception {
|
||||||
if (serial != null) return;
|
if (serial != null) return;
|
||||||
|
|
||||||
serial = new Serial(port, serialRate);
|
serial = new Serial(port, serialRate);
|
||||||
serial.addListener(this);
|
serial.addListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() throws IOException {
|
public void close() throws Exception {
|
||||||
if (serial != null) {
|
if (serial != null) {
|
||||||
int[] location = getPlacement();
|
int[] location = getPlacement();
|
||||||
String locationStr = PApplet.join(PApplet.str(location), ",");
|
String locationStr = PApplet.join(PApplet.str(location), ",");
|
||||||
|
@ -1671,7 +1671,7 @@ public class Sketch {
|
|||||||
boolean success = false;
|
boolean success = false;
|
||||||
do {
|
do {
|
||||||
if (uploader.requiresAuthorization() && !Preferences.has(uploader.getAuthorizationKey())) {
|
if (uploader.requiresAuthorization() && !Preferences.has(uploader.getAuthorizationKey())) {
|
||||||
PasswordAuthorizationDialog dialog = new PasswordAuthorizationDialog(editor);
|
PasswordAuthorizationDialog dialog = new PasswordAuthorizationDialog(editor, _("Type board password to upload a new sketch"));
|
||||||
dialog.setLocationRelativeTo(editor);
|
dialog.setLocationRelativeTo(editor);
|
||||||
dialog.setVisible(true);
|
dialog.setVisible(true);
|
||||||
|
|
||||||
@ -1680,7 +1680,7 @@ public class Sketch {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Preferences.set(uploader.getAuthorizationKey(), DigestUtils.sha256Hex(dialog.getPassword()));
|
Preferences.set(uploader.getAuthorizationKey(), dialog.getPassword());
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -22,7 +22,7 @@ public class PasswordAuthorizationDialog extends JDialog {
|
|||||||
protected boolean cancelled;
|
protected boolean cancelled;
|
||||||
protected String password;
|
protected String password;
|
||||||
|
|
||||||
public PasswordAuthorizationDialog(Frame parent) {
|
public PasswordAuthorizationDialog(Frame parent, String dialogText) {
|
||||||
super(parent, true);
|
super(parent, true);
|
||||||
|
|
||||||
this.cancelled = false;
|
this.cancelled = false;
|
||||||
@ -37,7 +37,7 @@ public class PasswordAuthorizationDialog extends JDialog {
|
|||||||
|
|
||||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||||
|
|
||||||
typePasswordLabel.setText(_("Type board password to upload a new sketch"));
|
typePasswordLabel.setText(dialogText);
|
||||||
|
|
||||||
icon.setIcon(new ImageIcon(new File(Base.getContentFile("lib"), "theme/lock.png").getAbsolutePath()));
|
icon.setIcon(new ImageIcon(new File(Base.getContentFile("lib"), "theme/lock.png").getAbsolutePath()));
|
||||||
|
|
||||||
|
@ -24,13 +24,14 @@
|
|||||||
<fileset dir=".." id="runtime.jars">
|
<fileset dir=".." id="runtime.jars">
|
||||||
<include name="core/core.jar" />
|
<include name="core/core.jar" />
|
||||||
<include name="app/pde.jar" />
|
<include name="app/pde.jar" />
|
||||||
<include name="app/lib/ecj.jar" />
|
|
||||||
<include name="app/lib/commons-codec-1.7.jar" />
|
<include name="app/lib/commons-codec-1.7.jar" />
|
||||||
<include name="app/lib/commons-exec-1.1.jar" />
|
<include name="app/lib/commons-exec-1.1.jar" />
|
||||||
<include name="app/lib/commons-httpclient-3.1.jar" />
|
<include name="app/lib/commons-httpclient-3.1.jar" />
|
||||||
<include name="app/lib/commons-logging-1.0.4.jar" />
|
<include name="app/lib/commons-logging-1.0.4.jar" />
|
||||||
|
<include name="app/lib/ecj.jar" />
|
||||||
<include name="app/lib/jmdns-3.4.1.jar" />
|
<include name="app/lib/jmdns-3.4.1.jar" />
|
||||||
<include name="app/lib/jna.jar" />
|
<include name="app/lib/jna.jar" />
|
||||||
|
<include name="app/lib/jsch-0.1.50.jar" />
|
||||||
<include name="app/lib/RXTXcomm.jar" />
|
<include name="app/lib/RXTXcomm.jar" />
|
||||||
<include name="app/lib/ant.jar" />
|
<include name="app/lib/ant.jar" />
|
||||||
<include name="app/lib/ant-launcher.jar" />
|
<include name="app/lib/ant-launcher.jar" />
|
||||||
|
@ -70,13 +70,13 @@
|
|||||||
<string>processing.app.Base</string>
|
<string>processing.app.Base</string>
|
||||||
|
|
||||||
<key>JVMVersion</key>
|
<key>JVMVersion</key>
|
||||||
<string>1.5*</string>
|
<string>1.6*</string>
|
||||||
|
|
||||||
<key>ClassPath</key>
|
<key>ClassPath</key>
|
||||||
<!-- In 0149, removed /System/Library/Java from the CLASSPATH because
|
<!-- In 0149, removed /System/Library/Java from the CLASSPATH because
|
||||||
it can cause problems if users have installed weird files there.
|
it can cause problems if users have installed weird files there.
|
||||||
http://dev.processing.org/bugs/show_bug.cgi?id=1045 -->
|
http://dev.processing.org/bugs/show_bug.cgi?id=1045 -->
|
||||||
<string>$JAVAROOT/pde.jar:$JAVAROOT/core.jar:$JAVAROOT/antlr.jar:$JAVAROOT/ecj.jar:$JAVAROOT/registry.jar:$JAVAROOT/quaqua.jar:$JAVAROOT/RXTXcomm.jar:$JAVAROOT/commons-codec-1.7.jar:$JAVAROOT/commons-exec-1.1.jar:$JAVAROOT/commons-httpclient-3.1.jar:$JAVAROOT/commons-logging-1.0.4.jar:$JAVAROOT/jmdns-3.4.1.jar</string>
|
<string>$JAVAROOT/pde.jar:$JAVAROOT/core.jar:$JAVAROOT/antlr.jar:$JAVAROOT/ecj.jar:$JAVAROOT/registry.jar:$JAVAROOT/quaqua.jar:$JAVAROOT/RXTXcomm.jar:$JAVAROOT/commons-codec-1.7.jar:$JAVAROOT/commons-exec-1.1.jar:$JAVAROOT/commons-httpclient-3.1.jar:$JAVAROOT/commons-logging-1.0.4.jar:$JAVAROOT/jmdns-3.4.1.jar:$JAVAROOT/jsch-0.1.50.jar</string>
|
||||||
|
|
||||||
<key>JVMArchs</key>
|
<key>JVMArchs</key>
|
||||||
<array>
|
<array>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user