forked from jenkinsci/jenkins
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CliProtocol2.java
83 lines (72 loc) · 2.94 KB
/
CliProtocol2.java
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
package hudson.cli;
import hudson.Extension;
import jenkins.model.Jenkins;
import org.jenkinsci.Symbol;
import org.jenkinsci.remoting.nio.NioChannelHub;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;
import java.security.Signature;
/**
* {@link CliProtocol} Version 2, which adds transport encryption.
*
* @author Kohsuke Kawaguchi
* @since 1.467
*/
@Extension @Symbol("cli2")
public class CliProtocol2 extends CliProtocol {
@Override
public String getName() {
return "CLI2-connect";
}
@Override
public void handle(Socket socket) throws IOException, InterruptedException {
new Handler2(nio.getHub(), socket).run();
}
protected static class Handler2 extends Handler {
/**
* @deprecated as of 1.559
* Use {@link #Handler2(NioChannelHub, Socket)}
*/
@Deprecated
public Handler2(Socket socket) {
super(socket);
}
public Handler2(NioChannelHub hub, Socket socket) {
super(hub, socket);
}
@Override
public void run() throws IOException, InterruptedException {
try {
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeUTF("Welcome");
// perform coin-toss and come up with a session key to encrypt data
Connection c = new Connection(socket);
byte[] secret = c.diffieHellman(true).generateSecret();
SecretKey sessionKey = new SecretKeySpec(Connection.fold(secret,128/8),"AES");
c = c.encryptConnection(sessionKey,"AES/CFB8/NoPadding");
try {
// HACK: TODO: move the transport support into modules
Class<?> cls = Jenkins.getActiveInstance().pluginManager.uberClassLoader.loadClass("org.jenkinsci.main.modules.instance_identity.InstanceIdentity");
Object iid = cls.getDeclaredMethod("get").invoke(null);
PrivateKey instanceId = (PrivateKey)cls.getDeclaredMethod("getPrivate").invoke(iid);
// send a signature to prove our identity
Signature signer = Signature.getInstance("SHA1withRSA");
signer.initSign(instanceId);
signer.update(secret);
c.writeByteArray(signer.sign());
} catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new Error(e);
}
runCli(c);
} catch (GeneralSecurityException e) {
throw new IOException("Failed to encrypt the CLI channel",e);
}
}
}
}