This commit is contained in:
2024-11-30 19:03:49 +08:00
commit 1e6763c160
3806 changed files with 737676 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
/*
* 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.security;
public class Constants {
public static final String PACKAGE = "org.apache.catalina.security";
public static final String CRLF = "\r\n";
}

View File

@@ -0,0 +1,38 @@
/*
* 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.security;
import java.security.BasicPermission;
/**
* Grant this permission to a docBase to permit the web application to use any
* <code>META-INF/context.xml</code> that might be present with in the
* application when <code>deployXML</code> has been disabled at the Host level.
* The name of the permission should be the base name for the web application.
*/
public class DeployXmlPermission extends BasicPermission {
private static final long serialVersionUID = 1L;
public DeployXmlPermission(String name) {
super(name);
}
public DeployXmlPermission(String name, String actions) {
super(name, actions);
}
}

View File

@@ -0,0 +1,22 @@
# 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.
SecurityListener.checkUmaskFail=Start attempted with umask setting of [{0}]. Running Tomcat without a umask at least as restrictive as [{1}] has been blocked by the Lifecycle listener org.apache.catalina.security.SecurityListener (usually configured in CATALINA_BASE/conf/server.xml)
SecurityListener.checkUmaskNone=No umask setting was found in system property [{0}]. However, it appears Tomcat is running on a platform that supports umask. The system property is typically set in CATALINA_HOME/bin/catalina.sh. The Lifecycle listener org.apache.catalina.security.SecurityListener (usually configured in CATALINA_BASE/conf/server.xml) expects a umask at least as restrictive as [{1}]
SecurityListener.checkUmaskParseFail=Failed to parse value [{0}] as a valid umask.
SecurityListener.checkUmaskSkip=Unable to determine umask. It appears Tomcat is running on Windows so skip the umask check.
SecurityListener.checkUserWarning=Start attempted while running as user [{0}]. Running Tomcat as this user has been blocked by the Lifecycle listener org.apache.catalina.security.SecurityListener (usually configured in CATALINA_BASE/conf/server.xml)
SecurityUtil.doAsPrivilege=An exception occurs when running the PrivilegedExceptionAction block.

View File

@@ -0,0 +1,16 @@
# 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.
SecurityListener.checkUmaskSkip=Kann die umask nicht ermitteln. Es scheint Tomcat läuft auf Windows. Überspringe den umask Test.

View File

@@ -0,0 +1,22 @@
# 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.
SecurityListener.checkUmaskFail=Intentado arranque con valor de umask de [{0}]. Ejecutando Tomcat sin umask al menos tan restrictivo como [{1}] ha sido bloqueado por el oyente de Ciclo de Vida org.apache.catalina.security.SecurityListener (normalmente configurado en CATALINA_BASE/conf/server.xml)
SecurityListener.checkUmaskNone=No se ha hallado valor de umask en propiedad de sistema [{0}]. Si embargo, parece que Tomcat está siendo ejecutado en una plataforma que soporta umask. La propiedad del sistema se pone normalmente en CATALINA_HOME/bin/catalina.sh. El oyente de Ciclo de Vida org.apache.catalina.security.SecurityListener (normalmente configurado en CATALINA_BASE/conf/server.xml) espera un umask al menos tan restrictivo como [{1}]
SecurityListener.checkUmaskParseFail=No pude anallizar el valor [{0}] como in válido umask.
SecurityListener.checkUmaskSkip=No pude determinar umask. Parece que Tomcat se está ejecutando en Windows, por lo que se salta el chequeo de umsak.
SecurityListener.checkUserWarning=Se ha intentado arrancar mientras se ejecutaba como usuario [{0}]. Ejecutando Tomcat como este usuario user ha sido bloqueado por el oyente de Ciclos de Vida org.apache.catalina.security.SecurityListener (normalmente configurado en CATALINA_BASE/conf/server.xml)
SecurityUtil.doAsPrivilege=Ha tenido lugar una excepción al ejecutar el bloque PrivilegedExceptionAction.

View File

@@ -0,0 +1,22 @@
# 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.
SecurityListener.checkUmaskFail=Tentative de démarrage avec un paramètre umask [{0}}, qui a été bloquée par l'écouteur org.apache.catalina.security.SecurityListener (configuré habituellement dans CATALINA_BASE/conf/server.xml) car l'umask doit être au moins aussi restreint que [{1}]
SecurityListener.checkUmaskNone=Pas de définition du "umask" trouvée dans la propriété système [{0}]. Il apparaît toutefois que Tomcat tourne sur une plateforme qui supporte l''utilisation de umask. La propriété système est typiquement définie dans CATALINA_HOME/bin/catalina.sh. Le Lifecycle Listener org.apache.catalina.security.SecurityListener (généralement configuré dans CATALINA_BASE/conf/server.xml) s''attend à un umask au moins aussi restrictif que [{1}]
SecurityListener.checkUmaskParseFail=Impossible de traiter la valeur [{0}] comme un umask valide
SecurityListener.checkUmaskSkip=Impossible de déterminer le "umask". Il semble que Tomcat tourne ici sous Windows, donc évitez la vérification du "umask".
SecurityListener.checkUserWarning=Tentative de démarrage avec l'utilisateur [{0}}, qui a été bloquée par l'écouteur org.apache.catalina.security.SecurityListener (configuré habituellement dans CATALINA_BASE/conf/server.xml)
SecurityUtil.doAsPrivilege=Une exception s'est produite lors de l'exécution du bloc "PrivilegedExceptionAction".

View File

@@ -0,0 +1,22 @@
# 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.
SecurityListener.checkUmaskFail=[{0}]のumask設定で開始しようとしました。 少なくとも[{1}]と同じようにumaskを指定しないでTomcatを実行すると、ライフサイクルリスナーのorg.apache.catalina.security.SecurityListener通常はCATALINA_BASE/conf/server.xmlで構成されていますによってブロックされます。
SecurityListener.checkUmaskNone=システムプロパティ[{0}]にumask設定が見つかりませんでした。 しかし、Tomcatはumaskをサポートするプラットフォームで動作しているようです。 システムプロパティは通常、CATALINA_HOME/bin/catalina.shに設定されます。 ライフサイクルリスナーのorg.apache.catalina.security.SecurityListener通常はCATALINA_BASE/conf/server.xmlに設定されていますでは、少なくとも[{1}]と同じくらい拘束されたumaskが必要です。
SecurityListener.checkUmaskParseFail=値[{0}]を有効なumaskとして解析できませんでした。
SecurityListener.checkUmaskSkip=umask を取得できません。Tomcat を Windows で実行するときは umask をチェックしません。
SecurityListener.checkUserWarning=ユーザー[{0}]として実行中に開始しようとしました。 このユーザーでTomcatを実行するとがライフサイクルリスナーorg.apache.catalina.security.SecurityListener通常はCATALINA_BASE/conf /server.xmlで構成されているによってブロックされています。
SecurityUtil.doAsPrivilege=PrivilegedExceptionActionブロックを実行中に例外が発生しました。

View File

@@ -0,0 +1,22 @@
# 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.
SecurityListener.checkUmaskFail=umask 설정 [{0}]을(를) 사용하여 시작을 시도했습니다. 적어도 umask를 [{1}] 만큼 제한적으로 설정하지 않고 Tomcat을 시작하는 것은, Lifecycle 리스너인 org.apache.catalina.security.SecurityListener (통상 CATALINA_BASE/conf/server.xml에서 설정)에 의해 차단되었습니다.
SecurityListener.checkUmaskNone=시스템 프로퍼티 [{0}]에 umask 설정이 없습니다. 하지만, Tomcat은 umask를 지원하는 플랫폼에서 실행 중인 것으로 보입니다. 해당 시스템 프로퍼티는 보통 CATALINA_HOME/bin/catalina.sh에서 설정됩니다. Lifecycle 리스너인 org.apache.catalina.security.SecurityListener(통상 CATALINA_BASE/conf/server.xml에서 설정)는, umask 값이 적어도 [{1}] 만큼 제한적으로 설정되기를 요구합니다.
SecurityListener.checkUmaskParseFail=값 [{0}]이(가) 유효한 umask 값이 아니어서, 파싱하지 못했습니다.
SecurityListener.checkUmaskSkip=umask를 결정할 수 없습니다. Tomcat이 Windows에서 실행되는 것으로 보이므로, umask 점검을 건너뜁니다.
SecurityListener.checkUserWarning=사용자 [{0}](으)로서 실행하면서, 프로그램 시작이 시도 되었습니다. 이 사용자로서 Tomcat을 실행하는 것은, Lifecycle 리스너인 org.apache.catalina.security.SecurityListener (보통 CATALINA_BASE/conf/server.xml에서 설정)에 의해 차단되었습니다.
SecurityUtil.doAsPrivilege=PrivilegedExceptionAction 블록을 실행하는 중 예외가 발생했습니다.

View File

@@ -0,0 +1,16 @@
# 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.
SecurityListener.checkUmaskSkip=无法确定权限。这表示 Tomcat 正在 Windows 上运行,所以跳过权限检查。

View File

