提交 2f7c7390 编写于 作者: K kohsuke

moved secret key from TCP agent listener to the core so that it can be used...

moved secret key from TCP agent listener to the core so that it can be used for other things (like remember-me authentication)


git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@6760 71c3de6d-444a-0410-be80-ed276b4c234a
上级 b25056b3
......@@ -4,16 +4,13 @@ import hudson.model.Hudson;
import hudson.model.Slave.ComputerImpl;
import hudson.remoting.Channel;
import hudson.remoting.Channel.Listener;
import hudson.util.TextFile;
import java.io.DataInputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.SecureRandom;
import java.util.logging.Level;
import java.util.logging.Logger;
......@@ -28,7 +25,7 @@ import java.util.logging.Logger;
* unauthorized remote slaves.
*
* <p>
* The approach here is to have {@link #secretKey a secret key} on the master.
* The approach here is to have {@link Hudson#getSecretKey() a secret key} on the master.
* This key is sent to the slave inside the <tt>.jnlp</tt> file
* (this file itself is protected by HTTP form-based authentication that
* we use everywhere else in Hudson), and the slave sends this
......@@ -48,7 +45,6 @@ public class TcpSlaveAgentListener extends Thread {
private final ServerSocket serverSocket;
private volatile boolean shuttingDown;
private final String secretKey;
public final int configuredPort;
......@@ -63,18 +59,6 @@ public class TcpSlaveAgentListener extends Thread {
LOGGER.info("JNLP slave agent listener started on TCP port "+getPort());
// get or create the secret
TextFile secretFile = new TextFile(new File(Hudson.getInstance().getRootDir(),"secret.key"));
if(secretFile.exists()) {
secretKey = secretFile.readTrim();
} else {
SecureRandom sr = new SecureRandom();
byte[] random = new byte[32];
sr.nextBytes(random);
secretKey = Util.toHexString(random);
secretFile.write(secretKey);
}
start();
}
......@@ -85,8 +69,8 @@ public class TcpSlaveAgentListener extends Thread {
return serverSocket.getLocalPort();
}
public String getSecretKey() {
return secretKey;
private String getSecretKey() {
return Hudson.getInstance().getSecretKey();
}
public void run() {
......@@ -169,7 +153,7 @@ public class TcpSlaveAgentListener extends Thread {
* Handles JNLP slave agent connection request.
*/
private void runJnlpConnect(DataInputStream in, PrintWriter out) throws IOException, InterruptedException {
if(!secretKey.equals(in.readUTF())) {
if(!getSecretKey().equals(in.readUTF())) {
error(out, "Unauthorized access");
return;
}
......
......@@ -37,9 +37,9 @@ import hudson.security.HudsonFilter;
import hudson.security.LegacyAuthorizationStrategy;
import hudson.security.LegacySecurityRealm;
import hudson.security.Permission;
import hudson.security.PermissionGroup;
import hudson.security.SecurityMode;
import hudson.security.SecurityRealm;
import hudson.security.PermissionGroup;
import hudson.tasks.BuildStep;
import hudson.tasks.BuildWrapper;
import hudson.tasks.BuildWrappers;
......@@ -58,14 +58,15 @@ import hudson.util.DaemonThreadFactory;
import hudson.util.FormFieldValidator;
import hudson.util.HudsonIsLoading;
import hudson.util.MultipartFormDataParser;
import hudson.util.TextFile;
import hudson.util.XStream2;
import hudson.widgets.Widget;
import net.sf.json.JSONObject;
import org.acegisecurity.Authentication;
import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;
import org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.providers.anonymous.AnonymousAuthenticationToken;
import org.acegisecurity.ui.AbstractProcessingFilter;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
......@@ -83,8 +84,8 @@ import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.FileFilter;
......@@ -94,6 +95,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.security.SecureRandom;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
......@@ -287,6 +289,12 @@ public final class Hudson extends View implements ItemGroup<TopLevelItem>, Node,
return theInstance;
}
/**
* Secrete key generated once and used for a long time, beyond
* container start/stop.
*/
private final String secretKey;
public Hudson(File root, ServletContext context) throws IOException {
this.root = root;
......@@ -304,6 +312,18 @@ public final class Hudson extends View implements ItemGroup<TopLevelItem>, Node,
throw e;
}
// get or create the secret
TextFile secretFile = new TextFile(new File(Hudson.getInstance().getRootDir(),"secret.key"));
if(secretFile.exists()) {
secretKey = secretFile.readTrim();
} else {
SecureRandom sr = new SecureRandom();
byte[] random = new byte[32];
sr.nextBytes(random);
secretKey = Util.toHexString(random);
secretFile.write(secretKey);
}
// load plugins.
pluginManager = new PluginManager(context);
......@@ -359,6 +379,15 @@ public final class Hudson extends View implements ItemGroup<TopLevelItem>, Node,
return pluginManager;
}
/**
* Returns a secret key that survives across container start/stop.
* <p>
* This value is useful for implementing some of the security features.
*/
public String getSecretKey() {
return secretKey;
}
/**
* Gets the SCM descriptor by name. Primarily used for making them web-visible.
*/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册