Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 Please unblock package jenkins The version I have just uploaded to unstable fixes two security issues as outlined in http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=688298. One is classified as 'Critical' and the other is classified as 'High'. The fix was cherry picked from the latest upstream LTS release under guidance from the project leader, Kohsuke Kawaguchi. Debdiff attached. unblock jenkins/1.447.2+dfsg-2 - -- System Information: Debian Release: wheezy/sid APT prefers unstable APT policy: (500, 'unstable') Architecture: amd64 (x86_64) Kernel: Linux 3.5.0-15-generic (SMP w/8 CPU cores) Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) Shell: /bin/sh linked to /bin/dash -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iQIcBAEBCAAGBQJQYbS2AAoJEL/srsug59jDYLsQAMYWKYTkCG7Y4E8TEtHAv4xu ETxn6ZTBje9MPGa5ldNEpM032ZzcO1AOpDzrdZ39VYw4f+iAQpj4e1AvO2TvJccJ cUPxvMGuPAbuB8ZD/cawQoD+6svcrqdHtwdRig91yEk2imXy7w6DIMu2YfxK8In8 +lg+uRlOFJSLEXKQd1hhb6pYRmJtj6FPX8ZIn3VPSpZhfvkw5Wk1yi37r8z248tY 3zzwMz9T2eNR2YbYhC/H8IcImruXx6gOSDzpDPQ1ZydivjGoPOHWshKefTn/dqPV I1+Yv3kFGtkhllZlRaI8IKFsRbFA+B7TmiK2lmvz1CZR1EdZ8uzwARPjF/JtzV6m m01XbAfCEylwJu/1edJ9M17sfc83iDBM6v3+83WXvix64yZoeaZt3THD275XJzIV UASNGucjQ8bk7cTNAsCt73VYzsOhD5IT7XGApFjXswbn00huauwu7NrJjNOy2jzF 4qncAJ02scs+ZD9c0D0ZgtSfKsDBYwyjCABSObkY0E/av6PJyfGkjOD4C9FCCpcH c9BpdhZMa+fXy5Iq4DV1zsjmGzJW4c3ZyLPXw3IxsY4keK1f/RPBeFfG1yPiQzsH n9xdQ2NCsCKAJv9kC55a0rowh3vgJ7irMUiRwze+uoMOzfHZxkGiCT2hDj88njy+ qWZH8txRw7Dd0o8KhRc3 =5s7y -----END PGP SIGNATURE-----
diff -Nru jenkins-1.447.2+dfsg/debian/changelog jenkins-1.447.2+dfsg/debian/changelog --- jenkins-1.447.2+dfsg/debian/changelog 2012-06-21 10:18:11.000000000 +0100 +++ jenkins-1.447.2+dfsg/debian/changelog 2012-09-25 12:21:13.000000000 +0100 @@ -1,3 +1,15 @@ +jenkins (1.447.2+dfsg-2) unstable; urgency=low + + * Fix multiple security issues in Jenkins core (Closes: #688298): + - d/p/security/CVE-2012-4438_CVE-2012-4439.patch: Cherry picked + fixes from 1.466.2 release to resolve remote code execution + and XSS security vulnerabilities. + - d/rules: Tweaked handling of groovy -> java source file copy to + accommodate the file created by the above patch. + - Fixes: CVE-2012-4438, CVE-2012-4439 + + -- James Page <james.p...@ubuntu.com> Tue, 25 Sep 2012 11:01:53 +0100 + jenkins (1.447.2+dfsg-1) unstable; urgency=low * New upstream release. diff -Nru jenkins-1.447.2+dfsg/debian/patches/security/CVE-2012-4438_CVE-2012-4439.patch jenkins-1.447.2+dfsg/debian/patches/security/CVE-2012-4438_CVE-2012-4439.patch --- jenkins-1.447.2+dfsg/debian/patches/security/CVE-2012-4438_CVE-2012-4439.patch 1970-01-01 01:00:00.000000000 +0100 +++ jenkins-1.447.2+dfsg/debian/patches/security/CVE-2012-4438_CVE-2012-4439.patch 2012-09-25 12:21:13.000000000 +0100 @@ -0,0 +1,559 @@ +Decription: Cherry picked fixes from 1.466.2 to resolve + two security issues: + - CVE-2012-4438 jenkins remote code execution + - CVE-2012-4439 jenkins XSS +Origin: Upstream, commits fb73bac50f22526a3d3b...43ff1688eee6ea +Bug: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=688298 + +diff --git a/core/src/main/java/hudson/model/DownloadService.java b/core/src/main/java/hudson/model/DownloadService.java +index 7f8d86d..820a44a 100644 +--- a/core/src/main/java/hudson/model/DownloadService.java ++++ b/core/src/main/java/hudson/model/DownloadService.java +@@ -26,18 +26,20 @@ package hudson.model; + import hudson.Extension; + import hudson.ExtensionList; + import hudson.ExtensionPoint; ++import hudson.util.FormValidation; ++import hudson.util.FormValidation.Kind; + import hudson.util.IOException2; + import hudson.util.IOUtils; + import hudson.util.QuotedStringTokenizer; + import hudson.util.TextFile; + import hudson.util.TimeUnit2; + import jenkins.model.Jenkins; ++import jenkins.util.JSONSignatureValidator; + import net.sf.json.JSONException; + import org.kohsuke.stapler.Stapler; + + import java.io.File; + import java.io.IOException; +-import java.util.logging.Level; + import java.util.logging.Logger; + + import net.sf.json.JSONObject; +@@ -61,7 +63,8 @@ public class DownloadService extends PageDecorator { + */ + public String generateFragment() { + if (neverUpdate) return ""; +- ++ if (doesNotSupportPostMessage()) return ""; ++ + StringBuilder buf = new StringBuilder(); + if(Jenkins.getInstance().hasPermission(Jenkins.READ)) { + long now = System.currentTimeMillis(); +@@ -88,6 +91,23 @@ public class DownloadService extends PageDecorator { + return buf.toString(); + } + ++ private boolean doesNotSupportPostMessage() { ++ StaplerRequest req = Stapler.getCurrentRequest(); ++ if (req==null) return false; ++ ++ String ua = req.getHeader("User-Agent"); ++ if (ua==null) return false; ++ ++ // according to http://caniuse.com/#feat=x-doc-messaging, IE <=7 doesn't support pstMessage ++ // see http://www.useragentstring.com/pages/Internet%20Explorer/ for user agents ++ ++ // we want to err on the cautious side here. ++ // Because of JENKINS-15105, we can't serve signed metadata from JSON, which means we need to be ++ // using a modern browser as a vehicle to request these data. This check is here to prevent Jenkins ++ // from using older browsers that are known not to support postMessage as the vehicle. ++ return ua.contains("Windows") && (ua.contains(" MSIE 5.") || ua.contains(" MSIE 6.") || ua.contains(" MSIE 7.")); ++ } ++ + private String mapHttps(String url) { + /* + HACKISH: +@@ -223,11 +243,24 @@ public class DownloadService extends PageDecorator { + */ + public void doPostBack(StaplerRequest req, StaplerResponse rsp) throws IOException { + long dataTimestamp = System.currentTimeMillis(); ++ due = dataTimestamp+getInterval(); // success or fail, don't try too often ++ ++ String json = IOUtils.toString(req.getInputStream(),"UTF-8"); ++ JSONObject o = JSONObject.fromObject(json); ++ ++ if (signatureCheck) { ++ FormValidation e = new JSONSignatureValidator("downloadable '"+id+"'").verifySignature(o); ++ if (e.kind!= Kind.OK) { ++ LOGGER.severe(e.renderHtml()); ++ throw e; ++ } ++ } ++ + TextFile df = getDataFile(); +- df.write(IOUtils.toString(req.getInputStream(),"UTF-8")); ++ df.write(json); + df.file.setLastModified(dataTimestamp); +- due = dataTimestamp+getInterval(); + LOGGER.info("Obtained the updated data file for "+id); ++ + rsp.setContentType("text/plain"); // So browser won't try to parse response + } + +@@ -253,5 +286,10 @@ public class DownloadService extends PageDecorator { + } + + public static boolean neverUpdate = Boolean.getBoolean(DownloadService.class.getName()+".never"); ++ ++ /** ++ * Off by default until we know this is reasonably working. ++ */ ++ public static boolean signatureCheck = !Boolean.getBoolean(DownloadService.class.getName()+".noSignatureCheck"); + } + +diff --git a/core/src/main/java/hudson/model/UpdateSite.java b/core/src/main/java/hudson/model/UpdateSite.java +index 74bccfb..578237e 100644 +--- a/core/src/main/java/hudson/model/UpdateSite.java ++++ b/core/src/main/java/hudson/model/UpdateSite.java +@@ -25,7 +25,6 @@ + + package hudson.model; + +-import com.trilead.ssh2.crypto.Base64; + import hudson.PluginManager; + import hudson.PluginWrapper; + import hudson.lifecycle.Lifecycle; +@@ -37,12 +36,9 @@ import hudson.util.IOUtils; + import hudson.util.TextFile; + import hudson.util.VersionNumber; + import jenkins.model.Jenkins; ++import jenkins.util.JSONSignatureValidator; + import net.sf.json.JSONException; + import net.sf.json.JSONObject; +-import org.apache.commons.io.output.NullOutputStream; +-import org.apache.commons.io.output.TeeOutputStream; +-import org.jvnet.hudson.crypto.CertificateUtil; +-import org.jvnet.hudson.crypto.SignatureOutputStream; + import org.kohsuke.stapler.DataBoundConstructor; + import org.kohsuke.stapler.HttpResponse; + import org.kohsuke.stapler.QueryParameter; +@@ -52,23 +48,14 @@ import org.kohsuke.stapler.StaplerResponse; + import javax.servlet.ServletContext; + import java.io.ByteArrayInputStream; + import java.io.File; +-import java.io.FileInputStream; + import java.io.IOException; + import java.io.OutputStreamWriter; + import java.io.Writer; + import java.security.DigestOutputStream; + import java.security.GeneralSecurityException; +-import java.security.MessageDigest; +-import java.security.Signature; +-import java.security.cert.CertificateExpiredException; +-import java.security.cert.CertificateFactory; +-import java.security.cert.CertificateNotYetValidException; +-import java.security.cert.TrustAnchor; +-import java.security.cert.X509Certificate; + import java.util.ArrayList; + import java.util.Collections; + import java.util.HashMap; +-import java.util.HashSet; + import java.util.List; + import java.util.Map; + import java.util.Set; +@@ -174,100 +161,7 @@ public class UpdateSite { + * Verifies the signature in the update center data file. + */ + private FormValidation verifySignature(JSONObject o) throws IOException { +- try { +- FormValidation warning = null; +- +- JSONObject signature = o.getJSONObject("signature"); +- if (signature.isNullObject()) { +- return FormValidation.error("No signature block found in update center '"+id+"'"); +- } +- o.remove("signature"); +- +- List<X509Certificate> certs = new ArrayList<X509Certificate>(); +- {// load and verify certificates +- CertificateFactory cf = CertificateFactory.getInstance("X509"); +- for (Object cert : signature.getJSONArray("certificates")) { +- X509Certificate c = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(Base64.decode(cert.toString().toCharArray()))); +- try { +- c.checkValidity(); +- } catch (CertificateExpiredException e) { // even if the certificate isn't valid yet, we'll proceed it anyway +- warning = FormValidation.warning(e,String.format("Certificate %s has expired in update center '%s'",cert.toString(),id)); +- } catch (CertificateNotYetValidException e) { +- warning = FormValidation.warning(e,String.format("Certificate %s is not yet valid in update center '%s'",cert.toString(),id)); +- } +- certs.add(c); +- } +- +- // if we trust default root CAs, we end up trusting anyone who has a valid certificate, +- // which isn't useful at all +- Set<TrustAnchor> anchors = new HashSet<TrustAnchor>(); // CertificateUtil.getDefaultRootCAs(); +- Jenkins j = Jenkins.getInstance(); +- for (String cert : (Set<String>) j.servletContext.getResourcePaths("/WEB-INF/update-center-rootCAs")) { +- if (cert.endsWith(".txt")) continue; // skip text files that are meant to be documentation +- anchors.add(new TrustAnchor((X509Certificate)cf.generateCertificate(j.servletContext.getResourceAsStream(cert)),null)); +- } +- File[] cas = new File(j.root, "update-center-rootCAs").listFiles(); +- if (cas!=null) { +- for (File cert : cas) { +- if (cert.getName().endsWith(".txt")) continue; // skip text files that are meant to be documentation +- FileInputStream in = new FileInputStream(cert); +- try { +- anchors.add(new TrustAnchor((X509Certificate)cf.generateCertificate(in),null)); +- } finally { +- in.close(); +- } +- } +- } +- CertificateUtil.validatePath(certs,anchors); +- } +- +- // this is for computing a digest to check sanity +- MessageDigest sha1 = MessageDigest.getInstance("SHA1"); +- DigestOutputStream dos = new DigestOutputStream(new NullOutputStream(),sha1); +- +- // this is for computing a signature +- Signature sig = Signature.getInstance("SHA1withRSA"); +- sig.initVerify(certs.get(0)); +- SignatureOutputStream sos = new SignatureOutputStream(sig); +- +- // until JENKINS-11110 fix, UC used to serve invalid digest (and therefore unverifiable signature) +- // that only covers the earlier portion of the file. This was caused by the lack of close() call +- // in the canonical writing, which apparently leave some bytes somewhere that's not flushed to +- // the digest output stream. This affects Jenkins [1.424,1,431]. +- // Jenkins 1.432 shipped with the "fix" (1eb0c64abb3794edce29cbb1de50c93fa03a8229) that made it +- // compute the correct digest, but it breaks all the existing UC json metadata out there. We then +- // quickly discovered ourselves in the catch-22 situation. If we generate UC with the correct signature, +- // it'll cut off [1.424,1.431] from the UC. But if we don't, we'll cut off [1.432,*). +- // +- // In 1.433, we revisited 1eb0c64abb3794edce29cbb1de50c93fa03a8229 so that the original "digest"/"signature" +- // pair continues to be generated in a buggy form, while "correct_digest"/"correct_signature" are generated +- // correctly. +- // +- // Jenkins should ignore "digest"/"signature" pair. Accepting it creates a vulnerability that allows +- // the attacker to inject a fragment at the end of the json. +- o.writeCanonical(new OutputStreamWriter(new TeeOutputStream(dos,sos),"UTF-8")).close(); +- +- // did the digest match? this is not a part of the signature validation, but if we have a bug in the c14n +- // (which is more likely than someone tampering with update center), we can tell +- String computedDigest = new String(Base64.encode(sha1.digest())); +- String providedDigest = signature.optString("correct_digest"); +- if (providedDigest==null) { +- return FormValidation.error("No correct_digest parameter in update center '"+id+"'. This metadata appears to be old."); +- } +- if (!computedDigest.equalsIgnoreCase(providedDigest)) { +- return FormValidation.error("Digest mismatch: "+computedDigest+" vs "+providedDigest+" in update center '"+id+"'"); +- } +- +- String providedSignature = signature.getString("correct_signature"); +- if (!sig.verify(Base64.decode(providedSignature.toCharArray()))) { +- return FormValidation.error("Signature in the update center doesn't match with the certificate in update center '"+id+"'"); +- } +- +- if (warning!=null) return warning; +- return FormValidation.ok(); +- } catch (GeneralSecurityException e) { +- return FormValidation.error(e,"Signature verification failed in the update center '"+id+"'"); +- } ++ return new JSONSignatureValidator("update site '"+id+"'").verifySignature(o); + } + + /** +diff --git a/core/src/main/java/hudson/search/Search.java b/core/src/main/java/hudson/search/Search.java +index 55737b8..f439d8a 100644 +--- a/core/src/main/java/hudson/search/Search.java ++++ b/core/src/main/java/hudson/search/Search.java +@@ -84,6 +84,7 @@ public class Search { + * See http://developer.mozilla.org/en/docs/Supporting_search_suggestions_in_search_plugins + */ + public void doSuggestOpenSearch(StaplerRequest req, StaplerResponse rsp, @QueryParameter String q) throws IOException, ServletException { ++ rsp.setContentType(Flavor.JSON.contentType); + DataWriter w = Flavor.JSON.createDataWriter(null, rsp); + w.startArray(); + w.value(q); +diff --git a/core/src/main/java/hudson/tasks/junit/History.java b/core/src/main/java/hudson/tasks/junit/History.java +index 6d5333c..7a46b60 100644 +--- a/core/src/main/java/hudson/tasks/junit/History.java ++++ b/core/src/main/java/hudson/tasks/junit/History.java +@@ -293,4 +293,12 @@ public class History { + + } + ++ public static int asInt(String s, int defalutValue) { ++ if (s==null) return defalutValue; ++ try { ++ return Integer.parseInt(s); ++ } catch (NumberFormatException e) { ++ return defalutValue; ++ } ++ } + } +diff --git a/core/src/main/java/jenkins/util/JSONSignatureValidator.java b/core/src/main/java/jenkins/util/JSONSignatureValidator.java +new file mode 100644 +index 0000000..69c6144 +--- /dev/null ++++ b/core/src/main/java/jenkins/util/JSONSignatureValidator.java +@@ -0,0 +1,140 @@ ++package jenkins.util; ++ ++import com.trilead.ssh2.crypto.Base64; ++import hudson.util.FormValidation; ++import jenkins.model.Jenkins; ++import net.sf.json.JSONObject; ++import org.apache.commons.io.output.NullOutputStream; ++import org.apache.commons.io.output.TeeOutputStream; ++import org.jvnet.hudson.crypto.CertificateUtil; ++import org.jvnet.hudson.crypto.SignatureOutputStream; ++ ++import java.io.ByteArrayInputStream; ++import java.io.File; ++import java.io.FileInputStream; ++import java.io.IOException; ++import java.io.OutputStreamWriter; ++import java.security.DigestOutputStream; ++import java.security.GeneralSecurityException; ++import java.security.MessageDigest; ++import java.security.Signature; ++import java.security.cert.CertificateExpiredException; ++import java.security.cert.CertificateFactory; ++import java.security.cert.CertificateNotYetValidException; ++import java.security.cert.TrustAnchor; ++import java.security.cert.X509Certificate; ++import java.util.ArrayList; ++import java.util.HashSet; ++import java.util.List; ++import java.util.Set; ++ ++/** ++ * @author Kohsuke Kawaguchi ++ */ ++public class JSONSignatureValidator { ++ private final String name; ++ ++ public JSONSignatureValidator(String name) { ++ this.name = name; ++ } ++ ++ /** ++ * Verifies the signature in the update center data file. ++ */ ++ public FormValidation verifySignature(JSONObject o) throws IOException { ++ try { ++ FormValidation warning = null; ++ ++ JSONObject signature = o.getJSONObject("signature"); ++ if (signature.isNullObject()) { ++ return FormValidation.error("No signature block found in "+name); ++ } ++ o.remove("signature"); ++ ++ List<X509Certificate> certs = new ArrayList<X509Certificate>(); ++ {// load and verify certificates ++ CertificateFactory cf = CertificateFactory.getInstance("X509"); ++ for (Object cert : signature.getJSONArray("certificates")) { ++ X509Certificate c = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(Base64.decode(cert.toString().toCharArray()))); ++ try { ++ c.checkValidity(); ++ } catch (CertificateExpiredException e) { // even if the certificate isn't valid yet, we'll proceed it anyway ++ warning = FormValidation.warning(e,String.format("Certificate %s has expired in %s",cert.toString(),name)); ++ } catch (CertificateNotYetValidException e) { ++ warning = FormValidation.warning(e,String.format("Certificate %s is not yet valid in %s",cert.toString(),name)); ++ } ++ certs.add(c); ++ } ++ ++ // if we trust default root CAs, we end up trusting anyone who has a valid certificate, ++ // which isn't useful at all ++ Set<TrustAnchor> anchors = new HashSet<TrustAnchor>(); // CertificateUtil.getDefaultRootCAs(); ++ Jenkins j = Jenkins.getInstance(); ++ for (String cert : (Set<String>) j.servletContext.getResourcePaths("/WEB-INF/update-center-rootCAs")) { ++ if (cert.endsWith(".txt")) continue; // skip text files that are meant to be documentation ++ anchors.add(new TrustAnchor((X509Certificate)cf.generateCertificate(j.servletContext.getResourceAsStream(cert)),null)); ++ } ++ File[] cas = new File(j.root, "update-center-rootCAs").listFiles(); ++ if (cas!=null) { ++ for (File cert : cas) { ++ if (cert.getName().endsWith(".txt")) continue; // skip text files that are meant to be documentation ++ FileInputStream in = new FileInputStream(cert); ++ try { ++ anchors.add(new TrustAnchor((X509Certificate)cf.generateCertificate(in),null)); ++ } finally { ++ in.close(); ++ } ++ } ++ } ++ CertificateUtil.validatePath(certs, anchors); ++ } ++ ++ // this is for computing a digest to check sanity ++ MessageDigest sha1 = MessageDigest.getInstance("SHA1"); ++ DigestOutputStream dos = new DigestOutputStream(new NullOutputStream(),sha1); ++ ++ // this is for computing a signature ++ Signature sig = Signature.getInstance("SHA1withRSA"); ++ sig.initVerify(certs.get(0)); ++ SignatureOutputStream sos = new SignatureOutputStream(sig); ++ ++ // until JENKINS-11110 fix, UC used to serve invalid digest (and therefore unverifiable signature) ++ // that only covers the earlier portion of the file. This was caused by the lack of close() call ++ // in the canonical writing, which apparently leave some bytes somewhere that's not flushed to ++ // the digest output stream. This affects Jenkins [1.424,1,431]. ++ // Jenkins 1.432 shipped with the "fix" (1eb0c64abb3794edce29cbb1de50c93fa03a8229) that made it ++ // compute the correct digest, but it breaks all the existing UC json metadata out there. We then ++ // quickly discovered ourselves in the catch-22 situation. If we generate UC with the correct signature, ++ // it'll cut off [1.424,1.431] from the UC. But if we don't, we'll cut off [1.432,*). ++ // ++ // In 1.433, we revisited 1eb0c64abb3794edce29cbb1de50c93fa03a8229 so that the original "digest"/"signature" ++ // pair continues to be generated in a buggy form, while "correct_digest"/"correct_signature" are generated ++ // correctly. ++ // ++ // Jenkins should ignore "digest"/"signature" pair. Accepting it creates a vulnerability that allows ++ // the attacker to inject a fragment at the end of the json. ++ o.writeCanonical(new OutputStreamWriter(new TeeOutputStream(dos,sos),"UTF-8")).close(); ++ ++ // did the digest match? this is not a part of the signature validation, but if we have a bug in the c14n ++ // (which is more likely than someone tampering with update center), we can tell ++ String computedDigest = new String(Base64.encode(sha1.digest())); ++ String providedDigest = signature.optString("correct_digest"); ++ if (providedDigest==null) { ++ return FormValidation.error("No correct_digest parameter in "+name+". This metadata appears to be old."); ++ } ++ if (!computedDigest.equalsIgnoreCase(providedDigest)) { ++ return FormValidation.error("Digest mismatch: "+computedDigest+" vs "+providedDigest+" in "+name); ++ } ++ ++ String providedSignature = signature.getString("correct_signature"); ++ if (!sig.verify(Base64.decode(providedSignature.toCharArray()))) { ++ return FormValidation.error("Signature in the update center doesn't match with the certificate in "+name); ++ } ++ ++ if (warning!=null) return warning; ++ return FormValidation.ok(); ++ } catch (GeneralSecurityException e) { ++ return FormValidation.error(e,"Signature verification failed in "+name); ++ } ++ } ++} +diff --git a/core/src/main/resources/hudson/tasks/junit/History/index.jelly b/core/src/main/resources/hudson/tasks/junit/History/index.jelly +index 8ad7ee4..cda7a24 100644 +--- a/core/src/main/resources/hudson/tasks/junit/History/index.jelly ++++ b/core/src/main/resources/hudson/tasks/junit/History/index.jelly +@@ -26,8 +26,8 @@ THE SOFTWARE. + <?jelly escape-by-default='true'?> + <j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define" xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:i="jelly:fmt"> + <l:layout title="${%title(it.testObject.displayName)}"> +- <j:set var="start" value="${request.getParameter('start')?:0}"/> +- <j:set var="end" value="${request.getParameter('end')?:start+24}"/> ++ <j:set var="start" value="${it.asInt(request.getParameter('start'),0)}"/> ++ <j:set var="end" value="${it.asInt(request.getParameter('end'),start+24)}"/> + <j:set var="rangeParameters" value="start=${start}&end=${end+1}"/> + <script type="text/javascript"> + function setCount() { +diff --git a/war/src/main/webapp/scripts/hudson-behavior.js b/war/src/main/webapp/scripts/hudson-behavior.js +index f4abe0b..7b74dda 100644 +--- a/war/src/main/webapp/scripts/hudson-behavior.js ++++ b/war/src/main/webapp/scripts/hudson-behavior.js +@@ -2308,12 +2308,69 @@ function loadScript(href,callback) { + head.insertBefore( script, head.firstChild ); + } + ++/** ++ * Loads a dynamically created invisible IFRAME. ++ */ ++function createIframe(src,callback) { ++ var iframe = document.createElement("iframe"); ++ iframe.src = src; ++ iframe.style.display = "none"; ++ ++ var done = false; ++ iframe.onload = iframe.onreadystatechange = function() { ++ if ( !done && (!this.readyState || ++ this.readyState === "loaded" || this.readyState === "complete") ) { ++ done = true; ++ callback(); ++ } ++ }; ++ ++ document.body.appendChild(iframe); ++ return iframe; ++} ++ + var downloadService = { + continuations: {}, + + download : function(id,url,info, postBack,completionHandler) { +- this.continuations[id] = {postBack:postBack,completionHandler:completionHandler}; +- loadScript(url+"?"+Hash.toQueryString(info)); ++ var tag = {id:id,postBack:postBack,completionHandler:completionHandler,received:false}; ++ this.continuations[id] = tag; ++ ++ // use JSONP to download the data ++ function fallback() { ++ loadScript(url+"?id="+id+'&'+Hash.toQueryString(info)); ++ } ++ ++ if (window.postMessage) { ++ // try downloading the postMessage version of the data, ++ // if we don't receive postMessage (which probably means the server isn't ready with these new datasets), ++ // fallback to JSONP ++ tag.iframe = createIframe(url+".html?id="+id+'&'+Hash.toQueryString(info),function() { ++ window.setTimeout(function() { ++ if (!tag.received) ++ fallback(); ++ },100); // bit of delay in case onload on our side fires first ++ }); ++ } else { ++ // this browser doesn't support postMessage ++ fallback(); ++ } ++ ++ // NOTE: ++ // the only reason we even try fallback() is in case our server accepts the submission without a signature ++ // (which it really shouldn't) ++ }, ++ ++ /** ++ * Call back to postMessage ++ */ ++ receiveMessage : function(ev) { ++ var self = this; ++ Object.values(this.continuations).each(function(tag) { ++ if (tag.iframe.contentWindow==ev.source) { ++ self.post(tag.id,JSON.parse(ev.data)); ++ } ++ }) + }, + + post : function(id,data) { +@@ -2322,15 +2379,22 @@ var downloadService = { + data = id; + id = data.id; + } +- var o = this.continuations[id]; ++ var tag = this.continuations[id]; ++ if (tag==undefined) { ++ console.log("Submission from update center that we don't know: "+id); ++ console.log("Likely mismatch between the registered ID vs ID in JSON"); ++ return; ++ } ++ tag.received = true; ++ + // send the payload back in the body. We used to send this in as a form submission, but that hits the form size check in Jetty. +- new Ajax.Request(o.postBack, { ++ new Ajax.Request(tag.postBack, { + contentType:"application/json", + encoding:"UTF-8", + postBody:Object.toJSON(data), + onSuccess: function() { +- if(o.completionHandler!=null) +- o.completionHandler(); ++ if(tag.completionHandler!=null) ++ tag.completionHandler(); + else if(downloadService.completionHandler!=null) + downloadService.completionHandler(); + } +@@ -2341,6 +2405,8 @@ var downloadService = { + // update center service. to remain compatible with earlier version of Hudson, aliased. + var updateCenter = downloadService; + ++YAHOO.util.Event.addListener(window, "message", function(ev) { downloadService.receiveMessage(ev); }) ++ + /* + redirects to a page once the page is ready. + diff -Nru jenkins-1.447.2+dfsg/debian/patches/series jenkins-1.447.2+dfsg/debian/patches/series --- jenkins-1.447.2+dfsg/debian/patches/series 2012-06-21 10:18:11.000000000 +0100 +++ jenkins-1.447.2+dfsg/debian/patches/series 2012-09-25 12:21:13.000000000 +0100 @@ -16,3 +16,4 @@ dependency-upgrades/animal-sniffer-upgrade.patch build/use-stock-jmdns.patch ubuntu/ubuntu-font.patch +security/CVE-2012-4438_CVE-2012-4439.patch diff -Nru jenkins-1.447.2+dfsg/debian/rules jenkins-1.447.2+dfsg/debian/rules --- jenkins-1.447.2+dfsg/debian/rules 2012-06-21 10:18:11.000000000 +0100 +++ jenkins-1.447.2+dfsg/debian/rules 2012-09-25 12:21:13.000000000 +0100 @@ -57,7 +57,7 @@ [ ! -f dummy.keystore ] || rm dummy.keystore rm -rf debian/*.upstart rm -rf debian/plugin-debian.pom - rm -rf core/src/main/java/jenkins/util + rm -rf core/src/main/java/jenkins/util/ServerTcpPort.java get-orig-source: uscan --download-version $(DEB_UPSTREAM_VERSION) --force-download --rename @@ -73,7 +73,6 @@ done # Hack in java files from groovy source folder - no idea why they are there # might be maven3 related. - mkdir -p core/src/main/java/jenkins/util cp core/src/main/groovy/jenkins/util/ServerTcpPort.java core/src/main/java/jenkins/util dummy.keystore: