ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/catalina/valves/rewrite/ResolverImpl.java

Path
ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/catalina/valves/rewrite/ResolverImpl.java
Status
scanned
Type
file
Name
ResolverImpl.java
Extension
.java
Programming language
Java
Mime type
text/plain
File type
ASCII text, with CRLF line terminators
Tag

      
    
Rootfs path

      
    
Size
16223 (15.8 KB)
MD5
0c1d06ad22b3157c1cb189ee8adaf1fc
SHA1
488f36cac07a2512369b707018430d15f9aa0fda
SHA256
9f1101de38fb02a12b2d334ae13bf515f885a771515bd00b85b9b741b4a3afd3
SHA512

      
    
SHA1_git
03aff6e7b320e8c12332bb2d1315f1d743a3f8de
Is binary

      
    
Is text
True
Is archive

      
    
Is media

      
    
Is legal

      
    
Is manifest

      
    
Is readme

      
    
Is top level

      
    
Is key file

      
    
ResolverImpl.java | 15.8 KB |

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.catalina.valves.rewrite; import java.io.IOException; import java.nio.charset.Charset; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.StringTokenizer; import java.util.concurrent.TimeUnit; import org.apache.catalina.WebResource; import org.apache.catalina.WebResourceRoot; import org.apache.catalina.connector.Request; import org.apache.juli.logging.Log; import org.apache.tomcat.util.http.FastHttpDateFormat; import org.apache.tomcat.util.net.SSLSupport; import org.apache.tomcat.util.net.jsse.PEMFile; import org.apache.tomcat.util.net.openssl.ciphers.Cipher; import org.apache.tomcat.util.net.openssl.ciphers.EncryptionLevel; import org.apache.tomcat.util.net.openssl.ciphers.OpenSSLCipherConfigurationParser; import org.apache.tomcat.util.res.StringManager; public class ResolverImpl extends Resolver { private static final StringManager sm = StringManager.getManager(ResolverImpl.class); protected final Request request; private final Log containerLog; /** * Create a resolver for the given request. * * @param request The request * * @deprecated Will be removed in Tomcat 12 onwards. Use {@link #ResolverImpl(Request, Log)} */ @Deprecated public ResolverImpl(Request request) { this(request, request.getContext().getLogger()); } public ResolverImpl(Request request, Log containerLog) { this.request = request; this.containerLog = containerLog; } /** * The following are not implemented: * <ul> * <li>SERVER_ADMIN</li> * <li>API_VERSION</li> * <li>IS_SUBREQ</li> * </ul> */ @Override public String resolve(String key) { return switch (key) { case "HTTP_USER_AGENT" -> request.getHeader("user-agent"); case "HTTP_REFERER" -> request.getHeader("referer"); case "HTTP_COOKIE" -> request.getHeader("cookie"); case "HTTP_FORWARDED" -> request.getHeader("forwarded"); case "HTTP_HOST" -> // Don't look directly at the host header to handle: // - Host name in HTTP/1.1 request line // - HTTP/0.9 & HTTP/1.0 requests // - HTTP/2 :authority pseudo header request.getServerName(); case "HTTP_PROXY_CONNECTION" -> request.getHeader("proxy-connection"); case "HTTP_ACCEPT" -> request.getHeader("accept"); case "REMOTE_ADDR" -> request.getRemoteAddr(); case "REMOTE_HOST" -> request.getRemoteHost(); case "REMOTE_PORT" -> String.valueOf(request.getRemotePort()); case "REMOTE_USER" -> request.getRemoteUser(); case "REMOTE_IDENT" -> request.getRemoteUser(); case "REQUEST_METHOD" -> request.getMethod(); case "SCRIPT_FILENAME" -> request.getServletContext().getRealPath(request.getServletPath()); case "REQUEST_PATH" -> request.getRequestPathMB().toString(); case "CONTEXT_PATH" -> request.getContextPath(); case "SERVLET_PATH" -> emptyStringIfNull(request.getServletPath()); case "PATH_INFO" -> emptyStringIfNull(request.getPathInfo()); case "QUERY_STRING" -> emptyStringIfNull(request.getQueryString()); case "AUTH_TYPE" -> request.getAuthType(); case "DOCUMENT_ROOT" -> request.getServletContext().getRealPath("/"); case "SERVER_NAME" -> request.getLocalName(); case "SERVER_ADDR" -> request.getLocalAddr(); case "SERVER_PORT" -> String.valueOf(request.getLocalPort()); case "SERVER_PROTOCOL" -> request.getProtocol(); case "SERVER_SOFTWARE" -> "tomcat"; case "THE_REQUEST" -> request.getMethod() + " " + request.getRequestURI() + " " + request.getProtocol(); case "REQUEST_URI" -> request.getRequestURI(); case "REQUEST_FILENAME" -> request.getPathTranslated(); case "HTTPS" -> request.isSecure() ? "on" : "off"; case "TIME_YEAR" -> String.valueOf(Calendar.getInstance().get(Calendar.YEAR)); case "TIME_MON" -> String.valueOf(Calendar.getInstance().get(Calendar.MONTH)); case "TIME_DAY" -> String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_MONTH)); case "TIME_HOUR" -> String.valueOf(Calendar.getInstance().get(Calendar.HOUR_OF_DAY)); case "TIME_MIN" -> String.valueOf(Calendar.getInstance().get(Calendar.MINUTE)); case "TIME_SEC" -> String.valueOf(Calendar.getInstance().get(Calendar.SECOND)); case "TIME_WDAY" -> String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_WEEK)); case "TIME" -> FastHttpDateFormat.getCurrentDate(); default -> null; }; } @Override public String resolveEnv(String key) { Object result = request.getAttribute(key); return (result != null) ? result.toString() : System.getProperty(key); } @Override public String resolveSsl(String key) { SSLSupport sslSupport = (SSLSupport) request.getAttribute(SSLSupport.SESSION_MGR); try { // SSL_SRP_USER: no planned support for SRP // SSL_SRP_USERINFO: no planned support for SRP if (key.equals("HTTPS")) { return String.valueOf(sslSupport != null); } else if (key.equals("SSL_PROTOCOL")) { return sslSupport.getProtocol(); } else if (key.equals("SSL_SESSION_ID")) { return sslSupport.getSessionId(); } else if (key.equals("SSL_SESSION_RESUMED")) { // FIXME session resumption state, not available anywhere } else if (key.equals("SSL_SECURE_RENEG")) { // FIXME available from SSLHostConfig } else if (key.equals("SSL_COMPRESS_METHOD")) { // FIXME available from SSLHostConfig } else if (key.equals("SSL_TLS_SNI")) { // FIXME from handshake SNI processing } else if (key.equals("SSL_CIPHER")) { return sslSupport.getCipherSuite(); } else if (key.equals("SSL_CIPHER_EXPORT")) { String cipherSuite = sslSupport.getCipherSuite(); if (cipherSuite != null) { Set<Cipher> cipherList = OpenSSLCipherConfigurationParser.parse(cipherSuite); if (cipherList.size() == 1) { Cipher cipher = cipherList.iterator().next(); if (cipher.getLevel().equals(EncryptionLevel.EXP40) || cipher.getLevel().equals(EncryptionLevel.EXP56)) { return "true"; } else { return "false"; } } } } else if (key.equals("SSL_CIPHER_ALGKEYSIZE")) { String cipherSuite = sslSupport.getCipherSuite(); if (cipherSuite != null) { Set<Cipher> cipherList = OpenSSLCipherConfigurationParser.parse(cipherSuite); if (cipherList.size() == 1) { Cipher cipher = cipherList.iterator().next(); return String.valueOf(cipher.getAlg_bits()); } } } else if (key.equals("SSL_CIPHER_USEKEYSIZE")) { Integer keySize = sslSupport.getKeySize(); return (keySize == null) ? null : sslSupport.getKeySize().toString(); } else if (key.startsWith("SSL_CLIENT_")) { X509Certificate[] certificates = sslSupport.getPeerCertificateChain(); if (certificates != null && certificates.length > 0) { key = key.substring("SSL_CLIENT_".length()); String result = resolveSslCertificates(key, certificates); if (result != null) { return result; } else if (key.startsWith("SAN_OTHER_msUPN_")) { // Type otherName, which is 0 key = key.substring("SAN_OTHER_msUPN_".length()); // FIXME OID from resolveAlternateName } else if (key.equals("CERT_RFC4523_CEA")) { // FIXME return certificate[0] format CertificateExactAssertion in RFC4523 } else if (key.equals("VERIFY")) { // FIXME return verification state, not available anywhere } } } else if (key.startsWith("SSL_SERVER_")) { X509Certificate[] certificates = sslSupport.getLocalCertificateChain(); if (certificates != null && certificates.length > 0) { key = key.substring("SSL_SERVER_".length()); String result = resolveSslCertificates(key, certificates); if (result != null) { return result; } else if (key.startsWith("SAN_OTHER_dnsSRV_")) { // Type otherName, which is 0 key = key.substring("SAN_OTHER_dnsSRV_".length()); // FIXME OID from resolveAlternateName } } } } catch (IOException ioe) { // TLS access error if (containerLog.isDebugEnabled()) { containerLog.debug(sm.getString("resolverImpl.tlsError"), ioe); } } return null; } private String resolveSslCertificates(String key, X509Certificate[] certificates) { if (key.equals("M_VERSION")) { return String.valueOf(certificates[0].getVersion()); } else if (key.equals("M_SERIAL")) { return certificates[0].getSerialNumber().toString(); } else if (key.equals("S_DN")) { return certificates[0].getSubjectX500Principal().toString(); } else if (key.startsWith("S_DN_")) { key = key.substring("S_DN_".length()); return resolveComponent(certificates[0].getSubjectX500Principal().getName(), key); } else if (key.startsWith("SAN_Email_")) { // Type rfc822Name, which is 1 key = key.substring("SAN_Email_".length()); return resolveAlternateName(certificates[0], 1, Integer.parseInt(key)); } else if (key.startsWith("SAN_DNS_")) { // Type dNSName, which is 2 key = key.substring("SAN_DNS_".length()); return resolveAlternateName(certificates[0], 2, Integer.parseInt(key)); } else if (key.equals("I_DN")) { return certificates[0].getIssuerX500Principal().getName(); } else if (key.startsWith("I_DN_")) { key = key.substring("I_DN_".length()); return resolveComponent(certificates[0].getIssuerX500Principal().toString(), key); } else if (key.equals("V_START")) { return String.valueOf(certificates[0].getNotBefore().getTime()); } else if (key.equals("V_END")) { return String.valueOf(certificates[0].getNotAfter().getTime()); } else if (key.equals("V_REMAIN")) { long remain = certificates[0].getNotAfter().getTime() - System.currentTimeMillis(); if (remain < 0) { remain = 0L; } // Return remaining days return String.valueOf(TimeUnit.MILLISECONDS.toDays(remain)); } else if (key.equals("A_SIG")) { return certificates[0].getSigAlgName(); } else if (key.equals("A_KEY")) { return certificates[0].getPublicKey().getAlgorithm(); } else if (key.equals("CERT")) { try { return PEMFile.toPEM(certificates[0]); } catch (CertificateEncodingException ignore) { // Ignore } } else if (key.startsWith("CERT_CHAIN_")) { key = key.substring("CERT_CHAIN_".length()); try { return PEMFile.toPEM(certificates[Integer.parseInt(key)]); } catch (NumberFormatException | ArrayIndexOutOfBoundsException | CertificateEncodingException ignore) { // Ignore } } return null; } private String resolveComponent(String fullDN, String component) { HashMap<String,String> components = new HashMap<>(); StringTokenizer tokenizer = new StringTokenizer(fullDN, ","); while (tokenizer.hasMoreElements()) { String token = tokenizer.nextToken().trim(); int pos = token.indexOf('='); if (pos > 0 && (pos + 1) < token.length()) { components.put(token.substring(0, pos), token.substring(pos + 1)); } } return components.get(component); } private String resolveAlternateName(X509Certificate certificate, int type, int n) { try { Collection<List<?>> alternateNames = certificate.getSubjectAlternativeNames(); if (alternateNames != null) { List<String> elements = new ArrayList<>(); for (List<?> alternateName : alternateNames) { Integer alternateNameType = (Integer) alternateName.get(0); if (alternateNameType.intValue() == type) { elements.add(String.valueOf(alternateName.get(1))); } } if (elements.size() > n) { return elements.get(n); } } } catch (NumberFormatException | ArrayIndexOutOfBoundsException | CertificateParsingException ignore) { // Ignore } return null; } @Override public String resolveHttp(String key) { return Objects.requireNonNullElse(request.getHeader(key), ""); } @Override public boolean resolveResource(int type, String name) { WebResourceRoot resources = request.getContext().getResources(); WebResource resource = resources.getResource(name); if (!resource.exists()) { return false; } else { return switch (type) { case 0 -> resource.isDirectory(); case 1 -> resource.isFile(); case 2 -> resource.isFile() && resource.getContentLength() > 0; default -> false; }; } } private static String emptyStringIfNull(String value) { return Objects.requireNonNullElse(value, ""); } @Override public Charset getUriCharset() { return request.getConnector().getURICharset(); } }
Detected license expression
apache-2.0
Detected license expression (SPDX)
Apache-2.0
Percentage of license text
8.12
Copyrights

      
    
Holders

      
    
Authors

      
    
License detections License expression License expression SPDX
apache_2_0-4bde3f57-78aa-4201-96bf-531cba09e7de apache-2.0 Apache-2.0
URL Start line End line
http://www.apache.org/licenses/LICENSE-2.0 9 9