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 Tomcat10ContainerAdapter extends AbstractTomcatContainer {
46
47 @Override
48 protected Valve createValve() {
49 return new Tomcat10AgentValve();
50 }
51
52 @Override
53 public boolean canBoundTo(String binding) {
54 if (binding == null) {
55 return false;
56 }
57 return binding.startsWith("Apache Tomcat/10.1")
58 || binding.startsWith("Apache Tomcat (TomEE)/10.0")
59 || binding.startsWith("NonStop(tm) Servlets For JavaServer Pages(tm) v10.1")
60 || binding.startsWith("Vmware tc") && binding.contains("/10.1");
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 throw new IllegalArgumentException(
153 "Unknown dispatcher mapping: " + filterMap.getDispatcherMapping());
154 }
155
156 String filterClass = "";
157 FilterDef fd = context.findFilterDef(filterMap.getFilterName());
158 if (fd != null) {
159 filterClass = fd.getFilterClass();
160 }
161
162 List<FilterMapping> filterMappings = getFilterMappings(filterMap, dm, filterClass);
163 filterMaps.addAll(filterMappings);
164 }
165 }
166 return filterMaps;
167 }
168
169 @Override
170 public List<FilterInfo> getApplicationFilters(Context context) {
171 FilterDef[] fds = context.findFilterDefs();
172 List<FilterInfo> filterDefs = new ArrayList<>(fds.length);
173 for (FilterDef filterDef : fds) {
174 if (filterDef != null) {
175 FilterInfo fi = getFilterInfo(filterDef);
176 filterDefs.add(fi);
177 }
178 }
179 return filterDefs;
180 }
181
182
183
184
185
186
187
188
189 private static FilterInfo getFilterInfo(FilterDef fd) {
190 FilterInfo fi = new FilterInfo();
191 fi.setFilterName(fd.getFilterName());
192 fi.setFilterClass(fd.getFilterClass());
193 fi.setFilterDesc(fd.getDescription());
194 return fi;
195 }
196
197 @Override
198 public List<ApplicationParam> getApplicationInitParams(Context context) {
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218 Set<String> nonOverridableParams = new HashSet<>();
219 for (ApplicationParameter appParam : context.findApplicationParameters()) {
220 if (appParam != null && !appParam.getOverride()) {
221 nonOverridableParams.add(appParam.getName());
222 }
223 }
224 List<ApplicationParam> initParams = new ArrayList<>(20);
225 ServletContext servletCtx = context.getServletContext();
226 for (String paramName : Collections.list(servletCtx.getInitParameterNames())) {
227 ApplicationParam param = new ApplicationParam();
228 param.setName(paramName);
229 param.setValue(servletCtx.getInitParameter(paramName));
230
231
232
233
234 param.setFromDeplDescr(
235 context.findParameter(paramName) != null && !nonOverridableParams.contains(paramName));
236 initParams.add(param);
237 }
238 return initParams;
239 }
240
241 @Override
242 public boolean resourceExists(String name, Context context) {
243 return context.getResources().getResource(name) != null;
244 }
245
246 @Override
247 public InputStream getResourceStream(String name, Context context) throws IOException {
248 WebResource resource = context.getResources().getResource(name);
249 return resource.getInputStream();
250 }
251
252 @Override
253 public Long[] getResourceAttributes(String name, Context context) {
254 Long[] result = new Long[2];
255 WebResource resource = context.getResources().getResource(name);
256 result[0] = resource.getContentLength();
257 result[1] = resource.getLastModified();
258 return result;
259 }
260
261
262
263
264
265
266
267
268 @Override
269 protected Object getNamingToken(Context context) {
270
271 Object token = context.getNamingToken();
272 if (!ContextAccessController.checkSecurityToken(context, token)) {
273 logger.error("Couldn't get a valid security token. ClassLoader binding will fail.");
274 }
275 return token;
276 }
277
278 }