1
2
3
4
5
6
7
8
9
10
11 package psiprobe;
12
13 import jakarta.servlet.ServletContext;
14
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.HashSet;
20 import java.util.List;
21 import java.util.Set;
22
23 import org.apache.catalina.Context;
24 import org.apache.catalina.Valve;
25 import org.apache.catalina.WebResource;
26 import org.apache.catalina.deploy.NamingResourcesImpl;
27 import org.apache.jasper.JspCompilationContext;
28 import org.apache.jasper.Options;
29 import org.apache.jasper.compiler.JspRuntimeContext;
30 import org.apache.naming.ContextAccessController;
31 import org.apache.tomcat.util.descriptor.web.ApplicationParameter;
32 import org.apache.tomcat.util.descriptor.web.ContextResource;
33 import org.apache.tomcat.util.descriptor.web.ContextResourceLink;
34 import org.apache.tomcat.util.descriptor.web.FilterDef;
35 import org.apache.tomcat.util.descriptor.web.FilterMap;
36
37 import psiprobe.model.ApplicationParam;
38 import psiprobe.model.ApplicationResource;
39 import psiprobe.model.FilterInfo;
40 import psiprobe.model.FilterMapping;
41
42
43
44
45 public class Tomcat11ContainerAdapter extends AbstractTomcatContainer {
46
47 @Override
48 protected Valve createValve() {
49 return new Tomcat11AgentValve();
50 }
51
52 @Override
53 public boolean canBoundTo(String binding) {
54 if (binding == null) {
55 return false;
56 }
57 return binding.startsWith("Apache Tomcat/11.0");
58
59
60
61 }
62
63
64
65
66
67
68
69
70
71
72 protected List<FilterMapping> getFilterMappings(FilterMap fmap, String dm, String filterClass) {
73 String[] urls = fmap.getURLPatterns();
74 String[] servlets = fmap.getServletNames();
75 List<FilterMapping> results = new ArrayList<>(urls.length + servlets.length);
76 addFilterMapping(fmap.getFilterName(), dm, filterClass, urls, results, FilterMapType.URL);
77 addFilterMapping(fmap.getFilterName(), dm, filterClass, servlets, results,
78 FilterMapType.SERVLET_NAME);
79 return results;
80 }
81
82 @Override
83 protected JspCompilationContext createJspCompilationContext(String name, Options opt,
84 ServletContext sctx, JspRuntimeContext jrctx, ClassLoader classLoader) {
85
86 JspCompilationContext jcctx = new JspCompilationContext(name, opt, sctx, null, jrctx);
87 jcctx.setClassLoader(classLoader);
88 return jcctx;
89 }
90
91 @Override
92 public void addContextResourceLink(Context context, List<ApplicationResource> resourceList) {
93
94 NamingResourcesImpl namingResources = context.getNamingResources();
95 for (ContextResourceLink link : namingResources.findResourceLinks()) {
96 ApplicationResource resource = new ApplicationResource();
97
98 logger.debug("reading resourceLink: {}", link.getName());
99 resource.setApplicationName(context.getName());
100 resource.setName(link.getName());
101 resource.setType(link.getType());
102 resource.setLinkTo(link.getGlobal());
103
104 registerGlobalResourceAccess(link);
105
106 resourceList.add(resource);
107 }
108 }
109
110 @Override
111 public void addContextResource(Context context, List<ApplicationResource> resourceList) {
112 NamingResourcesImpl namingResources = context.getNamingResources();
113 for (ContextResource contextResource : namingResources.findResources()) {
114 ApplicationResource resource = new ApplicationResource();
115
116 logger.info("reading resource: {}", contextResource.getName());
117 resource.setApplicationName(context.getName());
118 resource.setName(contextResource.getName());
119 resource.setType(contextResource.getType());
120 resource.setScope(contextResource.getScope());
121 resource.setAuth(contextResource.getAuth());
122 resource.setDescription(contextResource.getDescription());
123
124 resourceList.add(resource);
125 }
126 }
127
128 @Override
129 public List<FilterMapping> getApplicationFilterMaps(Context context) {
130 FilterMap[] fms = context.findFilterMaps();
131 List<FilterMapping> filterMaps = new ArrayList<>(fms.length);
132 for (FilterMap filterMap : fms) {
133 if (filterMap != null) {
134 String dm;
135 switch (filterMap.getDispatcherMapping()) {
136 case FilterMap.ASYNC:
137 dm = "ASYNC";
138 break;
139 case FilterMap.ERROR:
140 dm = "ERROR";
141 break;
142 case FilterMap.FORWARD:
143 dm = "FORWARD";
144 break;
145 case FilterMap.INCLUDE:
146 dm = "INCLUDE";
147 break;
148 case FilterMap.REQUEST:
149 dm = "REQUEST";
150 break;
151 default:
152 dm = "";
153 }
154
155 String filterClass = "";
156 FilterDef fd = context.findFilterDef(filterMap.getFilterName());
157 if (fd != null) {
158 filterClass = fd.getFilterClass();
159 }
160
161 List<FilterMapping> filterMappings = getFilterMappings(filterMap, dm, filterClass);
162 filterMaps.addAll(filterMappings);
163 }
164 }
165 return filterMaps;
166 }
167
168 @Override
169 public List<FilterInfo> getApplicationFilters(Context context) {
170 FilterDef[] fds = context.findFilterDefs();
171 List<FilterInfo> filterDefs = new ArrayList<>(fds.length);
172 for (FilterDef filterDef : fds) {
173 if (filterDef != null) {
174 FilterInfo fi = getFilterInfo(filterDef);
175 filterDefs.add(fi);
176 }
177 }
178 return filterDefs;
179 }
180
181
182
183
184
185
186
187
188 private static FilterInfo getFilterInfo(FilterDef fd) {
189 FilterInfo fi = new FilterInfo();
190 fi.setFilterName(fd.getFilterName());
191 fi.setFilterClass(fd.getFilterClass());
192 fi.setFilterDesc(fd.getDescription());
193 return fi;
194 }
195
196 @Override
197 public List<ApplicationParam> getApplicationInitParams(Context context) {
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217 Set<String> nonOverridableParams = new HashSet<>();
218 for (ApplicationParameter appParam : context.findApplicationParameters()) {
219 if (appParam != null && !appParam.getOverride()) {
220 nonOverridableParams.add(appParam.getName());
221 }
222 }
223 List<ApplicationParam> initParams = new ArrayList<>(20);
224 ServletContext servletCtx = context.getServletContext();
225 for (String paramName : Collections.list(servletCtx.getInitParameterNames())) {
226 ApplicationParam param = new ApplicationParam();
227 param.setName(paramName);
228 param.setValue(servletCtx.getInitParameter(paramName));
229
230
231
232
233 param.setFromDeplDescr(
234 context.findParameter(paramName) != null && !nonOverridableParams.contains(paramName));
235 initParams.add(param);
236 }
237 return initParams;
238 }
239
240 @Override
241 public boolean resourceExists(String name, Context context) {
242 return context.getResources().getResource(name) != null;
243 }
244
245 @Override
246 public InputStream getResourceStream(String name, Context context) throws IOException {
247 WebResource resource = context.getResources().getResource(name);
248 return resource.getInputStream();
249 }
250
251 @Override
252 public Long[] getResourceAttributes(String name, Context context) {
253 Long[] result = new Long[2];
254 WebResource resource = context.getResources().getResource(name);
255 result[0] = resource.getContentLength();
256 result[1] = resource.getLastModified();
257 return result;
258 }
259
260
261
262
263
264
265
266
267 @Override
268 protected Object getNamingToken(Context context) {
269
270 Object token = context.getNamingToken();
271 if (!ContextAccessController.checkSecurityToken(context, token)) {
272 logger.error("Couldn't get a valid security token. ClassLoader binding will fail.");
273 }
274 return token;
275 }
276
277 }