@@ -0,0 +1,208 @@
/*
* 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.security;
/**
* Static class used to preload java classes when using the
* Java SecurityManager so that the defineClassInPackage
* RuntimePermission does not trigger an AccessControlException.
*
* @author Glenn L. Nielsen
*/
public final class SecurityClassLoad {
public static void securityClassLoad(ClassLoader loader) throws Exception {
securityClassLoad(loader, true);
}
static void securityClassLoad(ClassLoader loader, boolean requireSecurityManager) throws Exception {
if (requireSecurityManager && System.getSecurityManager() == null) {
return;
}
loadCorePackage(loader);
loadCoyotePackage(loader);
loadLoaderPackage(loader);
loadRealmPackage(loader);
loadServletsPackage(loader);
loadSessionPackage(loader);
loadUtilPackage(loader);
loadJavaxPackage(loader);
loadConnectorPackage(loader);
loadTomcatPackage(loader);
}
private static final void loadCorePackage(ClassLoader loader) throws Exception {
final String basePackage = "org.apache.catalina.core.";
loader.loadClass(basePackage + "AccessLogAdapter");
loader.loadClass(basePackage + "ApplicationContextFacade$PrivilegedExecuteMethod");
loader.loadClass(basePackage + "ApplicationDispatcher$PrivilegedForward");
loader.loadClass(basePackage + "ApplicationDispatcher$PrivilegedInclude");
loader.loadClass(basePackage + "ApplicationPushBuilder");
loader.loadClass(basePackage + "AsyncContextImpl");
loader.loadClass(basePackage + "AsyncContextImpl$AsyncRunnable");
loader.loadClass(basePackage + "AsyncContextImpl$DebugException");
loader.loadClass(basePackage + "AsyncListenerWrapper");
loader.loadClass(basePackage + "ContainerBase$PrivilegedAddChild");
loadAnonymousInnerClasses(loader, basePackage + "DefaultInstanceManager");
loader.loadClass(basePackage + "DefaultInstanceManager$AnnotationCacheEntry");
loader.loadClass(basePackage + "DefaultInstanceManager$AnnotationCacheEntryType");
loader.loadClass(basePackage + "ApplicationHttpRequest$AttributeNamesEnumerator");
}
private static final void loadLoaderPackage(ClassLoader loader) throws Exception {
final String basePackage = "org.apache.catalina.loader.";
loader.loadClass(basePackage + "WebappClassLoaderBase$PrivilegedFindClassByName");
loader.loadClass(basePackage + "WebappClassLoaderBase$PrivilegedHasLoggingConfig");
}
private static final void loadRealmPackage(ClassLoader loader) throws Exception {
final String basePackage = "org.apache.catalina.realm.";
loader.loadClass(basePackage + "LockOutRealm$LockRecord");
}
private static final void loadServletsPackage(ClassLoader loader) throws Exception {
final String basePackage = "org.apache.catalina.servlets.";
// Avoid a possible memory leak in the DefaultServlet when running with
// a security manager. The DefaultServlet needs to load an XML parser
// when running under a security manager. We want this to be loaded by
// the container rather than a web application to prevent a memory leak
// via web application class loader.
loader.loadClass(basePackage + "DefaultServlet");
}
private static final void loadSessionPackage(ClassLoader loader) throws Exception {
final String basePackage = "org.apache.catalina.session.";
loader.loadClass(basePackage + "StandardSession");
loadAnonymousInnerClasses(loader, basePackage + "StandardSession");
loader.loadClass(basePackage + "StandardManager$PrivilegedDoUnload");
}
private static final void loadUtilPackage(ClassLoader loader) throws Exception {
final String basePackage = "org.apache.catalina.util.";
loader.loadClass(basePackage + "ParameterMap");
loader.loadClass(basePackage + "RequestUtil");
loader.loadClass(basePackage + "TLSUtil");
}
private static final void loadCoyotePackage(ClassLoader loader) throws Exception {
final String basePackage = "org.apache.coyote.";
loader.loadClass(basePackage + "http11.Constants");
// Make sure system property is read at this point
Class<?> clazz = loader.loadClass(basePackage + "Constants");
clazz.getConstructor().newInstance();
loader.loadClass(basePackage + "http2.Stream$PrivilegedPush");
}
private static final void loadJavaxPackage(ClassLoader loader) throws Exception {
loader.loadClass("javax.servlet.http.Cookie");
}
private static final void loadConnectorPackage(ClassLoader loader) throws Exception {
final String basePackage = "org.apache.catalina.connector.";
loader.loadClass(basePackage + "RequestFacade$GetAttributePrivilegedAction");
loader.loadClass(basePackage + "RequestFacade$GetParameterMapPrivilegedAction");
loader.loadClass(basePackage + "RequestFacade$GetRequestDispatcherPrivilegedAction");
loader.loadClass(basePackage + "RequestFacade$GetParameterPrivilegedAction");
loader.loadClass(basePackage + "RequestFacade$GetParameterNamesPrivilegedAction");
loader.loadClass(basePackage + "RequestFacade$GetParameterValuePrivilegedAction");
loader.loadClass(basePackage + "RequestFacade$GetCharacterEncodingPrivilegedAction");
loader.loadClass(basePackage + "RequestFacade$GetHeadersPrivilegedAction");
loader.loadClass(basePackage + "RequestFacade$GetHeaderNamesPrivilegedAction");
loader.loadClass(basePackage + "RequestFacade$GetCookiesPrivilegedAction");
loader.loadClass(basePackage + "RequestFacade$GetLocalePrivilegedAction");
loader.loadClass(basePackage + "RequestFacade$GetLocalesPrivilegedAction");
loader.loadClass(basePackage + "ResponseFacade$SetContentTypePrivilegedAction");
loader.loadClass(basePackage + "ResponseFacade$DateHeaderPrivilegedAction");
loader.loadClass(basePackage + "RequestFacade$GetSessionPrivilegedAction");
loadAnonymousInnerClasses(loader, basePackage + "ResponseFacade");
loadAnonymousInnerClasses(loader, basePackage + "OutputBuffer");
loadAnonymousInnerClasses(loader, basePackage + "CoyoteInputStream");
loadAnonymousInnerClasses(loader, basePackage + "InputBuffer");
loadAnonymousInnerClasses(loader, basePackage + "Response");
}
private static final void loadTomcatPackage(ClassLoader loader) throws Exception {
final String basePackage = "org.apache.tomcat.";
// buf
loader.loadClass(basePackage + "util.buf.B2CConverter");
loader.loadClass(basePackage + "util.buf.ByteBufferUtils");
loader.loadClass(basePackage + "util.buf.C2BConverter");
loader.loadClass(basePackage + "util.buf.HexUtils");
loader.loadClass(basePackage + "util.buf.StringCache");
loader.loadClass(basePackage + "util.buf.StringCache$ByteEntry");
loader.loadClass(basePackage + "util.buf.StringCache$CharEntry");
loader.loadClass(basePackage + "util.buf.UriUtil");
// collections
Class<?> clazz = loader.loadClass(basePackage + "util.collections.CaseInsensitiveKeyMap");
// Ensure StringManager is configured
clazz.getConstructor().newInstance();
loader.loadClass(basePackage + "util.collections.CaseInsensitiveKeyMap$EntryImpl");
loader.loadClass(basePackage + "util.collections.CaseInsensitiveKeyMap$EntryIterator");
loader.loadClass(basePackage + "util.collections.CaseInsensitiveKeyMap$EntrySet");
loader.loadClass(basePackage + "util.collections.CaseInsensitiveKeyMap$Key");
// http
loader.loadClass(basePackage + "util.http.CookieProcessor");
loader.loadClass(basePackage + "util.http.NamesEnumerator");
// Make sure system property is read at this point
clazz = loader.loadClass(basePackage + "util.http.FastHttpDateFormat");
clazz.getConstructor().newInstance();
loader.loadClass(basePackage + "util.http.parser.HttpParser");
loader.loadClass(basePackage + "util.http.parser.MediaType");
loader.loadClass(basePackage + "util.http.parser.MediaTypeCache");
loader.loadClass(basePackage + "util.http.parser.SkipResult");
// net
loader.loadClass(basePackage + "util.net.Constants");
loader.loadClass(basePackage + "util.net.DispatchType");
loader.loadClass(basePackage + "util.net.NioBlockingSelector$BlockPoller$RunnableAdd");
loader.loadClass(basePackage + "util.net.NioBlockingSelector$BlockPoller$RunnableCancel");
loader.loadClass(basePackage + "util.net.NioBlockingSelector$BlockPoller$RunnableRemove");
loader.loadClass(basePackage + "util.net.AprEndpoint$AprSocketWrapper$AprOperationState");
loader.loadClass(basePackage + "util.net.NioEndpoint$NioSocketWrapper$NioOperationState");
loader.loadClass(basePackage + "util.net.Nio2Endpoint$Nio2SocketWrapper$Nio2OperationState");
loader.loadClass(basePackage + "util.net.SocketWrapperBase$BlockingMode");
loader.loadClass(basePackage + "util.net.SocketWrapperBase$CompletionCheck");
loader.loadClass(basePackage + "util.net.SocketWrapperBase$CompletionHandlerCall");
loader.loadClass(basePackage + "util.net.SocketWrapperBase$CompletionState");
loader.loadClass(basePackage + "util.net.SocketWrapperBase$VectoredIOCompletionHandler");
// security
loader.loadClass(basePackage + "util.security.PrivilegedGetTccl");
loader.loadClass(basePackage + "util.security.PrivilegedSetTccl");
}
private static final void loadAnonymousInnerClasses(ClassLoader loader, String enclosingClass) {
try {
for (int i = 1;; i++) {
loader.loadClass(enclosingClass + '$' + i);
}
} catch (ClassNotFoundException ignored) {
//
}
}
}

