Skip to content

Commit 79fa8ce

Browse files
committed
remove hard-coded ssh public key from check-static
1 parent d36e99a commit 79fa8ce

File tree

4 files changed

+52
-15
lines changed

4 files changed

+52
-15
lines changed

src/main/java/hudson/plugins/ec2/SlaveTemplate.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ public class SlaveTemplate implements Describable<SlaveTemplate> {
238238

239239
public HostKeyVerificationStrategyEnum hostKeyVerificationStrategy;
240240

241+
public final String staticHostKeys;
242+
241243
public final boolean associatePublicIp;
242244

243245
protected transient EC2Cloud parent;
@@ -292,7 +294,7 @@ public SlaveTemplate(String ami, String zone, SpotConfiguration spotConfig, Stri
292294
boolean useEphemeralDevices, boolean useDedicatedTenancy, String launchTimeoutStr, boolean associatePublicIp,
293295
String customDeviceMapping, boolean connectBySSHProcess, boolean monitoring,
294296
boolean t2Unlimited, ConnectionStrategy connectionStrategy, int maxTotalUses,
295-
List<? extends NodeProperty<?>> nodeProperties, HostKeyVerificationStrategyEnum hostKeyVerificationStrategy) {
297+
List<? extends NodeProperty<?>> nodeProperties, HostKeyVerificationStrategyEnum hostKeyVerificationStrategy, String staticHostKeys) {
296298
if(StringUtils.isNotBlank(remoteAdmin) || StringUtils.isNotBlank(jvmopts) || StringUtils.isNotBlank(tmpDir)){
297299
LOGGER.log(Level.FINE, "As remoteAdmin, jvmopts or tmpDir is not blank, we must ensure the user has ADMINISTER rights.");
298300
// Can be null during tests
@@ -355,7 +357,8 @@ public SlaveTemplate(String ami, String zone, SpotConfiguration spotConfig, Stri
355357
this.customDeviceMapping = customDeviceMapping;
356358
this.t2Unlimited = t2Unlimited;
357359

358-
this.hostKeyVerificationStrategy = hostKeyVerificationStrategy != null ? hostKeyVerificationStrategy : HostKeyVerificationStrategyEnum.CHECK_NEW_SOFT;
360+
this.hostKeyVerificationStrategy = hostKeyVerificationStrategy != null ? hostKeyVerificationStrategy : HostKeyVerificationStrategyEnum.CHECK_NEW_SOFT;
361+
this.staticHostKeys = staticHostKeys;
359362

360363
readResolve(); // initialize
361364
}
@@ -378,7 +381,7 @@ public SlaveTemplate(String ami, String zone, SpotConfiguration spotConfig, Stri
378381
useEphemeralDevices, useDedicatedTenancy, launchTimeoutStr, associatePublicIp,
379382
customDeviceMapping, connectBySSHProcess, monitoring,
380383
t2Unlimited, connectionStrategy, maxTotalUses,
381-
nodeProperties, null);
384+
nodeProperties, null, "");
382385
}
383386

384387
@Deprecated
@@ -738,7 +741,11 @@ public void setHostKeyVerificationStrategy(HostKeyVerificationStrategyEnum hostK
738741
public HostKeyVerificationStrategyEnum getHostKeyVerificationStrategy() {
739742
return hostKeyVerificationStrategy != null ? hostKeyVerificationStrategy : HostKeyVerificationStrategyEnum.CHECK_NEW_SOFT;
740743
}
741-
744+
745+
public String getStaticHostKeys() {
746+
return staticHostKeys;
747+
}
748+
742749
@Override
743750
public String toString() {
744751
return "SlaveTemplate{" +

src/main/java/hudson/plugins/ec2/ssh/verifiers/CheckStaticStrategy.java

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,12 @@
2727
import hudson.plugins.ec2.EC2Cloud;
2828
import hudson.plugins.ec2.EC2Computer;
2929
import hudson.slaves.OfflineCause;
30+
31+
import java.util.ArrayList;
3032
import java.util.Base64;
3133

3234
import java.io.IOException;
35+
import java.util.Scanner;
3336
import java.util.logging.Level;
3437
import java.util.logging.Logger;
3538

@@ -47,21 +50,44 @@
4750
public class CheckStaticStrategy extends SshHostKeyVerificationStrategy {
4851
private static final Logger LOGGER = Logger.getLogger(CheckStaticStrategy.class.getName());
4952

53+
private ArrayList<HostKey> getStaticHostKeys(EC2Computer computer) {
54+
ArrayList<HostKey> hostKeys = new ArrayList<>();
55+
56+
Scanner scanner = new Scanner(computer.getSlaveTemplate().getStaticHostKeys());
57+
while (scanner.hasNextLine()) {
58+
String hostKeyString = scanner.nextLine();
59+
String[] hostKeyParts = hostKeyString.split(" ");
60+
if (hostKeyParts.length != 2) {
61+
EC2Cloud.log(LOGGER, Level.WARNING, computer.getListener(), "invalid static SSH key");
62+
continue;
63+
}
64+
HostKey hostKey = new HostKey(hostKeyParts[0], Base64.getDecoder().decode(hostKeyParts[1]));
65+
hostKeys.add(hostKey);
66+
}
67+
scanner.close();
68+
return hostKeys;
69+
}
70+
5071
@Override
5172
public boolean verify(EC2Computer computer, HostKey hostKey, TaskListener listener) throws IOException {
5273
HostKey existingHostKey = HostKeyHelper.getInstance().getHostKey(computer);
53-
if (null == existingHostKey) {
54-
byte[] key = Base64.getDecoder().decode("AAAAC3NzaC1lZDI1NTE5AAAAIFGNRfg0pVrEdViJgKEdRKqFRG6kS/jOnFQC+wa5cp0v");
55-
HostKey staticHostKey = new HostKey("ssh-ed25519", key);
74+
ArrayList<HostKey> staticHostKeys = getStaticHostKeys(computer);
5675

57-
if (hostKey.equals(staticHostKey)) {
58-
HostKeyHelper.getInstance().saveHostKey(computer, hostKey);
59-
EC2Cloud.log(LOGGER, Level.INFO, computer.getListener(), String.format("The SSH key %s %s has been successfully checked against the instance console for connections to %s", hostKey.getAlgorithm(), hostKey.getFingerprint(), computer.getName()));
60-
return true;
61-
}
76+
if (staticHostKeys.size() < 1) {
77+
EC2Cloud.log(LOGGER, Level.WARNING, computer.getListener(), "No static SSH keys found");
78+
// To avoid reconnecting continuously
79+
computer.setTemporarilyOffline(true, OfflineCause.create(Messages._OfflineCause_SSHKeyCheckFailed()));
80+
return false;
81+
}
6282

63-
EC2Cloud.log(LOGGER, Level.WARNING, computer.getListener(), String.format("The SSH key (%s %s) presented by the instance is different from the one printed out on the instance console (%s %s). The connection to %s is closed to prevent a possible man-in-the-middle attack",
64-
hostKey.getAlgorithm(), hostKey.getFingerprint(), staticHostKey.getAlgorithm(), staticHostKey.getFingerprint(), computer.getName()));
83+
if (null == existingHostKey) {
84+
for (HostKey staticHostKey : staticHostKeys) {
85+
if (hostKey.equals(staticHostKey)) {
86+
HostKeyHelper.getInstance().saveHostKey(computer, hostKey);
87+
EC2Cloud.log(LOGGER, Level.INFO, computer.getListener(), String.format("The SSH key %s %s has been successfully checked against the instance console for connections to %s", hostKey.getAlgorithm(), hostKey.getFingerprint(), computer.getName()));
88+
return true;
89+
}
90+
}
6591
// To avoid reconnecting continuously
6692
computer.setTemporarilyOffline(true, OfflineCause.create(Messages._OfflineCause_SSHKeyCheckFailed()));
6793
return false;

src/main/resources/hudson/plugins/ec2/SlaveTemplate/config.jelly

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,10 @@ THE SOFTWARE.
199199
<f:entry title="${%Host Key Verification Strategy}" field="hostKeyVerificationStrategy">
200200
<f:select default="${descriptor.defaultHostKeyVerificationStrategy}"/>
201201
</f:entry>
202+
203+
<f:entry title="${%Static Host Keys}" field="staticHostKeys">
204+
<f:textbox />
205+
</f:entry>
202206

203207
<f:entry title="${%Maximum Total Uses}" field="maxTotalUses">
204208
<f:textbox default="-1"/>

src/test/java/hudson/plugins/ec2/SlaveTemplateTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ public void testConfigRoundtripWithCustomSSHHostKeyVerificationStrategy() throws
167167
// We check this one is set
168168
final HostKeyVerificationStrategyEnum STRATEGY_TO_CHECK = HostKeyVerificationStrategyEnum.OFF;
169169

170-
SlaveTemplate orig = new SlaveTemplate(ami, EC2AbstractSlave.TEST_ZONE, null, "default", "foo", InstanceType.M1Large, false, "ttt", Node.Mode.NORMAL, description, "bar", "bbb", "aaa", "10", "fff", null, "-Xmx1g", false, "subnet 456", tags, null, 0, 0, null, "", true, false, false, "", false, "", false, false, false, ConnectionStrategy.PUBLIC_IP, -1, null, STRATEGY_TO_CHECK);
170+
SlaveTemplate orig = new SlaveTemplate(ami, EC2AbstractSlave.TEST_ZONE, null, "default", "foo", InstanceType.M1Large, false, "ttt", Node.Mode.NORMAL, description, "bar", "bbb", "aaa", "10", "fff", null, "-Xmx1g", false, "subnet 456", tags, null, 0, 0, null, "", true, false, false, "", false, "", false, false, false, ConnectionStrategy.PUBLIC_IP, -1, null, STRATEGY_TO_CHECK, "");
171171

172172
List<SlaveTemplate> templates = new ArrayList<SlaveTemplate>();
173173
templates.add(orig);

0 commit comments

Comments
 (0)