mirror of
https://github.com/apache/cloudstack.git
synced 2025-12-16 02:22:52 +01:00
1) Merge following change from 2.1.X
Add time stamped ticket to console access URL to make it more secure 2) Fix a problem caused by the inconsistency of using different path seperator between windows platform and linux platform
This commit is contained in:
parent
1877200575
commit
5f3bb36650
@ -314,8 +314,8 @@ public class ConsoleProxyResource extends ServerResourceBase implements ServerRe
|
|||||||
_consoleProxyMain.start();
|
_consoleProxyMain.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean authenticateConsoleAccess(String vmId, String sid) {
|
public boolean authenticateConsoleAccess(String host, String port, String vmId, String sid, String ticket) {
|
||||||
ConsoleAccessAuthenticationCommand cmd = new ConsoleAccessAuthenticationCommand(vmId, sid);
|
ConsoleAccessAuthenticationCommand cmd = new ConsoleAccessAuthenticationCommand(host, port, vmId, sid, ticket);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
AgentControlAnswer answer = getAgentControl().sendRequest(cmd, 10000);
|
AgentControlAnswer answer = getAgentControl().sendRequest(cmd, 10000);
|
||||||
|
|||||||
@ -180,14 +180,14 @@ public class ConsoleProxy {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean authenticateConsoleAccess(String vmId, String sid) {
|
public static boolean authenticateConsoleAccess(String host, String port, String vmId, String sid, String ticket) {
|
||||||
if(standaloneStart)
|
if(standaloneStart)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if(authMethod != null) {
|
if(authMethod != null) {
|
||||||
Object result;
|
Object result;
|
||||||
try {
|
try {
|
||||||
result = authMethod.invoke(ConsoleProxy.context, vmId, sid);
|
result = authMethod.invoke(ConsoleProxy.context, host, port, vmId, sid, ticket);
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
s_logger.error("Unable to invoke authenticateConsoleAccess due to IllegalAccessException" + " for vm: " + vmId, e);
|
s_logger.error("Unable to invoke authenticateConsoleAccess due to IllegalAccessException" + " for vm: " + vmId, e);
|
||||||
return false;
|
return false;
|
||||||
@ -252,7 +252,7 @@ public class ConsoleProxy {
|
|||||||
ConsoleProxy.context = context;
|
ConsoleProxy.context = context;
|
||||||
try {
|
try {
|
||||||
Class<?> contextClazz = Class.forName("com.cloud.agent.resource.consoleproxy.ConsoleProxyResource");
|
Class<?> contextClazz = Class.forName("com.cloud.agent.resource.consoleproxy.ConsoleProxyResource");
|
||||||
authMethod = contextClazz.getDeclaredMethod("authenticateConsoleAccess", String.class, String.class);
|
authMethod = contextClazz.getDeclaredMethod("authenticateConsoleAccess", String.class, String.class, String.class, String.class, String.class);
|
||||||
reportMethod = contextClazz.getDeclaredMethod("reportLoadInfo", String.class);
|
reportMethod = contextClazz.getDeclaredMethod("reportLoadInfo", String.class);
|
||||||
ensureRouteMethod = contextClazz.getDeclaredMethod("ensureRoute", String.class);
|
ensureRouteMethod = contextClazz.getDeclaredMethod("ensureRoute", String.class);
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
@ -419,8 +419,8 @@ public class ConsoleProxy {
|
|||||||
return viewer;
|
return viewer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void initViewer(ConsoleProxyViewer viewer, String host, int port, String tag, String sid) throws AuthenticationException {
|
static void initViewer(ConsoleProxyViewer viewer, String host, int port, String tag, String sid, String ticket) throws AuthenticationException {
|
||||||
ConsoleProxyViewer.authenticationExternally(tag, sid);
|
ConsoleProxyViewer.authenticationExternally(host, String.valueOf(port), tag, sid, ticket);
|
||||||
|
|
||||||
viewer.host = host;
|
viewer.host = host;
|
||||||
viewer.port = port;
|
viewer.port = port;
|
||||||
@ -430,7 +430,7 @@ public class ConsoleProxy {
|
|||||||
viewer.init();
|
viewer.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static ConsoleProxyViewer getVncViewer(String host, int port, String sid, String tag) throws Exception {
|
static ConsoleProxyViewer getVncViewer(String host, int port, String sid, String tag, String ticket) throws Exception {
|
||||||
ConsoleProxyViewer viewer = null;
|
ConsoleProxyViewer viewer = null;
|
||||||
|
|
||||||
boolean reportLoadChange = false;
|
boolean reportLoadChange = false;
|
||||||
@ -438,7 +438,7 @@ public class ConsoleProxy {
|
|||||||
viewer = connectionMap.get(host + ":" + port);
|
viewer = connectionMap.get(host + ":" + port);
|
||||||
if (viewer == null) {
|
if (viewer == null) {
|
||||||
viewer = createViewer();
|
viewer = createViewer();
|
||||||
initViewer(viewer, host, port, tag, sid);
|
initViewer(viewer, host, port, tag, sid, ticket);
|
||||||
connectionMap.put(host + ":" + port, viewer);
|
connectionMap.put(host + ":" + port, viewer);
|
||||||
s_logger.info("Added viewer object " + viewer);
|
s_logger.info("Added viewer object " + viewer);
|
||||||
|
|
||||||
@ -446,12 +446,12 @@ public class ConsoleProxy {
|
|||||||
} else if (!viewer.rfbThread.isAlive()) {
|
} else if (!viewer.rfbThread.isAlive()) {
|
||||||
s_logger.info("The rfb thread died, reinitializing the viewer " +
|
s_logger.info("The rfb thread died, reinitializing the viewer " +
|
||||||
viewer);
|
viewer);
|
||||||
initViewer(viewer, host, port, tag, sid);
|
initViewer(viewer, host, port, tag, sid, ticket);
|
||||||
|
|
||||||
reportLoadChange = true;
|
reportLoadChange = true;
|
||||||
} else if (!sid.equals(viewer.passwordParam)) {
|
} else if (!sid.equals(viewer.passwordParam)) {
|
||||||
s_logger.warn("Bad sid detected(VNC port may be reused). sid in session: " + viewer.passwordParam + ", sid in request: " + sid);
|
s_logger.warn("Bad sid detected(VNC port may be reused). sid in session: " + viewer.passwordParam + ", sid in request: " + sid);
|
||||||
initViewer(viewer, host, port, tag, sid);
|
initViewer(viewer, host, port, tag, sid, ticket);
|
||||||
|
|
||||||
reportLoadChange = true;
|
reportLoadChange = true;
|
||||||
|
|
||||||
@ -484,7 +484,7 @@ public class ConsoleProxy {
|
|||||||
return viewer;
|
return viewer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ConsoleProxyViewer getAjaxVncViewer(String host, int port, String sid, String tag) throws Exception {
|
static ConsoleProxyViewer getAjaxVncViewer(String host, int port, String sid, String tag, String ticket, String ajaxSession) throws Exception {
|
||||||
boolean reportLoadChange = false;
|
boolean reportLoadChange = false;
|
||||||
synchronized (connectionMap) {
|
synchronized (connectionMap) {
|
||||||
ConsoleProxyViewer viewer = connectionMap.get(host + ":" + port);
|
ConsoleProxyViewer viewer = connectionMap.get(host + ":" + port);
|
||||||
@ -494,25 +494,29 @@ public class ConsoleProxy {
|
|||||||
viewer = createViewer();
|
viewer = createViewer();
|
||||||
viewer.ajaxViewer = true;
|
viewer.ajaxViewer = true;
|
||||||
|
|
||||||
initViewer(viewer, host, port, tag, sid);
|
initViewer(viewer, host, port, tag, sid, ticket);
|
||||||
connectionMap.put(host + ":" + port, viewer);
|
connectionMap.put(host + ":" + port, viewer);
|
||||||
s_logger.info("Added viewer object " + viewer);
|
s_logger.info("Added viewer object " + viewer);
|
||||||
reportLoadChange = true;
|
reportLoadChange = true;
|
||||||
} else if (!viewer.rfbThread.isAlive()) {
|
} else if (!viewer.rfbThread.isAlive()) {
|
||||||
s_logger.info("The rfb thread died, reinitializing the viewer " +
|
s_logger.info("The rfb thread died, reinitializing the viewer " +
|
||||||
viewer);
|
viewer);
|
||||||
initViewer(viewer, host, port, tag, sid);
|
initViewer(viewer, host, port, tag, sid, ticket);
|
||||||
reportLoadChange = true;
|
reportLoadChange = true;
|
||||||
} else if (!sid.equals(viewer.passwordParam)) {
|
} else if (!sid.equals(viewer.passwordParam)) {
|
||||||
s_logger.warn("Bad sid detected(VNC port may be reused). sid in session: " + viewer.passwordParam + ", sid in request: " + sid);
|
s_logger.warn("Bad sid detected(VNC port may be reused). sid in session: " + viewer.passwordParam + ", sid in request: " + sid);
|
||||||
initViewer(viewer, host, port, tag, sid);
|
initViewer(viewer, host, port, tag, sid, ticket);
|
||||||
reportLoadChange = true;
|
reportLoadChange = true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
throw new AuthenticationException ("Cannot use the existing viewer " +
|
throw new AuthenticationException ("Cannot use the existing viewer " +
|
||||||
viewer + ": bad sid");
|
viewer + ": bad sid");
|
||||||
*/
|
*/
|
||||||
|
} else {
|
||||||
|
if(ajaxSession == null || ajaxSession.isEmpty())
|
||||||
|
ConsoleProxyViewer.authenticationExternally(host, String.valueOf(port), tag, sid, ticket);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (viewer.status == ConsoleProxyViewer.STATUS_NORMAL_OPERATION) {
|
if (viewer.status == ConsoleProxyViewer.STATUS_NORMAL_OPERATION) {
|
||||||
// Do not update lastUsedTime if the viewer is in the process of starting up
|
// Do not update lastUsedTime if the viewer is in the process of starting up
|
||||||
// or if it failed to authenticate.
|
// or if it failed to authenticate.
|
||||||
|
|||||||
@ -72,7 +72,8 @@ public class ConsoleProxyAjaxHandler implements HttpHandler {
|
|||||||
String host = queryMap.get("host");
|
String host = queryMap.get("host");
|
||||||
String portStr = queryMap.get("port");
|
String portStr = queryMap.get("port");
|
||||||
String sid = queryMap.get("sid");
|
String sid = queryMap.get("sid");
|
||||||
String tag = queryMap.get("tag");
|
String tag = queryMap.get("tag");
|
||||||
|
String ticket = queryMap.get("ticket");
|
||||||
String ajaxSessionIdStr = queryMap.get("sess");
|
String ajaxSessionIdStr = queryMap.get("sess");
|
||||||
String eventStr = queryMap.get("event");
|
String eventStr = queryMap.get("event");
|
||||||
if(tag == null)
|
if(tag == null)
|
||||||
@ -113,7 +114,7 @@ public class ConsoleProxyAjaxHandler implements HttpHandler {
|
|||||||
|
|
||||||
ConsoleProxyViewer viewer = null;
|
ConsoleProxyViewer viewer = null;
|
||||||
try {
|
try {
|
||||||
viewer = ConsoleProxy.getAjaxVncViewer(host, port, sid, tag);
|
viewer = ConsoleProxy.getAjaxVncViewer(host, port, sid, tag, ticket, ajaxSessionIdStr);
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -62,7 +62,8 @@ public class ConsoleProxyAjaxImageHandler implements HttpHandler {
|
|||||||
String host = queryMap.get("host");
|
String host = queryMap.get("host");
|
||||||
String portStr = queryMap.get("port");
|
String portStr = queryMap.get("port");
|
||||||
String sid = queryMap.get("sid");
|
String sid = queryMap.get("sid");
|
||||||
String tag = queryMap.get("tag");
|
String tag = queryMap.get("tag");
|
||||||
|
String ticket = queryMap.get("ticket");
|
||||||
String keyStr = queryMap.get("key");
|
String keyStr = queryMap.get("key");
|
||||||
int key = 0;
|
int key = 0;
|
||||||
|
|
||||||
@ -87,7 +88,7 @@ public class ConsoleProxyAjaxImageHandler implements HttpHandler {
|
|||||||
throw new IllegalArgumentException(e);
|
throw new IllegalArgumentException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleProxyViewer viewer = ConsoleProxy.getVncViewer(host, port, sid, tag);
|
ConsoleProxyViewer viewer = ConsoleProxy.getVncViewer(host, port, sid, tag, ticket);
|
||||||
byte[] img = viewer.getAjaxImageCache().getImage(key);
|
byte[] img = viewer.getAjaxImageCache().getImage(key);
|
||||||
if(img != null) {
|
if(img != null) {
|
||||||
Headers hds = t.getResponseHeaders();
|
Headers hds = t.getResponseHeaders();
|
||||||
|
|||||||
@ -88,7 +88,7 @@ public class ConsoleProxyClientHandler extends Thread {
|
|||||||
String host = stk.nextToken();
|
String host = stk.nextToken();
|
||||||
int port = Integer.parseInt(stk.nextToken());
|
int port = Integer.parseInt(stk.nextToken());
|
||||||
String sid = stk.nextToken();
|
String sid = stk.nextToken();
|
||||||
ConsoleProxyViewer viewer = ConsoleProxy.getVncViewer(host, port, sid, "");
|
ConsoleProxyViewer viewer = ConsoleProxy.getVncViewer(host, port, sid, "", "");
|
||||||
|
|
||||||
ConsoleProxy.waitForViewerToStart(viewer);
|
ConsoleProxy.waitForViewerToStart(viewer);
|
||||||
|
|
||||||
|
|||||||
@ -135,7 +135,8 @@ public class ConsoleProxyThumbnailHandler implements HttpHandler {
|
|||||||
String host = queryMap.get("host");
|
String host = queryMap.get("host");
|
||||||
String portStr = queryMap.get("port");
|
String portStr = queryMap.get("port");
|
||||||
String sid = queryMap.get("sid");
|
String sid = queryMap.get("sid");
|
||||||
String tag = queryMap.get("tag");
|
String tag = queryMap.get("tag");
|
||||||
|
String ticket = queryMap.get("ticket");
|
||||||
if(tag == null)
|
if(tag == null)
|
||||||
tag = "";
|
tag = "";
|
||||||
|
|
||||||
@ -150,7 +151,7 @@ public class ConsoleProxyThumbnailHandler implements HttpHandler {
|
|||||||
throw new IllegalArgumentException(e);
|
throw new IllegalArgumentException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleProxyViewer viewer = ConsoleProxy.getVncViewer(host, port, sid, tag);
|
ConsoleProxyViewer viewer = ConsoleProxy.getVncViewer(host, port, sid, tag, ticket);
|
||||||
|
|
||||||
if (viewer.status != ConsoleProxyViewer.STATUS_NORMAL_OPERATION) {
|
if (viewer.status != ConsoleProxyViewer.STATUS_NORMAL_OPERATION) {
|
||||||
// use generated image instead of static
|
// use generated image instead of static
|
||||||
|
|||||||
@ -315,7 +315,7 @@ public class ConsoleProxyViewer implements java.lang.Runnable, RfbViewer, RfbPro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void authenticationExternally(String tag, String sid) throws AuthenticationException {
|
static void authenticationExternally(String host, String port, String tag, String sid, String ticket) throws AuthenticationException {
|
||||||
/*
|
/*
|
||||||
if(ConsoleProxy.management_host != null) {
|
if(ConsoleProxy.management_host != null) {
|
||||||
try {
|
try {
|
||||||
@ -352,7 +352,7 @@ public class ConsoleProxyViewer implements java.lang.Runnable, RfbViewer, RfbPro
|
|||||||
s_logger.warn("No external authentication source being setup.");
|
s_logger.warn("No external authentication source being setup.");
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if(!ConsoleProxy.authenticateConsoleAccess(tag, sid)) {
|
if(!ConsoleProxy.authenticateConsoleAccess(host, port, tag, sid, ticket)) {
|
||||||
s_logger.warn("External authenticator failed authencation request for vm " + tag + " with sid " + sid);
|
s_logger.warn("External authenticator failed authencation request for vm " + tag + " with sid " + sid);
|
||||||
|
|
||||||
throw new AuthenticationException("External authenticator failed request for vm " + tag + " with sid " + sid);
|
throw new AuthenticationException("External authenticator failed request for vm " + tag + " with sid " + sid);
|
||||||
|
|||||||
@ -19,17 +19,31 @@
|
|||||||
package com.cloud.agent.api;
|
package com.cloud.agent.api;
|
||||||
|
|
||||||
public class ConsoleAccessAuthenticationCommand extends AgentControlCommand {
|
public class ConsoleAccessAuthenticationCommand extends AgentControlCommand {
|
||||||
|
|
||||||
|
private String _host;
|
||||||
|
private String _port;
|
||||||
private String _vmId;
|
private String _vmId;
|
||||||
private String _sid;
|
private String _sid;
|
||||||
|
private String _ticket;
|
||||||
|
|
||||||
public ConsoleAccessAuthenticationCommand() {
|
public ConsoleAccessAuthenticationCommand() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConsoleAccessAuthenticationCommand(String vmId, String sid) {
|
public ConsoleAccessAuthenticationCommand(String host, String port, String vmId, String sid, String ticket) {
|
||||||
|
_host = host;
|
||||||
|
_port = port;
|
||||||
_vmId = vmId;
|
_vmId = vmId;
|
||||||
_sid = sid;
|
_sid = sid;
|
||||||
|
_ticket = ticket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getHost() {
|
||||||
|
return _host;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPort() {
|
||||||
|
return _port;
|
||||||
|
}
|
||||||
|
|
||||||
public String getVmId() {
|
public String getVmId() {
|
||||||
return _vmId;
|
return _vmId;
|
||||||
@ -37,5 +51,9 @@ public class ConsoleAccessAuthenticationCommand extends AgentControlCommand {
|
|||||||
|
|
||||||
public String getSid() {
|
public String getSid() {
|
||||||
return _sid;
|
return _sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTicket() {
|
||||||
|
return _ticket;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -30,6 +30,9 @@ public abstract class AbstractDownloadCommand extends StorageCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected AbstractDownloadCommand(String name, String url, ImageFormat format, long accountId) {
|
protected AbstractDownloadCommand(String name, String url, ImageFormat format, long accountId) {
|
||||||
|
assert(url != null);
|
||||||
|
url = url.replace('\\', '/');
|
||||||
|
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.format = format;
|
this.format = format;
|
||||||
this.accountId = accountId;
|
this.accountId = accountId;
|
||||||
@ -62,6 +65,8 @@ public abstract class AbstractDownloadCommand extends StorageCommand {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setUrl(String url) {
|
public void setUrl(String url) {
|
||||||
|
assert(url != null);
|
||||||
|
url = url.replace('\\', '/');
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -107,6 +107,7 @@ import com.cloud.offerings.NetworkOfferingVO;
|
|||||||
import com.cloud.offerings.dao.NetworkOfferingDao;
|
import com.cloud.offerings.dao.NetworkOfferingDao;
|
||||||
import com.cloud.service.ServiceOfferingVO;
|
import com.cloud.service.ServiceOfferingVO;
|
||||||
import com.cloud.service.dao.ServiceOfferingDao;
|
import com.cloud.service.dao.ServiceOfferingDao;
|
||||||
|
import com.cloud.servlet.ConsoleProxyServlet;
|
||||||
import com.cloud.storage.GuestOSVO;
|
import com.cloud.storage.GuestOSVO;
|
||||||
import com.cloud.storage.StorageManager;
|
import com.cloud.storage.StorageManager;
|
||||||
import com.cloud.storage.StoragePoolVO;
|
import com.cloud.storage.StoragePoolVO;
|
||||||
@ -1268,6 +1269,13 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, VirtualMach
|
|||||||
@Override
|
@Override
|
||||||
public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd) {
|
public AgentControlAnswer onConsoleAccessAuthentication(ConsoleAccessAuthenticationCommand cmd) {
|
||||||
long vmId = 0;
|
long vmId = 0;
|
||||||
|
|
||||||
|
String ticket = ConsoleProxyServlet.genAccessTicket(cmd.getHost(), cmd.getPort(), cmd.getSid(), cmd.getVmId());
|
||||||
|
String ticketInUrl = cmd.getTicket();
|
||||||
|
if(!ticket.startsWith(ticketInUrl)) {
|
||||||
|
s_logger.error("Access ticket expired or has been modified. vmId: " + cmd.getVmId());
|
||||||
|
return new ConsoleAccessAuthenticationAnswer(cmd, false);
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd.getVmId() != null && cmd.getVmId().isEmpty()) {
|
if (cmd.getVmId() != null && cmd.getVmId().isEmpty()) {
|
||||||
if (s_logger.isTraceEnabled())
|
if (s_logger.isTraceEnabled())
|
||||||
|
|||||||
@ -20,8 +20,10 @@ package com.cloud.servlet;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -214,73 +216,112 @@ public class ConsoleProxyServlet extends HttpServlet {
|
|||||||
String vmName = vm.getName();
|
String vmName = vm.getName();
|
||||||
if(vmName == null)
|
if(vmName == null)
|
||||||
vmName = vm.getInstanceName();
|
vmName = vm.getInstanceName();
|
||||||
|
|
||||||
StringBuffer sb = new StringBuffer();
|
StringBuffer sb = new StringBuffer();
|
||||||
sb.append("<html><title>").append(vmName).append("</title><frameset><frame src=\"").append(composeConsoleAccessUrl(rootUrl, vm, host));
|
sb.append("<html><title>").append(vmName).append("</title><frameset><frame src=\"").append(composeConsoleAccessUrl(rootUrl, vm, host));
|
||||||
sb.append("\"></frame></frameset></html>");
|
sb.append("\"></frame></frameset></html>");
|
||||||
sendResponse(resp, sb.toString());
|
sendResponse(resp, sb.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleAuthRequest(HttpServletRequest req, HttpServletResponse resp, long vmId) {
|
private void handleAuthRequest(HttpServletRequest req, HttpServletResponse resp, long vmId) {
|
||||||
|
|
||||||
// TODO authentication channel between console proxy VM and management server needs to be secured,
|
// TODO authentication channel between console proxy VM and management server needs to be secured,
|
||||||
// the data is now being sent through private network, but this is apparently not enough
|
// the data is now being sent through private network, but this is apparently not enough
|
||||||
VMInstanceVO vm = _ms.findVMInstanceById(vmId);
|
VMInstanceVO vm = _ms.findVMInstanceById(vmId);
|
||||||
if(vm == null) {
|
if(vm == null) {
|
||||||
s_logger.warn("VM " + vmId + " does not exist, sending failed response for authentication request from console proxy");
|
s_logger.warn("VM " + vmId + " does not exist, sending failed response for authentication request from console proxy");
|
||||||
sendResponse(resp, "failed");
|
sendResponse(resp, "failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(vm.getHostId() == null) {
|
if(vm.getHostId() == null) {
|
||||||
s_logger.warn("VM " + vmId + " lost host info, failed response for authentication request from console proxy");
|
s_logger.warn("VM " + vmId + " lost host info, failed response for authentication request from console proxy");
|
||||||
sendResponse(resp, "failed");
|
sendResponse(resp, "failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
HostVO host = _ms.getHostBy(vm.getHostId());
|
HostVO host = _ms.getHostBy(vm.getHostId());
|
||||||
if(host == null) {
|
if(host == null) {
|
||||||
s_logger.warn("VM " + vmId + "'s host does not exist, sending failed response for authentication request from console proxy");
|
s_logger.warn("VM " + vmId + "'s host does not exist, sending failed response for authentication request from console proxy");
|
||||||
sendResponse(resp, "failed");
|
sendResponse(resp, "failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String sid = req.getParameter("sid");
|
String sid = req.getParameter("sid");
|
||||||
if(sid == null || !sid.equals(vm.getVncPassword())) {
|
if(sid == null || !sid.equals(vm.getVncPassword())) {
|
||||||
s_logger.warn("sid " + sid + " in url does not match stored sid " + vm.getVncPassword());
|
s_logger.warn("sid " + sid + " in url does not match stored sid " + vm.getVncPassword());
|
||||||
sendResponse(resp, "failed");
|
sendResponse(resp, "failed");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendResponse(resp, "success");
|
sendResponse(resp, "success");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String composeThumbnailUrl(String rootUrl, VMInstanceVO vm, HostVO host, int w, int h) {
|
private String composeThumbnailUrl(String rootUrl, VMInstanceVO vm, HostVO hostVo, int w, int h) {
|
||||||
StringBuffer sb = new StringBuffer(rootUrl);
|
StringBuffer sb = new StringBuffer(rootUrl);
|
||||||
sb.append("/getscreen?host=").append(host.getPrivateIpAddress());
|
|
||||||
sb.append("&port=").append(_ms.getVncPort(vm));
|
String host = hostVo.getPrivateIpAddress();
|
||||||
sb.append("&sid=").append(vm.getVncPassword());
|
int port = _ms.getVncPort(vm);
|
||||||
sb.append("&w=").append(w).append("&h=").append(h);
|
String sid = vm.getVncPassword();
|
||||||
sb.append("&tag=").append(vm.getId());
|
long tag = vm.getId();
|
||||||
|
String ticket = URLEncoder.encode(genAccessTicket(host, String.valueOf(port), sid, String.valueOf(tag)));
|
||||||
if(s_logger.isInfoEnabled())
|
|
||||||
s_logger.info("Compose thumbnail url: " + sb.toString());
|
sb.append("/getscreen?host=").append(host);
|
||||||
return sb.toString();
|
sb.append("&port=").append(port);
|
||||||
}
|
sb.append("&sid=").append(sid);
|
||||||
|
sb.append("&w=").append(w).append("&h=").append(h);
|
||||||
private String composeConsoleAccessUrl(String rootUrl, VMInstanceVO vm, HostVO host) {
|
sb.append("&tag=").append(tag);
|
||||||
StringBuffer sb = new StringBuffer(rootUrl);
|
sb.append("&ticket=").append(ticket);
|
||||||
sb.append("/ajax?host=").append(host.getPrivateIpAddress());
|
|
||||||
sb.append("&port=").append(_ms.getVncPort(vm));
|
if(s_logger.isInfoEnabled())
|
||||||
sb.append("&sid=").append(vm.getVncPassword());
|
s_logger.info("Compose thumbnail url: " + sb.toString());
|
||||||
sb.append("&tag=").append(vm.getId());
|
return sb.toString();
|
||||||
|
}
|
||||||
if(s_logger.isInfoEnabled())
|
|
||||||
s_logger.info("Compose console url: " + sb.toString());
|
private String composeConsoleAccessUrl(String rootUrl, VMInstanceVO vm, HostVO hostVo) {
|
||||||
return sb.toString();
|
StringBuffer sb = new StringBuffer(rootUrl);
|
||||||
}
|
|
||||||
|
String host = hostVo.getPrivateIpAddress();
|
||||||
private void sendResponse(HttpServletResponse resp, String content) {
|
int port = _ms.getVncPort(vm);
|
||||||
|
String sid = vm.getVncPassword();
|
||||||
|
long tag = vm.getId();
|
||||||
|
String ticket = URLEncoder.encode(genAccessTicket(host, String.valueOf(port), sid, String.valueOf(tag)));
|
||||||
|
|
||||||
|
sb.append("/ajax?host=").append(host);
|
||||||
|
sb.append("&port=").append(port);
|
||||||
|
sb.append("&sid=").append(sid);
|
||||||
|
sb.append("&tag=").append(tag);
|
||||||
|
sb.append("&ticket=").append(ticket);
|
||||||
|
|
||||||
|
if(s_logger.isInfoEnabled())
|
||||||
|
s_logger.info("Compose console url: " + sb.toString());
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String genAccessTicket(String host, String port, String sid, String tag) {
|
||||||
|
String params = "host=" + host + "&port=" + port + "&sid=" + sid + "&tag=" + tag;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Mac mac = Mac.getInstance("HmacSHA1");
|
||||||
|
|
||||||
|
long ts = (new Date()).getTime();
|
||||||
|
ts = ts/60000; // round up to 1 minute
|
||||||
|
String secretKey = "cloud.com";
|
||||||
|
|
||||||
|
SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(), "HmacSHA1");
|
||||||
|
mac.init(keySpec);
|
||||||
|
mac.update(params.getBytes());
|
||||||
|
mac.update(String.valueOf(ts).getBytes());
|
||||||
|
|
||||||
|
byte[] encryptedBytes = mac.doFinal();
|
||||||
|
return Base64.encodeBytes(encryptedBytes);
|
||||||
|
} catch(Exception e) {
|
||||||
|
s_logger.error("Unexpected exception ", e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendResponse(HttpServletResponse resp, String content) {
|
||||||
try {
|
try {
|
||||||
resp.setContentType("text/html");
|
resp.setContentType("text/html");
|
||||||
resp.getWriter().print(content);
|
resp.getWriter().print(content);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user