View File

@@ -0,0 +1,147 @@
/*
* 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.security;
import java.security.Security;
import org.apache.catalina.startup.CatalinaProperties;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
/**
* Util class to protect Catalina against package access and insertion.
* The code are been moved from Catalina.java
* @author the Catalina.java authors
*/
public final class SecurityConfig{
private static final Object singletonLock = new Object();
private static volatile SecurityConfig singleton = null;
private static final Log log = LogFactory.getLog(SecurityConfig.class);
private static final String PACKAGE_ACCESS = "sun.,"
+ "org.apache.catalina."
+ ",org.apache.jasper."
+ ",org.apache.coyote."
+ ",org.apache.tomcat.";
// FIX ME package "javax." was removed to prevent HotSpot
// fatal internal errors
private static final String PACKAGE_DEFINITION= "java.,sun."
+ ",org.apache.catalina."
+ ",org.apache.coyote."
+ ",org.apache.tomcat."
+ ",org.apache.jasper.";
/**
* List of protected package from conf/catalina.properties
*/
private final String packageDefinition;
/**
* List of protected package from conf/catalina.properties
*/
private final String packageAccess;
/**
* Create a single instance of this class.
*/
private SecurityConfig() {
String definition = null;
String access = null;
try{
definition = CatalinaProperties.getProperty("package.definition");
access = CatalinaProperties.getProperty("package.access");
} catch (java.lang.Exception ex){
if (log.isDebugEnabled()){
log.debug("Unable to load properties using CatalinaProperties", ex);
}
} finally {
packageDefinition = definition;
packageAccess = access;
}
}
/**
* Returns the singleton instance of that class.
* @return an instance of that class.
*/
public static SecurityConfig newInstance(){
if (singleton == null) {
synchronized (singletonLock) {
if (singleton == null) {
singleton = new SecurityConfig();
}
}
}
return singleton;
}
/**
* Set the security package.access value.
*/
public void setPackageAccess(){
// If catalina.properties is missing, protect all by default.
if (packageAccess == null){
setSecurityProperty("package.access", PACKAGE_ACCESS);
} else {
setSecurityProperty("package.access", packageAccess);
}
}
/**
* Set the security package.definition value.
*/
public void setPackageDefinition(){
// If catalina.properties is missing, protect all by default.
if (packageDefinition == null){
setSecurityProperty("package.definition", PACKAGE_DEFINITION);
} else {
setSecurityProperty("package.definition", packageDefinition);
}
}
/**
* Set the proper security property
* @param properties the package.* property.
*/
private final void setSecurityProperty(String properties, String packageList){
if (System.getSecurityManager() != null){
String definition = Security.getProperty(properties);
if( definition != null && definition.length() > 0 ){
if (packageList.length() > 0) {
definition = definition + ',' + packageList;
}
} else {
definition = packageList;
}
Security.setProperty(properties, definition);
}
}
}

