| /******************************************************************************* |
| * 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; |
| } |
| |
| } |