Skip to content

Commit 9898fd7

Browse files
author
Federico Fissore
committed
Added support to openssh config file
1 parent 88f7504 commit 9898fd7

16 files changed

+266
-94
lines changed

app/src/cc/arduino/packages/DiscoveryManager.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,19 @@ public void run() {
7373

7474
public List<BoardPort> discovery() {
7575
List<BoardPort> res = new ArrayList<BoardPort>();
76-
for (Discovery d : discoverers)
76+
for (Discovery d : discoverers) {
7777
res.addAll(d.discovery());
78+
}
7879
return res;
7980
}
8081

82+
public BoardPort find(String address) {
83+
for (BoardPort boardPort : discovery()) {
84+
if (boardPort.getAddress().equals(address)) {
85+
return boardPort;
86+
}
87+
}
88+
return null;
89+
}
90+
8191
}

app/src/cc/arduino/packages/UploaderAndMonitorFactory.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,21 +31,24 @@
3131

3232
import cc.arduino.packages.uploaders.SSHUploader;
3333
import cc.arduino.packages.uploaders.SerialUploader;
34-
import processing.app.*;
34+
import processing.app.AbstractMonitor;
35+
import processing.app.Base;
36+
import processing.app.NetworkMonitor;
37+
import processing.app.SerialMonitor;
3538
import processing.app.debug.TargetBoard;
3639