View File

@@ -0,0 +1,185 @@
/*
* 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.security;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.buf.StringUtils;
import org.apache.tomcat.util.res.StringManager;
public class SecurityListener implements LifecycleListener {
private static final Log log = LogFactory.getLog(SecurityListener.class);
private static final StringManager sm =
StringManager.getManager(Constants.PACKAGE);
private static final String UMASK_PROPERTY_NAME =
Constants.PACKAGE + ".SecurityListener.UMASK";
private static final String UMASK_FORMAT = "%04o";
/**
* The list of operating system users not permitted to run Tomcat.
*/
private final Set<String> checkedOsUsers = new HashSet<>();
/**
* The minimum umask that must be configured for the operating system user
* running Tomcat. The umask is handled as an octal.
*/
private Integer minimumUmask = Integer.valueOf(7);
public SecurityListener() {
checkedOsUsers.add("root");
}
@Override
public void lifecycleEvent(LifecycleEvent event) {
// This is the earliest event in Lifecycle
if (event.getType().equals(Lifecycle.BEFORE_INIT_EVENT)) {
doChecks();
}
}
/**
* Set the list of operating system users not permitted to run Tomcat. By
* default, only root is prevented from running Tomcat. Calling this method
* with null or the empty string will clear the list of users and
* effectively disables this check. User names will always be checked in a
* case insensitive manner using the system default Locale.
*
* @param userNameList A comma separated list of operating system users not
* permitted to run Tomcat
*/
public void setCheckedOsUsers(String userNameList) {
if (userNameList == null || userNameList.length() == 0) {
checkedOsUsers.clear();
} else {
String[] userNames = userNameList.split(",");
for (String userName : userNames) {
if (userName.length() > 0) {
checkedOsUsers.add(userName.toLowerCase(Locale.getDefault()));
}
}
}
}
/**
* Returns the current list of operating system users not permitted to run
* Tomcat.
*
* @return A comma separated list of operating system user names.
*/
public String getCheckedOsUsers() {
return StringUtils.join(checkedOsUsers);
}
/**
* Set the minimum umask that must be configured before Tomcat will start.
*
* @param umask The 4-digit umask as returned by the OS command <i>umask</i>
*/
public void setMinimumUmask(String umask) {
if (umask == null || umask.length() == 0) {
minimumUmask = Integer.valueOf(0);
} else {
minimumUmask = Integer.valueOf(umask, 8);
}
}
/**
* Get the minimum umask that must be configured before Tomcat will start.
*
* @return The 4-digit umask as used by the OS command <i>umask</i>
*/
public String getMinimumUmask() {
return String.format(UMASK_FORMAT, minimumUmask);
}
/**
* Execute the security checks. Each check should be in a separate method.
*/
protected void doChecks() {
checkOsUser();
checkUmask();
}
protected void checkOsUser() {
String userName = System.getProperty("user.name");
if (userName != null) {
String userNameLC = userName.toLowerCase(Locale.getDefault());
if (checkedOsUsers.contains(userNameLC)) {
// Have to throw Error to force start process to be aborted
throw new Error(sm.getString(
"SecurityListener.checkUserWarning", userName));
}
}
}
protected void checkUmask() {
String prop = System.getProperty(UMASK_PROPERTY_NAME);
Integer umask = null;
if (prop != null) {
try {
umask = Integer.valueOf(prop, 8);
} catch (NumberFormatException nfe) {
log.warn(sm.getString("SecurityListener.checkUmaskParseFail",
prop));
}
}
if (umask == null) {
if (Constants.CRLF.equals(System.lineSeparator())) {
// Probably running on Windows so no umask
if (log.isDebugEnabled()) {
log.debug(sm.getString("SecurityListener.checkUmaskSkip"));
}
return;
} else {
if (minimumUmask.intValue() > 0) {
log.warn(sm.getString(
"SecurityListener.checkUmaskNone",
UMASK_PROPERTY_NAME, getMinimumUmask()));
}
return;
}
}
if ((umask.intValue() & minimumUmask.intValue()) !=
minimumUmask.intValue()) {
throw new Error(sm.getString("SecurityListener.checkUmaskFail",
String.format(UMASK_FORMAT, umask), getMinimumUmask()));
}
}
}

