import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Random;
import java.util.TreeMap;
import javax.servlet.ServletContext;
protected static final URLEncoder URL_ENCODER;
protected static final String APPLICATION_MESSAGE = "message";
protected static final String APPLICATION_ERROR = "error";
- protected String sessionsListJspPath = "/sessionsList.jsp";
- protected String sessionDetailJspPath = "/sessionDetail.jsp";
+
+ protected static final String NONCE_SESSION =
+ "org.apache.catalina.manager.NONCE";
+ protected static final String NONCE_REQUEST = "nonce";
+
+ protected static final String sessionsListJspPath = "/sessionsList.jsp";
+ protected static final String sessionDetailJspPath = "/sessionDetail.jsp";
static {
URL_ENCODER = new URLEncoder();
// '/' should not be encoded in context paths
URL_ENCODER.addSafeCharacter('/');
}
+
+ private final Random randomSource = new Random();
+
// --------------------------------------------------------- Public Methods
/**
String deployPath = request.getParameter("deployPath");
String deployConfig = request.getParameter("deployConfig");
String deployWar = request.getParameter("deployWar");
+ String requestNonce = request.getParameter(NONCE_REQUEST);
// Prepare our output writer to generate the response message
response.setContentType("text/html; charset=" + Constants.CHARSET);
String message = "";
+ // Check nonce
+ // There *must* be a nonce in the session before any POST is processed
+ HttpSession session = request.getSession();
+ String sessionNonce = (String) session.getAttribute(NONCE_SESSION);
+ if (sessionNonce == null) {
+ message = "FAIL: No nonce found in session. Command [" + command + "] was ignored.";
+ // Reset the command
+ command = null;
+ } else {
+ if (!sessionNonce.equals(requestNonce)) {
+ // Nonce mis-match.
+ message = "FAIL: Nonce mismatch. Command [" + command + "] was ignored.";
+ // Reset the command
+ command = null;
+ }
+ }
+
if (command == null || command.length() == 0) {
// No command == list
// List always displayed -> do nothing
list(request, response, message);
}
+ /**
+ * Generate a once time token (nonce) for authenticating subsequent
+ * requests. This will also add the token to the session. The nonce
+ * generation is a simplified version of ManagerBase.generateSessionId().
+ *
+ */
+ protected synchronized String generateNonce() {
+ byte random[] = new byte[16];
+
+ // Render the result as a String of hexadecimal digits
+ StringBuffer buffer = new StringBuffer();
+
+ randomSource.nextBytes(random);
+
+ for (int j = 0; j < random.length; j++) {
+ byte b1 = (byte) ((random[j] & 0xf0) >> 4);
+ byte b2 = (byte) (random[j] & 0x0f);
+ if (b1 < 10)
+ buffer.append((char) ('0' + b1));
+ else
+ buffer.append((char) ('A' + (b1 - 10)));
+ if (b2 < 10)
+ buffer.append((char) ('0' + b2));
+ else
+ buffer.append((char) ('A' + (b2 - 10)));
+ }
+
+ return buffer.toString();
+ }
+
protected String upload(HttpServletRequest request) throws IOException {
String message = "";
log("list: Listing contexts for virtual host '" +
host.getName() + "'");
+ String newNonce = generateNonce();
+ request.getSession().setAttribute(NONCE_SESSION, newNonce);
+
PrintWriter writer = response.getWriter();
// HTML Header Section
writer.print
(MessageFormat.format(APPS_ROW_DETAILS_SECTION, args));
- args = new Object[14];
+ args = new Object[15];
args[0] = response.encodeURL
(request.getContextPath() +
"/html/start?path=" + URL_ENCODER.encode(displayPath));
context.getManager().getMaxInactiveInterval()/60);
}
args[12] = sm.getString("htmlManagerServlet.expire.unit");
-
args[13] = highlightColor;
-
+ args[14] = newNonce;
+
if (context.getPath().equals(this.context.getPath())) {
writer.print(MessageFormat.format(
MANAGER_APP_ROW_BUTTON_SECTION, args));
}
// Deploy Section
- args = new Object[7];
+ args = new Object[8];
args[0] = sm.getString("htmlManagerServlet.deployTitle");
args[1] = sm.getString("htmlManagerServlet.deployServer");
args[2] = response.encodeURL(request.getContextPath() + "/html/deploy");
args[4] = sm.getString("htmlManagerServlet.deployConfig");
args[5] = sm.getString("htmlManagerServlet.deployWar");
args[6] = sm.getString("htmlManagerServlet.deployButton");
+ args[7] = newNonce;
writer.print(MessageFormat.format(DEPLOY_SECTION, args));
- args = new Object[4];
+ args = new Object[5];
args[0] = sm.getString("htmlManagerServlet.deployUpload");
args[1] = response.encodeURL(request.getContextPath() + "/html/upload");
args[2] = sm.getString("htmlManagerServlet.deployUploadFile");
args[3] = sm.getString("htmlManagerServlet.deployButton");
+ args[4] = newNonce;
writer.print(MessageFormat.format(UPLOAD_SECTION, args));
// Server Header Section
" <td class=\"row-left\" bgcolor=\"{13}\">\n" +
" <form method=\"POST\" action=\"{8}\">\n" +
" <small>\n" +
+ " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\"" +
" <input type=\"submit\" value=\"{9}\"> {10} <input type=\"text\" name=\"idle\" size=\"5\" value=\"{11}\"> {12} \n" +
" </small>\n" +
" </form>\n" +
private static final String STARTED_DEPLOYED_APPS_ROW_BUTTON_SECTION =
" <td class=\"row-left\" bgcolor=\"{13}\">\n" +
" <small>{1}</small> \n" +
- " <form class=\"inline\" method=\"POST\" action=\"{2}\"><small><input type=\"submit\" value=\"{3}\"></small></form>\n" +
- " <form class=\"inline\" method=\"POST\" action=\"{4}\"><small><input type=\"submit\" value=\"{5}\"></small></form>\n" +
- " <form class=\"inline\" method=\"POST\" action=\"{6}\"><small><input type=\"submit\" value=\"{7}\"></small></form>\n" +
+ " <form class=\"inline\" method=\"POST\" action=\"{2}\">" +
+ " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\"" +
+ " <small><input type=\"submit\" value=\"{3}\"></small>" +
+ " </form>\n" +
+ " <form class=\"inline\" method=\"POST\" action=\"{4}\">" +
+ " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\"" +
+ " <small><input type=\"submit\" value=\"{5}\"></small>" +
+ " </form>\n" +
+ " <form class=\"inline\" method=\"POST\" action=\"{6}\">" +
+ " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\"" +
+ " <small><input type=\"submit\" value=\"{7}\"></small>" +
+ " </form>\n" +
" </td>\n" +
" </tr><tr>\n" +
" <td class=\"row-left\" bgcolor=\"{13}\">\n" +
" <form method=\"POST\" action=\"{8}\">\n" +
" <small>\n" +
+ " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\"" +
" <input type=\"submit\" value=\"{9}\"> {10} <input type=\"text\" name=\"idle\" size=\"5\" value=\"{11}\"> {12} \n" +
" </small>\n" +
" </form>\n" +
private static final String STOPPED_DEPLOYED_APPS_ROW_BUTTON_SECTION =
" <td class=\"row-left\" bgcolor=\"{13}\" rowspan=\"2\">\n" +
- " <form class=\"inline\" method=\"POST\" action=\"{0}\"><small><input type=\"submit\" value=\"{1}\"></small></form>\n" +
+ " <form class=\"inline\" method=\"POST\" action=\"{0}\">" +
+ " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\"" +
+ " <small><input type=\"submit\" value=\"{1}\"></small>" +
+ " </form>\n" +
" <small>{3}</small> \n" +
" <small>{5}</small> \n" +
- " <form class=\"inline\" method=\"POST\" action=\"{6}\"><small><input type=\"submit\" value=\"{7}\"></small></form>\n" +
+ " <form class=\"inline\" method=\"POST\" action=\"{6}\">" +
+ " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\"" +
+ " <small><input type=\"submit\" value=\"{7}\"></small>" +
+ " </form>\n" +
" </td>\n" +
"</tr>\n<tr></tr>\n";
private static final String STARTED_NONDEPLOYED_APPS_ROW_BUTTON_SECTION =
" <td class=\"row-left\" bgcolor=\"{13}\" rowspan=\"2\">\n" +
" <small>{1}</small> \n" +
- " <form class=\"inline\" method=\"POST\" action=\"{2}\"><small><input type=\"submit\" value=\"{3}\"></small></form>\n" +
- " <form class=\"inline\" method=\"POST\" action=\"{4}\"><small><input type=\"submit\" value=\"{5}\"></small></form>\n" +
+ " <form class=\"inline\" method=\"POST\" action=\"{2}\">" +
+ " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\"" +
+ " <small><input type=\"submit\" value=\"{3}\"></small>" +
+ " </form>\n" +
+ " <form class=\"inline\" method=\"POST\" action=\"{4}\">" +
+ " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\"" +
+ " <small><input type=\"submit\" value=\"{5}\"></small>" +
+ " </form>\n" +
" <small>{7}</small> \n" +
" </td>\n" +
"</tr>\n<tr></tr>\n";
private static final String STOPPED_NONDEPLOYED_APPS_ROW_BUTTON_SECTION =
" <td class=\"row-left\" bgcolor=\"{13}\" rowspan=\"2\">\n" +
- " <form class=\"inline\" method=\"POST\" action=\"{0}\"><small><input type=\"submit\" value=\"{1}\"></small></form>\n" +
+ " <form class=\"inline\" method=\"POST\" action=\"{0}\">" +
+ " <input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{14}\"" +
+ " <small><input type=\"submit\" value=\"{1}\"></small>" +
+ " </form>\n" +
" <small>{3}</small> \n" +
" <small>{5}</small> \n" +
" <small>{7}</small> \n" +
"</tr>\n" +
"<tr>\n" +
" <td colspan=\"2\">\n" +
- "<form method=\"get\" action=\"{2}\">\n" +
+ "<form method=\"post\" action=\"{2}\">\n" +
+ "<input type=\"hidden\" name=\"" + NONCE_REQUEST + "\" value=\"{7}\"" +
"<table cellspacing=\"0\" cellpadding=\"3\">\n" +
"<tr>\n" +
" <td class=\"row-right\">\n" +
"</tr>\n" +
"<tr>\n" +
" <td colspan=\"2\">\n" +
- "<form action=\"{1}\" method=\"post\" " +
+ "<form action=\"{1}?" + NONCE_REQUEST + "={4}\" method=\"post\" " +
"enctype=\"multipart/form-data\">\n" +
"<table cellspacing=\"0\" cellpadding=\"3\">\n" +
"<tr>\n" +