3740
public class UploaderAndMonitorFactory {
3841

39-
public Uploader newUploader(TargetBoard board, String port) {
40-
if ("true".equals(board.getPreferences().get("upload.via_ssh")) && Constants.IPV4_ADDRESS.matcher(port).find()) {
42+
public Uploader newUploader(TargetBoard board, BoardPort port) {
43+
if ("true".equals(board.getPreferences().get("upload.via_ssh")) && "network".equals(port.getProtocol())) {
4144
return new SSHUploader(port);
4245
}
4346

4447
return new SerialUploader();
4548
}
4649

47-
public AbstractMonitor newMonitor(String port, Base base) {
48-
if (Constants.IPV4_ADDRESS.matcher(port).find()) {
50+
public AbstractMonitor newMonitor(BoardPort port, Base base) {
51+
if ("network".equals(port.getProtocol())) {
4952
return new NetworkMonitor(port, base);
5053
}
5154

app/src/cc/arduino/packages/discoverers/NetworkDiscovery.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
import cc.arduino.packages.BoardPort;
3333
import cc.arduino.packages.Discovery;
34-
import cc.arduino.packages.discoverers.network.NetworkChecker;
34+
import cc.arduino.packages.discoverers.network.*;
3535
import processing.app.Base;
3636
import processing.app.helpers.NetUtils;
3737
import processing.app.helpers.PreferencesMap;
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package cc.arduino.packages.ssh;
2+
3+
import com.jcraft.jsch.UserInfo;
4+
5+
public class NoInteractionUserInfo implements UserInfo {
6+
7+
private final String password;
8+
9+
public NoInteractionUserInfo(String password) {
10+
this.password = password;
11+
}
12+
13+
public String getPassword() {
14+
return password;
15+
}
16+
17+
public boolean promptYesNo(String str) {
18+
return true;
19+
}
20+
21+
public String getPassphrase() {
22+
return password;
23+
}
24+
25+
public boolean promptPassphrase(String message) {
26+
return true;
27+
}
28+
29+
public boolean promptPassword(String message) {
30+
return true;
31+
}
32+
33+
public void showMessage(String message) {
34+
}
35+
36+
}

app/src/cc/arduino/packages/uploaders/ssh/SCP.java renamed to app/src/cc/arduino/packages/ssh/SCP.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,10 @@
2727
* Copyright 2013 Arduino LLC (http://www.arduino.cc/)
2828
*/
2929

30-
package cc.arduino.packages.uploaders.ssh;
30+
package cc.arduino.packages.ssh;
3131

3232
import com.jcraft.jsch.Channel;
3333
import com.jcraft.jsch.ChannelExec;
34-
import com.jcraft.jsch.JSchException;
3534
import com.jcraft.jsch.Session;
3635

3736
import java.io.*;

app/src/cc/arduino/packages/uploaders/ssh/SSH.java renamed to app/src/cc/arduino/packages/ssh/SSH.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
* Copyright 2013 Arduino LLC (http://www.arduino.cc/)
2828
*/
2929

30-
package cc.arduino.packages.uploaders.ssh;
30+
package cc.arduino.packages.ssh;
3131

3232
import com.jcraft.jsch.Channel;
3333
import com.jcraft.jsch.ChannelExec;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package cc.arduino.packages.ssh;
2+
3+
import cc.arduino.packages.BoardPort;
4+
import com.jcraft.jsch.JSch;
5+
import com.jcraft.jsch.JSchException;
6+
import com.jcraft.jsch.Session;
7+
8+
import java.io.IOException;
9+
10+
public interface SSHClientSetupChainRing {
11+
12+
/*
13+
Chain is actually useless as default JSCH behaviour is to follow SSH Server authentication methods list
14+
*/
15+
Session setup(BoardPort port, JSch jSch) throws JSchException, IOException;
16+
17+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package cc.arduino.packages.ssh;
2+
3+
import cc.arduino.packages.BoardPort;
4+
import com.jcraft.jsch.*;
5+
6+
import java.io.File;
7+
import java.io.IOException;
8+
9+
public class SSHConfigFileSetup implements SSHClientSetupChainRing {
10+
11+
private final SSHClientSetupChainRing nextChainRing;
12+
13+
public SSHConfigFileSetup(SSHClientSetupChainRing nextChainRing) {
14+
this.nextChainRing = nextChainRing;
15+
}
16+
17+
public Session setup(BoardPort port, JSch jSch) throws JSchException, IOException {
18+
String ipAddress = port.getAddress();
19+
String hostname = port.getBoardName().contains(".local") ? port.getBoardName() : port.getBoardName() + ".local";
20+
21+
File sshFolder = new File(System.getProperty("user.home"), ".ssh");
22+
File sshConfig = new File(sshFolder, "config");
23+
24+
if (!sshFolder.exists() || !sshConfig.exists()) {
25+
if (nextChainRing != null) {
26+
return nextChainRing.setup(port, jSch);
27+
}
28+
throw new JSchException("Unable to find a way to connect");
29+
}
30+
31+
OpenSSHConfig configRepository = OpenSSHConfig.parseFile(sshConfig.getAbsolutePath());
32+
33+
jSch.setConfigRepository(new OpenSSHConfigWrapper(configRepository, ipAddress));
34+
35+
return jSch.getSession(hostname);
36+
}
37+
38+
public static class OpenSSHConfigWrapper implements ConfigRepository {
39+
40+
private final OpenSSHConfig config;
41+
private final String ipAddress;
42+
43+
public OpenSSHConfigWrapper(OpenSSHConfig config, String ipAddress) {
44+
this.config = config;
45+
this.ipAddress = ipAddress;
46+
}
47+
48+
@Override
49+
public Config getConfig(String host) {
50+
return new ConfigWrapper(config.getConfig(host), ipAddress);
51+
}
52+
}
53+
54+
public static class ConfigWrapper implements ConfigRepository.Config {
55+
56+
private final ConfigRepository.Config config;
57+
private final String ipAddress;
58+
59+
public ConfigWrapper(OpenSSHConfig.Config config, String ipAddress) {
60+
this.config = config;
61+
this.ipAddress = ipAddress;
62+
}
63+
64+
@Override
65+
public String getHostname() {
66+
return ipAddress;
67+
}
68+
69+
@Override
70+
public String getUser() {
71+
String user = config.getUser();
72+
if (user != null) {
73+
return user;
74+
}
75+
return "root";
76+
}
77+
78+
@Override
79+
public int getPort() {
80+
return config.getPort();
81+
}
82+
83+
@Override
84+
public String getValue(String key) {
85+
return config.getValue(key);
86+
}
87+
88+
@Override
89+
public String[] getValues(String key) {
90+
return config.getValues(key);
91+
}
92+
}
93+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package cc.arduino.packages.ssh;
2+
3+
import cc.arduino.packages.BoardPort;
4+
import com.jcraft.jsch.JSch;
5+
import com.jcraft.jsch.JSchException;
6+
import com.jcraft.jsch.Session;
7+
import processing.app.Preferences;
8+
9+
public class SSHPwdSetup implements SSHClientSetupChainRing {
10+
11+
@Override
12+
public Session setup(BoardPort port, JSch jSch) throws JSchException {
13+
String ipAddress = port.getAddress();
14+
15+
Session session = jSch.getSession("root", ipAddress, 22);
16+
session.setPassword(Preferences.get("runtime.pwd." + ipAddress));
17+
18+
return session;
19+
}
20+
21+
}

app/src/cc/arduino/packages/uploaders/SSHUploader.java

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,13 @@
2929

3030
package cc.arduino.packages.uploaders;
3131

32+
import cc.arduino.packages.BoardPort;
3233
import cc.arduino.packages.Uploader;
33-
import cc.arduino.packages.uploaders.ssh.SCP;
34-
import cc.arduino.packages.uploaders.ssh.SSH;
34+
import cc.arduino.packages.ssh.*;
3535
import com.jcraft.jsch.JSch;
3636
import com.jcraft.jsch.JSchException;
3737
import com.jcraft.jsch.Session;
3838
import processing.app.Base;
39-
import processing.app.Constants;
40-
import processing.app.NetworkMonitor;
4139
import processing.app.Preferences;
4240
import processing.app.debug.RunnerException;
4341
import processing.app.debug.TargetPlatform;
@@ -48,30 +46,26 @@
4846
import java.io.IOException;
4947
import java.util.Arrays;
5048
import java.util.List;
51-
import java.util.regex.Matcher;
5249

5350
import static processing.app.I18n._;
5451

5552
public class SSHUploader extends Uploader {
5653

5754
private static final List<String> FILES_NOT_TO_COPY = Arrays.asList(".DS_Store", ".Trash", "Thumbs.db", "__MACOSX");
5855

59-
private final String ipAddress;
56+
private final BoardPort port;
6057

61-
public SSHUploader(String port) {
62-
Matcher matcher = Constants.IPV4_ADDRESS.matcher(port);
63-
if (!matcher.find()) {
64-
throw new IllegalArgumentException(port);
65-
}
66-
ipAddress = matcher.group();
58+
public SSHUploader(BoardPort port) {
59+
this.port = port;
6760
}
6861

6962
public boolean requiresAuthorization() {
7063
return true;
7164
}
7265

66+
@Override
7367
public String getAuthorizationKey() {
74-
return "runtime.pwd." + ipAddress;
68+
return "runtime.pwd." + port.getAddress();
7569
}
7670

7771
@Override
@@ -84,10 +78,10 @@ public boolean uploadUsingPreferences(File sourcePath, String buildPath, String
8478
SCP scp = null;
8579
try {
8680
JSch jSch = new JSch();
87-
session = jSch.getSession("root", ipAddress, 22);
88-
session.setPassword(Preferences.get(getAuthorizationKey()));
81+
SSHClientSetupChainRing sshClientSetupChain = new SSHConfigFileSetup(new SSHPwdSetup());
82+
session = sshClientSetupChain.setup(port, jSch);
8983

90-
session.setUserInfo(new NetworkMonitor.NoInteractionUserInfo());
84+
session.setUserInfo(new NoInteractionUserInfo(Preferences.get("runtime.pwd." + port.getAddress())));
9185
session.connect(30000);
9286

9387
scp = new SCP(session);
@@ -97,7 +91,8 @@ public boolean uploadUsingPreferences(File sourcePath, String buildPath, String
9791

9892
return runAVRDude(ssh);
9993
} catch (JSchException e) {
100-
if ("Auth cancel".equals(e.getMessage())) {
94+
String message = e.getMessage();
95+
if ("Auth cancel".equals(message) || "Auth fail".equals(message)) {
10196
return false;
10297
}
10398
throw new RunnerException(e);

0 commit comments

Comments
 (0)