View File

@@ -0,0 +1,432 @@
/*
* 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.security;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.Principal;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.security.auth.Subject;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.UnavailableException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.apache.catalina.Globals;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.ExceptionUtils;
import org.apache.tomcat.util.res.StringManager;
/**
* This utility class associates a <code>Subject</code> to the current
* <code>AccessControlContext</code>. When a <code>SecurityManager</code> is
* used, the container will always associate the called thread with an
* AccessControlContext containing only the principal of the requested
* Servlet/Filter.
*
* This class uses reflection to invoke the methods.
*/
public final class SecurityUtil{
// Note that indexes overlap.
// A Servlet uses "init", "service", "event", "destroy".
// A Filter uses "doFilter", "doFilterEvent", "destroy".
private static final int INIT= 0;
private static final int SERVICE = 1;
private static final int DOFILTER = 1;
private static final int EVENT = 2;
private static final int DOFILTEREVENT = 2;
private static final int DESTROY = 3;
private static final String INIT_METHOD = "init";
private static final String DOFILTER_METHOD = "doFilter";
private static final String SERVICE_METHOD = "service";
private static final String EVENT_METHOD = "event";
private static final String DOFILTEREVENT_METHOD = "doFilterEvent";
private static final String DESTROY_METHOD = "destroy";
/**
* Cache every class for which we are creating methods.
*/
private static final Map<Class<?>,Method[]> classCache = new ConcurrentHashMap<>();
private static final Log log = LogFactory.getLog(SecurityUtil.class);
private static final boolean packageDefinitionEnabled =
(System.getProperty("package.definition") == null &&
System.getProperty("package.access") == null) ? false : true;
/**
* The string resources for this package.
*/
private static final StringManager sm =
StringManager.getManager(Constants.PACKAGE);
/**
* Perform work as a particular <code>Subject</code>. Here the work
* will be granted to a <code>null</code> subject.
*
* @param methodName the method to apply the security restriction
* @param targetObject the <code>Servlet</code> on which the method will
* be called.
* @throws Exception an execution error occurred
*/
public static void doAsPrivilege(final String methodName,
final Servlet targetObject) throws Exception {
doAsPrivilege(methodName, targetObject, null, null, null);
}
/**
* Perform work as a particular <code>Subject</code>. Here the work
* will be granted to a <code>null</code> subject.
*
* @param methodName the method to apply the security restriction
* @param targetObject the <code>Servlet</code> on which the method will
* be called.
* @param targetType <code>Class</code> array used to instantiate a
* <code>Method</code> object.
* @param targetArguments <code>Object</code> array contains the runtime
* parameters instance.
* @throws Exception an execution error occurred
*/
public static void doAsPrivilege(final String methodName,
final Servlet targetObject,
final Class<?>[] targetType,
final Object[] targetArguments)
throws Exception {
doAsPrivilege(methodName,
targetObject,
targetType,
targetArguments,
null);
}
/**
* Perform work as a particular <code>Subject</code>. Here the work
* will be granted to a <code>null</code> subject.
*
* @param methodName the method to apply the security restriction
* @param targetObject the <code>Servlet</code> on which the method will
* be called.
* @param targetParameterTypes <code>Class</code> array used to instantiate a
* <code>Method</code> object.
* @param targetArguments <code>Object</code> array contains the
* runtime parameters instance.
* @param principal the <code>Principal</code> to which the security
* privilege applies
* @throws Exception an execution error occurred
*/
public static void doAsPrivilege(final String methodName,
final Servlet targetObject,
final Class<?>[] targetParameterTypes,
final Object[] targetArguments,
Principal principal)
throws Exception {
Method method = null;
Method[] methodsCache = classCache.get(Servlet.class);
if(methodsCache == null) {
method = createMethodAndCacheIt(null,
Servlet.class,
methodName,
targetParameterTypes);
} else {
method = findMethod(methodsCache, methodName);
if (method == null) {
method = createMethodAndCacheIt(methodsCache,
Servlet.class,
methodName,
targetParameterTypes);
}
}
execute(method, targetObject, targetArguments, principal);
}
/**
* Perform work as a particular <code>Subject</code>. Here the work
* will be granted to a <code>null</code> subject.
*
* @param methodName the method to apply the security restriction
* @param targetObject the <code>Filter</code> on which the method will
* be called.
* @throws Exception an execution error occurred
*/
public static void doAsPrivilege(final String methodName,
final Filter targetObject)
throws Exception {
doAsPrivilege(methodName, targetObject, null, null);
}
/**
* Perform work as a particular <code>Subject</code>. Here the work
* will be granted to a <code>null</code> subject.
*
* @param methodName the method to apply the security restriction
* @param targetObject the <code>Filter</code> on which the method will
* be called.
* @param targetType <code>Class</code> array used to instantiate a
* <code>Method</code> object.
* @param targetArguments <code>Object</code> array contains the
* runtime parameters instance.
* @throws Exception an execution error occurred
*/
public static void doAsPrivilege(final String methodName,
final Filter targetObject,
final Class<?>[] targetType,
final Object[] targetArguments)
throws Exception {
doAsPrivilege(
methodName, targetObject, targetType, targetArguments, null);
}
/**
* Perform work as a particular <code>Subject</code>. Here the work
* will be granted to a <code>null</code> subject.
*
* @param methodName the method to apply the security restriction
* @param targetObject the <code>Filter</code> on which the method will
* be called.
* @param targetParameterTypes <code>Class</code> array used to instantiate a
* <code>Method</code> object.
* @param targetParameterValues <code>Object</code> array contains the
* runtime parameters instance.
* @param principal the <code>Principal</code> to which the security
* privilege applies
* @throws Exception an execution error occurred
*/
public static void doAsPrivilege(final String methodName,
final Filter targetObject,
final Class<?>[] targetParameterTypes,
final Object[] targetParameterValues,
Principal principal)
throws Exception {
Method method = null;
Method[] methodsCache = classCache.get(Filter.class);
if(methodsCache == null) {
method = createMethodAndCacheIt(null,
Filter.class,
methodName,
targetParameterTypes);
} else {
method = findMethod(methodsCache, methodName);
if (method == null) {
method = createMethodAndCacheIt(methodsCache,
Filter.class,
methodName,
targetParameterTypes);
}
}
execute(method, targetObject, targetParameterValues, principal);
}
/**
* Perform work as a particular <code>Subject</code>. Here the work
* will be granted to a <code>null</code> subject.
*
* @param method the method to apply the security restriction
* @param targetObject the <code>Servlet</code> on which the method will
* be called.
* @param targetArguments <code>Object</code> array contains the
* runtime parameters instance.
* @param principal the <code>Principal</code> to which the security
* privilege applies
* @throws Exception an execution error occurred
*/
private static void execute(final Method method,
final Object targetObject,
final Object[] targetArguments,
Principal principal)
throws Exception {
try{
Subject subject = null;
PrivilegedExceptionAction<Void> pea =
new PrivilegedExceptionAction<Void>(){
@Override
public Void run() throws Exception{
method.invoke(targetObject, targetArguments);
return null;
}
};
// The first argument is always the request object
if (targetArguments != null
&& targetArguments[0] instanceof HttpServletRequest){
HttpServletRequest request =
(HttpServletRequest)targetArguments[0];
boolean hasSubject = false;
HttpSession session = request.getSession(false);
if (session != null){
subject =
(Subject)session.getAttribute(Globals.SUBJECT_ATTR);
hasSubject = (subject != null);
}
if (subject == null){
subject = new Subject();
if (principal != null){
subject.getPrincipals().add(principal);
}
}
if (session != null && !hasSubject) {
session.setAttribute(Globals.SUBJECT_ATTR, subject);
}
}
Subject.doAsPrivileged(subject, pea, null);
} catch( PrivilegedActionException pe) {
Throwable e;
if (pe.getException() instanceof InvocationTargetException) {
e = pe.getException().getCause();
ExceptionUtils.handleThrowable(e);
} else {
e = pe;
}
if (log.isDebugEnabled()){
log.debug(sm.getString("SecurityUtil.doAsPrivilege"), e);
}
if (e instanceof UnavailableException)
throw (UnavailableException) e;
else if (e instanceof ServletException)
throw (ServletException) e;
else if (e instanceof IOException)
throw (IOException) e;
else if (e instanceof RuntimeException)
throw (RuntimeException) e;
else
throw new ServletException(e.getMessage(), e);
}
}
/**
* Find a method stored within the cache.
* @param methodsCache the cache used to store method instance
* @param methodName the method to apply the security restriction
* @return the method instance, null if not yet created.
*/
private static Method findMethod(Method[] methodsCache,
String methodName){
if (methodName.equals(INIT_METHOD)){
return methodsCache[INIT];
} else if (methodName.equals(DESTROY_METHOD)){
return methodsCache[DESTROY];
} else if (methodName.equals(SERVICE_METHOD)){
return methodsCache[SERVICE];
} else if (methodName.equals(DOFILTER_METHOD)){
return methodsCache[DOFILTER];
} else if (methodName.equals(EVENT_METHOD)){
return methodsCache[EVENT];
} else if (methodName.equals(DOFILTEREVENT_METHOD)){
return methodsCache[DOFILTEREVENT];
}
return null;
}
/**
* Create the method and cache it for further re-use.
* @param methodsCache the cache used to store method instance
* @param targetType the class on which the method will be called.
* @param methodName the method to apply the security restriction
* @param parameterTypes <code>Class</code> array used to instantiate a
* <code>Method</code> object.
* @return the method instance.
* @throws Exception an execution error occurred
*/
private static Method createMethodAndCacheIt(Method[] methodsCache,
Class<?> targetType,
String methodName,
Class<?>[] parameterTypes)
throws Exception {
if (methodsCache == null) {
methodsCache = new Method[4];
}
Method method = targetType.getMethod(methodName, parameterTypes);
if (methodName.equals(INIT_METHOD)){
methodsCache[INIT] = method;
} else if (methodName.equals(DESTROY_METHOD)){
methodsCache[DESTROY] = method;
} else if (methodName.equals(SERVICE_METHOD)){
methodsCache[SERVICE] = method;
} else if (methodName.equals(DOFILTER_METHOD)){
methodsCache[DOFILTER] = method;
} else if (methodName.equals(EVENT_METHOD)){
methodsCache[EVENT] = method;
} else if (methodName.equals(DOFILTEREVENT_METHOD)){
methodsCache[DOFILTEREVENT] = method;
}
classCache.put(targetType, methodsCache);
return method;
}
/**
* Remove the object from the cache.
*
* @param cachedObject The object to remove
*/
public static void remove(Object cachedObject){
classCache.remove(cachedObject);
}
/**
* Return the <code>SecurityManager</code> only if Security is enabled AND
* package protection mechanism is enabled.
* @return <code>true</code> if package level protection is enabled
*/
public static boolean isPackageProtectionEnabled(){
if (packageDefinitionEnabled && Globals.IS_SECURITY_ENABLED){
return true;
}
return false;
}
}