From f4496df19e36465ae8d7cfebc6cde75f2888585b Mon Sep 17 00:00:00 2001 From: Kohsuke Kawaguchi Date: Tue, 12 Feb 2013 11:51:08 -0800 Subject: [PATCH] [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 --- .../main/java/hudson/slaves/SlaveComputer.java | 16 +++++++++++----- .../slaves/SlaveComputer/slave-agent.jnlp.jelly | 2 +- war/pom.xml | 5 +++++ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/hudson/slaves/SlaveComputer.java b/core/src/main/java/hudson/slaves/SlaveComputer.java index 7c841d0693..429774d096 100644 --- a/core/src/main/java/hudson/slaves/SlaveComputer.java +++ b/core/src/main/java/hudson/slaves/SlaveComputer.java @@ -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); } } diff --git a/core/src/main/resources/hudson/slaves/SlaveComputer/slave-agent.jnlp.jelly b/core/src/main/resources/hudson/slaves/SlaveComputer/slave-agent.jnlp.jelly index 12c7bb12e1..0652d4559f 100644 --- a/core/src/main/resources/hudson/slaves/SlaveComputer/slave-agent.jnlp.jelly +++ b/core/src/main/resources/hudson/slaves/SlaveComputer/slave-agent.jnlp.jelly @@ -61,7 +61,7 @@ THE SOFTWARE. - ${jnlpMac} + ${it.jnlpMac} ${it.node.nodeName} -tunnel diff --git a/war/pom.xml b/war/pom.xml index e3fc7232e8..1fa962fecb 100644 --- a/war/pom.xml +++ b/war/pom.xml @@ -117,6 +117,11 @@ THE SOFTWARE. ssh-cli-auth 1.2 + + org.jenkins-ci.modules + slave-installer + 1.2 + org.jenkins-ci.modules windows-slave-installer -- GitLab