KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > reverseproxy > actions > LaunchReverseProxyAction


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.sslexplorer.reverseproxy.actions;
21
22 import java.net.URL JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.StringTokenizer JavaDoc;
25
26 import javax.servlet.http.HttpServletRequest JavaDoc;
27 import javax.servlet.http.HttpServletResponse JavaDoc;
28
29 import org.apache.struts.action.ActionForm;
30 import org.apache.struts.action.ActionForward;
31 import org.apache.struts.action.ActionMapping;
32
33 import com.sslexplorer.boot.HostService;
34 import com.sslexplorer.boot.Util;
35 import com.sslexplorer.core.CoreEvent;
36 import com.sslexplorer.core.CoreServlet;
37 import com.sslexplorer.core.actions.AuthenticatedAction;
38 import com.sslexplorer.core.stringreplacement.VariableReplacement;
39 import com.sslexplorer.policyframework.LaunchSession;
40 import com.sslexplorer.policyframework.LaunchSessionFactory;
41 import com.sslexplorer.policyframework.NoPermissionException;
42 import com.sslexplorer.policyframework.ResourceAccessEvent;
43 import com.sslexplorer.properties.Property;
44 import com.sslexplorer.properties.impl.systemconfig.SystemConfigKey;
45 import com.sslexplorer.security.LogonControllerFactory;
46 import com.sslexplorer.security.SessionInfo;
47 import com.sslexplorer.webforwards.ReverseProxyWebForward;
48 import com.sslexplorer.webforwards.WebForwardEventConstants;
49 import com.sslexplorer.webforwards.WebForwardPlugin;
50 import com.sslexplorer.webforwards.WebForwardTypeItem;
51 import com.sslexplorer.webforwards.WebForwardTypes;
52
53 /**
54  * Implementation of {@link com.sslexplorer.core.actions.AuthenticatedAction}
55  * that launches a <i>Reverse Proxy Web Forward</i>.
56  * <p>
57  *
58  *
59  * @author Brett Smith <a HREF="mailto: brett@3sp.com">&lt;brett@3sp.com&gt;</a>
60  */

