mirror of
https://github.com/jenkinsci/jenkins.git
synced 2026-11-14 04:22:16 +00:00
Merge branch 'security' into security-rc
Conflicts: core/src/main/java/hudson/model/AbstractItem.java core/src/main/java/hudson/security/ACL.java test/src/test/groovy/hudson/model/AbstractProjectTest.groovy
This commit is contained in:
commit
8aafca039d
5 files changed
+132
-15
No files matched your search
@@ -43,6 +43,7 @@ import hudson.util.AlternativeUiTextProvider.Message;
|
||||
import hudson.util.AtomicFileWriter;
|
||||
import hudson.util.IOUtils;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.acegisecurity.Authentication;
|
||||
import org.apache.tools.ant.taskdefs.Copy;
|
||||
import org.apache.tools.ant.types.FileSet;
|
||||
import org.kohsuke.stapler.WebMethod;
|
||||
@@ -210,7 +211,7 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet
|
||||
* Not all the Items need to support this operation, but if you decide to do so,
|
||||
* you can use this method.
|
||||
*/
|
||||
protected void renameTo(String newName) throws IOException {
|
||||
protected void renameTo(final String newName) throws IOException {
|
||||
// always synchronize from bigger objects first
|
||||
final ItemGroup parent = getParent();
|
||||
synchronized (parent) {
|
||||
@@ -223,13 +224,28 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet
|
||||
if (this.name.equals(newName))
|
||||
return;
|
||||
|
||||
Item existing = parent.getItem(newName);
|
||||
if (existing != null && existing!=this)
|
||||
// the look up is case insensitive, so we need "existing!=this"
|
||||
// to allow people to rename "Foo" to "foo", for example.
|
||||
// see http://www.nabble.com/error-on-renaming-project-tt18061629.html
|
||||
throw new IllegalArgumentException("Job " + newName
|
||||
+ " already exists");
|
||||
// the test to see if the project already exists or not needs to be done in escalated privilege
|
||||
// to avoid overwriting
|
||||
ACL.impersonate(ACL.SYSTEM,new Callable<Void,IOException>() {
|
||||
final Authentication user = Jenkins.getAuthentication();
|
||||
@Override
|
||||
public Void call() throws IOException {
|
||||
Item existing = parent.getItem(newName);
|
||||
if (existing != null && existing!=AbstractItem.this) {
|
||||
if (existing.getACL().hasPermission(user,Item.DISCOVER))
|
||||
// the look up is case insensitive, so we need "existing!=this"
|
||||
// to allow people to rename "Foo" to "foo", for example.
|
||||
// see http://www.nabble.com/error-on-renaming-project-tt18061629.html
|
||||
throw new IllegalArgumentException("Job " + newName + " already exists");
|
||||
else {
|
||||
// can't think of any real way to hide this, but at least the error message could be vague.
|
||||
throw new IOException("Unable to rename to " + newName);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
String oldName = this.name;
|
||||
String oldFullName = getFullName();
|
||||
@@ -634,7 +650,13 @@ public abstract class AbstractItem extends Actionable implements Item, HttpDelet
|
||||
}
|
||||
|
||||
// try to reflect the changes by reloading
|
||||
new XmlFile(Items.XSTREAM, out.getTemporaryFile()).unmarshal(this);
|
||||
Object o = new XmlFile(Items.XSTREAM, out.getTemporaryFile()).unmarshal(this);
|
||||
if (o!=this) {
|
||||
// ensure that we've got the same job type. extending this code to support updating
|
||||
// to different job type requires destroying & creating a new job type
|
||||
throw new IOException("Expecting "+this.getClass()+" but got "+o.getClass()+" instead");
|
||||
}
|
||||
|
||||
Items.whileUpdatingByXml(new Callable<Void,IOException>() {
|
||||
@Override public Void call() throws IOException {
|
||||
onLoad(getParent(), getRootDir().getName());
|
||||
|
||||
@@ -28,6 +28,8 @@ import hudson.remoting.PingThread;
|
||||
import hudson.remoting.Channel.Mode;
|
||||
import hudson.util.ChunkedOutputStream;
|
||||
import hudson.util.ChunkedInputStream;
|
||||
import org.kohsuke.accmod.Restricted;
|
||||
import org.kohsuke.accmod.restrictions.NoExternalUse;
|
||||
import org.kohsuke.stapler.StaplerRequest;
|
||||
import org.kohsuke.stapler.StaplerResponse;
|
||||
|
||||
@@ -151,10 +153,12 @@ abstract public class FullDuplexHttpChannel {
|
||||
/**
|
||||
* Set to true if the servlet container doesn't support chunked encoding.
|
||||
*/
|
||||
@Restricted(NoExternalUse.class)
|
||||
public static boolean DIY_CHUNKING = Boolean.getBoolean("hudson.diyChunking");
|
||||
|
||||
/**
|
||||
* Controls the time out of waiting for the 2nd HTTP request to arrive.
|
||||
*/
|
||||
private static long CONNECTION_TIMEOUT = TimeUnit.SECONDS.toMillis(15);
|
||||
@Restricted(NoExternalUse.class)
|
||||
public static long CONNECTION_TIMEOUT = TimeUnit.SECONDS.toMillis(15);
|
||||
}
|
||||
@@ -24,6 +24,7 @@
|
||||
package hudson.security;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import hudson.remoting.Callable;
|
||||
import jenkins.security.NonSerializableSecurityContext;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.acegisecurity.AccessDeniedException;
|
||||
@@ -146,4 +147,19 @@ public abstract class ACL {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Safer variant of {@link #impersonate(Authentication)} that does not require a finally-block.
|
||||
* @param auth authentication, such as {@link #SYSTEM}
|
||||
* @param body an action to run with this alternate authentication in effect
|
||||
* @since TODO
|
||||
*/
|
||||
public static <V,T extends Exception> V impersonate(Authentication auth, Callable<V,T> body) throws T {
|
||||
SecurityContext old = impersonate(auth);
|
||||
try {
|
||||
return body.call();
|
||||
} finally {
|
||||
SecurityContextHolder.setContext(old);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,6 @@ import javax.mail.internet.InternetAddress;
|
||||
import javax.servlet.ServletContext;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@@ -108,9 +107,14 @@ public class JenkinsLocationConfiguration extends GlobalConfiguration {
|
||||
*/
|
||||
private void updateSecureSessionFlag() {
|
||||
try {
|
||||
boolean v = fixNull(jenkinsUrl).startsWith("https");
|
||||
ServletContext context = Jenkins.getInstance().servletContext;
|
||||
Method m = context.getClass().getMethod("getSessionCookieConfig");
|
||||
Method m;
|
||||
try {
|
||||
m = context.getClass().getMethod("getSessionCookieConfig");
|
||||
} catch (NoSuchMethodException x) { // 3.0+
|
||||
LOGGER.log(Level.FINE, "Failed to set secure cookie flag", x);
|
||||
return;
|
||||
}
|
||||
Object sessionCookieConfig = m.invoke(context);
|
||||
|
||||
// not exposing session cookie to JavaScript to mitigate damage caused by XSS
|
||||
@@ -119,9 +123,10 @@ public class JenkinsLocationConfiguration extends GlobalConfiguration {
|
||||
setHttpOnly.invoke(sessionCookieConfig,true);
|
||||
|
||||
Method setSecure = scc.getMethod("setSecure",boolean.class);
|
||||
boolean v = fixNull(jenkinsUrl).startsWith("https");
|
||||
setSecure.invoke(sessionCookieConfig,v);
|
||||
} catch (Exception e) {
|
||||
LOGGER.log(Level.WARNING, "Failed to set secure cookie flag. Maybe running on Servlet 2.5 and younger?", e);
|
||||
LOGGER.log(Level.WARNING, "Failed to set secure cookie flag", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user