提交 f4496df1 编写于 作者: K Kohsuke Kawaguchi

[SECURITY-54] Massaging the original fix.

- Use the proper block cipher mode.
  Or else the information about the plain text still ends up revealing as a pattern without the attacker knowing the key.
- No need to hide SLAVE_SECRET from the encrypted payload.
  jnlpMac is needed to decrypt this payload to begin with, so there's no point in hiding it. This simplifies the code a little bit.
- Using a newer slave installer that uses the -secret option
上级 01a24e2c
......@@ -24,6 +24,7 @@
package hudson.slaves;
import hudson.model.*;
import hudson.util.IOException2;
import hudson.util.IOUtils;
import hudson.util.io.ReopenableRotatingFileOutputStream;
import jenkins.model.Jenkins.MasterComputer;
......@@ -47,6 +48,7 @@ import java.io.OutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.security.SecureRandom;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
......@@ -64,6 +66,7 @@ import java.io.PrintWriter;
import java.security.GeneralSecurityException;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.RequestDispatcher;
import jenkins.model.Jenkins;
......@@ -554,7 +557,6 @@ public class SlaveComputer extends Computer {
public void doSlaveAgentJnlp(StaplerRequest req, StaplerResponse res) throws IOException, ServletException {
RequestDispatcher view = req.getView(this, "slave-agent.jnlp.jelly");
if ("true".equals(req.getParameter("encrypt"))) {
req.setAttribute("jnlpMac", "SLAVE_SECRET");
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
StaplerResponse temp = new ResponseImpl(req.getStapler(), new HttpServletResponseWrapper(res) {
@Override public ServletOutputStream getOutputStream() throws IOException {
......@@ -565,21 +567,25 @@ public class SlaveComputer extends Computer {
}
});
view.forward(req, temp);
byte[] iv = new byte[128/8];
new SecureRandom().nextBytes(iv);
byte[] jnlpMac = JnlpSlaveAgentProtocol.SLAVE_SECRET.mac(getName().getBytes("UTF-8"));
SecretKey key = new SecretKeySpec(jnlpMac, 0, /* export restrictions */ 128 / 8, "AES");
byte[] encrypted;
try {
Cipher c = Secret.getCipher("AES");
c.init(Cipher.ENCRYPT_MODE, key);
Cipher c = Secret.getCipher("AES/CFB8/NoPadding");
c.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
encrypted = c.doFinal(baos.toByteArray());
} catch (GeneralSecurityException x) {
throw new IOException(x);
throw new IOException2(x);
}
res.setContentType("application/octet-stream");
res.getOutputStream().write(iv);
res.getOutputStream().write(encrypted);
} else {
checkPermission(CONNECT);
req.setAttribute("jnlpMac", getJnlpMac());
view.forward(req, res);
}
}
......
......@@ -61,7 +61,7 @@ THE SOFTWARE.
</resources>
<application-desc main-class="hudson.remoting.jnlp.Main">
<argument>${jnlpMac}</argument>
<argument>${it.jnlpMac}</argument>
<argument>${it.node.nodeName}</argument>
<j:if test="${it.launcher.tunnel!=null}">
<argument>-tunnel</argument>
......
......@@ -117,6 +117,11 @@ THE SOFTWARE.
<artifactId>ssh-cli-auth</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.modules</groupId>
<artifactId>slave-installer</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.modules</groupId>
<artifactId>windows-slave-installer</artifactId>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册