blob: 20625215d733d46249e4aa89dcb1f020edb7795c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 1997, 2008 by ProSyst Software GmbH
* http://www.prosyst.com
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* ProSyst Software GmbH - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.internal.ip.provider.http;
import java.util.*;
import javax.servlet.http.*;
import org.eclipse.equinox.internal.ip.ProvisioningInfoProvider;
import org.eclipse.equinox.internal.ip.impl.Log;
import org.eclipse.equinox.internal.ip.impl.ProvisioningAgent;
import org.eclipse.equinox.internal.ip.provider.BaseProvider;
import org.osgi.framework.*;
import org.osgi.service.http.HttpService;
import org.osgi.service.provisioning.ProvisioningService;
import org.osgi.service.useradmin.*;
/**
* Implements ProvisioningInfoProvider. Allows remote data loading through HTTP.
* Acts as dynamic provider. On <I>load(Dictionary)</I> it just get reference
* to provisioning data.
*
* @author Avgustin Marinov
* @author Pavlin Dobrev
* @version 1.0
*/
public class HttpProvider extends BaseProvider implements ProvisioningInfoProvider, ServiceListener {
/** Alias this servlet will be registered if remote configuration is allowed. */
public static final String ALIAS = "/rminit";
/**
* This is a key for property that points if remote setting of info is
* allowed.
*/
public static final String HTTP_SUPPORT = "equinox.provisioning.http.provider.allowed";
/**
* This system property is used to be determined if to accepts only
* HttpServletRequest-s with scheme "https".
*/
public static final String SECURE = "equinox.provisioning.http.provider.secure";
/** This system property determines if to requires authentication. */
public static final String REQUIRE_AUTH = "equinox.provisioning.require.auth";
/** If to accepts only HttpServletRequests with scheme "https". */
static boolean secure;
/** Reference to provisioning service. */
ProvisioningService prvSrv;
/** Bundle context reference. */
private BundleContext bc;
/** HTTP service that is used for registration of servlet. */
private HttpService http;
/** Servlet that is registered. */
private HttpServlet servlet = new HttpServletImpl();
/**
* @see org.eclipse.equinox.internal.ip.impl.provider.BaseProvider#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext bc) throws Exception {
boolean httpsupport = true;
if (bc.getProperty(HTTP_SUPPORT) != null)
if (bc.getProperty(HTTP_SUPPORT).equals("false"))
httpsupport = false;
if (!httpsupport) {
Log.debug(this + " is not an allowed provider.");
return;
}
this.bc = bc;
super.start(bc);
}
/**
* Stops provider. Unregister servlet.
*
* @see org.eclipse.equinox.internal.ip.impl.provider.BaseProvider#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext bc) {
super.stop(bc);
if (http != null) {
try {
http.unregister(ALIAS);
} catch (Exception e) {
// Not fatal
}
http = null;
}
}
/**
* @see org.eclipse.equinox.internal.ip.ProvisioningInfoProvider#init(org.osgi.service.provisioning.ProvisioningService)
*/
public Dictionary init(ProvisioningService prvSrv) {
this.prvSrv = prvSrv;
secure = false;
if (ProvisioningAgent.bc.getProperty(SECURE) != null)
if (ProvisioningAgent.bc.getProperty(SECURE).equals("true"))
secure = true;
try {
bc.addServiceListener(this, '(' + "objectClass" + '=' + HttpService.class.getName() + ')');
} catch (Exception e) {
Log.debug(e);
}
synchronized (this) {
if (http == null) {
ServiceReference sref = bc.getServiceReference(HttpService.class.getName());
if (sref != null) {
http = (HttpService) bc.getService(sref);
registerServlet();
}
}
}
return null; // Do not loads
}
/**
* @see org.eclipse.equinox.internal.ip.ProvisioningInfoProvider#get(java.lang.Object)
*/
public Object get(Object key) {
return null;
}
/**
* Manages servlet (un)registration.
*
* @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
*/
public synchronized void serviceChanged(ServiceEvent se) {
if (se.getType() == ServiceEvent.REGISTERED) {
if (http == null) {
http = (HttpService) bc.getService(se.getServiceReference());
registerServlet();
}
} else if (se.getType() == ServiceEvent.UNREGISTERING) {
if (http != null) {
try {
http.unregister(ALIAS);
} catch (Exception e) {
// Not fatal
}
http = null;
ServiceReference sref = bc.getServiceReference(HttpService.class.getName());
if (sref != null) {
http = (HttpService) bc.getService(sref);
registerServlet();
}
}
}
}
// Registers servlet with ALIAS.
private void registerServlet() {
try {
http.registerServlet(ALIAS, servlet, null, Context.getInstance());
Log.debug("Servlet \"" + ALIAS + "\" registered.");
} catch (Exception e) {
// Servlet won't be registered
Log.debug("Error registering HTTP provider servlet!", e);
}
}
/**
* Return name of provider.
*
* @return name.
*/
public String toString() {
return "Http";
}
/**
* Class implements servlet which enables (un)secure remote configuration.
*/
class HttpServletImpl extends HttpServlet {
private static final long serialVersionUID = 1L;
// If supports remote configuration
/**
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
public void doGet(HttpServletRequest request, HttpServletResponse response) {
Log.debug("doGet ...");
if (request.getHeader("Get-Id") == null) {
Log.debug("Redirect to doPost.");
doPost(request, response);
} else {
Log.debug("Request for spid.");
if (secure && !request.getScheme().equals("https")) {
Log.debug("Request to secure HttpLoader must be via https!");
response.setHeader("error", "Request to secure HttpLoader must be via https!");
response.setStatus(HttpServletResponse.SC_OK);
return;
}
String spid = (String) prvSrv.getInformation().get(ProvisioningService.PROVISIONING_SPID);
if (spid != null && spid.length() != 0) {
response.setHeader("Gw-Id", spid);
}
response.setStatus(HttpServletResponse.SC_OK);
}
}
// If supports remote configuration
/**
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse)
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) {
Log.debug("doPost ...");
if (secure && !request.getScheme().equals("https")) {
Log.debug("Request to secure HttpLoader must be via https!");
response.setHeader("error", "Request to secure HttpLoader must be via https!");
response.setStatus(HttpServletResponse.SC_OK);
return;
}
String user = request.getParameter("user");
String pass = request.getParameter("pass");
boolean req_auth = false;
if (ProvisioningAgent.bc.getProperty(REQUIRE_AUTH) != null)
if (ProvisioningAgent.bc.getProperty(REQUIRE_AUTH).equals("true"))
req_auth = true;
if (!req_auth && !checkAccount(user, pass)) {
Log.debug("Incorrect Account!");
response.setHeader("error", "Incorrect account!");
return;
}
Dictionary info = new Hashtable();
Log.debug("HttpLoader loads:");
for (Enumeration e = request.getParameterNames(); e.hasMoreElements();) {
String name = (String) e.nextElement();
if (!"user".equals(name) && !"pass".equals(name)) {
String param = request.getParameter(name);
if (ProvisioningInfoProvider.GM_HOST.equals(name) && "no".equals(param)) {
continue;
}
Log.debug(" " + name + '=' + param);
info.put(name, param);
}
}
prvSrv.addInformation(info);
response.setStatus(HttpServletResponse.SC_OK);
}
}
/*
* Returns if account is correct.
*
* TODO: add user admin to tracked services
*/
boolean checkAccount(String user, String pass) {
if (user == null || pass == null) {
return false;
}
ServiceReference sref = bc.getServiceReference(UserAdmin.class.getName());
if (sref == null) {
return false;
}
UserAdmin userAdmin = (UserAdmin) bc.getService(sref);
if (userAdmin != null) {
try {
User userRole = (User) userAdmin.getRole(user);
if (userRole != null && userRole.hasCredential("password", pass)) {
Authorization authorization = userAdmin.getAuthorization(userRole);
return authorization.hasRole("administration");
}
} catch (Exception e) {
Log.debug(e);
}
}
return false;
}
}