61 public class LaunchReverseProxyAction extends AuthenticatedAction {
62
63     /**
64      * Constructor.
65      *
66      */

67     public LaunchReverseProxyAction() {
68     }
69
70     /*
71      * (non-Javadoc)
72      *
73      * @see com.sslexplorer.core.actions.AuthenticatedAction#isIgnoreSessionLock()
74      */

75     protected boolean isIgnoreSessionLock() {
76         return true;
77     }
78
79     public ActionForward onExecute(ActionMapping mapping, ActionForm form, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
80                     throws Exception JavaDoc {
81         // Get the web forward
82

83         String JavaDoc launchId = request.getParameter(LaunchSession.LAUNCH_ID);
84         if (Util.isNullOrTrimmedBlank(launchId)) {
85             throw new Exception JavaDoc("No launch ID supplied.");
86         }
87
88         LaunchSession launchSession = LaunchSessionFactory.getInstance().getLaunchSession(launchId);
89         ReverseProxyWebForward wf = (ReverseProxyWebForward) launchSession.getResource();
90         
91         /* Remove all other launch sessions for this resource, we can only ever have
92          * one at a time
93          */

94         Collection JavaDoc<LaunchSession> sessions = LaunchSessionFactory.getInstance().getLaunchSessionsForType(launchSession.getSession(),
95                 WebForwardPlugin.WEBFORWARD_RESOURCE_TYPE);
96         for (LaunchSession rs : sessions) {
97             if (rs != launchSession && rs.getResource() instanceof ReverseProxyWebForward && rs.getResource().getResourceId() == wf.getResourceId()) {
98                 LaunchSessionFactory.getInstance().removeLaunchSession(rs);
99             }
100         }
101
102         if (wf.getActiveDNS() && !isValidForActiveDNS(request.getServerName()))
103             throw new Exception JavaDoc("Invalid host '" + request.getServerName() + "'; only FQDNs are valid for Active DNS forwarding");
104
105         String JavaDoc path;
106         String JavaDoc url = wf.getDestinationURL();
107         String JavaDoc hostField = request.getHeader("Host");
108         HostService hostService = hostField == null ? null : new HostService(hostField);
109         SessionInfo session = getSessionInfo(request);
110
111         try {
112             launchSession.checkAccessRights(null, session);
113
114             /*
115              * This requires more thought.
116              *
117              * 1. We can only have on launch session per resource
118              * 2. This doesn't take into account other features of reverse proxy
119              * (authentication, encoding, host headers etc)
120              *
121              */

122             
123             /**
124              * Setup other reverse proxies so they have access to each other. Only
125              * reverse proxies with the same policy attached will be allowed.
126             List resources = ResourceUtil.getGrantedResource(launchSession.getSession(), WebForwardPlugin.WEBFORWARD_RESOURCE_TYPE);
127             
128             Resource resource;
129             for(Iterator it = resources.iterator(); it.hasNext();) {
130                 resource = (Resource) it.next();
131                 if(resource instanceof ReverseProxyWebForward && resource.getResourceId()!=launchSession.getResource().getResourceId()) {
132                     if(PolicyDatabaseFactory.getInstance().isResourceAttachedToPolicy(resource, launchSession.getPolicy(), launchSession.getSession().getRealm())) {
133                         LaunchSession ls = LaunchSessionFactory.getInstance().createLaunchSession(launchSession.getSession(), resource, launchSession.getPolicy());
134                         ls.checkAccessRights(null, session);
135                     }
136                     
137                 }
138             }
139              */

140             
141             VariableReplacement r = new VariableReplacement();
142             r.setServletRequest(request);
143             r.setLaunchSession(launchSession);
144             url = r.replace(url);
145
146             CoreEvent evt = new ResourceAccessEvent(this,
147                             WebForwardEventConstants.WEB_FORWARD_STARTED,
148                             wf,
149                             launchSession.getPolicy(),
150                             launchSession.getSession(),
151                             CoreEvent.STATE_SUCCESSFUL).addAttribute(WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_TYPE,
152                 ((WebForwardTypeItem) WebForwardTypes.WEB_FORWARD_TYPES.get(wf.getType())).getName())
153                             .addAttribute(WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_URL, url);
154
155             CoreServlet.getServlet().fireCoreEvent(evt);
156
157             // Get the URL to redirect to
158
if (wf.getActiveDNS()) {
159                 URL JavaDoc u = new URL JavaDoc(url);
160                 URL JavaDoc adu;
161                 if (Property.getPropertyInt(new SystemConfigKey("webforward.activeDNSFormat")) == 1) {
162                     adu = new URL JavaDoc("https", launchSession.getId() + "." + hostService.getHost(), hostService.getPort() == 0 ? -1
163                         : hostService.getPort(), u.getFile());
164                 } else {
165                     int idx = hostService.getHost().indexOf('.');
166                     adu = new URL JavaDoc("https",
167                                     launchSession.getId() + "." + hostService.getHost().substring(idx + 1),
168                                     hostService.getPort() == 0 ? -1 : hostService.getPort(),
169                                     u.getFile());
170                 }
171                 path = adu.toExternalForm();
172
173             } else if (wf.getHostHeader() != null && !wf.getHostHeader().equals("")) {
174                 URL JavaDoc u = new URL JavaDoc(url);
175
176                 URL JavaDoc adu = new URL JavaDoc("https", wf.getHostHeader(), hostService.getPort() == 0 ? -1 : hostService.getPort(), u.getFile());
177
178                 path = adu.toExternalForm();
179
180                 if (adu.getQuery() == null || adu.getQuery().equals("")) {
181                     path += "?" + LaunchSession.LAUNCH_ID + "=" + launchSession.getId();
182                 } else {
183                     path += "&" + LaunchSession.LAUNCH_ID + "=" + launchSession.getId();
184                 }
185
186                 /**
187                  * Why do we need to use a JSP redirect? Because the new host
188                  * will be created in a new session and we need the JSESSIONID
189                  * which is only set once the first response has been returned
190                  * to the browser. This redirect allows the browser to load a
191                  * page on the new host and set the session cookie before an
192                  * automatic redirect takes the user to the correct reverse
193                  * proxy page.
194                  */

195                 URL JavaDoc adu2 = new URL JavaDoc("https",
196                                 hostService.getHost(),
197                                 hostService.getPort() == 0 ? -1 : hostService.getPort(),
198                                 "/reverseProxyRedirect.jsp?redirectURL=" + Util.urlEncode(path));
199
200                 return new ActionForward(adu2.toExternalForm(), true);
201
202             } else {
203                 URL JavaDoc u = new URL JavaDoc(url);
204                 path = u.getPath();
205                 if (u.getQuery() == null || u.getQuery().equals("")) {
206                     path += "?" + LaunchSession.LONG_LAUNCH_ID + "=" + launchSession.getId();
207                 } else {
208                     path += "?" + u.getQuery() + "&" + LaunchSession.LONG_LAUNCH_ID + "=" + launchSession.getId();
209                 }
210                 
211                 URL JavaDoc redir = new URL JavaDoc("https",
212                     hostService.getHost(),
213                     hostService.getPort() == 0 ? -1 : hostService.getPort(),
214                     path);
215                 path = redir.toExternalForm();
216             }
217         } catch (NoPermissionException npe) {
218
219             CoreEvent evt = new ResourceAccessEvent(this,
220                             WebForwardEventConstants.WEB_FORWARD_STARTED,
221                             wf,
222                             launchSession.getPolicy(),
223                             launchSession.getSession(),
224                             npe).addAttribute(WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_TYPE,
225                 ((WebForwardTypeItem) WebForwardTypes.WEB_FORWARD_TYPES.get(wf.getType())).getName())
226                             .addAttribute(WebForwardEventConstants.EVENT_ATTR_WEB_FORWARD_URL, url);
227             CoreServlet.getServlet().fireCoreEvent(evt);
228
229             throw npe;
230         }
231
232         return new ActionForward(path, true);
233     }
234
235     /* (non-Javadoc)
236      * @see com.sslexplorer.core.actions.AuthenticatedAction#getNavigationContext(org.apache.struts.action.ActionMapping, org.apache.struts.action.ActionForm, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
237      */

238     public int getNavigationContext(ActionMapping mapping, ActionForm form, HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) {
239         return SessionInfo.MANAGEMENT_CONSOLE_CONTEXT | SessionInfo.USER_CONSOLE_CONTEXT;
240     }
241
242     private boolean isValidForActiveDNS(String JavaDoc host) {
243
244         StringTokenizer JavaDoc tokens = new StringTokenizer JavaDoc(host, ".");
245         if (tokens.countTokens() == 1)
246             return false;
247
248         boolean numerical = true;
249         while (tokens.hasMoreTokens()) {
250             String JavaDoc token = tokens.nextToken();
251
252             try {
253                 int val = Integer.parseInt(token);
254
255                 if (val > 255) {
256                     numerical = false;
257                     break;
258                 }
259             } catch (NumberFormatException JavaDoc ex) {
260                 numerical = false;
261                 break;
262             }
263         }
264
265         return !numerical;
266
267     }
268
269 }
270
Popular Tags