diff --git a/apache-tomcat-9.0.43-src.tar.gz b/apache-tomcat-9.0.43-src.tar.gz deleted file mode 100644 index a580240..0000000 --- a/apache-tomcat-9.0.43-src.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:28db36e1f1440c8517513a282f71383d825fe1383d8e5317e22e5122803c40ca -size 6042010 diff --git a/apache-tomcat-9.0.43-src.tar.gz.asc b/apache-tomcat-9.0.43-src.tar.gz.asc deleted file mode 100644 index 898a610..0000000 --- a/apache-tomcat-9.0.43-src.tar.gz.asc +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN PGP SIGNATURE----- - -iQIzBAABCAAdFiEEqcXfTSLpmZjZh1pREMAcWi9gWecFAmATIH8ACgkQEMAcWi9g -Wecu9hAAhNGHtILVHGLWoqGJPVC29l2kgXiDshkFbgHKxeR6K5kooaxIB0N9QGGb -9H/BEwM92Kdl2VwQwtZBrW+x+worRQWIAHLCS9KF/UaVMLSIO54E5+aeJ6+vgBPC -AQdIn2mZ4o4RtUfYWsGgtPrQvGR/M+VSLKALn6SeB9O60zHrDvgpdVp0coFw0aIY -mi0HWsfoZltGTqscsgVEsSvolkvo7Au0c9DAGVGSLzhavlHT3Wnvsg8RuQ+oV2G+ -aX1R1J7xuPyDxrvLHShOu9ERxxHmEIgJ5/wrWgGUEwJJQmSAqFQHW7q1kswOmL5a -mfWYSsqrqcsc+8QI6oYnVfN6Yu/Podcb1Tbs0elYdn+rEU0j73j6gGITSzSFokkZ -2tueXJ/U5rHthWMiL8xLZXp9RpOzGgpo91TY3qSHsvpVi7HSX9kLsUq4gHFPDehF -s+5ycfYy+fzsRUs6Fsa/2FfRIy9zEatzcjX2yvFCjBaeKbv8cRixeVCqsERopIwW -5hwh1hmqQNn4FuOS/Ei03QkRHGPHWhrBU5GS0ZEruhUNfc4kfogBBsaUBQkfv94C -EScu+rTeOSEv4exWAH/IiaOHPPYQTH9RXJ+aPbZpZ+7BOzpYU30hFGZwhRli1hqa -Ib7wuGMQXfNJQ8ndAlzPIMjp12dLOYeOeoRqHK5duaXfK9e+WN8= -=KHse ------END PGP SIGNATURE----- diff --git a/apache-tomcat-9.0.75-src.tar.gz b/apache-tomcat-9.0.75-src.tar.gz new file mode 100644 index 0000000..15f46e6 --- /dev/null +++ b/apache-tomcat-9.0.75-src.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:35fee3552179eb0ee1ed3b0ec4785d94b9e7402bb23f1aeb223178b7e4645a82 +size 6241477 diff --git a/apache-tomcat-9.0.75-src.tar.gz.asc b/apache-tomcat-9.0.75-src.tar.gz.asc new file mode 100644 index 0000000..ee92a76 --- /dev/null +++ b/apache-tomcat-9.0.75-src.tar.gz.asc @@ -0,0 +1,16 @@ +-----BEGIN PGP SIGNATURE----- + +iQIzBAABCAAdFiEESPjmn2OQyfJc/tzSaCSJWTWecisFAmRTrhwACgkQaCSJWTWe +cisKuA/+IQFNKHTyMq7uCBmSMpfqzdFH6tE3MiUFAvHfNE7MuYBtyCFkTmryNP2j +wAHuvT8qJYyglhTkP6Ra+4EipLltAZEPF6a5K9PYQEtCmEo0BlpJq8Bln0Re8nzs +z1JEPsPlIlJkx3utfX+QSVn9/roTK+RdP0x4FMxD7Ujg00UOZ1kr5Z+VY4ArT3QC +H2yriYiPAk5WX2ovtyhvnF606TcZGU9wUcUVaQMNDETjmFD4aS7PuhcwpNU/ZbS9 +vB8psCwb75U1iOE9oRfXDQbxvOAUhcAJPPVaS88I0iDNYlp870l/nUCTotFm14yG +uHXEE/XDVN2aojLH302AxZjTbXqXAga5TBT0aFAL3UWzqdz9UA/2sZqbjr0gN4U6 +ggZ6wc8B1CqzuT7xFOI+ugMNokXt4CZdZ4bjFLfRCU8ZEpIoPsW6f6vtVRKUwAU2 +1Fr/XsGnTwVcIvnlD0PrLd4RGRqgdAzhIXZ5+q//1ls/hEXDx63AkYkv0T6AtaFn +tuoLXcF7plWAQXHq+qKtjWIKjLDItZAEpvLI3Jd3Nf9cJgS+qiyCfijh9Z9y24ts +FgcYFPVxbDMsv4nEPdHDRw9rwx0AJzLSw4XofrBiw3uEYvUbV+zJQSxzNa2hPAGd +IJEADr8Ou1JLg5HgH7qVyx94ifeOKocBOoO3RhTMP6lOJN0cJ3E= +=bv2c +-----END PGP SIGNATURE----- diff --git a/tomcat-9.0-CVE-2021-30640.patch b/tomcat-9.0-CVE-2021-30640.patch deleted file mode 100644 index fd19e88..0000000 --- a/tomcat-9.0-CVE-2021-30640.patch +++ /dev/null @@ -1,2666 +0,0 @@ -Index: apache-tomcat-9.0.43-src/build.properties.default -=================================================================== ---- apache-tomcat-9.0.43-src.orig/build.properties.default -+++ apache-tomcat-9.0.43-src/build.properties.default -@@ -244,6 +244,15 @@ objenesis.home=${base.path}/objenesis-${ - objenesis.jar=${objenesis.home}/objenesis-${objenesis.version}.jar - objenesis.loc=${base-maven.loc}/org/objenesis/objenesis/${objenesis.version}/objenesis-${objenesis.version}.jar - -+# ----- UnboundID, used by unit tests, version 5.1.4 or later ----- -+unboundid.version=5.1.4 -+unboundid.checksum.enabled=true -+unboundid.checksum.algorithm=SHA-512 -+unboundid.checksum.value=04cf7f59eddebdd5b51e5be55021f9d9c667cca6101eac954e7a8d5b51f4c23372cd8f041640157f082435a166b75d85e79252b516130ede7d966dae6d3eae67 -+unboundid.home=${base.path}/unboundid-${unboundid.version} -+unboundid.jar=${unboundid.home}/unboundid-ldapsdk-${unboundid.version}.jar -+unboundid.loc=${base-maven.loc}/com/unboundid/unboundid-ldapsdk/${unboundid.version}/unboundid-ldapsdk-${unboundid.version}.jar -+ - # ----- Checkstyle, version 6.16 or later ----- - checkstyle.version=8.22 - checkstyle.checksum.enabled=true -Index: apache-tomcat-9.0.43-src/build.xml -=================================================================== ---- apache-tomcat-9.0.43-src.orig/build.xml -+++ apache-tomcat-9.0.43-src/build.xml -@@ -3164,6 +3164,15 @@ skip.installer property in build.propert - - - -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - connectionPool = null; - -- - /** - * The pool size limit. If 1, pooling is not used. - */ - protected int connectionPoolSize = 1; - -- - /** - * Whether to use context ClassLoader or default ClassLoader. - * True means use context ClassLoader, and True is the default -@@ -504,37 +476,35 @@ public class JNDIRealm extends RealmBase - return forceDnHexEscape; - } - -+ - public void setForceDnHexEscape(boolean forceDnHexEscape) { - this.forceDnHexEscape = forceDnHexEscape; - } - -+ - /** - * @return the type of authentication to use. - */ - public String getAuthentication() { -- - return authentication; -- - } - -+ - /** - * Set the type of authentication to use. - * - * @param authentication The authentication - */ - public void setAuthentication(String authentication) { -- - this.authentication = authentication; -- - } - -+ - /** - * @return the connection username for this Realm. - */ - public String getConnectionName() { -- - return this.connectionName; -- - } - - -@@ -544,9 +514,7 @@ public class JNDIRealm extends RealmBase - * @param connectionName The new connection username - */ - public void setConnectionName(String connectionName) { -- - this.connectionName = connectionName; -- - } - - -@@ -554,9 +522,7 @@ public class JNDIRealm extends RealmBase - * @return the connection password for this Realm. - */ - public String getConnectionPassword() { -- - return this.connectionPassword; -- - } - - -@@ -566,9 +532,7 @@ public class JNDIRealm extends RealmBase - * @param connectionPassword The new connection password - */ - public void setConnectionPassword(String connectionPassword) { -- - this.connectionPassword = connectionPassword; -- - } - - -@@ -576,9 +540,7 @@ public class JNDIRealm extends RealmBase - * @return the connection URL for this Realm. - */ - public String getConnectionURL() { -- - return this.connectionURL; -- - } - - -@@ -588,9 +550,7 @@ public class JNDIRealm extends RealmBase - * @param connectionURL The new connection URL - */ - public void setConnectionURL(String connectionURL) { -- - this.connectionURL = connectionURL; -- - } - - -@@ -598,9 +558,7 @@ public class JNDIRealm extends RealmBase - * @return the JNDI context factory for this Realm. - */ - public String getContextFactory() { -- - return this.contextFactory; -- - } - - -@@ -610,11 +568,10 @@ public class JNDIRealm extends RealmBase - * @param contextFactory The new context factory - */ - public void setContextFactory(String contextFactory) { -- - this.contextFactory = contextFactory; -- - } - -+ - /** - * @return the derefAliases setting to be used. - */ -@@ -622,33 +579,32 @@ public class JNDIRealm extends RealmBase - return derefAliases; - } - -+ - /** - * Set the value for derefAliases to be used when searching the directory. - * - * @param derefAliases New value of property derefAliases. - */ - public void setDerefAliases(java.lang.String derefAliases) { -- this.derefAliases = derefAliases; -+ this.derefAliases = derefAliases; - } - -+ - /** - * @return the protocol to be used. - */ - public String getProtocol() { -- - return protocol; -- - } - -+ - /** - * Set the protocol for this Realm. - * - * @param protocol The new protocol. - */ - public void setProtocol(String protocol) { -- - this.protocol = protocol; -- - } - - -@@ -692,9 +648,7 @@ public class JNDIRealm extends RealmBase - * @return the base element for user searches. - */ - public String getUserBase() { -- - return this.userBase; -- - } - - -@@ -704,9 +658,7 @@ public class JNDIRealm extends RealmBase - * @param userBase The new base element - */ - public void setUserBase(String userBase) { -- - this.userBase = userBase; -- - } - - -@@ -714,9 +666,7 @@ public class JNDIRealm extends RealmBase - * @return the message format pattern for selecting users in this Realm. - */ - public String getUserSearch() { -- - return this.userSearch; -- - } - - -@@ -745,9 +695,7 @@ public class JNDIRealm extends RealmBase - * @return the "search subtree for users" flag. - */ - public boolean getUserSubtree() { -- - return this.userSubtree; -- - } - - -@@ -757,9 +705,7 @@ public class JNDIRealm extends RealmBase - * @param userSubtree The new search flag - */ - public void setUserSubtree(boolean userSubtree) { -- - this.userSubtree = userSubtree; -- - } - - -@@ -767,7 +713,6 @@ public class JNDIRealm extends RealmBase - * @return the user role name attribute name for this Realm. - */ - public String getUserRoleName() { -- - return userRoleName; - } - -@@ -778,9 +723,7 @@ public class JNDIRealm extends RealmBase - * @param userRoleName The new userRole name attribute name - */ - public void setUserRoleName(String userRoleName) { -- - this.userRoleName = userRoleName; -- - } - - -@@ -788,9 +731,7 @@ public class JNDIRealm extends RealmBase - * @return the base element for role searches. - */ - public String getRoleBase() { -- - return this.roleBase; -- - } - - -@@ -809,9 +750,7 @@ public class JNDIRealm extends RealmBase - * @return the role name attribute name for this Realm. - */ - public String getRoleName() { -- - return this.roleName; -- - } - - -@@ -821,9 +760,7 @@ public class JNDIRealm extends RealmBase - * @param roleName The new role name attribute name - */ - public void setRoleName(String roleName) { -- - this.roleName = roleName; -- - } - - -@@ -831,9 +768,7 @@ public class JNDIRealm extends RealmBase - * @return the message format pattern for selecting roles in this Realm. - */ - public String getRoleSearch() { -- - return this.roleSearch; -- - } - - -@@ -862,9 +797,7 @@ public class JNDIRealm extends RealmBase - * @return the "search subtree for roles" flag. - */ - public boolean getRoleSubtree() { -- - return this.roleSubtree; -- - } - - -@@ -874,18 +807,15 @@ public class JNDIRealm extends RealmBase - * @param roleSubtree The new search flag - */ - public void setRoleSubtree(boolean roleSubtree) { -- - this.roleSubtree = roleSubtree; -- - } - -+ - /** - * @return the "The nested group search flag" flag. - */ - public boolean getRoleNested() { -- - return this.roleNested; -- - } - - -@@ -895,9 +825,7 @@ public class JNDIRealm extends RealmBase - * @param roleNested The nested group search flag - */ - public void setRoleNested(boolean roleNested) { -- - this.roleNested = roleNested; -- - } - - -@@ -905,9 +833,7 @@ public class JNDIRealm extends RealmBase - * @return the password attribute used to retrieve the user password. - */ - public String getUserPassword() { -- - return this.userPassword; -- - } - - -@@ -917,9 +843,7 @@ public class JNDIRealm extends RealmBase - * @param userPassword The new password attribute - */ - public void setUserPassword(String userPassword) { -- - this.userPassword = userPassword; -- - } - - -@@ -927,6 +851,7 @@ public class JNDIRealm extends RealmBase - return userRoleAttribute; - } - -+ - public void setUserRoleAttribute(String userRoleAttribute) { - this.userRoleAttribute = userRoleAttribute; - } -@@ -935,14 +860,10 @@ public class JNDIRealm extends RealmBase - * @return the message format pattern for selecting users in this Realm. - */ - public String getUserPattern() { -- - return this.userPattern; -- - } - - -- -- - /** - * Set the message format pattern for selecting users in this Realm. - * This may be one simple pattern, or multiple patterns to be tried, -@@ -970,9 +891,7 @@ public class JNDIRealm extends RealmBase - * @return Value of property alternateURL. - */ - public String getAlternateURL() { -- - return this.alternateURL; -- - } - - -@@ -982,9 +901,7 @@ public class JNDIRealm extends RealmBase - * @param alternateURL New value of property alternateURL. - */ - public void setAlternateURL(String alternateURL) { -- - this.alternateURL = alternateURL; -- - } - - -@@ -992,9 +909,7 @@ public class JNDIRealm extends RealmBase - * @return the common role - */ - public String getCommonRole() { -- - return commonRole; -- - } - - -@@ -1004,9 +919,7 @@ public class JNDIRealm extends RealmBase - * @param commonRole The common role - */ - public void setCommonRole(String commonRole) { -- - this.commonRole = commonRole; -- - } - - -@@ -1014,9 +927,7 @@ public class JNDIRealm extends RealmBase - * @return the connection timeout. - */ - public String getConnectionTimeout() { -- - return connectionTimeout; -- - } - - -@@ -1026,18 +937,15 @@ public class JNDIRealm extends RealmBase - * @param timeout The new connection timeout - */ - public void setConnectionTimeout(String timeout) { -- - this.connectionTimeout = timeout; -- - } - -+ - /** - * @return the read timeout. - */ - public String getReadTimeout() { -- - return readTimeout; -- - } - - -@@ -1047,9 +955,7 @@ public class JNDIRealm extends RealmBase - * @param timeout The new read timeout - */ - public void setReadTimeout(String timeout) { -- - this.readTimeout = timeout; -- - } - - -@@ -1077,6 +983,7 @@ public class JNDIRealm extends RealmBase - return useDelegatedCredential; - } - -+ - public void setUseDelegatedCredential(boolean useDelegatedCredential) { - this.useDelegatedCredential = useDelegatedCredential; - } -@@ -1086,6 +993,7 @@ public class JNDIRealm extends RealmBase - return spnegoDelegationQop; - } - -+ - public void setSpnegoDelegationQop(String spnegoDelegationQop) { - this.spnegoDelegationQop = spnegoDelegationQop; - } -@@ -1098,6 +1006,7 @@ public class JNDIRealm extends RealmBase - return useStartTls; - } - -+ - /** - * Flag whether StartTLS should be used when connecting to the ldap server - * -@@ -1109,6 +1018,7 @@ public class JNDIRealm extends RealmBase - this.useStartTls = useStartTls; - } - -+ - /** - * @return list of the allowed cipher suites when connections are made using - * StartTLS -@@ -1128,6 +1038,7 @@ public class JNDIRealm extends RealmBase - return this.cipherSuitesArray; - } - -+ - /** - * Set the allowed cipher suites when opening a connection using StartTLS. - * The cipher suites are expected as a comma separated list. -@@ -1139,6 +1050,7 @@ public class JNDIRealm extends RealmBase - this.cipherSuites = suites; - } - -+ - /** - * @return the connection pool size, or the default value 1 if pooling - * is disabled -@@ -1147,6 +1059,7 @@ public class JNDIRealm extends RealmBase - return connectionPoolSize; - } - -+ - /** - * Set the connection pool size - * @param connectionPoolSize the new pool size -@@ -1155,6 +1068,7 @@ public class JNDIRealm extends RealmBase - this.connectionPoolSize = connectionPoolSize; - } - -+ - /** - * @return name of the {@link HostnameVerifier} class used for connections - * using StartTLS, or the empty string, if the default verifier -@@ -1167,6 +1081,7 @@ public class JNDIRealm extends RealmBase - return this.hostnameVerifier.getClass().getCanonicalName(); - } - -+ - /** - * Set the {@link HostnameVerifier} to be used when opening connections - * using StartTLS. An instance of the given class name will be constructed -@@ -1183,6 +1098,7 @@ public class JNDIRealm extends RealmBase - } - } - -+ - /** - * @return the {@link HostnameVerifier} to use for peer certificate - * verification when opening connections using StartTLS. -@@ -1191,8 +1107,7 @@ public class JNDIRealm extends RealmBase - if (this.hostnameVerifier != null) { - return this.hostnameVerifier; - } -- if (this.hostNameVerifierClassName == null -- || hostNameVerifierClassName.equals("")) { -+ if (this.hostNameVerifierClassName == null || hostNameVerifierClassName.equals("")) { - return null; - } - try { -@@ -1212,6 +1127,7 @@ public class JNDIRealm extends RealmBase - } - } - -+ - /** - * Set the {@link SSLSocketFactory} to be used when opening connections - * using StartTLS. An instance of the factory with the given name will be -@@ -1225,6 +1141,7 @@ public class JNDIRealm extends RealmBase - this.sslSocketFactoryClassName = factoryClassName; - } - -+ - /** - * Set the ssl protocol to be used for connections using StartTLS. - * -@@ -1235,6 +1152,7 @@ public class JNDIRealm extends RealmBase - this.sslProtocol = protocol; - } - -+ - /** - * @return the list of supported ssl protocols by the default - * {@link SSLContext} -@@ -1248,12 +1166,14 @@ public class JNDIRealm extends RealmBase - } - } - -+ - private Object constructInstance(String className) - throws ReflectiveOperationException { - Class clazz = Class.forName(className); - return clazz.getConstructor().newInstance(); - } - -+ - /** - * Sets whether to use the context or default ClassLoader. - * True means use context ClassLoader. -@@ -1264,6 +1184,7 @@ public class JNDIRealm extends RealmBase - useContextClassLoader = useContext; - } - -+ - /** - * Returns whether to use the context or default ClassLoader. - * True means to use the context ClassLoader. -@@ -1274,6 +1195,7 @@ public class JNDIRealm extends RealmBase - return useContextClassLoader; - } - -+ - // ---------------------------------------------------------- Realm Methods - - /** -@@ -1333,7 +1255,7 @@ public class JNDIRealm extends RealmBase - closePooledConnections(); - - // open a new directory context. -- connection = get(); -+ connection = get(true); - - // Try the authentication again. - principal = authenticate(connection, username, credentials); -@@ -1356,21 +1278,14 @@ public class JNDIRealm extends RealmBase - closePooledConnections(); - - // Return "not authenticated" for this request -- if (containerLog.isDebugEnabled()) -+ if (containerLog.isDebugEnabled()) { - containerLog.debug("Returning null principal."); -+ } - return null; -- - } -- - } - - -- // -------------------------------------------------------- Package Methods -- -- -- // ------------------------------------------------------ Protected Methods -- -- - /** - * Return the Principal associated with the specified username and - * credentials, if there is one; otherwise return null. -@@ -1383,22 +1298,18 @@ public class JNDIRealm extends RealmBase - * - * @exception NamingException if a directory server error occurs - */ -- public Principal authenticate(JNDIConnection connection, -- String username, -- String credentials) -- throws NamingException { -- -- if (username == null || username.equals("") -- || credentials == null || credentials.equals("")) { -- if (containerLog.isDebugEnabled()) -+ public Principal authenticate(JNDIConnection connection, String username, String credentials) -+ throws NamingException { -+ -+ if (username == null || username.equals("") || credentials == null || credentials.equals("")) { -+ if (containerLog.isDebugEnabled()) { - containerLog.debug("username null or empty: returning null principal."); -+ } - return null; - } - - if (userPatternArray != null) { -- for (int curUserPattern = 0; -- curUserPattern < userPatternArray.length; -- curUserPattern++) { -+ for (int curUserPattern = 0; curUserPattern < userPatternArray.length; curUserPattern++) { - // Retrieve user information - User user = getUser(connection, username, credentials, curUserPattern); - if (user != null) { -@@ -1426,12 +1337,14 @@ public class JNDIRealm extends RealmBase - } else { - // Retrieve user information - User user = getUser(connection, username, credentials); -- if (user == null) -+ if (user == null) { - return null; -+ } - - // Check the user's credentials -- if (!checkCredentials(connection.context, user, credentials)) -+ if (!checkCredentials(connection.context, user, credentials)) { - return null; -+ } - - // Search for additional roles - List roles = getRoles(connection, user); -@@ -1445,6 +1358,8 @@ public class JNDIRealm extends RealmBase - } - - -+ // ------------------------------------------------------ Protected Methods -+ - /** - * Return a User object containing information about the user - * with the specified username, if found in the directory; -@@ -1457,9 +1372,7 @@ public class JNDIRealm extends RealmBase - * - * @see #getUser(JNDIConnection, String, String, int) - */ -- protected User getUser(JNDIConnection connection, String username) -- throws NamingException { -- -+ protected User getUser(JNDIConnection connection, String username) throws NamingException { - return getUser(connection, username, null, -1); - } - -@@ -1477,9 +1390,7 @@ public class JNDIRealm extends RealmBase - * - * @see #getUser(JNDIConnection, String, String, int) - */ -- protected User getUser(JNDIConnection connection, String username, String credentials) -- throws NamingException { -- -+ protected User getUser(JNDIConnection connection, String username, String credentials) throws NamingException { - return getUser(connection, username, credentials, -1); - } - -@@ -1502,18 +1413,19 @@ public class JNDIRealm extends RealmBase - * @return the User object - * @exception NamingException if a directory server error occurs - */ -- protected User getUser(JNDIConnection connection, String username, -- String credentials, int curUserPattern) -- throws NamingException { -+ protected User getUser(JNDIConnection connection, String username, String credentials, int curUserPattern) -+ throws NamingException { - - User user = null; - - // Get attributes to retrieve from user entry - List list = new ArrayList<>(); -- if (userPassword != null) -+ if (userPassword != null) { - list.add(userPassword); -- if (userRoleName != null) -+ } -+ if (userRoleName != null) { - list.add(userRoleName); -+ } - if (userRoleAttribute != null) { - list.add(userRoleAttribute); - } -@@ -1545,8 +1457,7 @@ public class JNDIRealm extends RealmBase - if (userPassword == null && credentials != null && user != null) { - // The password is available. Insert it since it may be required for - // role searches. -- return new User(user.getUserName(), user.getDN(), credentials, -- user.getRoles(), user.getUserRoleId()); -+ return new User(user.getUserName(), user.getDN(), credentials, user.getRoles(), user.getUserRoleId()); - } - - return user; -@@ -1566,11 +1477,8 @@ public class JNDIRealm extends RealmBase - * @return the User object - * @exception NamingException if a directory server error occurs - */ -- protected User getUserByPattern(DirContext context, -- String username, -- String[] attrIds, -- String dn) -- throws NamingException { -+ protected User getUserByPattern(DirContext context, String username, String[] attrIds, String dn) -+ throws NamingException { - - // If no attributes are requested, no need to look for them - if (attrIds == null || attrIds.length == 0) { -@@ -1584,13 +1492,15 @@ public class JNDIRealm extends RealmBase - } catch (NameNotFoundException e) { - return null; - } -- if (attrs == null) -+ if (attrs == null) { - return null; -+ } - - // Retrieve value of userPassword - String password = null; -- if (userPassword != null) -+ if (userPassword != null) { - password = getAttributeValue(userPassword, attrs); -+ } - - String userRoleAttrValue = null; - if (userRoleAttribute != null) { -@@ -1599,8 +1509,9 @@ public class JNDIRealm extends RealmBase - - // Retrieve values of userRoleName attribute - ArrayList roles = null; -- if (userRoleName != null) -+ if (userRoleName != null) { - roles = addAttributeValues(userRoleName, attrs, roles); -+ } - - return new User(username, dn, password, roles, userRoleAttrValue); - } -@@ -1621,20 +1532,20 @@ public class JNDIRealm extends RealmBase - * @exception NamingException if a directory server error occurs - * @see #getUserByPattern(DirContext, String, String[], String) - */ -- protected User getUserByPattern(JNDIConnection connection, -- String username, -- String credentials, -- String[] attrIds, -- int curUserPattern) -- throws NamingException { -+ protected User getUserByPattern(JNDIConnection connection, String username, String credentials, String[] attrIds, -+ int curUserPattern) throws NamingException { - - User user = null; - -- if (username == null || userPatternArray[curUserPattern] == null) -+ if (username == null || userPatternArray[curUserPattern] == null) { - return null; -+ } - -- // Form the dn from the user pattern -- String dn = connection.userPatternFormatArray[curUserPattern].format(new String[] { username }); -+ // Form the DistinguishedName from the user pattern. -+ // Escape in case username contains a character with special meaning in -+ // an attribute value. -+ String dn = connection.userPatternFormatArray[curUserPattern].format( -+ new String[] { doAttributeValueEscaping(username) }); - - try { - user = getUserByPattern(connection.context, username, attrIds, dn); -@@ -1666,16 +1577,17 @@ public class JNDIRealm extends RealmBase - * @return the User object - * @exception NamingException if a directory server error occurs - */ -- protected User getUserBySearch(JNDIConnection connection, -- String username, -- String[] attrIds) -- throws NamingException { -+ protected User getUserBySearch(JNDIConnection connection, String username, String[] attrIds) -+ throws NamingException { - -- if (username == null || connection.userSearchFormat == null) -+ if (username == null || connection.userSearchFormat == null) { - return null; -+ } - - // Form the search filter -- String filter = connection.userSearchFormat.format(new String[] { username }); -+ // Escape in case username contains a character with special meaning in -+ // a search filter. -+ String filter = connection.userSearchFormat.format(new String[] { doFilterEscaping(username) }); - - // Set up the search controls - SearchControls constraints = new SearchControls(); -@@ -1690,12 +1602,12 @@ public class JNDIRealm extends RealmBase - constraints.setTimeLimit(timeLimit); - - // Specify the attributes to be retrieved -- if (attrIds == null) -+ if (attrIds == null) { - attrIds = new String[0]; -+ } - constraints.setReturningAttributes(attrIds); - -- NamingEnumeration results = -- connection.context.search(userBase, filter, constraints); -+ NamingEnumeration results = connection.context.search(userBase, filter, constraints); - - try { - // Fail if no entries found -@@ -1704,10 +1616,11 @@ public class JNDIRealm extends RealmBase - return null; - } - } catch (PartialResultException ex) { -- if (!adCompat) -+ if (!adCompat) { - throw ex; -- else -+ } else { - return null; -+ } - } - - // Get result for the first entry found -@@ -1722,24 +1635,28 @@ public class JNDIRealm extends RealmBase - return null; - } - } catch (PartialResultException ex) { -- if (!adCompat) -+ if (!adCompat) { - throw ex; -+ } - } - - String dn = getDistinguishedName(connection.context, userBase, result); - -- if (containerLog.isTraceEnabled()) -+ if (containerLog.isTraceEnabled()) { - containerLog.trace(" entry found for " + username + " with dn " + dn); -+ } - - // Get the entry's attributes - Attributes attrs = result.getAttributes(); -- if (attrs == null) -+ if (attrs == null) { - return null; -+ } - - // Retrieve value of userPassword - String password = null; -- if (userPassword != null) -+ if (userPassword != null) { - password = getAttributeValue(userPassword, attrs); -+ } - - String userRoleAttrValue = null; - if (userRoleAttribute != null) { -@@ -1748,8 +1665,9 @@ public class JNDIRealm extends RealmBase - - // Retrieve values of userRoleName attribute - ArrayList roles = null; -- if (userRoleName != null) -+ if (userRoleName != null) { - roles = addAttributeValues(userRoleName, attrs, roles); -+ } - - return new User(username, dn, password, roles, userRoleAttrValue); - } finally { -@@ -1775,30 +1693,25 @@ public class JNDIRealm extends RealmBase - * @return true if the credentials are validated - * @exception NamingException if a directory server error occurs - */ -- protected boolean checkCredentials(DirContext context, -- User user, -- String credentials) -- throws NamingException { -- -- boolean validated = false; -- -- if (userPassword == null) { -- validated = bindAsUser(context, user, credentials); -- } else { -- validated = compareCredentials(context, user, credentials); -- } -- -- if (containerLog.isTraceEnabled()) { -- if (validated) { -- containerLog.trace(sm.getString("jndiRealm.authenticateSuccess", -- user.getUserName())); -- } else { -- containerLog.trace(sm.getString("jndiRealm.authenticateFailure", -- user.getUserName())); -- } -- } -- return validated; -- } -+ protected boolean checkCredentials(DirContext context, User user, String credentials) throws NamingException { -+ -+ boolean validated = false; -+ -+ if (userPassword == null) { -+ validated = bindAsUser(context, user, credentials); -+ } else { -+ validated = compareCredentials(context, user, credentials); -+ } -+ -+ if (containerLog.isTraceEnabled()) { -+ if (validated) { -+ containerLog.trace(sm.getString("jndiRealm.authenticateSuccess", user.getUserName())); -+ } else { -+ containerLog.trace(sm.getString("jndiRealm.authenticateFailure", user.getUserName())); -+ } -+ } -+ return validated; -+ } - - - /** -@@ -1811,17 +1724,15 @@ public class JNDIRealm extends RealmBase - * @return true if the credentials are validated - * @exception NamingException if a directory server error occurs - */ -- protected boolean compareCredentials(DirContext context, -- User info, -- String credentials) -- throws NamingException { -- -+ protected boolean compareCredentials(DirContext context, User info, String credentials) throws NamingException { - // Validate the credentials specified by the user -- if (containerLog.isTraceEnabled()) -+ if (containerLog.isTraceEnabled()) { - containerLog.trace(" validating credentials"); -+ } - -- if (info == null || credentials == null) -+ if (info == null || credentials == null) { - return false; -+ } - - String password = info.getPassword(); - -@@ -1838,21 +1749,22 @@ public class JNDIRealm extends RealmBase - * @return true if the credentials are validated - * @exception NamingException if a directory server error occurs - */ -- protected boolean bindAsUser(DirContext context, -- User user, -- String credentials) -- throws NamingException { -- -- if (credentials == null || user == null) -- return false; -- -- String dn = user.getDN(); -- if (dn == null) -- return false; -- -- // Validate the credentials specified by the user -- if (containerLog.isTraceEnabled()) { -- containerLog.trace(" validating credentials by binding as the user"); -+ protected boolean bindAsUser(DirContext context, User user, String credentials) throws NamingException { -+ -+ if (credentials == null || user == null) { -+ return false; -+ } -+ -+ // This is returned from the directory so will be attribute value -+ // escaped if required -+ String dn = user.getDN(); -+ if (dn == null) { -+ return false; -+ } -+ -+ // Validate the credentials specified by the user -+ if (containerLog.isTraceEnabled()) { -+ containerLog.trace(" validating credentials by binding as the user"); - } - - userCredentialsAdd(context, dn, credentials); -@@ -1877,48 +1789,47 @@ public class JNDIRealm extends RealmBase - return validated; - } - -- /** -- * Configure the context to use the provided credentials for -- * authentication. -- * -- * @param context DirContext to configure -- * @param dn Distinguished name of user -- * @param credentials Credentials of user -- * @exception NamingException if a directory server error occurs -- */ -- private void userCredentialsAdd(DirContext context, String dn, -- String credentials) throws NamingException { -+ -+ /** -+ * Configure the context to use the provided credentials for -+ * authentication. -+ * -+ * @param context DirContext to configure -+ * @param dn Distinguished name of user -+ * @param credentials Credentials of user -+ * @exception NamingException if a directory server error occurs -+ */ -+ private void userCredentialsAdd(DirContext context, String dn, String credentials) throws NamingException { - // Set up security environment to bind as the user - context.addToEnvironment(Context.SECURITY_PRINCIPAL, dn); - context.addToEnvironment(Context.SECURITY_CREDENTIALS, credentials); - } - -+ - /** - * Configure the context to use {@link #connectionName} and - * {@link #connectionPassword} if specified or an anonymous connection if - * those attributes are not specified. - * -- * @param context DirContext to configure -- * @exception NamingException if a directory server error occurs -+ * @param context DirContext to configure -+ * @exception NamingException if a directory server error occurs - */ -- private void userCredentialsRemove(DirContext context) -- throws NamingException { -+ private void userCredentialsRemove(DirContext context) throws NamingException { - // Restore the original security environment - if (connectionName != null) { -- context.addToEnvironment(Context.SECURITY_PRINCIPAL, -- connectionName); -+ context.addToEnvironment(Context.SECURITY_PRINCIPAL, connectionName); - } else { - context.removeFromEnvironment(Context.SECURITY_PRINCIPAL); - } - - if (connectionPassword != null) { -- context.addToEnvironment(Context.SECURITY_CREDENTIALS, -- connectionPassword); -+ context.addToEnvironment(Context.SECURITY_CREDENTIALS, connectionPassword); - } else { - context.removeFromEnvironment(Context.SECURITY_CREDENTIALS); - } - } - -+ - /** - * Return a List of roles associated with the given User. Any - * roles present in the user's directory entry are supplemented by -@@ -1930,21 +1841,27 @@ public class JNDIRealm extends RealmBase - * @return the list of role names - * @exception NamingException if a directory server error occurs - */ -- protected List getRoles(JNDIConnection connection, User user) -- throws NamingException { -+ protected List getRoles(JNDIConnection connection, User user) throws NamingException { - -- if (user == null) -+ if (user == null) { - return null; -+ } - -+ // This is returned from the directory so will be attribute value -+ // escaped if required - String dn = user.getDN(); -+ // This is the name the user provided to the authentication process so -+ // it will not be escaped - String username = user.getUserName(); - String userRoleId = user.getUserRoleId(); - -- if (dn == null || username == null) -+ if (dn == null || username == null) { - return null; -+ } - -- if (containerLog.isTraceEnabled()) -+ if (containerLog.isTraceEnabled()) { - containerLog.trace(" getRoles(" + dn + ")"); -+ } - - // Start with roles retrieved from the user entry - List list = new ArrayList<>(); -@@ -1952,8 +1869,9 @@ public class JNDIRealm extends RealmBase - if (userRoles != null) { - list.addAll(userRoles); - } -- if (commonRole != null) -+ if (commonRole != null) { - list.add(commonRole); -+ } - - if (containerLog.isTraceEnabled()) { - containerLog.trace(" Found " + list.size() + " user internal roles"); -@@ -1961,16 +1879,23 @@ public class JNDIRealm extends RealmBase - } - - // Are we configured to do role searches? -- if ((connection.roleFormat == null) || (roleName == null)) -+ if ((connection.roleFormat == null) || (roleName == null)) { - return list; -+ } - -- // Set up parameters for an appropriate search -- String filter = connection.roleFormat.format(new String[] { doRFC2254Encoding(dn), username, userRoleId }); -+ // Set up parameters for an appropriate search filter -+ // The dn is already attribute value escaped but the others are not -+ // This is a filter so all input will require filter escaping -+ String filter = connection.roleFormat.format(new String[] { -+ doFilterEscaping(dn), -+ doFilterEscaping(doAttributeValueEscaping(username)), -+ doFilterEscaping(doAttributeValueEscaping(userRoleId)) }); - SearchControls controls = new SearchControls(); -- if (roleSubtree) -+ if (roleSubtree) { - controls.setSearchScope(SearchControls.SUBTREE_SCOPE); -- else -+ } else { - controls.setSearchScope(SearchControls.ONELEVEL_SCOPE); -+ } - controls.setReturningAttributes(new String[] {roleName}); - - String base = null; -@@ -1979,7 +1904,9 @@ public class JNDIRealm extends RealmBase - Name name = np.parse(dn); - String nameParts[] = new String[name.size()]; - for (int i = 0; i < name.size(); i++) { -- nameParts[i] = name.get(i); -+ // May have been returned with \ escaping rather than -+ // \. Make sure it is \. -+ nameParts[i] = convertToHexEscape(name.get(i)); - } - base = connection.roleBaseFormat.format(nameParts); - } else { -@@ -1990,25 +1917,28 @@ public class JNDIRealm extends RealmBase - NamingEnumeration results = searchAsUser(connection.context, user, base, filter, controls, - isRoleSearchAsUser()); - -- if (results == null) -+ if (results == null) { - return list; // Should never happen, but just in case ... -+ } - - Map groupMap = new HashMap<>(); - try { - while (results.hasMore()) { - SearchResult result = results.next(); - Attributes attrs = result.getAttributes(); -- if (attrs == null) -+ if (attrs == null) { - continue; -- String dname = getDistinguishedName(connection.context, roleBase, result); -+ } -+ String dname = getDistinguishedName(connection.context, base, result); - String name = getAttributeValue(roleName, attrs); - if (name != null && dname != null) { - groupMap.put(dname, name); - } - } - } catch (PartialResultException ex) { -- if (!adCompat) -+ if (!adCompat) { - throw ex; -+ } - } finally { - results.close(); - } -@@ -2033,22 +1963,28 @@ public class JNDIRealm extends RealmBase - Map newThisRound = new HashMap<>(); // Stores the groups we find in this iteration - - for (Entry group : newGroups.entrySet()) { -- filter = connection.roleFormat.format(new String[] { doRFC2254Encoding(group.getKey()), -- group.getValue(), group.getValue() }); -+ // Group key is already value escaped if required -+ // Group value is not value escaped -+ // Everything needs to be filter escaped -+ filter = connection.roleFormat.format(new String[] { -+ doFilterEscaping(group.getKey()), -+ doFilterEscaping(doAttributeValueEscaping(group.getValue())), -+ doFilterEscaping(doAttributeValueEscaping(group.getValue())) }); - - if (containerLog.isTraceEnabled()) { -- containerLog.trace("Perform a nested group search with base "+ roleBase + " and filter " + filter); -+ containerLog.trace("Perform a nested group search with base "+ roleBase + -+ " and filter " + filter); - } - -- results = searchAsUser(connection.context, user, roleBase, filter, controls, -- isRoleSearchAsUser()); -+ results = searchAsUser(connection.context, user, base, filter, controls, isRoleSearchAsUser()); - - try { - while (results.hasMore()) { - SearchResult result = results.next(); - Attributes attrs = result.getAttributes(); -- if (attrs == null) -+ if (attrs == null) { - continue; -+ } - String dname = getDistinguishedName(connection.context, roleBase, result); - String name = getAttributeValue(roleName, attrs); - if (name != null && dname != null && !groupMap.keySet().contains(dname)) { -@@ -2058,12 +1994,12 @@ public class JNDIRealm extends RealmBase - if (containerLog.isTraceEnabled()) { - containerLog.trace(" Found nested role " + dname + " -> " + name); - } -- - } -- } -+ } - } catch (PartialResultException ex) { -- if (!adCompat) -+ if (!adCompat) { - throw ex; -+ } - } finally { - results.close(); - } -@@ -2077,6 +2013,7 @@ public class JNDIRealm extends RealmBase - return list; - } - -+ - /** - * Perform the search on the context as the {@code dn}, when - * {@code searchAsUser} is {@code true}, otherwise search the context with -@@ -2099,8 +2036,7 @@ public class JNDIRealm extends RealmBase - * @throws NamingException - * if a directory server error occurs - */ -- private NamingEnumeration searchAsUser(DirContext context, -- User user, String base, String filter, -+ private NamingEnumeration searchAsUser(DirContext context, User user, String base, String filter, - SearchControls controls, boolean searchAsUser) throws NamingException { - NamingEnumeration results; - try { -@@ -2125,26 +2061,30 @@ public class JNDIRealm extends RealmBase - * @return the attribute value - * @exception NamingException if a directory server error occurs - */ -- private String getAttributeValue(String attrId, Attributes attrs) -- throws NamingException { -+ private String getAttributeValue(String attrId, Attributes attrs) throws NamingException { - -- if (containerLog.isTraceEnabled()) -+ if (containerLog.isTraceEnabled()) { - containerLog.trace(" retrieving attribute " + attrId); -+ } - -- if (attrId == null || attrs == null) -+ if (attrId == null || attrs == null) { - return null; -+ } - - Attribute attr = attrs.get(attrId); -- if (attr == null) -+ if (attr == null) { - return null; -+ } - Object value = attr.get(); -- if (value == null) -+ if (value == null) { - return null; -+ } - String valueString = null; -- if (value instanceof byte[]) -+ if (value instanceof byte[]) { - valueString = new String((byte[]) value); -- else -+ } else { - valueString = value.toString(); -+ } - - return valueString; - } -@@ -2159,20 +2099,22 @@ public class JNDIRealm extends RealmBase - * @return the list of attribute values - * @exception NamingException if a directory server error occurs - */ -- private ArrayList addAttributeValues(String attrId, -- Attributes attrs, -- ArrayList values) -- throws NamingException{ -+ private ArrayList addAttributeValues(String attrId, Attributes attrs, ArrayList values) -+ throws NamingException { - -- if (containerLog.isTraceEnabled()) -+ if (containerLog.isTraceEnabled()) { - containerLog.trace(" retrieving values for attribute " + attrId); -- if (attrId == null || attrs == null) -+ } -+ if (attrId == null || attrs == null) { - return values; -- if (values == null) -+ } -+ if (values == null) { - values = new ArrayList<>(); -+ } - Attribute attr = attrs.get(attrId); -- if (attr == null) -+ if (attr == null) { - return values; -+ } - NamingEnumeration e = attr.getAll(); - try { - while(e.hasMore()) { -@@ -2180,8 +2122,9 @@ public class JNDIRealm extends RealmBase - values.add(value); - } - } catch (PartialResultException ex) { -- if (!adCompat) -+ if (!adCompat) { - throw ex; -+ } - } finally { - e.close(); - } -@@ -2214,8 +2157,9 @@ public class JNDIRealm extends RealmBase - } - // Close our opened connection - try { -- if (containerLog.isDebugEnabled()) -+ if (containerLog.isDebugEnabled()) { - containerLog.debug("Closing directory context"); -+ } - connection.context.close(); - } catch (NamingException e) { - containerLog.error(sm.getString("jndiRealm.close"), e); -@@ -2225,9 +2169,9 @@ public class JNDIRealm extends RealmBase - if (connectionPool == null) { - singleConnectionLock.unlock(); - } -- - } - -+ - /** - * Close all pooled connections. - */ -@@ -2243,6 +2187,7 @@ public class JNDIRealm extends RealmBase - } - } - -+ - /** - * Get the password for the specified user. - * @param username The user name -@@ -2258,7 +2203,6 @@ public class JNDIRealm extends RealmBase - JNDIConnection connection = null; - User user = null; - try { -- - // Ensure that we have a directory context available - connection = get(); - -@@ -2281,7 +2225,6 @@ public class JNDIRealm extends RealmBase - user = getUser(connection, username, null); - } - -- - // Release this context - release(connection); - -@@ -2292,15 +2235,14 @@ public class JNDIRealm extends RealmBase - // ... and have a password - return user.getPassword(); - } -- - } catch (NamingException e) { - // Log the problem for posterity - containerLog.error(sm.getString("jndiRealm.exception"), e); - return null; - } -- - } - -+ - /** - * Get the principal associated with the specified certificate. - * @param username The user name -@@ -2311,9 +2253,9 @@ public class JNDIRealm extends RealmBase - return getPrincipal(username, null); - } - -+ - @Override -- protected Principal getPrincipal(GSSName gssName, -- GSSCredential gssCredential) { -+ protected Principal getPrincipal(GSSName gssName, GSSCredential gssCredential) { - String name = gssName.toString(); - - if (isStripRealmForGss()) { -@@ -2327,15 +2269,14 @@ public class JNDIRealm extends RealmBase - return getPrincipal(name, gssCredential); - } - -+ - @Override -- protected Principal getPrincipal(String username, -- GSSCredential gssCredential) { -+ protected Principal getPrincipal(String username, GSSCredential gssCredential) { - - JNDIConnection connection = null; - Principal principal = null; - - try { -- - // Ensure that we have a directory context available - connection = get(); - -@@ -2347,7 +2288,6 @@ public class JNDIRealm extends RealmBase - principal = getPrincipal(connection, username, gssCredential); - - } catch (CommunicationException | ServiceUnavailableException e) { -- - // log the exception so we know it's there. - containerLog.info(sm.getString("jndiRealm.exception.retry"), e); - -@@ -2360,10 +2300,8 @@ public class JNDIRealm extends RealmBase - - // Try the authentication again. - principal = getPrincipal(connection, username, gssCredential); -- - } - -- - // Release this context - release(connection); - -@@ -2371,16 +2309,12 @@ public class JNDIRealm extends RealmBase - return principal; - - } catch (NamingException e) { -- - // Log the problem for posterity - containerLog.error(sm.getString("jndiRealm.exception"), e); - - // Return "not authenticated" for this request - return null; -- - } -- -- - } - - -@@ -2392,9 +2326,8 @@ public class JNDIRealm extends RealmBase - * @return the Principal associated with the given certificate. - * @exception NamingException if a directory server error occurs - */ -- protected Principal getPrincipal(JNDIConnection connection, -- String username, GSSCredential gssCredential) -- throws NamingException { -+ protected Principal getPrincipal(JNDIConnection connection, String username, GSSCredential gssCredential) -+ throws NamingException { - - User user = null; - List roles = null; -@@ -2406,12 +2339,9 @@ public class JNDIRealm extends RealmBase - // Preserve the current context environment parameters - preservedEnvironment = context.getEnvironment(); - // Set up context -- context.addToEnvironment( -- Context.SECURITY_AUTHENTICATION, "GSSAPI"); -- context.addToEnvironment( -- "javax.security.sasl.server.authentication", "true"); -- context.addToEnvironment( -- "javax.security.sasl.qop", spnegoDelegationQop); -+ context.addToEnvironment(Context.SECURITY_AUTHENTICATION, "GSSAPI"); -+ context.addToEnvironment("javax.security.sasl.server.authentication", "true"); -+ context.addToEnvironment("javax.security.sasl.qop", spnegoDelegationQop); - // Note: Subject already set in SPNEGO authenticator so no need - // for Subject.doAs() here - } -@@ -2421,23 +2351,20 @@ public class JNDIRealm extends RealmBase - } - } finally { - if (gssCredential != null && isUseDelegatedCredential()) { -- restoreEnvironmentParameter(context, -- Context.SECURITY_AUTHENTICATION, preservedEnvironment); -- restoreEnvironmentParameter(context, -- "javax.security.sasl.server.authentication", preservedEnvironment); -- restoreEnvironmentParameter(context, "javax.security.sasl.qop", -- preservedEnvironment); -+ restoreEnvironmentParameter(context, Context.SECURITY_AUTHENTICATION, preservedEnvironment); -+ restoreEnvironmentParameter(context, "javax.security.sasl.server.authentication", preservedEnvironment); -+ restoreEnvironmentParameter(context, "javax.security.sasl.qop", preservedEnvironment); - } - } - - if (user != null) { -- return new GenericPrincipal(user.getUserName(), user.getPassword(), -- roles, null, null, gssCredential); -+ return new GenericPrincipal(user.getUserName(), user.getPassword(), roles, null, null, gssCredential); - } - - return null; - } - -+ - private void restoreEnvironmentParameter(DirContext context, - String parameterName, Hashtable preservedEnvironment) { - try { -@@ -2451,6 +2378,7 @@ public class JNDIRealm extends RealmBase - } - } - -+ - /** - * Open (if necessary) and return a connection to the configured - * directory server for this Realm. -@@ -2458,12 +2386,28 @@ public class JNDIRealm extends RealmBase - * @exception NamingException if a directory server error occurs - */ - protected JNDIConnection get() throws NamingException { -+ return get(false); -+ } -+ -+ /** -+ * Open (if necessary) and return a connection to the configured -+ * directory server for this Realm. -+ * @param create when pooling, this forces creation of a new connection, -+ * for example after an error -+ * @return the connection -+ * @exception NamingException if a directory server error occurs -+ */ -+ protected JNDIConnection get(boolean create) throws NamingException { - JNDIConnection connection = null; - // Use the pool if available, otherwise use the single connection - if (connectionPool != null) { -- connection = connectionPool.pop(); -- if (connection == null) { -+ if (create) { - connection = create(); -+ } else { -+ connection = connectionPool.pop(); -+ if (connection == null) { -+ connection = create(); -+ } - } - } else { - singleConnectionLock.lock(); -@@ -2475,6 +2419,7 @@ public class JNDIRealm extends RealmBase - return connection; - } - -+ - /** - * Release our use of this connection so that it can be recycled. - * -@@ -2491,6 +2436,7 @@ public class JNDIRealm extends RealmBase - } - } - -+ - /** - * Create a new connection wrapper, along with the - * message formats. -@@ -2505,8 +2451,7 @@ public class JNDIRealm extends RealmBase - int len = userPatternArray.length; - connection.userPatternFormatArray = new MessageFormat[len]; - for (int i = 0; i < len; i++) { -- connection.userPatternFormatArray[i] = -- new MessageFormat(userPatternArray[i]); -+ connection.userPatternFormatArray[i] = new MessageFormat(userPatternArray[i]); - } - } - if (roleBase != null) { -@@ -2518,6 +2463,7 @@ public class JNDIRealm extends RealmBase - return connection; - } - -+ - /** - * Create a new connection to the directory server. - * @param connection The directory server connection wrapper -@@ -2552,12 +2498,14 @@ public class JNDIRealm extends RealmBase - } - } - -+ - @Override - public boolean isAvailable() { - // Simple best effort check - return (connectionPool != null || singleConnection.context != null); - } - -+ - private DirContext createDirContext(Hashtable env) throws NamingException { - if (useStartTls) { - return createTlsDirContext(env); -@@ -2566,13 +2514,13 @@ public class JNDIRealm extends RealmBase - } - } - -+ - private SSLSocketFactory getSSLSocketFactory() { - if (sslSocketFactory != null) { - return sslSocketFactory; - } - final SSLSocketFactory result; -- if (this.sslSocketFactoryClassName != null -- && !sslSocketFactoryClassName.trim().equals("")) { -+ if (this.sslSocketFactoryClassName != null && !sslSocketFactoryClassName.trim().equals("")) { - result = createSSLSocketFactoryFromClassName(this.sslSocketFactoryClassName); - } else { - result = createSSLContextFactoryFromProtocol(sslProtocol); -@@ -2581,6 +2529,7 @@ public class JNDIRealm extends RealmBase - return result; - } - -+ - private SSLSocketFactory createSSLSocketFactoryFromClassName(String className) { - try { - Object o = constructInstance(className); -@@ -2598,6 +2547,7 @@ public class JNDIRealm extends RealmBase - } - } - -+ - private SSLSocketFactory createSSLContextFactoryFromProtocol(String protocol) { - try { - SSLContext sslContext; -@@ -2609,14 +2559,13 @@ public class JNDIRealm extends RealmBase - } - return sslContext.getSocketFactory(); - } catch (NoSuchAlgorithmException | KeyManagementException e) { -- List allowedProtocols = Arrays -- .asList(getSupportedSslProtocols()); -- throw new IllegalArgumentException( -- sm.getString("jndiRealm.invalidSslProtocol", protocol, -- allowedProtocols), e); -+ List allowedProtocols = Arrays.asList(getSupportedSslProtocols()); -+ throw new IllegalArgumentException(sm.getString("jndiRealm.invalidSslProtocol", -+ protocol, allowedProtocols), e); - } - } - -+ - /** - * Create a tls enabled LdapContext and set the StartTlsResponse tls - * instance variable. -@@ -2627,12 +2576,10 @@ public class JNDIRealm extends RealmBase - * @throws NamingException - * when something goes wrong while negotiating the connection - */ -- private DirContext createTlsDirContext( -- Hashtable env) throws NamingException { -+ private DirContext createTlsDirContext(Hashtable env) throws NamingException { - Map savedEnv = new HashMap<>(); -- for (String key : Arrays.asList(Context.SECURITY_AUTHENTICATION, -- Context.SECURITY_CREDENTIALS, Context.SECURITY_PRINCIPAL, -- Context.SECURITY_PROTOCOL)) { -+ for (String key : Arrays.asList(Context.SECURITY_AUTHENTICATION, Context.SECURITY_CREDENTIALS, -+ Context.SECURITY_PRINCIPAL, Context.SECURITY_PROTOCOL)) { - Object entry = env.remove(key); - if (entry != null) { - savedEnv.put(key, entry); -@@ -2641,8 +2588,7 @@ public class JNDIRealm extends RealmBase - LdapContext result = null; - try { - result = new InitialLdapContext(env, null); -- tls = (StartTlsResponse) result -- .extendedOperation(new StartTlsRequest()); -+ tls = (StartTlsResponse) result.extendedOperation(new StartTlsRequest()); - if (getHostnameVerifier() != null) { - tls.setHostnameVerifier(getHostnameVerifier()); - } -@@ -2651,22 +2597,21 @@ public class JNDIRealm extends RealmBase - } - try { - SSLSession negotiate = tls.negotiate(getSSLSocketFactory()); -- containerLog.debug(sm.getString("jndiRealm.negotiatedTls", -- negotiate.getProtocol())); -+ containerLog.debug(sm.getString("jndiRealm.negotiatedTls", negotiate.getProtocol())); - } catch (IOException e) { - throw new NamingException(e.getMessage()); - } - } finally { - if (result != null) { - for (Map.Entry savedEntry : savedEnv.entrySet()) { -- result.addToEnvironment(savedEntry.getKey(), -- savedEntry.getValue()); -+ result.addToEnvironment(savedEntry.getKey(), savedEntry.getValue()); - } - } - } - return result; - } - -+ - /** - * Create our directory context configuration. - * -@@ -2677,40 +2622,48 @@ public class JNDIRealm extends RealmBase - Hashtable env = new Hashtable<>(); - - // Configure our directory context environment. -- if (containerLog.isDebugEnabled() && connectionAttempt == 0) -+ if (containerLog.isDebugEnabled() && connectionAttempt == 0) { - containerLog.debug("Connecting to URL " + connectionURL); -- else if (containerLog.isDebugEnabled() && connectionAttempt > 0) -+ } else if (containerLog.isDebugEnabled() && connectionAttempt > 0) { - containerLog.debug("Connecting to URL " + alternateURL); -+ } - env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory); -- if (connectionName != null) -+ if (connectionName != null) { - env.put(Context.SECURITY_PRINCIPAL, connectionName); -- if (connectionPassword != null) -+ } -+ if (connectionPassword != null) { - env.put(Context.SECURITY_CREDENTIALS, connectionPassword); -- if (connectionURL != null && connectionAttempt == 0) -+ } -+ if (connectionURL != null && connectionAttempt == 0) { - env.put(Context.PROVIDER_URL, connectionURL); -- else if (alternateURL != null && connectionAttempt > 0) -+ } else if (alternateURL != null && connectionAttempt > 0) { - env.put(Context.PROVIDER_URL, alternateURL); -- if (authentication != null) -+ } -+ if (authentication != null) { - env.put(Context.SECURITY_AUTHENTICATION, authentication); -- if (protocol != null) -+ } -+ if (protocol != null) { - env.put(Context.SECURITY_PROTOCOL, protocol); -- if (referrals != null) -+ } -+ if (referrals != null) { - env.put(Context.REFERRAL, referrals); -- if (derefAliases != null) -+ } -+ if (derefAliases != null) { - env.put(JNDIRealm.DEREF_ALIASES, derefAliases); -- if (connectionTimeout != null) -+ } -+ if (connectionTimeout != null) { - env.put("com.sun.jndi.ldap.connect.timeout", connectionTimeout); -- if (readTimeout != null) -+ } -+ if (readTimeout != null) { - env.put("com.sun.jndi.ldap.read.timeout", readTimeout); -+ } - - return env; -- - } - - - // ------------------------------------------------------ Lifecycle Methods - -- - /** - * Prepare for the beginning of active use of the public methods of this - * component and implement the requirements of -@@ -2752,7 +2705,7 @@ public class JNDIRealm extends RealmBase - * @exception LifecycleException if this component detects a fatal error - * that needs to be reported - */ -- @Override -+ @Override - protected void stopInternal() throws LifecycleException { - super.stopInternal(); - // Close any open directory server connection -@@ -2765,6 +2718,7 @@ public class JNDIRealm extends RealmBase - } - } - -+ - /** - * Given a string containing LDAP patterns for user locations (separated by - * parentheses in a pseudo-LDAP search string format - -@@ -2799,8 +2753,7 @@ public class JNDIRealm extends RealmBase - while (userPatternString.charAt(endParenLoc - 1) == '\\') { - endParenLoc = userPatternString.indexOf(')', endParenLoc+1); - } -- String nextPathPart = userPatternString.substring -- (startParenLoc+1, endParenLoc); -+ String nextPathPart = userPatternString.substring(startParenLoc+1, endParenLoc); - pathList.add(nextPathPart); - startingPoint = endParenLoc+1; - startParenLoc = userPatternString.indexOf('(', startingPoint); -@@ -2808,7 +2761,6 @@ public class JNDIRealm extends RealmBase - return pathList.toArray(new String[] {}); - } - return null; -- - } - - -@@ -2823,10 +2775,36 @@ public class JNDIRealm extends RealmBase - * ) -> \29 - * \ -> \5c - * \0 -> \00 -+ * - * @param inString string to escape according to RFC 2254 guidelines -+ * - * @return String the escaped/encoded result -+ * -+ * @deprecated Will be removed in Tomcat 10.1.x onwards - */ -+ @Deprecated - protected String doRFC2254Encoding(String inString) { -+ return doFilterEscaping(inString); -+ } -+ -+ -+ /** -+ * Given an LDAP search string, returns the string with certain characters -+ * escaped according to RFC 2254 guidelines. -+ * The character mapping is as follows: -+ * char -> Replacement -+ * --------------------------- -+ * * -> \2a -+ * ( -> \28 -+ * ) -> \29 -+ * \ -> \5c -+ * \0 -> \00 -+ * -+ * @param inString string to escape according to RFC 2254 guidelines -+ * -+ * @return String the escaped/encoded result -+ */ -+ protected String doFilterEscaping(String inString) { - StringBuilder buf = new StringBuilder(inString.length()); - for (int i = 0; i < inString.length(); i++) { - char c = inString.charAt(i); -@@ -2864,47 +2842,42 @@ public class JNDIRealm extends RealmBase - * @return String containing the distinguished name - * @exception NamingException if a directory server error occurs - */ -- protected String getDistinguishedName(DirContext context, String base, -- SearchResult result) throws NamingException { -+ protected String getDistinguishedName(DirContext context, String base, SearchResult result) throws NamingException { - // Get the entry's distinguished name. For relative results, this means - // we need to composite a name with the base name, the context name, and - // the result name. For non-relative names, use the returned name. - String resultName = result.getName(); - Name name; - if (result.isRelative()) { -- if (containerLog.isTraceEnabled()) { -- containerLog.trace(" search returned relative name: " + resultName); -- } -- NameParser parser = context.getNameParser(""); -- Name contextName = parser.parse(context.getNameInNamespace()); -- Name baseName = parser.parse(base); -+ if (containerLog.isTraceEnabled()) { -+ containerLog.trace(" search returned relative name: " + resultName); -+ } -+ NameParser parser = context.getNameParser(""); -+ Name contextName = parser.parse(context.getNameInNamespace()); -+ Name baseName = parser.parse(base); - -- // Bugzilla 32269 -- Name entryName = parser.parse(new CompositeName(resultName).get(0)); -+ // Bugzilla 32269 -+ Name entryName = parser.parse(new CompositeName(resultName).get(0)); - -- name = contextName.addAll(baseName); -- name = name.addAll(entryName); -+ name = contextName.addAll(baseName); -+ name = name.addAll(entryName); - } else { -- if (containerLog.isTraceEnabled()) { -- containerLog.trace(" search returned absolute name: " + resultName); -- } -- try { -- // Normalize the name by running it through the name parser. -- NameParser parser = context.getNameParser(""); -- URI userNameUri = new URI(resultName); -- String pathComponent = userNameUri.getPath(); -- // Should not ever have an empty path component, since that is /{DN} -- if (pathComponent.length() < 1 ) { -- throw new InvalidNameException( -- "Search returned unparseable absolute name: " + -- resultName ); -- } -- name = parser.parse(pathComponent.substring(1)); -- } catch ( URISyntaxException e ) { -- throw new InvalidNameException( -- "Search returned unparseable absolute name: " + -- resultName ); -- } -+ if (containerLog.isTraceEnabled()) { -+ containerLog.trace(" search returned absolute name: " + resultName); -+ } -+ try { -+ // Normalize the name by running it through the name parser. -+ NameParser parser = context.getNameParser(""); -+ URI userNameUri = new URI(resultName); -+ String pathComponent = userNameUri.getPath(); -+ // Should not ever have an empty path component, since that is /{DN} -+ if (pathComponent.length() < 1 ) { -+ throw new InvalidNameException("Search returned unparseable absolute name: " + resultName); -+ } -+ name = parser.parse(pathComponent.substring(1)); -+ } catch ( URISyntaxException e ) { -+ throw new InvalidNameException("Search returned unparseable absolute name: " + resultName); -+ } - } - - if (getForceDnHexEscape()) { -@@ -2916,6 +2889,78 @@ public class JNDIRealm extends RealmBase - } - - -+ /** -+ * Implements the necessary escaping to represent an attribute value as a -+ * String as per RFC 4514. -+ * -+ * @param input The original attribute value -+ * @return The string representation of the attribute value -+ */ -+ protected String doAttributeValueEscaping(String input) { -+ int len = input.length(); -+ StringBuilder result = new StringBuilder(); -+ -+ for (int i = 0; i < len; i++) { -+ char c = input.charAt(i); -+ switch (c) { -+ case ' ': { -+ if (i == 0 || i == (len -1)) { -+ result.append("\\20"); -+ } else { -+ result.append(c); -+ } -+ break; -+ } -+ case '#': { -+ if (i == 0 ) { -+ result.append("\\23"); -+ } else { -+ result.append(c); -+ } -+ break; -+ } -+ case '\"': { -+ result.append("\\22"); -+ break; -+ } -+ case '+': { -+ result.append("\\2B"); -+ break; -+ } -+ case ',': { -+ result.append("\\2C"); -+ break; -+ } -+ case ';': { -+ result.append("\\3B"); -+ break; -+ } -+ case '<': { -+ result.append("\\3C"); -+ break; -+ } -+ case '>': { -+ result.append("\\3E"); -+ break; -+ } -+ case '\\': { -+ result.append("\\5C"); -+ break; -+ } -+ case '\u0000': { -+ result.append("\\00"); -+ break; -+ } -+ default: -+ result.append(c); -+ } -+ -+ } -+ -+ return result.toString(); -+ } -+ -+ - protected static String convertToHexEscape(String input) { - if (input.indexOf('\\') == -1) { - // No escaping present. Return original. -@@ -2992,7 +3037,7 @@ public class JNDIRealm extends RealmBase - } - - -- // ------------------------------------------------------ Private Classes -+ // ------------------------------------------------------ Protected Classes - - /** - * A protected class representing a User -@@ -3005,9 +3050,7 @@ public class JNDIRealm extends RealmBase - private final List roles; - private final String userRoleId; - -- -- public User(String username, String dn, String password, -- List roles, String userRoleId) { -+ public User(String username, String dn, String password, List roles, String userRoleId) { - this.username = username; - this.dn = dn; - this.password = password; -@@ -3040,6 +3083,7 @@ public class JNDIRealm extends RealmBase - } - } - -+ - /** - * Class holding the connection to the directory plus the associated - * non thread safe message formats. -@@ -3074,8 +3118,5 @@ public class JNDIRealm extends RealmBase - * The directory context linking us to our directory server. - */ - protected DirContext context = null; -- - } -- - } -- -Index: apache-tomcat-9.0.43-src/test/org/apache/catalina/realm/TestJNDIRealmAttributeValueEscape.java -=================================================================== ---- /dev/null -+++ apache-tomcat-9.0.43-src/test/org/apache/catalina/realm/TestJNDIRealmAttributeValueEscape.java -@@ -0,0 +1,88 @@ -+ -+@@ -0,0 +1,86 @@ -+/* -+ * 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.realm; -+ -+import java.util.ArrayList; -+import java.util.Collection; -+import java.util.List; -+ -+import org.junit.Assert; -+import org.junit.Test; -+import org.junit.runner.RunWith; -+import org.junit.runners.Parameterized; -+import org.junit.runners.Parameterized.Parameter; -+ -+@RunWith(Parameterized.class) -+public class TestJNDIRealmAttributeValueEscape { -+ -+ @Parameterized.Parameters(name = "{index}: in[{0}], out[{1}]") -+ public static Collection parameters() { -+ List parameterSets = new ArrayList<>(); -+ -+ // No escaping required -+ parameterSets.add(new String[] { "none", "none" }); -+ // Simple cases (same order as RFC 4512 section 2) -+ // Each appearing at the beginning, middle and ent -+ parameterSets.add(new String[] { " test", "\\20test" }); -+ parameterSets.add(new String[] { "te st", "te st" }); -+ parameterSets.add(new String[] { "test ", "test\\20" }); -+ parameterSets.add(new String[] { "#test", "\\23test" }); -+ parameterSets.add(new String[] { "te#st", "te#st" }); -+ parameterSets.add(new String[] { "test#", "test#" }); -+ parameterSets.add(new String[] { "\"test", "\\22test" }); -+ parameterSets.add(new String[] { "te\"st", "te\\22st" }); -+ parameterSets.add(new String[] { "test\"", "test\\22" }); -+ parameterSets.add(new String[] { "+test", "\\2Btest" }); -+ parameterSets.add(new String[] { "te+st", "te\\2Bst" }); -+ parameterSets.add(new String[] { "test+", "test\\2B" }); -+ parameterSets.add(new String[] { ",test", "\\2Ctest" }); -+ parameterSets.add(new String[] { "te,st", "te\\2Cst" }); -+ parameterSets.add(new String[] { "test,", "test\\2C" }); -+ parameterSets.add(new String[] { ";test", "\\3Btest" }); -+ parameterSets.add(new String[] { "te;st", "te\\3Bst" }); -+ parameterSets.add(new String[] { "test;", "test\\3B" }); -+ parameterSets.add(new String[] { "test", "\\3Etest" }); -+ parameterSets.add(new String[] { "te>st", "te\\3Est" }); -+ parameterSets.add(new String[] { "test>", "test\\3E" }); -+ parameterSets.add(new String[] { "\\test", "\\5Ctest" }); -+ parameterSets.add(new String[] { "te\\st", "te\\5Cst" }); -+ parameterSets.add(new String[] { "test\\", "test\\5C" }); -+ parameterSets.add(new String[] { "\u0000test", "\\00test" }); -+ parameterSets.add(new String[] { "te\u0000st", "te\\00st" }); -+ parameterSets.add(new String[] { "test\u0000", "test\\00" }); -+ return parameterSets; -+ } -+ -+ -+ @Parameter(0) -+ public String in; -+ @Parameter(1) -+ public String out; -+ -+ private JNDIRealm realm = new JNDIRealm(); -+ -+ @Test -+ public void testConvertToHexEscape() throws Exception { -+ String result = realm.doAttributeValueEscaping(in); -+ Assert.assertEquals(out, result); -+ } -+} -Index: apache-tomcat-9.0.43-src/test/org/apache/catalina/realm/TestJNDIRealmIntegration.java -=================================================================== ---- /dev/null -+++ apache-tomcat-9.0.43-src/test/org/apache/catalina/realm/TestJNDIRealmIntegration.java -@@ -0,0 +1,263 @@ -+/* -+ * 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.realm; -+ -+import java.util.ArrayList; -+import java.util.Arrays; -+import java.util.Collection; -+import java.util.HashSet; -+import java.util.List; -+import java.util.Set; -+ -+import org.junit.AfterClass; -+import org.junit.Assert; -+import org.junit.BeforeClass; -+import org.junit.Test; -+import org.junit.runner.RunWith; -+import org.junit.runners.Parameterized; -+import org.junit.runners.Parameterized.Parameter; -+ -+import org.apache.juli.logging.LogFactory; -+ -+import com.unboundid.ldap.listener.InMemoryDirectoryServer; -+import com.unboundid.ldap.listener.InMemoryDirectoryServerConfig; -+import com.unboundid.ldap.sdk.AddRequest; -+import com.unboundid.ldap.sdk.LDAPConnection; -+import com.unboundid.ldap.sdk.LDAPResult; -+import com.unboundid.ldap.sdk.ResultCode; -+ -+@RunWith(Parameterized.class) -+public class TestJNDIRealmIntegration { -+ -+ private static final String USER_PATTERN = "cn={0},ou=people,dc=example,dc=com"; -+ private static final String USER_SEARCH = "cn={0}"; -+ private static final String USER_BASE = "ou=people,dc=example,dc=com"; -+ private static final String ROLE_SEARCH_A = "member={0}"; -+ private static final String ROLE_SEARCH_B = "member=cn={1},ou=people,dc=example,dc=com"; -+ private static final String ROLE_SEARCH_C = "member=cn={2},ou=people,dc=example,dc=com"; -+ private static final String ROLE_BASE = "ou=people,dc=example,dc=com"; -+ -+ private static InMemoryDirectoryServer ldapServer; -+ -+ @Parameterized.Parameters(name = "{index}: user[{5}], pwd[{6}]") -+ public static Collection parameters() { -+ List parameterSets = new ArrayList<>(); -+ for (String roleSearch : new String[] { ROLE_SEARCH_A, ROLE_SEARCH_B, ROLE_SEARCH_C }) { -+ addUsers(USER_PATTERN, null, null, roleSearch, ROLE_BASE, parameterSets); -+ addUsers(null, USER_SEARCH, USER_BASE, roleSearch, ROLE_BASE, parameterSets); -+ } -+ parameterSets.add(new Object[] { "cn={0},ou=s\\;ub,ou=people,dc=example,dc=com", null, null, ROLE_SEARCH_A, -+ "{3},ou=people,dc=example,dc=com", "testsub", "test", new String[] {"TestGroup4"} }); -+ return parameterSets; -+ } -+ -+ -+ private static void addUsers(String userPattern, String userSearch, String userBase, String roleSearch, -+ String roleBase, List parameterSets) { -+ parameterSets.add(new Object[] { userPattern, userSearch, userBase, roleSearch, roleBase, -+ "test", "test", new String[] {"TestGroup"} }); -+ parameterSets.add(new Object[] { userPattern, userSearch, userBase, roleSearch, roleBase, -+ "t;", "test", new String[] {"TestGroup"} }); -+ parameterSets.add(new Object[] { userPattern, userSearch, userBase, roleSearch, roleBase, -+ "t*", "test", new String[] {"TestGroup"} }); -+ parameterSets.add(new Object[] { userPattern, userSearch, userBase, roleSearch, roleBase, -+ "t=", "test", new String[] {"TestGroup*3"} }); -+ } -+ -+ -+ @Parameter(0) -+ public String realmConfigUserPattern; -+ @Parameter(1) -+ public String realmConfigUserSearch; -+ @Parameter(2) -+ public String realmConfigUserBase; -+ @Parameter(3) -+ public String realmConfigRoleSearch; -+ @Parameter(4) -+ public String realmConfigRoleBase; -+ @Parameter(5) -+ public String username; -+ @Parameter(6) -+ public String credentials; -+ @Parameter(7) -+ public String[] groups; -+ -+ @Test -+ public void testAuthenication() throws Exception { -+ JNDIRealm realm = new JNDIRealm(); -+ realm.containerLog = LogFactory.getLog(TestJNDIRealmIntegration.class); -+ -+ realm.setConnectionURL("ldap://localhost:" + ldapServer.getListenPort()); -+ realm.setUserPattern(realmConfigUserPattern); -+ realm.setUserSearch(realmConfigUserSearch); -+ realm.setUserBase(realmConfigUserBase); -+ realm.setUserRoleAttribute("cn"); -+ realm.setRoleName("cn"); -+ realm.setRoleBase(realmConfigRoleBase); -+ realm.setRoleSearch(realmConfigRoleSearch); -+ realm.setRoleNested(true); -+ -+ GenericPrincipal p = (GenericPrincipal) realm.authenticate(username, credentials); -+ -+ Assert.assertNotNull(p); -+ Assert.assertEquals(username, p.name); -+ -+ Set actualGroups = new HashSet<>(Arrays.asList(p.getRoles())); -+ Set expectedGroups = new HashSet<>(Arrays.asList(groups)); -+ -+ Assert.assertEquals(expectedGroups.size(), actualGroups.size()); -+ Set tmp = new HashSet<>(); -+ tmp.addAll(expectedGroups); -+ tmp.removeAll(actualGroups); -+ Assert.assertEquals(0, tmp.size()); -+ } -+ -+ -+ @BeforeClass -+ public static void createLDAP() throws Exception { -+ InMemoryDirectoryServerConfig config = new InMemoryDirectoryServerConfig("dc=example,dc=com"); -+ config.addAdditionalBindCredentials("cn=admin", "password"); -+ ldapServer = new InMemoryDirectoryServer(config); -+ -+ ldapServer.startListening(); -+ -+ try (LDAPConnection conn = ldapServer.getConnection()) { -+ -+ // Note: Only the DNs need attribute value escaping -+ AddRequest addBase = new AddRequest( -+ "dn: dc=example,dc=com", -+ "objectClass: top", -+ "objectClass: domain", -+ "dc: example"); -+ LDAPResult result = conn.processOperation(addBase); -+ Assert.assertEquals(ResultCode.SUCCESS, result.getResultCode()); -+ -+ AddRequest addPeople = new AddRequest( -+ "dn: ou=people,dc=example,dc=com", -+ "objectClass: top", -+ "objectClass: organizationalUnit"); -+ result = conn.processOperation(addPeople); -+ Assert.assertEquals(ResultCode.SUCCESS, result.getResultCode()); -+ -+ AddRequest addUserTest = new AddRequest( -+ "dn: cn=test,ou=people,dc=example,dc=com", -+ "objectClass: top", -+ "objectClass: person", -+ "objectClass: organizationalPerson", -+ "cn: test", -+ "sn: Test", -+ "userPassword: test"); -+ result = conn.processOperation(addUserTest); -+ Assert.assertEquals(ResultCode.SUCCESS, result.getResultCode()); -+ -+ AddRequest addUserTestSemicolon = new AddRequest( -+ "dn: cn=t\\;,ou=people,dc=example,dc=com", -+ "objectClass: top", -+ "objectClass: person", -+ "objectClass: organizationalPerson", -+ "cn: t;", -+ "sn: Tsemicolon", -+ "userPassword: test"); -+ result = conn.processOperation(addUserTestSemicolon); -+ Assert.assertEquals(ResultCode.SUCCESS, result.getResultCode()); -+ -+ AddRequest addUserTestAsterisk = new AddRequest( -+ "dn: cn=t*,ou=people,dc=example,dc=com", -+ "objectClass: top", -+ "objectClass: person", -+ "objectClass: organizationalPerson", -+ "cn: t*", -+ "sn: Tasterisk", -+ "userPassword: test"); -+ result = conn.processOperation(addUserTestAsterisk); -+ Assert.assertEquals(ResultCode.SUCCESS, result.getResultCode()); -+ -+ AddRequest addUserTestEquals = new AddRequest( -+ "dn: cn=t\\=,ou=people,dc=example,dc=com", -+ "objectClass: top", -+ "objectClass: person", -+ "objectClass: organizationalPerson", -+ "cn: t=", -+ "sn: Tequals", -+ "userPassword: test"); -+ result = conn.processOperation(addUserTestEquals); -+ Assert.assertEquals(ResultCode.SUCCESS, result.getResultCode()); -+ -+ AddRequest addGroupTest = new AddRequest( -+ "dn: cn=TestGroup,ou=people,dc=example,dc=com", -+ "objectClass: top", -+ "objectClass: groupOfNames", -+ "cn: TestGroup", -+ "member: cn=test,ou=people,dc=example,dc=com", -+ "member: cn=t\\;,ou=people,dc=example,dc=com", -+ "member: cn=t\\*,ou=people,dc=example,dc=com"); -+ result = conn.processOperation(addGroupTest); -+ Assert.assertEquals(ResultCode.SUCCESS, result.getResultCode()); -+ -+ AddRequest addGroupTest2 = new AddRequest( -+ "dn: cn=Test\\Group*3,ou=people,dc=example,dc=com", -+ "objectClass: top", -+ "objectClass: groupOfNames", -+ "cn: Test>Group*3", -+ "member: cn=Test\\65106: Fix the ConfigFileLoader handling of file URIs when - running under a security manager on some JREs. (markt) - -+ -+ Expand coverage of unit tests for JNDIRealm using the UnboundID LDAP SDK -+ for Java. (markt) -+ - - - -@@ -576,6 +580,11 @@ - JRE bug. - (markt) - -+ -+ Fix JNDIRealm pooling problems retrying on another bad connection. Any -+ retries are made on a new connection, just like with the single -+ connection scenario. (remm) -+ - - - diff --git a/tomcat-9.0-CVE-2021-33037.patch b/tomcat-9.0-CVE-2021-33037.patch deleted file mode 100644 index 193d404..0000000 --- a/tomcat-9.0-CVE-2021-33037.patch +++ /dev/null @@ -1,195 +0,0 @@ -Index: apache-tomcat-9.0.43-src/java/org/apache/coyote/http11/Http11Processor.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/coyote/http11/Http11Processor.java -+++ apache-tomcat-9.0.43-src/java/org/apache/coyote/http11/Http11Processor.java -@@ -212,11 +212,8 @@ public class Http11Processor extends Abs - - // Parsing trims and converts to lower case. - -- if (encodingName.equals("identity")) { -- // Skip -- } else if (encodingName.equals("chunked")) { -- inputBuffer.addActiveFilter -- (inputFilters[Constants.CHUNKED_FILTER]); -+ if (encodingName.equals("chunked")) { -+ inputBuffer.addActiveFilter(inputFilters[Constants.CHUNKED_FILTER]); - contentDelimitation = true; - } else { - for (int i = pluggableFilterIndex; i < inputFilters.length; i++) { -@@ -753,13 +750,14 @@ public class Http11Processor extends Abs - InputFilter[] inputFilters = inputBuffer.getFilters(); - - // Parse transfer-encoding header -- if (http11) { -+ // HTTP specs say an HTTP 1.1 server should accept any recognised -+ // HTTP 1.x header from a 1.x client unless the specs says otherwise. -+ if (!http09) { - MessageBytes transferEncodingValueMB = headers.getValue("transfer-encoding"); - if (transferEncodingValueMB != null) { - List encodingNames = new ArrayList<>(); - if (TokenList.parseTokenList(headers.values("transfer-encoding"), encodingNames)) { - for (String encodingName : encodingNames) { -- // "identity" codings are ignored - addInputFilter(inputFilters, encodingName); - } - } else { -Index: apache-tomcat-9.0.43-src/test/org/apache/coyote/http11/TestHttp11Processor.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/test/org/apache/coyote/http11/TestHttp11Processor.java -+++ apache-tomcat-9.0.43-src/test/org/apache/coyote/http11/TestHttp11Processor.java -@@ -254,31 +254,6 @@ public class TestHttp11Processor extends - - - @Test -- public void testWithTEIdentity() throws Exception { -- getTomcatInstanceTestWebapp(false, true); -- -- String request = -- "POST /test/echo-params.jsp HTTP/1.1" + SimpleHttpClient.CRLF + -- "Host: any" + SimpleHttpClient.CRLF + -- "Transfer-encoding: identity" + SimpleHttpClient.CRLF + -- "Content-Length: 9" + SimpleHttpClient.CRLF + -- "Content-Type: application/x-www-form-urlencoded" + -- SimpleHttpClient.CRLF + -- "Connection: close" + SimpleHttpClient.CRLF + -- SimpleHttpClient.CRLF + -- "test=data"; -- -- Client client = new Client(getPort()); -- client.setRequest(new String[] {request}); -- -- client.connect(); -- client.processRequest(); -- Assert.assertTrue(client.isResponse200()); -- Assert.assertTrue(client.getResponseBody().contains("test - data")); -- } -- -- -- @Test - public void testWithTESavedRequest() throws Exception { - getTomcatInstanceTestWebapp(false, true); - -@@ -1859,4 +1834,102 @@ public class TestHttp11Processor extends - // NO-OP - } - } -+ -+ -+ @Test -+ public void testTEHeaderUnknown01() throws Exception { -+ doTestTEHeaderUnknown("identity"); -+ } -+ -+ -+ @Test -+ public void testTEHeaderUnknown02() throws Exception { -+ doTestTEHeaderUnknown("identity, chunked"); -+ } -+ -+ -+ @Test -+ public void testTEHeaderUnknown03() throws Exception { -+ doTestTEHeaderUnknown("unknown, chunked"); -+ } -+ -+ -+ @Test -+ public void testTEHeaderUnknown04() throws Exception { -+ doTestTEHeaderUnknown("void"); -+ } -+ -+ -+ @Test -+ public void testTEHeaderUnknown05() throws Exception { -+ doTestTEHeaderUnknown("void, chunked"); -+ } -+ -+ -+ @Test -+ public void testTEHeaderUnknown06() throws Exception { -+ doTestTEHeaderUnknown("void, identity"); -+ } -+ -+ -+ @Test -+ public void testTEHeaderUnknown07() throws Exception { -+ doTestTEHeaderUnknown("identity, void"); -+ } -+ -+ -+ private void doTestTEHeaderUnknown(String headerValue) throws Exception { -+ Tomcat tomcat = getTomcatInstance(); -+ -+ // No file system docBase required -+ Context ctx = tomcat.addContext("", null); -+ -+ // Add servlet -+ Tomcat.addServlet(ctx, "TesterServlet", new TesterServlet(false)); -+ ctx.addServletMappingDecoded("/foo", "TesterServlet"); -+ -+ tomcat.start(); -+ -+ String request = -+ "GET /foo HTTP/1.1" + SimpleHttpClient.CRLF + -+ "Host: localhost:" + getPort() + SimpleHttpClient.CRLF + -+ "Transfer-Encoding: " + headerValue + SimpleHttpClient.CRLF + -+ SimpleHttpClient.CRLF; -+ -+ Client client = new Client(tomcat.getConnector().getLocalPort()); -+ client.setRequest(new String[] {request}); -+ -+ client.connect(); -+ client.processRequest(false); -+ -+ Assert.assertTrue(client.isResponse501()); -+ } -+ -+ -+ @Test -+ public void testWithTEChunkedHttp10() throws Exception { -+ -+ getTomcatInstanceTestWebapp(false, true); -+ -+ String request = -+ "POST /test/echo-params.jsp HTTP/1.0" + SimpleHttpClient.CRLF + -+ "Host: any" + SimpleHttpClient.CRLF + -+ "Transfer-encoding: chunked" + SimpleHttpClient.CRLF + -+ "Content-Type: application/x-www-form-urlencoded" + -+ SimpleHttpClient.CRLF + -+ "Connection: close" + SimpleHttpClient.CRLF + -+ SimpleHttpClient.CRLF + -+ "9" + SimpleHttpClient.CRLF + -+ "test=data" + SimpleHttpClient.CRLF + -+ "0" + SimpleHttpClient.CRLF + -+ SimpleHttpClient.CRLF; -+ -+ Client client = new Client(getPort()); -+ client.setRequest(new String[] {request}); -+ -+ client.connect(); -+ client.processRequest(); -+ Assert.assertTrue(client.isResponse200()); -+ Assert.assertTrue(client.getResponseBody().contains("test - data")); -+ } - } -Index: apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -=================================================================== ---- apache-tomcat-9.0.43-src.orig/webapps/docs/changelog.xml -+++ apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -@@ -347,6 +347,16 @@ - connections are attempted and fail. Patch provided by Maurizio Adami. - (markt) - -+ -+ Remove support for the identity transfer encoding. The -+ inclusion of this encoding in RFC 2616 was an error that was corrected -+ in 2001. Requests using this transfer encoding will now receive a 501 -+ response. (markt) -+ -+ -+ Process transfer encoding headers from both HTTP 1.0 and HTTP 1.1 -+ clients. (markt) -+ - - - diff --git a/tomcat-9.0-CVE-2021-41079.patch b/tomcat-9.0-CVE-2021-41079.patch deleted file mode 100644 index 045c2e9..0000000 --- a/tomcat-9.0-CVE-2021-41079.patch +++ /dev/null @@ -1,55 +0,0 @@ -From d4b340fa8feaf55831f9a59350578f7b6ca048b8 Mon Sep 17 00:00:00 2001 -From: Mark Thomas -Date: Wed, 3 Mar 2021 12:00:46 +0000 -Subject: [PATCH] Improve robustness - ---- - .../apache/tomcat/util/net/openssl/LocalStrings.properties | 1 + - java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java | 6 ++++-- - webapps/docs/changelog.xml | 4 ++++ - 3 files changed, 9 insertions(+), 2 deletions(-) - -Index: apache-tomcat-9.0.43-src/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties -+++ apache-tomcat-9.0.43-src/java/org/apache/tomcat/util/net/openssl/LocalStrings.properties -@@ -17,6 +17,7 @@ engine.ciphersFailure=Failed getting cip - engine.emptyCipherSuite=Empty cipher suite - engine.engineClosed=Engine is closed - engine.failedCipherSuite=Failed to enable cipher suite [{0}] -+engine.failedToReadAvailableBytes=There are plain text bytes available to read but no bytes were read - engine.inboundClose=Inbound closed before receiving peer's close_notify - engine.invalidBufferArray=offset: [{0}], length: [{1}] (expected: offset <= offset + length <= srcs.length [{2}]) - engine.invalidDestinationBuffersState=The state of the destination buffers changed concurrently while unwrapping bytes -Index: apache-tomcat-9.0.43-src/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java -+++ apache-tomcat-9.0.43-src/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java -@@ -592,8 +592,10 @@ public final class OpenSSLEngine extends - throw new SSLException(e); - } - -- if (bytesRead == 0) { -- break; -+ if (bytesRead <= 0) { -+ // This should not be possible. pendingApp is positive -+ // therefore the read should have read at least one byte. -+ throw new IllegalStateException(sm.getString("engine.failedToReadAvailableBytes")); - } - - bytesProduced += bytesRead; -Index: apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -=================================================================== ---- apache-tomcat-9.0.43-src.orig/webapps/docs/changelog.xml -+++ apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -@@ -173,6 +173,10 @@ - the access log file, include information on the current user in the - associated log message (markt) - -+ -+ Make handling of OpenSSL read errors more robust when plain text data is -+ reported to be available to read. (markt) -+ - - - diff --git a/tomcat-9.0-CVE-2022-23181.patch b/tomcat-9.0-CVE-2022-23181.patch deleted file mode 100644 index db05ed5..0000000 --- a/tomcat-9.0-CVE-2022-23181.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 1385c624b4a1e994426e810075c850edc38a700e Mon Sep 17 00:00:00 2001 -From: Mark Thomas -Date: Wed, 12 Jan 2022 11:11:29 +0000 -Subject: [PATCH] Make calculation of session storage location more robust - ---- - java/org/apache/catalina/session/FileStore.java | 5 +++-- - webapps/docs/changelog.xml | 4 ++++ - 2 files changed, 7 insertions(+), 2 deletions(-) - -Index: apache-tomcat-9.0.43-src/java/org/apache/catalina/session/FileStore.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/catalina/session/FileStore.java -+++ apache-tomcat-9.0.43-src/java/org/apache/catalina/session/FileStore.java -@@ -349,13 +349,14 @@ public final class FileStore extends Sto - - String filename = id + FILE_EXT; - File file = new File(storageDir, filename); -+ File canonicalFile = file.getCanonicalFile(); - - // Check the file is within the storage directory -- if (!file.getCanonicalFile().toPath().startsWith(storageDir.getCanonicalFile().toPath())) { -+ if (!canonicalFile.toPath().startsWith(storageDir.getCanonicalFile().toPath())) { - log.warn(sm.getString("fileStore.invalid", file.getPath(), id)); - return null; - } - -- return file; -+ return canonicalFile; - } - } -Index: apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -=================================================================== ---- apache-tomcat-9.0.43-src.orig/webapps/docs/changelog.xml -+++ apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -@@ -118,6 +118,10 @@ - Expand coverage of unit tests for JNDIRealm using the UnboundID LDAP SDK - for Java. (markt) - -+ -+ Make the calculation of the session storage location more robust when -+ using file based persistent storage. (markt) -+ - - - diff --git a/tomcat-9.0-NPE-JNDIRealm.patch b/tomcat-9.0-NPE-JNDIRealm.patch deleted file mode 100644 index 0006866..0000000 --- a/tomcat-9.0-NPE-JNDIRealm.patch +++ /dev/null @@ -1,123 +0,0 @@ -Index: apache-tomcat-9.0.43-src/java/org/apache/catalina/realm/JNDIRealm.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/catalina/realm/JNDIRealm.java -+++ apache-tomcat-9.0.43-src/java/org/apache/catalina/realm/JNDIRealm.java -@@ -2805,6 +2805,9 @@ public class JNDIRealm extends RealmBase - * @return String the escaped/encoded result - */ - protected String doFilterEscaping(String inString) { -+ if (inString == null) { -+ return null; -+ } - StringBuilder buf = new StringBuilder(inString.length()); - for (int i = 0; i < inString.length(); i++) { - char c = inString.charAt(i); -@@ -2897,6 +2900,9 @@ public class JNDIRealm extends RealmBase - * @return The string representation of the attribute value - */ - protected String doAttributeValueEscaping(String input) { -+ if (input == null) { -+ return null; -+ } - int len = input.length(); - StringBuilder result = new StringBuilder(); - -Index: apache-tomcat-9.0.43-src/test/org/apache/catalina/realm/TestJNDIRealmIntegration.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/test/org/apache/catalina/realm/TestJNDIRealmIntegration.java -+++ apache-tomcat-9.0.43-src/test/org/apache/catalina/realm/TestJNDIRealmIntegration.java -@@ -56,26 +56,33 @@ public class TestJNDIRealmIntegration { - @Parameterized.Parameters(name = "{index}: user[{5}], pwd[{6}]") - public static Collection parameters() { - List parameterSets = new ArrayList<>(); -- for (String roleSearch : new String[] { ROLE_SEARCH_A, ROLE_SEARCH_B, ROLE_SEARCH_C }) { -- addUsers(USER_PATTERN, null, null, roleSearch, ROLE_BASE, parameterSets); -- addUsers(null, USER_SEARCH, USER_BASE, roleSearch, ROLE_BASE, parameterSets); -+ for (String userRoleAttribute : new String[] { "cn", null }) { -+ for (String roleSearch : new String[] { ROLE_SEARCH_A, ROLE_SEARCH_B, ROLE_SEARCH_C }) { -+ if (userRoleAttribute != null) { -+ addUsers(USER_PATTERN, null, null, roleSearch, ROLE_BASE, userRoleAttribute, parameterSets); -+ addUsers(null, USER_SEARCH, USER_BASE, roleSearch, ROLE_BASE, userRoleAttribute, parameterSets); -+ } -+ } -+ parameterSets.add(new Object[] { "cn={0},ou=s\\;ub,ou=people,dc=example,dc=com", null, null, ROLE_SEARCH_A, -+ "{3},ou=people,dc=example,dc=com", "testsub", "test", new String[] { "TestGroup4" }, -+ userRoleAttribute }); - } -- parameterSets.add(new Object[] { "cn={0},ou=s\\;ub,ou=people,dc=example,dc=com", null, null, ROLE_SEARCH_A, -- "{3},ou=people,dc=example,dc=com", "testsub", "test", new String[] {"TestGroup4"} }); - return parameterSets; - } - - - private static void addUsers(String userPattern, String userSearch, String userBase, String roleSearch, -- String roleBase, List parameterSets) { -+ String roleBase, String userRoleAttribute, List parameterSets) { - parameterSets.add(new Object[] { userPattern, userSearch, userBase, roleSearch, roleBase, -- "test", "test", new String[] {"TestGroup"} }); -+ "test", "test", new String[] {"TestGroup"}, userRoleAttribute }); - parameterSets.add(new Object[] { userPattern, userSearch, userBase, roleSearch, roleBase, -- "t;", "test", new String[] {"TestGroup"} }); -+ "t;", "test", new String[] {"TestGroup"}, userRoleAttribute }); - parameterSets.add(new Object[] { userPattern, userSearch, userBase, roleSearch, roleBase, -- "t*", "test", new String[] {"TestGroup"} }); -+ "t*", "test", new String[] {"TestGroup"}, userRoleAttribute }); - parameterSets.add(new Object[] { userPattern, userSearch, userBase, roleSearch, roleBase, -- "t=", "test", new String[] {"TestGroup*3"} }); -+ "t=", "test", new String[] {"TestGroup*3"}, userRoleAttribute }); -+ parameterSets.add(new Object[] { userPattern, userSearch, userBase, roleSearch, roleBase, -+ "norole", "test", new String[0], userRoleAttribute }); - } - - -@@ -95,6 +102,8 @@ public class TestJNDIRealmIntegration { - public String credentials; - @Parameter(7) - public String[] groups; -+ @Parameter(8) -+ public String realmConfigUserRoleAttribute; - - @Test - public void testAuthenication() throws Exception { -@@ -105,7 +114,7 @@ public class TestJNDIRealmIntegration { - realm.setUserPattern(realmConfigUserPattern); - realm.setUserSearch(realmConfigUserSearch); - realm.setUserBase(realmConfigUserBase); -- realm.setUserRoleAttribute("cn"); -+ realm.setUserRoleAttribute(realmConfigUserRoleAttribute); - realm.setRoleName("cn"); - realm.setRoleBase(realmConfigRoleBase); - realm.setRoleSearch(realmConfigRoleSearch); -@@ -197,6 +206,17 @@ public class TestJNDIRealmIntegration { - result = conn.processOperation(addUserTestEquals); - Assert.assertEquals(ResultCode.SUCCESS, result.getResultCode()); - -+ AddRequest addUserNoRole = new AddRequest( -+ "dn: cn=norole,ou=people,dc=example,dc=com", -+ "objectClass: top", -+ "objectClass: person", -+ "objectClass: organizationalPerson", -+ "cn: norole", -+ "sn: No Role", -+ "userPassword: test"); -+ result = conn.processOperation(addUserNoRole); -+ Assert.assertEquals(ResultCode.SUCCESS, result.getResultCode()); -+ - AddRequest addGroupTest = new AddRequest( - "dn: cn=TestGroup,ou=people,dc=example,dc=com", - "objectClass: top", -Index: apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -=================================================================== ---- apache-tomcat-9.0.43-src.orig/webapps/docs/changelog.xml -+++ apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -@@ -107,6 +107,10 @@ - - - -+ 63508: NPE in JNDIRealm when no userRoleAttribute -+ is given. (fschumacher) -+ -+ - 65106: Fix the ConfigFileLoader handling of file URIs when - running under a security manager on some JREs. (markt) - diff --git a/tomcat-9.0-hardening_getResources.patch b/tomcat-9.0-hardening_getResources.patch deleted file mode 100644 index 325fa0b..0000000 --- a/tomcat-9.0-hardening_getResources.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 8a904f6065080409a1e00606cd7bceec6ad8918c Mon Sep 17 00:00:00 2001 -From: Mark Thomas -Date: Wed, 30 Mar 2022 20:22:49 +0100 -Subject: [PATCH] Security hardening. Deprecate getResources() and always - return null. - -This method is never used by Tomcat. If something accidently exposes the -class loader then this method can be used to gain access to Tomcat -internals. ---- - .../apache/catalina/loader/WebappClassLoaderBase.java | 7 ++++++- - webapps/docs/changelog.xml | 10 ++++++++++ - 2 files changed, 16 insertions(+), 1 deletion(-) -Index: apache-tomcat-9.0.43-src/java/org/apache/catalina/loader/WebappClassLoaderBase.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/catalina/loader/WebappClassLoaderBase.java -+++ apache-tomcat-9.0.43-src/java/org/apache/catalina/loader/WebappClassLoaderBase.java -@@ -425,10 +425,15 @@ public abstract class WebappClassLoaderB - // ------------------------------------------------------------- Properties - - /** -+ * Unused. Always returns {@code null}. -+ * - * @return associated resources. -+ * -+ * @deprecated This will be removed in Tomcat 10.1.x onwards - */ -+ @Deprecated - public WebResourceRoot getResources() { -- return this.resources; -+ return null; - } - - -Index: apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -=================================================================== ---- apache-tomcat-9.0.43-src.orig/webapps/docs/changelog.xml -+++ apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -@@ -106,6 +106,12 @@ -
- - -+ -+ Effectively disable the -+ WebappClassLoaderBase.getResources() method as it is not -+ used and if something accidently exposes the class loader this method -+ can be used to gain access to Tomcat internals. (markt) -+ - - 63508: NPE in JNDIRealm when no userRoleAttribute - is given. (fschumacher) diff --git a/tomcat-9.0-javadoc.patch b/tomcat-9.0-javadoc.patch index 2c275b8..a16c32c 100644 --- a/tomcat-9.0-javadoc.patch +++ b/tomcat-9.0-javadoc.patch @@ -2,72 +2,6 @@ Index: apache-tomcat-9.0.35-src/build.xml =================================================================== --- apache-tomcat-9.0.35-src.orig/build.xml +++ apache-tomcat-9.0.35-src/build.xml -@@ -1902,7 +1902,7 @@ Apache Tomcat ${version} native binaries - source="${compile.source}" - maxmemory="512m" - failonerror="true" -- failonwarning="true"> -+ failonwarning="false"> - - - -@@ -1924,7 +1924,7 @@ Apache Tomcat ${version} native binaries - source="${compile.source}" - maxmemory="512m" - failonerror="true" -- failonwarning="true"> -+ failonwarning="false"> - - - -@@ -1945,7 +1945,7 @@ Apache Tomcat ${version} native binaries - source="${compile.source}" - maxmemory="512m" - failonerror="true" -- failonwarning="true"> -+ failonwarning="false"> - - - -@@ -1966,7 +1966,7 @@ Apache Tomcat ${version} native binaries - source="${compile.source}" - maxmemory="512m" - failonerror="true" -- failonwarning="true"> -+ failonwarning="false"> - - - -@@ -1987,7 +1987,7 @@ Apache Tomcat ${version} native binaries - source="${compile.source}" - maxmemory="512m" - failonerror="true" -- failonwarning="true"> -+ failonwarning="false"> - - - -@@ -2005,9 +2005,10 @@ Apache Tomcat ${version} native binaries - docencoding="UTF-8" - charset="UTF-8" - additionalparam="-breakiterator -notimestamp" -+ source="${compile.source}" - maxmemory="512m" - failonerror="true" -- failonwarning="true"> -+ failonwarning="false"> - - - -@@ -2027,7 +2028,7 @@ Apache Tomcat ${version} native binaries - source="${compile.source}" - maxmemory="512m" - failonerror="true" -- failonwarning="true"> -+ failonwarning="false"> - - - @@ -2038,8 +2039,6 @@ Apache Tomcat ${version} native binaries diff --git a/tomcat-9.0-jdt.patch b/tomcat-9.0-jdt.patch new file mode 100644 index 0000000..be1cdcc --- /dev/null +++ b/tomcat-9.0-jdt.patch @@ -0,0 +1,22 @@ +--- apache-tomcat-9.0.75-src/java/org/apache/jasper/compiler/JDTCompiler.java 2023-05-22 18:12:16.915658492 +0200 ++++ apache-tomcat-9.0.75-src/java/org/apache/jasper/compiler/JDTCompiler.java 2023-05-22 19:45:14.491706823 +0200 +@@ -310,7 +310,7 @@ + } else if(opt.equals("15")) { + settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15); + } else if(opt.equals("16")) { +- settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_16); ++ settings.put(CompilerOptions.OPTION_Source, "16"); + } else if(opt.equals("17")) { + // Constant not available in latest ECJ version that runs on + // Java 8. +@@ -392,8 +392,8 @@ + settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15); + settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15); + } else if(opt.equals("16")) { +- settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_16); +- settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_16); ++ settings.put(CompilerOptions.OPTION_TargetPlatform, "16"); ++ settings.put(CompilerOptions.OPTION_Compliance, "16"); + } else if(opt.equals("17")) { + // Constant not available in latest ECJ version that runs on + // Java 8. diff --git a/tomcat-9.0-osgi-build.patch b/tomcat-9.0-osgi-build.patch index 1f2826c..9a77a9b 100644 --- a/tomcat-9.0-osgi-build.patch +++ b/tomcat-9.0-osgi-build.patch @@ -1,8 +1,18 @@ -Index: apache-tomcat-9.0.37-src/build.xml -=================================================================== ---- apache-tomcat-9.0.37-src.orig/build.xml -+++ apache-tomcat-9.0.37-src/build.xml -@@ -3307,6 +3307,13 @@ Read the Building page on the Apache Tom +--- apache-tomcat-9.0.75-src/build.xml 2023-05-22 18:12:16.995658642 +0200 ++++ apache-tomcat-9.0.75-src/build.xml 2023-05-22 19:41:42.051370923 +0200 +@@ -215,10 +215,10 @@ + + + +- + + + ++ + + + +@@ -3845,6 +3845,13 @@ diff --git a/tomcat-9.0.31-secretRequired-default.patch b/tomcat-9.0.31-secretRequired-default.patch deleted file mode 100644 index e858d8d..0000000 --- a/tomcat-9.0.31-secretRequired-default.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: apache-tomcat-9.0.31-src/java/org/apache/coyote/ajp/AbstractAjpProtocol.java -=================================================================== ---- apache-tomcat-9.0.31-src.orig/java/org/apache/coyote/ajp/AbstractAjpProtocol.java -+++ apache-tomcat-9.0.31-src/java/org/apache/coyote/ajp/AbstractAjpProtocol.java -@@ -180,7 +180,7 @@ public abstract class AbstractAjpProtoco - } - - -- private boolean secretRequired = true; -+ private boolean secretRequired = false; - public void setSecretRequired(boolean secretRequired) { - this.secretRequired = secretRequired; - } diff --git a/tomcat-9.0.43-CVE-2021-43980.patch b/tomcat-9.0.43-CVE-2021-43980.patch deleted file mode 100644 index b667c46..0000000 --- a/tomcat-9.0.43-CVE-2021-43980.patch +++ /dev/null @@ -1,181 +0,0 @@ -From 170e0f792bd18ff031677890ba2fe50eb7a376c1 Mon Sep 17 00:00:00 2001 -From: Mark Thomas -Date: Tue, 29 Mar 2022 19:15:37 +0100 -Subject: [PATCH] Improve the recycling of Processor objects to make it more - robust. - ---- - java/org/apache/coyote/AbstractProtocol.java | 32 ++++++++++--------- - .../tomcat/util/net/SocketWrapperBase.java | 17 +++++++--- - webapps/docs/changelog.xml | 4 +++ - 3 files changed, 33 insertions(+), 20 deletions(-) - -Index: apache-tomcat-9.0.43-src/java/org/apache/coyote/AbstractProtocol.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/coyote/AbstractProtocol.java -+++ apache-tomcat-9.0.43-src/java/org/apache/coyote/AbstractProtocol.java -@@ -794,7 +794,11 @@ public abstract class AbstractProtocol socketWrapper) { -- Processor processor = (Processor) socketWrapper.getCurrentProcessor(); -- socketWrapper.setCurrentProcessor(null); -+ Processor processor = (Processor) socketWrapper.takeCurrentProcessor(); - release(processor); - } - -Index: apache-tomcat-9.0.43-src/java/org/apache/tomcat/util/net/SocketWrapperBase.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/tomcat/util/net/SocketWrapperBase.java -+++ apache-tomcat-9.0.43-src/java/org/apache/tomcat/util/net/SocketWrapperBase.java -@@ -29,6 +29,7 @@ import java.util.concurrent.RejectedExec - import java.util.concurrent.Semaphore; - import java.util.concurrent.TimeUnit; - import java.util.concurrent.atomic.AtomicBoolean; -+import java.util.concurrent.atomic.AtomicReference; - - import org.apache.juli.logging.Log; - import org.apache.juli.logging.LogFactory; -@@ -104,10 +105,12 @@ public abstract class SocketWrapperBase< - protected volatile OperationState writeOperation = null; - - /** -- * The org.apache.coyote.Processor instance currently associated -- * with the wrapper. -+ * The org.apache.coyote.Processor instance currently associated with the -+ * wrapper. Only populated when required to maintain wrapper<->Processor -+ * mapping between calls to -+ * {@link AbstractEndpoint.Handler#process(SocketWrapperBase, SocketEvent)}. - */ -- protected Object currentProcessor = null; -+ private final AtomicReference currentProcessor = new AtomicReference<>(); - - public SocketWrapperBase(E socket, AbstractEndpoint endpoint) { - this.socket = socket; -@@ -134,11 +137,15 @@ public abstract class SocketWrapperBase< - } - - public Object getCurrentProcessor() { -- return currentProcessor; -+ return currentProcessor.get(); - } - - public void setCurrentProcessor(Object currentProcessor) { -- this.currentProcessor = currentProcessor; -+ this.currentProcessor.set(currentProcessor); -+ } -+ -+ public Object takeCurrentProcessor() { -+ return currentProcessor.getAndSet(null); - } - - /** -Index: apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -=================================================================== ---- apache-tomcat-9.0.43-src.orig/webapps/docs/changelog.xml -+++ apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -@@ -485,6 +485,10 @@ - Fix a concurrency issue in the NIO connector that could cause newly - created connections to be removed from the poller. (markt) - -+ -+ Improve the recycling of Processor objects to make it more robust. -+ (markt) -+ - - - diff --git a/tomcat-9.0.43-CVE-2022-42252.patch b/tomcat-9.0.43-CVE-2022-42252.patch deleted file mode 100644 index 85b84e2..0000000 --- a/tomcat-9.0.43-CVE-2022-42252.patch +++ /dev/null @@ -1,108 +0,0 @@ -From 4c7f4fd09d2cc1692112ef70b8ee23a7a037ae77 Mon Sep 17 00:00:00 2001 -From: Mark Thomas -Date: Mon, 3 Oct 2022 11:59:01 +0100 -Subject: [PATCH] Requests with invalid content-length should always be - rejected ---- - -Index: apache-tomcat-9.0.43-src/java/org/apache/coyote/http11/Http11InputBuffer.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/coyote/http11/Http11InputBuffer.java -+++ apache-tomcat-9.0.43-src/java/org/apache/coyote/http11/Http11InputBuffer.java -@@ -886,7 +886,7 @@ public class Http11InputBuffer implement - headerData.lastSignificantChar = pos; - byteBuffer.position(byteBuffer.position() - 1); - // skipLine() will handle the error -- return skipLine(); -+ return skipLine(false); - } - - // chr is next byte of header name. Convert to lowercase. -@@ -897,7 +897,7 @@ public class Http11InputBuffer implement - - // Skip the line and ignore the header - if (headerParsePos == HeaderParsePosition.HEADER_SKIPLINE) { -- return skipLine(); -+ return skipLine(false); - } - - // -@@ -948,15 +948,11 @@ public class Http11InputBuffer implement - } else if (prevChr == Constants.CR && chr == Constants.LF) { - eol = true; - } else if (prevChr == Constants.CR) { -- // Invalid value -- // Delete the header (it will be the most recent one) -- headers.removeHeader(headers.size() - 1); -- return skipLine(); -+ // Invalid value - also need to delete header -+ return skipLine(true); - } else if (chr != Constants.HT && HttpParser.isControl(chr)) { -- // Invalid value -- // Delete the header (it will be the most recent one) -- headers.removeHeader(headers.size() - 1); -- return skipLine(); -+ // Invalid value - also need to delete header -+ return skipLine(true); - } else if (chr == Constants.SP || chr == Constants.HT) { - byteBuffer.put(headerData.realPos, chr); - headerData.realPos++; -@@ -1004,7 +1000,27 @@ public class Http11InputBuffer implement - } - - -- private HeaderParseStatus skipLine() throws IOException { -+ private HeaderParseStatus skipLine(boolean deleteHeader) throws IOException { -+ boolean rejectThisHeader = rejectIllegalHeader; -+ // Check if rejectIllegalHeader is disabled and needs to be overridden -+ // for this header. The header name is required to determine if this -+ // override is required. The header name is only available once the -+ // header has been created. If the header has been created then -+ // deleteHeader will be true. -+ if (!rejectThisHeader && deleteHeader) { -+ if (headers.getName(headers.size() - 1).equalsIgnoreCase("content-length")) { -+ // Malformed content-length headers must always be rejected -+ // RFC 9112, section 6.3, bullet 5. -+ rejectThisHeader = true; -+ } else { -+ // Only need to delete the header if the request isn't going to -+ // be rejected (it will be the most recent one) -+ headers.removeHeader(headers.size() - 1); -+ } -+ } -+ -+ // Parse the rest of the invalid header so we can construct a useful -+ // exception and/or debug message. - headerParsePos = HeaderParsePosition.HEADER_SKIPLINE; - boolean eol = false; - -@@ -1029,11 +1045,11 @@ public class Http11InputBuffer implement - headerData.lastSignificantChar = pos; - } - } -- if (rejectIllegalHeader || log.isDebugEnabled()) { -+ if (rejectThisHeader || log.isDebugEnabled()) { - String message = sm.getString("iib.invalidheader", - HeaderUtil.toPrintableString(byteBuffer.array(), headerData.lineStart, - headerData.lastSignificantChar - headerData.lineStart + 1)); -- if (rejectIllegalHeader) { -+ if (rejectThisHeader) { - throw new IllegalArgumentException(message); - } - log.debug(message); -Index: apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -=================================================================== ---- apache-tomcat-9.0.43-src.orig/webapps/docs/changelog.xml -+++ apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -@@ -223,6 +223,11 @@ - Avoid possible infinite loop in OpenSSLEngine.unwrap - when the destination buffers state is changed concurrently. (remm) - -+ -+ Enforce the requirement of RFC 7230 onwards that a request with a -+ malformed content-length header should always be rejected -+ with a 400 response. (markt) -+ - - - diff --git a/tomcat-9.0.43-CVE-2022-45143.patch b/tomcat-9.0.43-CVE-2022-45143.patch deleted file mode 100644 index f5e613e..0000000 --- a/tomcat-9.0.43-CVE-2022-45143.patch +++ /dev/null @@ -1,208 +0,0 @@ -From b336f4e58893ea35114f1e4a415657f723b1298e Mon Sep 17 00:00:00 2001 -From: Mark Thomas -Date: Wed, 9 Nov 2022 12:39:15 +0000 -Subject: [PATCH] Avoid invalid JSON in JSONErrorReportValve output - ---- - .../catalina/valves/JsonErrorReportValve.java | 7 +- - .../apache/tomcat/util/json/JSONFilter.java | 61 ++++++++++++++ - .../tomcat/util/json/TestJSONFilter.java | 82 +++++++++++++++++++ - webapps/docs/changelog.xml | 5 ++ - 4 files changed, 152 insertions(+), 3 deletions(-) - create mode 100644 java/org/apache/tomcat/util/json/JSONFilter.java - create mode 100644 test/org/apache/tomcat/util/json/TestJSONFilter.java - -Index: apache-tomcat-9.0.43-src/java/org/apache/catalina/valves/JsonErrorReportValve.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/catalina/valves/JsonErrorReportValve.java -+++ apache-tomcat-9.0.43-src/java/org/apache/catalina/valves/JsonErrorReportValve.java -@@ -24,6 +24,7 @@ import org.apache.catalina.connector.Req - import org.apache.catalina.connector.Response; - import org.apache.coyote.ActionCode; - import org.apache.tomcat.util.ExceptionUtils; -+import org.apache.tomcat.util.json.JSONFilter; - import org.apache.tomcat.util.res.StringManager; - - /** -@@ -82,9 +83,9 @@ public class JsonErrorReportValve extend - } - } - String jsonReport = "{\n" + -- " \"type\": \"" + type + "\",\n" + -- " \"message\": \"" + message + "\"\n" + -- " \"description\": \"" + description + "\"\n" + -+ " \"type\": \"" + JSONFilter.escape(type) + "\",\n" + -+ " \"message\": \"" + JSONFilter.escape(message) + "\",\n" + -+ " \"description\": \"" + JSONFilter.escape(description) + "\"\n" + - "}"; - try { - try { -Index: apache-tomcat-9.0.43-src/java/org/apache/tomcat/util/json/JSONFilter.java -=================================================================== ---- /dev/null -+++ apache-tomcat-9.0.43-src/java/org/apache/tomcat/util/json/JSONFilter.java -@@ -0,0 +1,61 @@ -+/* -+ * 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.tomcat.util.json; -+ -+/** -+ * Provides escaping of values so they can be included in a JSON document. -+ * Escaping is based on the definition of JSON found in -+ * RFC 8259. -+ */ -+public class JSONFilter { -+ -+ private JSONFilter() { -+ // Utility class. Hide the default constructor. -+ } -+ -+ public static String escape(String input) { -+ /* -+ * While any character MAY be escaped, only U+0000 to U+001F (control -+ * characters), U+0022 (quotation mark) and U+005C (reverse solidus) -+ * MUST be escaped. -+ */ -+ char[] chars = input.toCharArray(); -+ StringBuffer escaped = null; -+ int lastUnescapedStart = 0; -+ for (int i = 0; i < chars.length; i++) { -+ if (chars[i] < 0x20 || chars[i] == 0x22 || chars[i] == 0x5c) { -+ if (escaped == null) { -+ escaped = new StringBuffer(chars.length + 20); -+ } -+ if (lastUnescapedStart < i) { -+ escaped.append(input.subSequence(lastUnescapedStart, i)); -+ } -+ lastUnescapedStart = i + 1; -+ escaped.append("\\u"); -+ escaped.append(String.format("%04X", Integer.valueOf(chars[i]))); -+ } -+ } -+ if (escaped == null) { -+ return input; -+ } else { -+ if (lastUnescapedStart < chars.length) { -+ escaped.append(input.subSequence(lastUnescapedStart, chars.length)); -+ } -+ return escaped.toString(); -+ } -+ } -+} -Index: apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -=================================================================== ---- apache-tomcat-9.0.43-src.orig/webapps/docs/changelog.xml -+++ apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -@@ -133,6 +133,11 @@ - RemoteIpFilter determines that this request was submitted - via a secure channel. (lihan) - -+ -+ Escape values used to construct output for the -+ JsonErrorReportValve to ensure that it always outputs valid -+ JSON. (markt) -+ - - - -Index: apache-tomcat-9.0.43-src/test/org/apache/tomcat/util/json/TestJSONFilter.java -=================================================================== ---- /dev/null -+++ apache-tomcat-9.0.43-src/test/org/apache/tomcat/util/json/TestJSONFilter.java -@@ -0,0 +1,82 @@ -+/* -+ * 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.tomcat.util.json; -+ -+import java.util.ArrayList; -+import java.util.Collection; -+ -+import org.junit.Assert; -+import org.junit.Test; -+import org.junit.runner.RunWith; -+import org.junit.runners.Parameterized; -+import org.junit.runners.Parameterized.Parameter; -+ -+ -+@RunWith(Parameterized.class) -+public class TestJSONFilter { -+ -+ @Parameterized.Parameters(name = "{index}: input[{0}], output[{1}]") -+ public static Collection parameters() { -+ Collection parameterSets = new ArrayList<>(); -+ -+ // Empty -+ parameterSets.add(new String[] { "", "" }); -+ -+ // Must escape -+ parameterSets.add(new String[] { "\"", "\\u0022" }); -+ parameterSets.add(new String[] { "\\", "\\u005C" }); -+ // Sample of controls -+ parameterSets.add(new String[] { "\t", "\\u0009" }); -+ parameterSets.add(new String[] { "\n", "\\u000A" }); -+ parameterSets.add(new String[] { "\r", "\\u000D" }); -+ -+ // No escape -+ parameterSets.add(new String[] { "aaa", "aaa" }); -+ -+ // Start -+ parameterSets.add(new String[] { "\naaa", "\\u000Aaaa" }); -+ parameterSets.add(new String[] { "\n\naaa", "\\u000A\\u000Aaaa" }); -+ -+ // Middle -+ parameterSets.add(new String[] { "aaa\naaa", "aaa\\u000Aaaa" }); -+ parameterSets.add(new String[] { "aaa\n\naaa", "aaa\\u000A\\u000Aaaa" }); -+ -+ // End -+ parameterSets.add(new String[] { "aaa\n", "aaa\\u000A" }); -+ parameterSets.add(new String[] { "aaa\n\n", "aaa\\u000A\\u000A" }); -+ -+ // Start, middle and end -+ parameterSets.add(new String[] { "\naaa\naaa\n", "\\u000Aaaa\\u000Aaaa\\u000A" }); -+ parameterSets.add(new String[] { "\n\naaa\n\naaa\n\n", "\\u000A\\u000Aaaa\\u000A\\u000Aaaa\\u000A\\u000A" }); -+ -+ // Multiple -+ parameterSets.add(new String[] { "\n\n", "\\u000A\\u000A" }); -+ -+ return parameterSets; -+ } -+ -+ @Parameter(0) -+ public String input; -+ -+ @Parameter(1) -+ public String output; -+ -+ @Test -+ public void testStringEscaping() { -+ Assert.assertEquals(output, JSONFilter.escape(input));; -+ } -+} diff --git a/tomcat-9.0.43-CVE-2023-24998.patch b/tomcat-9.0.43-CVE-2023-24998.patch deleted file mode 100644 index 37c6b64..0000000 --- a/tomcat-9.0.43-CVE-2023-24998.patch +++ /dev/null @@ -1,262 +0,0 @@ -From cf77cc545de0488fb89e24294151504a7432df74 Mon Sep 17 00:00:00 2001 -From: Mark Thomas -Date: Tue, 13 Dec 2022 17:55:34 +0000 -Subject: [PATCH] Update packaged renamed fork of Commons File Upload - ---- - MERGE.txt | 2 +- - .../apache/catalina/connector/Request.java | 10 +++- - .../apache/tomcat/util/http/Parameters.java | 5 ++ - .../util/http/fileupload/FileUploadBase.java | 29 +++++++++++ - .../impl/FileCountLimitExceededException.java | 50 +++++++++++++++++++ - webapps/docs/changelog.xml | 8 +++ - webapps/docs/config/ajp.xml | 15 +++--- - webapps/docs/config/http.xml | 15 +++--- - 8 files changed, 120 insertions(+), 14 deletions(-) - create mode 100644 java/org/apache/tomcat/util/http/fileupload/impl/FileCountLimitExceededException.java - -Index: apache-tomcat-9.0.43-src/MERGE.txt -=================================================================== ---- apache-tomcat-9.0.43-src.orig/MERGE.txt -+++ apache-tomcat-9.0.43-src/MERGE.txt -@@ -51,7 +51,7 @@ FileUpload - Sub-tree: - src/main/java/org/apache/commons/fileupload2 - The SHA1 ID / tag for the most recent commit to be merged to Tomcat is: --ee0a7131b6b87586b28542de354951414dedac3f (2021-01-15) -+34eb241c051b02eca3b0b1b04f67b3b4e6c3a24d (2023-01-03) - - Note: Tomcat's copy of fileupload also includes classes copied manually from - Commons IO. -Index: apache-tomcat-9.0.43-src/java/org/apache/catalina/connector/Request.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/catalina/connector/Request.java -+++ apache-tomcat-9.0.43-src/java/org/apache/catalina/connector/Request.java -@@ -2862,8 +2862,9 @@ public class Request implements HttpServ - } - } - -+ int maxParameterCount = getConnector().getMaxParameterCount(); - Parameters parameters = coyoteRequest.getParameters(); -- parameters.setLimit(getConnector().getMaxParameterCount()); -+ parameters.setLimit(maxParameterCount); - - boolean success = false; - try { -@@ -2915,6 +2916,13 @@ public class Request implements HttpServ - upload.setFileItemFactory(factory); - upload.setFileSizeMax(mce.getMaxFileSize()); - upload.setSizeMax(mce.getMaxRequestSize()); -+ if (maxParameterCount > -1) { -+ // There is a limit. The limit for parts needs to be reduced by -+ // the number of parameters we have already parsed. -+ // Must be under the limit else parsing parameters would have -+ // triggered an exception. -+ upload.setFileCountMax(maxParameterCount - parameters.size()); -+ } - - parts = new ArrayList<>(); - try { -Index: apache-tomcat-9.0.43-src/java/org/apache/tomcat/util/http/Parameters.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/tomcat/util/http/Parameters.java -+++ apache-tomcat-9.0.43-src/java/org/apache/tomcat/util/http/Parameters.java -@@ -125,6 +125,11 @@ public final class Parameters { - } - - -+ public int size() { -+ return parameterCount; -+ } -+ -+ - public void recycle() { - parameterCount = 0; - paramHashValues.clear(); -Index: apache-tomcat-9.0.43-src/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java -+++ apache-tomcat-9.0.43-src/java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java -@@ -25,6 +25,7 @@ import java.util.Locale; - import java.util.Map; - import java.util.Objects; - -+import org.apache.tomcat.util.http.fileupload.impl.FileCountLimitExceededException; - import org.apache.tomcat.util.http.fileupload.impl.FileItemIteratorImpl; - import org.apache.tomcat.util.http.fileupload.impl.FileItemStreamImpl; - import org.apache.tomcat.util.http.fileupload.impl.FileUploadIOException; -@@ -133,6 +134,12 @@ public abstract class FileUploadBase { - private long fileSizeMax = -1; - - /** -+ * The maximum permitted number of files that may be uploaded in a single -+ * request. A value of -1 indicates no maximum. -+ */ -+ private long fileCountMax = -1; -+ -+ /** - * The content encoding to use when reading part headers. - */ - private String headerEncoding; -@@ -209,6 +216,24 @@ public abstract class FileUploadBase { - } - - /** -+ * Returns the maximum number of files allowed in a single request. -+ * -+ * @return The maximum number of files allowed in a single request. -+ */ -+ public long getFileCountMax() { -+ return fileCountMax; -+ } -+ -+ /** -+ * Sets the maximum number of files allowed per request/ -+ * -+ * @param fileCountMax The new limit. {@code -1} means no limit. -+ */ -+ public void setFileCountMax(long fileCountMax) { -+ this.fileCountMax = fileCountMax; -+ } -+ -+ /** - * Retrieves the character encoding used when reading the headers of an - * individual part. When not specified, or {@code null}, the request - * encoding is used. If that is also not specified, or {@code null}, -@@ -281,6 +306,10 @@ public abstract class FileUploadBase { - final FileItemFactory fileItemFactory = Objects.requireNonNull(getFileItemFactory(), "No FileItemFactory has been set."); - final byte[] buffer = new byte[Streams.DEFAULT_BUFFER_SIZE]; - while (iter.hasNext()) { -+ if (items.size() == fileCountMax) { -+ // The next item will exceed the limit. -+ throw new FileCountLimitExceededException(ATTACHMENT, getFileCountMax()); -+ } - final FileItemStream item = iter.next(); - // Don't use getName() here to prevent an InvalidFileNameException. - final String fileName = ((FileItemStreamImpl) item).getName(); -Index: apache-tomcat-9.0.43-src/java/org/apache/tomcat/util/http/fileupload/impl/FileCountLimitExceededException.java -=================================================================== ---- /dev/null -+++ apache-tomcat-9.0.43-src/java/org/apache/tomcat/util/http/fileupload/impl/FileCountLimitExceededException.java -@@ -0,0 +1,50 @@ -+/* -+ * 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.tomcat.util.http.fileupload.impl; -+ -+import org.apache.tomcat.util.http.fileupload.FileUploadException; -+ -+/** -+ * This exception is thrown if a request contains more files than the specified -+ * limit. -+ */ -+public class FileCountLimitExceededException extends FileUploadException { -+ -+ private static final long serialVersionUID = 2408766352570556046L; -+ -+ private final long limit; -+ -+ /** -+ * Creates a new instance. -+ * -+ * @param message The detail message -+ * @param limit The limit that was exceeded -+ */ -+ public FileCountLimitExceededException(final String message, final long limit) { -+ super(message); -+ this.limit = limit; -+ } -+ -+ /** -+ * Retrieves the limit that was exceeded. -+ * -+ * @return The limit that was exceeded by the request -+ */ -+ public long getLimit() { -+ return limit; -+ } -+} -Index: apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -=================================================================== ---- apache-tomcat-9.0.43-src.orig/webapps/docs/changelog.xml -+++ apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -@@ -142,6 +142,14 @@ - - - -+ -+ -+ -+ Update the internal fork of Apache Commons FileUpload to 34eb241 -+ (2023-01-03, 2.0-SNAPSHOT). (markt) -+ -+ -+ - -
- -Index: apache-tomcat-9.0.43-src/webapps/docs/config/ajp.xml -=================================================================== ---- apache-tomcat-9.0.43-src.orig/webapps/docs/config/ajp.xml -+++ apache-tomcat-9.0.43-src/webapps/docs/config/ajp.xml -@@ -136,12 +136,15 @@ - - - --

The maximum number of parameter and value pairs (GET plus POST) which -- will be automatically parsed by the container. Parameter and value pairs -- beyond this limit will be ignored. A value of less than 0 means no limit. -- If not specified, a default of 10000 is used. Note that -- FailedRequestFilter filter can be -- used to reject requests that hit the limit.

-+

The maximum total number of request parameters (including uploaded -+ files) obtained from the query string and, for POST requests, the request -+ body if the content type is -+ application/x-www-form-urlencoded or -+ multipart/form-data. Request parameters beyond this limit -+ will be ignored. A value of less than 0 means no limit. If not specified, -+ a default of 10000 is used. Note that FailedRequestFilter -+ filter can be used to reject requests that -+ exceed the limit.

-
- - -Index: apache-tomcat-9.0.43-src/webapps/docs/config/http.xml -=================================================================== ---- apache-tomcat-9.0.43-src.orig/webapps/docs/config/http.xml -+++ apache-tomcat-9.0.43-src/webapps/docs/config/http.xml -@@ -153,12 +153,15 @@ - - - --

The maximum number of parameter and value pairs (GET plus POST) which -- will be automatically parsed by the container. Parameter and value pairs -- beyond this limit will be ignored. A value of less than 0 means no limit. -- If not specified, a default of 10000 is used. Note that -- FailedRequestFilter filter can be -- used to reject requests that hit the limit.

-+

The maximum total number of request parameters (including uploaded -+ files) obtained from the query string and, for POST requests, the request -+ body if the content type is -+ application/x-www-form-urlencoded or -+ multipart/form-data. Request parameters beyond this limit -+ will be ignored. A value of less than 0 means no limit. If not specified, -+ a default of 10000 is used. Note that FailedRequestFilter -+ filter can be used to reject requests that -+ exceed the limit.

-
- - diff --git a/tomcat-9.0.43-CVE-2023-28708.patch b/tomcat-9.0.43-CVE-2023-28708.patch deleted file mode 100644 index 0385e44..0000000 --- a/tomcat-9.0.43-CVE-2023-28708.patch +++ /dev/null @@ -1,226 +0,0 @@ -From 3b51230764da595bb19e8d0962dd8c69ab40dfab Mon Sep 17 00:00:00 2001 -From: lihan -Date: Fri, 10 Feb 2023 10:01:27 +0800 -Subject: [PATCH] Fix BZ 66471 - JSessionId secure attribute missing with - RemoteIpFilter and X-Forwarded-Proto set to https - -https://bz.apache.org/bugzilla/show_bug.cgi?id=66471 ---- - java/org/apache/catalina/Globals.java | 7 ++ - .../apache/catalina/connector/Request.java | 14 +++ - .../catalina/filters/RemoteIpFilter.java | 7 +- - .../catalina/filters/TestRemoteIpFilter.java | 96 ++++++++++++++----- - webapps/docs/changelog.xml | 5 + - 5 files changed, 100 insertions(+), 29 deletions(-) - -Index: apache-tomcat-9.0.43-src/java/org/apache/catalina/Globals.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/catalina/Globals.java -+++ apache-tomcat-9.0.43-src/java/org/apache/catalina/Globals.java -@@ -113,6 +113,13 @@ public final class Globals { - - - /** -+ * The request attribute that is set to the value of {@code Boolean.TRUE} -+ * if {@link org.apache.catalina.filters.RemoteIpFilter} determines -+ * that this request was submitted via a secure channel. -+ */ -+ public static final String REMOTE_IP_FILTER_SECURE = "org.apache.catalina.filters.RemoteIpFilter.secure"; -+ -+ /** - * The request attribute that can be used by a servlet to pass - * to the connector the name of the file that is to be served - * by sendfile. The value should be {@code java.lang.String} -Index: apache-tomcat-9.0.43-src/java/org/apache/catalina/connector/Request.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/catalina/connector/Request.java -+++ apache-tomcat-9.0.43-src/java/org/apache/catalina/connector/Request.java -@@ -3601,6 +3601,20 @@ public class Request implements HttpServ - // NO-OP - } - }); -+ specialAttributes.put(Globals.REMOTE_IP_FILTER_SECURE, -+ new SpecialAttributeAdapter() { -+ @Override -+ public Object get(Request request, String name) { -+ return Boolean.valueOf(request.isSecure()); -+ } -+ -+ @Override -+ public void set(Request request, String name, Object value) { -+ if (value instanceof Boolean) { -+ request.setSecure(((Boolean) value).booleanValue()); -+ } -+ } -+ }); - specialAttributes.put(Globals.STREAM_ID, - new SpecialAttributeAdapter() { - @Override -Index: apache-tomcat-9.0.43-src/java/org/apache/catalina/filters/RemoteIpFilter.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/java/org/apache/catalina/filters/RemoteIpFilter.java -+++ apache-tomcat-9.0.43-src/java/org/apache/catalina/filters/RemoteIpFilter.java -@@ -581,11 +581,6 @@ public class RemoteIpFilter extends Gene - return serverPort; - } - -- @Override -- public boolean isSecure() { -- return secure; -- } -- - public void removeHeader(String name) { - Map.Entry> header = getHeaderEntry(name); - if (header != null) { -@@ -625,7 +620,7 @@ public class RemoteIpFilter extends Gene - } - - public void setSecure(boolean secure) { -- this.secure = secure; -+ super.getRequest().setAttribute(Globals.REMOTE_IP_FILTER_SECURE, Boolean.valueOf(secure)); - } - - public void setServerName(String serverName) { -Index: apache-tomcat-9.0.43-src/test/org/apache/catalina/filters/TestRemoteIpFilter.java -=================================================================== ---- apache-tomcat-9.0.43-src.orig/test/org/apache/catalina/filters/TestRemoteIpFilter.java -+++ apache-tomcat-9.0.43-src/test/org/apache/catalina/filters/TestRemoteIpFilter.java -@@ -82,15 +82,21 @@ public class TestRemoteIpFilter extends - - private static final long serialVersionUID = 1L; - -- private transient HttpServletRequest request; -- -- public HttpServletRequest getRequest() { -- return request; -- } -+ public String remoteAddr; -+ public String remoteHost; -+ public String scheme; -+ public String serverName; -+ public int serverPort; -+ public boolean isSecure; - - @Override - public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { -- this.request = request; -+ this.isSecure = request.isSecure(); -+ this.remoteAddr = request.getRemoteAddr(); -+ this.remoteHost = request.getRemoteHost(); -+ this.scheme = request.getScheme(); -+ this.serverName = request.getServerName(); -+ this.serverPort = request.getServerPort(); - PrintWriter writer = response.getWriter(); - - writer.println("request.remoteAddr=" + request.getRemoteAddr()); -@@ -130,16 +136,6 @@ public class TestRemoteIpFilter extends - } - - @Override -- public void setAttribute(String name, Object value) { -- getCoyoteRequest().getAttributes().put(name, value); -- } -- -- @Override -- public Object getAttribute(String name) { -- return getCoyoteRequest().getAttributes().get(name); -- } -- -- @Override - public String getServerName() { - return "localhost"; - } -@@ -770,16 +766,70 @@ public class TestRemoteIpFilter extends - - // VALIDATE - Assert.assertEquals(HttpURLConnection.HTTP_OK, httpURLConnection.getResponseCode()); -- HttpServletRequest request = mockServlet.getRequest(); -- Assert.assertNotNull(request); - - // VALIDATE X-FORWARDED-FOR -- Assert.assertEquals(expectedRemoteAddr, request.getRemoteAddr()); -- Assert.assertEquals(expectedRemoteAddr, request.getRemoteHost()); -+ Assert.assertEquals(expectedRemoteAddr, mockServlet.remoteAddr); -+ Assert.assertEquals(expectedRemoteAddr, mockServlet.remoteHost); - - // VALIDATE X-FORWARDED-PROTO -- Assert.assertTrue(request.isSecure()); -- Assert.assertEquals("https", request.getScheme()); -- Assert.assertEquals(443, request.getServerPort()); -+ Assert.assertTrue(mockServlet.isSecure); -+ Assert.assertEquals("https", mockServlet.scheme); -+ Assert.assertEquals(443, mockServlet.serverPort); -+ } -+ -+ @Test -+ public void testJSessionIdSecureAttributeMissing() throws Exception { -+ -+ // mostly default configuration : enable "x-forwarded-proto" -+ Map remoteIpFilterParameter = new HashMap<>(); -+ remoteIpFilterParameter.put("protocolHeader", "x-forwarded-proto"); -+ -+ // SETUP -+ Tomcat tomcat = getTomcatInstance(); -+ Context root = tomcat.addContext("", TEMP_DIR); -+ -+ FilterDef filterDef = new FilterDef(); -+ filterDef.getParameterMap().putAll(remoteIpFilterParameter); -+ filterDef.setFilterClass(RemoteIpFilter.class.getName()); -+ filterDef.setFilterName(RemoteIpFilter.class.getName()); -+ -+ root.addFilterDef(filterDef); -+ -+ FilterMap filterMap = new FilterMap(); -+ filterMap.setFilterName(RemoteIpFilter.class.getName()); -+ filterMap.addURLPatternDecoded("*"); -+ root.addFilterMap(filterMap); -+ -+ Bug66471Servlet bug66471Servlet = new Bug66471Servlet(); -+ -+ Tomcat.addServlet(root, bug66471Servlet.getClass().getName(), bug66471Servlet); -+ root.addServletMappingDecoded("/test", bug66471Servlet.getClass().getName()); -+ -+ getTomcatInstance().start(); -+ -+ Map> resHeaders = new HashMap<>(); -+ Map> reqHeaders = new HashMap<>(); -+ String expectedRemoteAddr = "my-remote-addr"; -+ List forwardedFor = new ArrayList<>(1); -+ forwardedFor.add(expectedRemoteAddr); -+ List forwardedProto = new ArrayList<>(1); -+ forwardedProto.add("https"); -+ reqHeaders.put("x-forwarded-for", forwardedFor); -+ reqHeaders.put("x-forwarded-proto", forwardedProto); -+ -+ getUrl("http://localhost:" + tomcat.getConnector().getLocalPort() + -+ "/test", null, reqHeaders, resHeaders); -+ String setCookie = resHeaders.get("Set-Cookie").get(0); -+ Assert.assertTrue(setCookie.contains("Secure")); -+ Assert.assertTrue(bug66471Servlet.isSecure.booleanValue()); -+ } -+ public static class Bug66471Servlet extends HttpServlet { -+ private static final long serialVersionUID = 1L; -+ public Boolean isSecure; -+ @Override -+ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { -+ req.getSession(); -+ isSecure = (Boolean) req.getAttribute(Globals.REMOTE_IP_FILTER_SECURE); -+ } - } - } -Index: apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -=================================================================== ---- apache-tomcat-9.0.43-src.orig/webapps/docs/changelog.xml -+++ apache-tomcat-9.0.43-src/webapps/docs/changelog.xml -@@ -128,6 +128,11 @@ - Make the calculation of the session storage location more robust when - using file based persistent storage. (markt) - -+ -+ 66471: Fix JSessionId secure attribute missing When -+ RemoteIpFilter determines that this request was submitted -+ via a secure channel. (lihan) -+ - -
- diff --git a/tomcat-9.0.43-java8compat.patch b/tomcat-9.0.43-java8compat.patch deleted file mode 100644 index d232214..0000000 --- a/tomcat-9.0.43-java8compat.patch +++ /dev/null @@ -1,32 +0,0 @@ ---- apache-tomcat-9.0.43-src/build.xml 2022-07-05 21:42:13.038838402 +0200 -+++ apache-tomcat-9.0.43-src/build.xml 2022-07-05 23:04:10.506328581 +0200 -@@ -957,6 +957,7 @@ - deprecation="${compile.deprecation}" - source="${compile.source}" - target="${compile.target}" -+ release="${compile.release}" - encoding="ISO-8859-1" - includeAntRuntime="true" > - - - -+ -+ -+ -+ -+ -+ -+ - - - diff --git a/tomcat-9.0.75-secretRequired-default.patch b/tomcat-9.0.75-secretRequired-default.patch new file mode 100644 index 0000000..dfadea7 --- /dev/null +++ b/tomcat-9.0.75-secretRequired-default.patch @@ -0,0 +1,11 @@ +--- apache-tomcat-9.0.75-src/java/org/apache/coyote/ajp/AbstractAjpProtocol.java 2023-05-22 18:12:16.907658477 +0200 ++++ apache-tomcat-9.0.75-src/java/org/apache/coyote/ajp/AbstractAjpProtocol.java 2023-05-22 18:31:07.969096813 +0200 +@@ -177,7 +177,7 @@ + } + + +- private boolean secretRequired = true; ++ private boolean secretRequired = false; + + public void setSecretRequired(boolean secretRequired) { + this.secretRequired = secretRequired; diff --git a/tomcat.keyring b/tomcat.keyring index e5c567f..df9bc1a 100644 --- a/tomcat.keyring +++ b/tomcat.keyring @@ -1,650 +1,50 @@ -This file contains the PGP&GPG keys of various Apache developers. -Please don't use them for email unless you have to. Their main -purpose is code signing. - -Apache users: pgp < KEYS -Apache developers: - (pgpk -ll && pgpk -xa ) >> this file. - or - (gpg --fingerprint --list-sigs - && gpg --armor --export ) >> this file. - -Apache developers: please ensure that your key is also available via the -PGP keyservers (such as pgpkeys.mit.edu). - - -Type Bits/KeyID Date User ID -pub 2048/F22C4FED 2001/07/02 Andy Armstrong - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: PGPfreeware 7.0.3 for non-commercial use - -mQGiBDtAWuURBADZ0KUEyUkSUiTA09e7tvEbX25STsjxrR+DNTainCls+XlkVOij -gBv216lqge9tIsS0L6hCP4OQbFf/64qVtJssX4QXdyiZGb5wpmcj0Mz602Ew8r+N -I0S5NvmogoYWW7BlP4r61jNxO5zrr03KaijM5r4ipJdLUxyOmM6P2jRPUwCg/5gm -bpqiYl7pXX5FgDeB36tmD+UD/06iLqOnoiKO0vMbOk7URclhCObMNrHqxTxozMTS -B9soYURbIeArei+plYo2n+1qB12ayybjhVu3uksXRdT9bEkyxMfslvLbIpDAG8Cz -gNftTbKx/MVS7cQU0II8BKo2Akr+1FZah+sD4ovK8SfkMXUQUbTeefTntsAQKyyU -9M9tA/9on9tBiHFl0qVJht6N4GiJ2G689v7rS2giLgKjetjiCduxBXEgvUSuyQID -nF9ATrpXjITwsRlGKFmpZiFm5oCeCXihIVH0u6q066xNW2AXkLVoJ1l1Rs2Z0lsb -0cq3xEAcwAmYLKQvCtgDV8CYgWKVmPi+49rSuQn7Lo9l02OUbLQgQW5keSBBcm1z -dHJvbmcgPGFuZHlAdGFnaXNoLmNvbT6JAFgEEBECABgFAjtAWuUICwMJCAcCAQoC -GQEFGwMAAAAACgkQajrT9PIsT+1plgCfXAovWnVL3MjrTfcGlFSKw7GHCSYAoJkz -x+r2ANe8/0e+u5ZcYtSaSry+uQINBDtAWuUQCAD2Qle3CH8IF3KiutapQvMF6PlT -ETlPtvFuuUs4INoBp1ajFOmPQFXz0AfGy0OplK33TGSGSfgMg71l6RfUodNQ+PVZ -X9x2Uk89PY3bzpnhV5JZzf24rnRPxfx2vIPFRzBhznzJZv8V+bv9kV7HAarTW56N -oKVyOtQa8L9GAFgr5fSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kj -wEPwpVsYjY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obE -AxnIByl6ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpMgs7AAIC -B/0eHkYQ0Rv6s21TgpOzRBon+rQAv9ka0PlC7bj2eYWsCOBib8K7qO8hND0sW59p -0uFQ01X7kC7L/4Ls1HTk0chEZMV0UrGAOKXHY1QFlxrNtFi5U3pTPITXDDfy+g/G -6FTX3PLnGGvwXbtaiAq5UjQ6iXm03lh0BW6Q+kPtm8swPPfqfjYv0rrT+I8Ic3p2 -HplWKR2bpi3wqCSKB/AaTQJwTbh2x2+2cPVONPodgjZSJ9eQkErejkNSvqbumlTx -dB81eoGa0Lo2xE7N+DNlCnILGE0X4hPMdj+N5fmyEbyx0WOB8crvCuODGGEQnXs/ -zbVO7FP+rj7YWjRh5pVD3bGiiQBMBBgRAgAMBQI7QFrlBRsMAAAAAAoJEGo60/Ty -LE/tj/QAoOFNFa7rbAy+eT6mRNb7XztfcAbWAKD6Gd6S/7lEJU0k2TS5tozt4jMl -vw== -=/91Q ------END PGP PUBLIC KEY BLOCK----- - -Type Bits/KeyID Date User ID -pub 1024D/86867BA6 2001-11-22 Jean-Frederic Clere (jfclere) - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.0.5 (GNU/Linux) -Comment: For info see http://www.gnupg.org - -mQGiBDv9Gx8RBADclmKwDLcibNVipQnhYW+bFIpuQjQnRrqRwn3gXM+/luzzJYJ4 -bbWpw13zjX0EkrAJ8qH2A/d0EIU1eZ0zHrLgRvMUfLGFUX7FFFw18JKFLTVGhG4/ -8sSl3ydHSA2Kd1PF6xjBP7iM7sg5dJfEkyMzvK5H4F0ZpTqy3087wsg1wwCgitRy -Zg4x3lWZSkOwBj472qaO9GkD/2q6kyWfAK6XFe3GuB5AAs3poMfN1eqW+duM4TA8 -zUiWK0Wxx4JXJbL7n0i4d+JdXJsrjSjF++KKfelcxsrSxoUIBegez25MUSvHe09D -R3nqkY8CVO+viEtzRBqkSgCMbUjAtfkQ+vp2jDnWSmmkNfY0OYAzt+KRyJKcjUSJ -gvOOA/45+DN9wuTELoFTvsXh1JgOL/QvW1fmQ2HrcQk94BkzIsfVGWClCiig5gNw -LCxTbfgA5htpI8U7vPR9/5gH7U8Wy3HR6xQUZxcbttMeYit2VbDEJzF5r5S0pJvD -vyk3n1kiKU7r49sjhxGgE8J/VvDpO6YcIsDs8LoULwuJTg0DTrRDSmVhbi1GcmVk -ZXJpYyBDbGVyZSAoamZjbGVyZSkgPEpGcmVkZXJpYy5DbGVyZUBmdWppdHN1LXNp -ZW1lbnMuY29tPohXBBMRAgAXBQI7/RsfBQsHCgMEAxUDAgMWAgECF4AACgkQ0+/m -toaGe6amGQCeJU5VZ8QCi8+PY0QJHPA63e5uPyoAmgOWIwFm8A/xmW8qjEvVAWtb -TjZxuQENBDv9GyMQBACCbFlSF+udW/Qz2oknDen8Hoql4Q1Q7CUQTbPjoQAcYgZg -LrsR6hc9aCIf3Kt4qZBgQ1Oe9M/AemOFhU04UNp3dgHk91EYRvx80Rua992p/8V7 -QOhwIBVb2XE8as5nL2j8w6Jz7eSs/bivxm9yD0AH/I5H01RAJivRbOTsUgSkDwAD -BQP5ARlW2Nqc0U17asQsmMYvT1UMiOiyBwUD/DIEG2Xy1hlEvdljg8WU26jcjpGq -MrT69T4Z+eZ2oVyiRQTW4qMUBKc0Nbz89hL0qv9K41ExxxH+JgE1csRVvmwAT8Iy -lnhof7TJLRBtvan3+p21Kxl1uQ7MbmLT875u+vc+J098fIiIRgQYEQIABgUCO/0b -IwAKCRDT7+a2hoZ7pn9UAJ9f0TK0QQOtjQBvxAissopYhDKHGACePZg0k9sj69yw -nVWrBS9fvFC9jcA= -=BTiM ------END PGP PUBLIC KEY BLOCK----- - -Type Bits/KeyID Date User ID -pub 1024D/E86E29AC 2002-02-13 kevin seguin - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.0.6 (MingW32) -Comment: For info see http://www.gnupg.org - -mQGiBDxqtR8RBACbySxGrtf+flbowryS1Hj4z3zzEXD4CAEq6RjSGMtIraCDRJfp -6Gexs+lQ6IhpdC4GfX70SUMjXXvT5suhXYeGOM4iJHqUsksgzEKjUqcfj1l3qmOs -/doE8lcGGHcYbMplBcfuop+shZYiv9GEJ3gutwn/dNnhs/QA9bCdIj03lwCgvAcy -QpT5JdTym2p2icd5e91mGIUEAJMw6JHTTcCiyoTRy7k8Cf65d8S7bTDLr6pqJVE2 -XU41CvW/pgL31akYAxpeZJJnsBaLaUiqh6K0qgfEMlDwDeC6gVogHBxWkEXdK1dr -tGL4GIUcxQ1+ZvQhGg7dtjanmfMlylVgS+C48awJySkinRmaQDbQ0MKdFchLc/y1 -OR3IA/0VkIvlidehMPbZCalqhS9AEsDiFq5/u5AsQzDEp2nmTGlmBqjhc39kEnu4 -qKq08az1Gt6Q7sxXbjH/jYtDgd49FW5Yg4k5B3hpTgnbyRE6SGlKksu8qTmYkDve -4rej6pvJRHwp6hDKxDG8qQoLWIgOfVC8960nurqx56QdV9YMsLQga2V2aW4gc2Vn -dWluIDxzZWd1aW5AYXBhY2hlLm9yZz6IVwQTEQIAFwUCPGq1HwULBwoDBAMVAwID -FgIBAheAAAoJEKy3f8Lobims3E0An0x3rrUMIijUMFoqnoT7muNGwmAzAJ990TWj -dZO4ayh1M+cWhjaw9W+44bkBDQQ8arUkEAQApaMm5HUB1Yk2x5MavAs/O4zfWnOx -YFOeXIPfGvhlhF2/Lrjs9icaa/tOM/CTCes19nDWP5Fc+pQxmgSPrgt3fsShwZJe -p3iYodLbM76uXEgSvI4Wh6kwViHbN4V1GxJAd2ZPVb1v+lauGUCOgPFGw99UV9sO -tTRXSbFS6AgqQzMAAwUD/jq6boxlnab/GUmKrILeLkv1X0G2/AEXEGRmG0nkhVdj -OShoqtPr4y/UhMzJUOequs2CdvRlTIyAyZqN7A0Qp4mFfmsvp0dYYssTtE4bCzZe -WxSKgjtBWBHXnH+Qzjb5R2Tz28kAxNY+dt7yxC+CkXWDZq/rsPgsXNbWXT49FnF8 -iEYEGBECAAYFAjxqtSQACgkQrLd/wuhuKazl7QCfQkz5t/3T6EtXZCcXz/hlswyI -z30AoLr/7hwXgedEepBk/Gm9HUsbMnM8 -=S1mb ------END PGP PUBLIC KEY BLOCK----- - - -Type bits keyID Date User ID -pub 1024D/307A10A5 2002-07-18 Henri Gomez *** RPM SIGNING KEY *** - - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.0.6 (GNU/Linux) -Comment: For info see http://www.gnupg.org - -mQGiBD02vbERBAC1v8fR6gjERpaz4UMfdy0hRVWCPSbOdF+Swm/IenjVzErco6zb -MTa13umUNrDPBy/tTWiCCZrOnqi7fgDzWqPEqrXJjKAFVLEWE6MmKylPPEPG1/bm -idkNGERSAZduvhKv777PzvEJJ/8eGe3wy/O8NbgIjCPtr4UklwCZS8cFuwCg8oMO -UdT8qZRtzdxdAyu1m5fUb+MD/3IKJYWXsdtb6iBphCU4f/BoyjVC9EZJ1ywLuiVM -siKbuaDUaXU9nWcbNKv+fx8uZ1NaadpfLokqqhnWcpnSiqw8HNR7SwsF1D33rkXK -O4FSuVss/tIoqGdWFcJyPkP4yP5shxqR335narVw2vDa0+BiWkALbA2qVsSIdZDB -LeFZA/47AMBS0U2BRk2rQT8LmMuFl7mR+wNBM4n7FUGdxsGn3TcYd4pXTNrEQPrV -YNdooKlikgGk4hgFnIFX09Spmimqgq0goFue81rttVdZZ4uep8dTghY6gwmvcOxX -jATbhWStBhdu9B35kzfHc+1QihD5Z94u4uyWIVBIzikcdiY8LbQqSGVucmkgR29t -ZXogPGhnb21lekB1c2Vycy5zb3VyY2Vmb3JnZS5uZXQ+iFcEExECABcFAj02vbEF -CwcKAwQDFQMCAxYCAQIXgAAKCRAZMdaEMHoQpYijAKCCP68ndU/kTXR9XAKLvibC -3S8+1QCfUFQYte3Jo+MHKaWjsu9JGptRzo+5Ag0EPTa93RAIAKlsRJ5gOGTFsmaR -W9k6MIh4c/MCy7J7HUxT5xTdHROa+3zUh+FAE/JaOx9ZtZtH863DFHA8cP4L+tpi -PjBT6g2E94dwGcuH/OiSSCT4JSBukbGbOuLLdmFXqUl8+4gsL90Xal67FtNLwyLG -1n7geLir0byD+OT7VLA5w+6G0NOpJEveV/FIa2qLgdRZ8vz73ybgMh18hBUrUmro -jncp0rln2VU7VCH1C2aClKm7kK4mGAjIFIzKbguK+kM3b8NDHmXKpT6syyCtIM3h -prkV1TUCAFqLI32aSdlTN79lpeA2zDga9k4/4X/RDHsFpRN2neRFGTNUtuUgYpQQ -E5zWBmMAAwUH/RiGxyeBsad923IwE1+GAjxFl2tqF9xWk0J6yTnSK4nfhYAE9evV -jwDEok9jRl4ILCcXx6YN/d/lWNuSbARKHz/3hLiTouPpwd3SSJ8is2x9PgpJz5JX -cD0y1SkbPLvs3jH3ZmdcxZpuAmJeI/typqFKK5pWP44oXIH+XH/8nWDtmLEBkgKQ -/ATQWenMTmZ6MIJ6aWKWGkO9QS6iYRz3PPPGQ1O8W02CeprM2wBtlb8J1Z3RxNhM -rZcg/1Qi3V3D1HI4zw6tAFmDeBb8J4PaBQzqlhzx2EBTbfwNPhV8AlPvpxHEeGGn -v+O1yhZr33SnyZdINNoNDn+owVMdmkobe9GIRgQYEQIABgUCPTa93QAKCRAZMdaE -MHoQpRsTAJ4qst3MhLm48fBAEnzuzi/BIKr+AgCfYaCB/AvPoncQbHc8BcNGRimR -P9A= -=hQhz ------END PGP PUBLIC KEY BLOCK----- - -Type Bits/KeyID Date User ID -pub 1024D/564C17A3 2003-01-11 Mladen Turk - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.0.6 (MingW32) - -mQGiBD4fwXIRBAC7WRS8PYxi2YH0T1mX4HCYsF8aHoqxBzMnyFR4J896m1s96vGM -BTSAwH2NKbiVqtfLokTbQkUVxtrgrF2HMB5NfYBg/JzT7pZL/Q2ThWUS7SJQQA4f -a7/DpiLiHalp6iX45om6JTdIWEyXv26csIVhmtlkGBEPRhNRX8X4//BM0wCg7wcA -yQ7c5NmoOJLVs+uHsRrnHo0D/R/dMyuWt7/o0eGIEuRlDl2q+YL8xLuVyJMXQBnd -jo7jKpQ+Q1zl93aVTzsJa7mP2zZ7jqaJ855sdz6rvwyhGF1/qYMtm6zrmgBy2XPm -J+57sfwSZr0bhIeMpCWjIw98z9sObq0v2r2oA3+J9E3Na/BZsCVTZVb3ew7ILmEp -F5D7A/4zvjY41dakCAJsD1Xo8TS6hSqJf4zq9vX3ayJVvUjeo8n4sHNOwcbEnnui -9zZaUH3F0x+3cDo7mS1Y4pD8THuqCZoSbSkiHnlved6nLXsKbqvVrVo+esEhfZCn -Iji3gp+2TVNwdHXGM+4BAzMJCLsdXjByO6SNzB9a+H8RsRlZKrQ8TWxhZGVuIFR1 -cmsgKCoqKiBERUZBVUxUIFNJR05JTkcgS0VZICoqKikgPG10dXJrQGFwYWNoZS5v -cmc+iF0EExECAB0FAj4fwXIFCRLP94AFCwcKAwQDFQMCAxYCAQIXgAAKCRAcUGQH -VkwXo0jxAKCgHzXPIB4IAgoD7GMAohPQfX7j2QCeL6pAsf4pPufmPvbrrpDp6rQH -GOS5Ag0EPh/BhhAIAKWzq7+/+nNYGpc7sXGkDNo9xncxcx/KbbJVT0rBteuaonQ4 -vYar1ITjIhOPmF9yPmpUddNrqgQTSO+Or+ZrVOndn+qC1gdY3qpKIN3KTjXloW38 -0Y84ezwdRLznQNkhgXwNcB55l/Z9kLaW2MS8CJzOuYSQT1CYbXg7XP3684ZmV1KC -cGgcUt9VkIGqwsa2RFDNGvMbySedSkJ/70Q+PJlkXN+W86f8hi3HTjw2MCkNa5NL -+Byg8FEAm95YWrO6kCY3qaJYV7NRt9oVd+2V/NNzwYp3Or/QoYofvfNerupfwBmU -GEXPyZCqqNH6nDv6chscsWvEA9KzhsWnsdKhmHsAAwUH/R6LwfWgtpaO42dQI4ZS -VRBmCeWrXCuyVk0d13Yz0xLi5Z5m4g3MON3d+cRVUiyNX+hbDGpi2mkbsnL559Ef -iqmzDmSz5GQHDutolhOPtLxLrC537ODn2q7hnYQwIQYYIUtYD5sYlzfGYC8olGCB -IcKIdlGRWcxxiFCIJm5CX/jnSBsyDRpanlSrdkxhzAGsifqj4NQ19ayoeNoZg2ZP -9SLIY7vbmOxJeHEYkx8AG25xOY1PLotb/0buSXPB8e71zb/DCV1rAhhUxAr/2JOQ -RqlZBq6PfcHKLRitXRCeVvfldRxuWBIzhuTLUfRPYR6phjP50EzZPlbJzIvGwsOI -RheITAQYEQIADAUCPh/BhgUJEs/3gAAKCRAcUGQHVkwXoy0JAJ9WTfqfYzW/F6qi -5MxmqDnU9/G+6ACfQVmhZNnGTSfcwQCttwCaW3CRhDY= -=MWUr ------END PGP PUBLIC KEY BLOCK----- - -Type bits keyID Date User ID -DSS 3072/1024 0x7C037D42 2003/08/05 *** DEFAULT SIGNING KEY *** - Yoav Shapira - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: PGP 6.5.8 - -mQGiBD8u/mgRBAD5WKD5xF3CLrnABeS1DvQQhYH+tJjvAmyZgFkYwaQT7eiiOzLa -PC5knbcBC4nuw+8OOPDFw0Ghb2MFogQzRxD6gpPH2t9eEUsrkPFax2Kw2vNTHRrQ -RGAastmi+EYJsQAoktX2dPseTdrkeJBk240Bfj08ZUFg4uPuho9C45ND6QCg/6SO -FMuan62QE+DwlUiMDo4ZcU0EAMDS8k6Dhb5m/0njO6w9OLTEyzohlsM9AP+4mfgB -NOJYhrzfkFoElOcWSA/V3nmYn2VS0oIYDDtBnjXVWZidzTAWKsbT9/AepS3/P2tG -KMhlXhas+uAiAbMpOglz8fdQ76ivQqyRdS99t4iy/cP2ZC3ShAqZQCacfWY5ZQ8Q -kTILBADvp/eayw8fvtfWQXJ9EjBRbhO4THmP6z8J+4ypG6l0V/RBjDWZybrqibO9 -ejnOjQYJNCnfrfpzQ5l6dHyy86zLyg+bkFxeId4jp/IfDfJX90sGbuQahNYYwqTp -SFiDMI3KN5ZhzhGnx+pKQh59pcux3HyKmcpPa4oB0CT828lWuLQfWW9hdiBTaGFw -aXJhIDx5b2F2c0BhcGFjaGUub3JnPokATgQQEQIADgUCPy7+aAQLAwECAhkBAAoJ -ECZhkcN8A31CGLkAoPRDGtLRwjkzS2F/OBPkRHKF9/atAKCIh3Fmcr2Cdn05P4qF -kBe3QeWVt7kDDQQ/Lv5qEAwAzB13VyQ4SuLE8OiOE2eXTpITYfbb6yUOF/32mPfI -fHmwch04dfv2wXPEgxEmK0Ngw+Po1gr9oSgmC66prrNlD6IAUwGgfNaroxIe+g8q -zh90hE/K8xfzpEDp19J3tkItAjbBJstoXp18mAkKjX4t7eRdefXUkk+bGI78KqdL -fDL2Qle3CH8IF3KiutapQvMF6PlTETlPtvFuuUs4INoBp1ajFOmPQFXz0AfGy0Op -lK33TGSGSfgMg71l6RfUodNQ+PVZX9x2Uk89PY3bzpnhV5JZzf24rnRPxfx2vIPF -RzBhznzJZv8V+bv9kV7HAarTW56NoKVyOtQa8L9GAFgr5fSI/VhOSdvNILSd5JEH -NmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsYjY67VYy4XTjTNP18F1dDox0YbN4z -ISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWakXUGf -nHy9iUsiGSa6q6Jew1XpTDJvAAICC/4iJF383WNktP9/SxeGVIV74r7C7q5Cxr4a -Liy7pEYs52DEft3JzTCLI5O4+NjOw+hEd3QiIytUJRW66V6zd50h4x9lBfK+eMYz -GKNN7kd3aBmH/vXEsG9m9bK1ExwyWq4uyf76nRx1Ya9YthNWmxPUHQnSrOYNPU0/ -beA87ouZG4RL9tYqdu3NKJ4g/DYiaw+twvhSoCUkBEFHFfKLDlv8zyQvPTaPUSAM -Ha5/G2Dj1D5RluMSCEMG1V8+YcYAFh63WEP7Afye0mR1LMJvmlba67ogh0ZSfR+I -ju3lhJ9XOp/2W372F9ZbRJofgofVwHQV6INB5uX7KHAdXtPTss+l1nTmydLhsiPC -5oh99ITPdOm8gRzrP10aFwCnwsqXvr+b7fX/CywpuCOQMIr4sbhbYTTClwDo6E0U -TQ+Nb7PWE+8KuJuobTvMUqDQSQaQBnkpLcvRt3cPppANtkaADAeNf0RqKxxLlym4 -AltN8G8IMLtSJoH9xlQHTQA4tEUeKOeJAEYEGBECAAYFAj8u/moACgkQJmGRw3wD -fUJh7ACdE7QuMkzSbxEzTXnbkS61AUPy06QAoI5b613vrWeqg5Gz9C7TzG+FEEoh -=O17Z ------END PGP PUBLIC KEY BLOCK----- - -pub 1024D/33C60243 2004-09-12 - Key fingerprint = DCFD 35E0 BF8C A734 4752 DE8B 6FB2 1E89 33C6 0243 -uid Mark E D Thomas -uid Mark E D Thomas -uid Mark E D Thomas -sub 2048g/0BECE548 2004-09-12 - -pub 4096R/2F6059E7 2009-09-18 - Key fingerprint = A9C5 DF4D 22E9 9998 D987 5A51 10C0 1C5A 2F60 59E7 -uid Mark E D Thomas -sub 4096R/5E763BEC 2009-09-18 - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.9 (MingW32) - -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 -bqWz71CpA7oP5jvoHaPqUihfWEugzOUbQnUzSauDWWOdMqQW+UUo/iDRz6HCKdlf -ww0288krLusAEQEAAYkCHwQYAQoACQUCSrQO6QIbDAAKCRAQwBxaL2BZ5y3tD/4t -+KCuXBNi5alBCExHEzveMdRF9FJrSqJEX0NwGFivF3hQ/HJkrcu9oTJC/tXNFf/+ -EHOd0lMiyFl5PBSlhe4XS988rgapUW+ee9tQmAt+RgP40fdKdJNb6+9NYGmrdnDU -zlQtP+h/XBOcmF0/szK/U0oigg8DjYYUm5gCWXOl9H4LJgg+yOcVCOVa4oTf1sdA -mQba1xlMhOIYBWmEhqbWZpGOS59XvpyNfOQXWu26S8HACBqyPZ2LVV4H+9cmxinT -z7RX1yKD17nLZ/fTOzZ1gYTbhg5rNmFpDgu3nlgU8SpGQ1kd70ZkcudgehsUe1Ep -Pyl7O8qhj5H0/3OAmRXzrq2VF17gtz7zpntA0JqsBMbSaK5qBuBcurLhBT634WDI -oE8u5Em1UwjgTI0Cx/lPxRTbIb4PfjP2b2ik/tJaUbwUrhuZ4LAtGztMVrF4W+qn -x9oed4OFXMBbwgS+SH6oAHlGwpxhhzXBlqZsHXm+w+2oazWUhxFFGEe5U245GEtN -f0AznBMDWTqg0SCVEDjlKt+e9tVXkTpHYWZjGbRZbEHkCbFqKhq0KP5BGInFZTFT -oI5jjszmuX0W/yKpRpQZ+GuJnt4VrYSy7TMvjjhIpuhDY57VUwUIkz/2Kq8Vg2wp -Gg+29nvcGOTdyZUcTCEB33B2jQ9z0XUEp+6B2F5iZQ== -=hSkx ------END PGP PUBLIC KEY BLOCK----- - -pub 1024D/288584E7 2008-07-02 -uid Rémy Maucherat -sub 4096g/4B6FAEFB 2008-07-02 - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.9 (GNU/Linux) - -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 -SiHKkU7BarrCyjm1Kg== -=1Oke ------END PGP PUBLIC KEY BLOCK----- - -pub 1024D/0D811BBE 2006-11-14 - Key fingerprint = F3A0 4C59 5DB5 B6A5 F1EC A43E 3B7B BB10 0D81 1BBE -uid Yoav Shapira -sig 3 0D811BBE 2006-11-14 Yoav Shapira -sub 2048g/286BACF1 2006-11-14 -sig 0D811BBE 2006-11-14 Yoav Shapira - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.5 (MingW32) - -mQGiBEVZ4AwRBAC9WDbCjRX9Q81Con7cycGkkui6JZndLhX3Jbzlc/eHG0/fUetP -0c5ZdIvTyjj+L/DRI6btrgl+jR64qkuapsYD/KDXQGkpK5zPpmxUPmXJ5tfVTbOj -gacUm2cZjYjSK3dsIs4sDUqNYfBfdwesJ+Hycc7XqkTF1lO2MN9yp8g+4wCg0W8x -/ZYCTb9D8JOPzfSNf8cIFCkD/j5GXA2xlSXuAFBgWpFak5OkeF8cwEkv0CQ0zCqP -R/rTmDGO/73dpQEzgY+gLMSvtkK0pVEYaE15lg2mxma9d0pGE+fmsu5w7SQUip15 -HN5E3qP/VB4X1yp+YiHPGTDjRgJm+xbvTGSFFr0wNSSYCVpVGdYHNmetYsB5JqkH -YmiWA/4vnkWnkzQeUNNPvep0lSrEG9jiON4k/d5opWwjxIP4aev8V7//V9ASzznF -D6eEL23ePX5ZuKLyDeOSRAwaPpa/Rp4AkiUGzKK21wAwKip+lcbT5m2ButoQhgNI -ZlmnfhN7E2t2S6iS9VzHEo1S8Jv9uQZJ89Tp5fiFe1pXL2qBHrQhWW9hdiBTaGFw -aXJhIDx5b2F2c0Bjb21wdXRlci5vcmc+iGAEExECACAFAkVZ4AwCGwMGCwkIBwMC -BBUCCAMEFgIDAQIeAQIXgAAKCRA7e7sQDYEbvgiLAKDHEgeJyxlrxNJ4m51jOnhG -xlsLOQCbBWAdTjpMVcNqmd6Fa5fgyCbh8XS5Ag0ERVngFBAIAIEVU1iOoq4CyD3I -f+AChfSFAgqjKmjqEyPv2RDLPkI3g2FvC6HvOlUucIe6IjqvTXztdxSRQu2EGq5i -W8e5ajTZiI9ZNs26XLL4/q/gYRaDjUsI7J3PAOL9lNdws6ZoqlCh44R/cvekuixx -HoHGskGxAHBRdjv9Oqy4x5hR5kebGq9Ayf8CQZ3l7aRekwlMUyCsmMkNxmqMls2g -ViBFD0/9a/xodE2VMVMg5eQ8A0enlrGDghG9d2m586JtOje55rMVnVPkEuNkz9AC -DkR0CiwQqX72Ub10t/qcNqbDeMHFacOBYRKfS7Qdm3/jb8Tc4jO/AXFcUGbH5niz -pPGs+UMAAwUH/1M2unaFyfJddVPQRZCJEFxdlxkg40tewgjaNJLwnqOJXw1RENNM -bSx4Gvz8M6WvZtkvITt29P+O4EmGq+LYTKmLM/E399KuqoZGbyCu3Gm+RIxKmRkf -Y3izseOhrUX2ycUIOF1BFzIYs6HeO/sZeba1bapOFo/xS6NwnuJl6uXUmynGjVtY -gvQ+dLYAcDXUQJd+QjyXdsbnp1jmdSrqqscPGOquRAw7/sp/ivom4DDHMTz4HErz -NfHzn4z8kUE7T1EEpnFU4SBiJkpm/+yEhEq9hDG2GZmxfQd34iRXpC5B4ZbRiwW8 -p/bhzvcxZcrahQzu5yyq2+kGhK7IA9APFGSISQQYEQIACQUCRVngFAIbDAAKCRA7 -e7sQDYEbvppSAJ9+i7TzCNvZ4PK/odiIWeZ61+KKyACfSjQXnC5UbxndwtkOzFKf -Io8ZP0E= -=xT1M ------END PGP PUBLIC KEY BLOCK----- -pub 4096R/731FABEE 2011-05-27 - Key fingerprint = 9BA4 4C26 2138 5CB9 66EB A586 F72C 284D 731F ABEE -uid Tim Whittington (CODE SIGNING KEY) -sig 3 731FABEE 2011-05-27 Tim Whittington (CODE SIGNING KEY) -sub 4096R/461B342D 2011-05-27 -sig 731FABEE 2011-05-27 Tim Whittington (CODE SIGNING KEY) - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.11 (Darwin) - -mQINBE3fcdABEADmpbGMmnQiMc4biU+CIhV6EJ7lBaRzXzh4tJ4eITfw6IbImDRn -0JHZNjeE5zXLeH0PQ0K8/bYzFhMGwQOgvZETV7LPVLid6F9LbvDnItcWyoiZ+HPG -9SNdxIAsIVxchW6j/4NcIWaEwJks/+3vveBbRc1q0UgL5b72Yxpwwk3o6LMb08vJ -wn0LuljqM/+MHc+/KuxO54jJZ2OwNbKr2cxsYwVCpj+vEF6wNh2s6v+5VLs7NimN -UufiKVGcz6fceza3eYOS+0aLe4JXUPfmbad55x7H7wGMbfv+XLsBUKJ9Bz5nF3QD -jLwGBId8/K51yXGqZUqwjzTkhIalJeZEMZuAxGkLXsYM47OH/BGPNvqfcX6X+17i -9urz5go5kWQJJLGiBDVxiwpyrcZfrqc2I0DicLUsAbdyd6q6gkEcQKLCFmm9GTW8 -c0Bb/kqlfGnDcBBl3kwK8MvvTeEAq7mteZEEOu/aV+417qDx+dNzFIx/jVjkihnC -O10vIXKmog8Dy36gNuJdnqsNuV8oGK4vPRFy80XajmYBl94xfR/ZsWWo7y66UGQr -NsCrCC+DV/AlDMJE8fjoLKyTtGnu7U5keyiuUIPvDurbrn2JKGefRnlRAoXRWdiO -nzO7vBbfOQ4g3pjUwuXqQTBzqHwnL9z8gX/MR0Wm5RU+B0ZielPkrt82YQARAQAB -tDRUaW0gV2hpdHRpbmd0b24gKENPREUgU0lHTklORyBLRVkpIDx0aW13QGFwYWNo -ZS5vcmc+iQI4BBMBAgAiBQJN33HQAhsDBgsJCAcDAgYVCAIJCgsEFgIDAQIeAQIX -gAAKCRD3LChNcx+r7gOgD/9DgtptXELyFxaazptqmNkjIp6X4JKjl1Kp99Aq2wwR -4DdHBbZNN2qpQ+Q66klxWeJRbf3t2z/4oCkY3G9g+UB0NTgZBcBMl9c4sDxYzlC/ -B9GaHTByaXLWhqv5I6IAiiECiyxhkAVHVqDYjpg5voCD0ZcYSWX9IMZLGAlBU2fe -/0g0QEaAV+4SSFsnp7xGaEwoFQd7VH9bS9Q8mdCPZf96Dz7S8XlSpm7Wc0Wvsd7z -wXGqmBZVQ0w4mVhGWeaaRUKuVn5nDF6djI+Erg079Vrla6pcXfoBiIugLOUhvvmv -Zb5yBi+RJ5CQAnb8ApKm1IXotUCq4GJ05SwDR7xvpS/s8BKIlXmY6h64q7sy66a1 -SdRtKL5dncVptknxVzyw3QjEMt9Q9v9W5kgeSabebjAztzPFRR9EBxWkcpL8lwml -bTSlheb/+fsEiE0Hw6460xCLPtLFm2RnigdacQgSffhtEzZ5OB7aoXRG/M1McN1v -zrjHxg8Vo7stPiGSSvWQKZJQFvWgFUbugoOum5GTNFJeHwlAyjBydkLJ0A/nwUgD -efXMV8a65+LUAFVJuEgnOw2Ut68bU96KOSHbNaauErqiWZlcnJIOqD3wRxB3OtBc -2lFL49n3bJ37k7CuhEZUAgU/cqN7meH0wo1aI4KOfo5PHm548qckLi4P/pAj8jHL -0bkCDQRN33HQARAAzeAQNb4AfB9v4r3qrN3bwF01VdMpVTaQl3RaJKGbdO52f4gW -8iIfR+Xc6ALeX/1ADsH6nyOuQ+gnTpf4Gr09Lf/EzcrJRN8okVFehjuaahWYdmbL -rln3ZorzbLxHp52dvLS1EX9L1+MEgGuUxsN9fDJSuif6f7+E/a80Q/WEbQ3261lB -f7GDSGvr3xz6M0OlTS08YgUeUsx33PQRHV1TU9RTSASsivy316u86gxMp+9PJ+6n -m99iNvZB1VXpthG6ybgyxhheQv1o2SBAhJ3Ee6Neds1kPkLiKiAbGq9K9IApqC8X -DYZ9FUYBT+CGm8KbU8QS10wJuIVIXRYuvNZBjjhZdbGIGJ2CGIn9cO8RmzDVVu0A -Ch9gCGh12Rsr4uZkY9tJ6/+s/ipHuft1AnPETbrET2Wm1rrUZ8sFykP6cOwP0gen -MNEjTAHnLE0x2yAjFfvjz/y0H+gMQqcbmyGvAgY0URl41+5+yxtLVJIcuszut77s -DV7sM8CoXz2I8/K+R/lB5p8d6AriAV+iYqzATmyfFD27GVHp18wTuyusfwy8301q -CqjZdR5cXQHcp+/yCxz/I+PXx21QE4e3nY8YpC6PWFC/XPy7s6L71uNauqPi5WwG -1CeYEwqd70Ds3aeVErYZxYg/kiInfFGnXjUplvz2goT3LQFWHFS5TN0sUqsAEQEA -AYkCHwQYAQIACQUCTd9x0AIbDAAKCRD3LChNcx+r7jscEADgCt4SmzeEWuU1fZYx -FsdnC3wLZUU57HnGMAQdxCzC6lMXNHUiS+y8of1TEYccjM8JK0zSTwnizhbQzOkh -ICR/0tGz3qCOAZjv91YHs5RcLzeWxbor29my4VlQU6vqEwOEPwFz1b1Grp2rbwhL -hot81tqv4PP/wn3ES/FIuTALZ3/hgunfGlO6FGZC20rtOJHd6DpX2ZPeYi2mfYom -KF9N7F9q0WhYn0GvMyV5pqZ6Ui7N8egvw1gokUtO3D8lWnjZy1BmbizozyLmrG13 -xr280Juv7zM0Jy5YR01vsqfvClBbczBzoEnkRijMYVJgUj03dr5Cdn5HFRfA5wLD -sNuSYKMTL/WWNQgIp24/MLxyYa4sVH9WMh9a7BbdRHJEjVR2HTA/lqrKVIfR6NwT -6DhThBA7XxGbQ9nuBOjClTpRBXyCnFN+krmyhvVk3caVcQu/BbaZZXFEuKhJzbon -YrQkfyvT/rQoM/ufLlIIPZgpKxP96a9zF/eyATiamAnU7idEHIZ0Drrj60vz4sPH -A5Ty5GWKYSZa6suPaalqZ+7dpD/UWiNMzSX+YPLQUW9jH/k7zuJ9aZN4AmIkm30c -YB5npZhfo59tF4uuvKvYKWghrF8wSwEE7F4cJAuqklo0TArBUd2WB0Wl8kAWtThf -/PLn/VX9dZEFVPVbPapJpkNv8A== -=Vxhw ------END PGP PUBLIC KEY BLOCK----- - -pub 3072D/0D498E23 2013-01-14 -uid Mladen Turk (Default signing key) -sig 3 0D498E23 2013-01-14 Mladen Turk (Default signing key) -sub 4096g/DC3D1B18 2013-01-14 -sig 0D498E23 2013-01-14 Mladen Turk (Default signing key) - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.12 (GNU/Linux) - -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 -XDH35tl64G5lNKNum0D8NSGV955R2g== -=gxY8 ------END PGP PUBLIC KEY BLOCK----- - -pub 4096R/D63011C7 2013-09-19 - Key fingerprint = 713D A88B E509 1153 5FE7 16F5 208B 0AB1 D630 11C7 -uid Violeta Georgieva Georgieva (CODE SIGNING KEY) -sig 3 D63011C7 2013-09-19 Violeta Georgieva Georgieva (CODE SIGNING KEY) -sub 4096R/30480593 2013-09-19 -sig D63011C7 2013-09-19 Violeta Georgieva Georgieva (CODE SIGNING KEY) - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v2.0.21 (MingW32) - -mQINBFI6WiwBEAD+kkswnsY8eaqvYkS+ZB5MJr7juWrv9Lw9OGsIXFlTvD1XK01c -E8k4+uA2sOtaXQ5wTMdc5N3YzAXqFxplWuafQgEvhyTTq37M5YCxvtYEZy/EHQYT -iok5H97lMRKbhLdZB+wkdsa0P/L1FveCUiEawKY/Rrfi+UeRAneSV+m7S+RrPphZ -M9aNSczqYKfAqlpUAlUcrF/bt59vjhepoHcE4ev6SB+PCs0vbvX4iTvvZCTk1lZ9 -InS2wdK80Jz9pRB0Uf3LEnZxt9e3RkIFdQOCcEISmNlBKQQKFG+zCpIAbVoMLKEw -rXWl8mLzGzBbhGmLpFroem3Ln1YiAxUqnPR/MoBquYnpTINwePgwKVWyQ1TXG2MF -Z7DPayBMN+G51rfLS/8iy35pAnNeqbWQjavdUis6/0aRMv5EYMFMAerutQ5v99bA -rGj6OL3R6repJLOGT4YWcD/Tw+eU1lMWxbq8BbbRU9Fd0iVFhFyKB/DQSxofvTCe -PdWXRrptrE0/SmvuoTRVPmB21WyJenKdNmVOQ6U+W1Rs+5IKAdWWrGPcUt0qTrRC -SL8vAQ7MejYLovFtRHslJRs7T3ratpRcQUNOx1jytJhmSUJktNWZWNHqBTe/eOAU -Yr+QAkQVQXvRVWzHkDHQRTOFmNYIDZYRkzSP19sBWRnYdCs6CbIVPgMJVwARAQAB -tEVWaW9sZXRhIEdlb3JnaWV2YSBHZW9yZ2lldmEgKENPREUgU0lHTklORyBLRVkp -IDx2aW9sZXRhZ2dAYXBhY2hlLm9yZz6JAjcEEwEKACEFAlI6WiwCGwMFCwkIBwMF -FQoJCAsFFgIDAQACHgECF4AACgkQIIsKsdYwEccMXA/+KMQKWfw2T2CXLhqvQLoh -Irj1Vi9leAttKqKp2NCHLK1jf1qKzUx5U81VvizIGUsDXGlAvnnavrj+hmQqZdsO -CoJAo7ViIR1ZhNca1tFK4Sy03wdpNyUkvxVuC+3peXmwhjPJoqU2ONCuDl/bCczl -QAQpgZCMO93h45U9H6JkjqK01aDorQHxvXo+Ap2IViQvDkNtJ515vG2k5K+x2XHw -Tv19wr5N2rz407TWKzS5hh7QHRgg+PZs/zPf1YHD7Tg5K6vvmZd+5EsDrse6tZXy -mzz2+8Yg1SNa765Aq6p1uAQf5NKeej/25TbRYT7RyIlgDXPcPrKxy0cKzpqFqCFs -jJEcN3NlQq+f1tOvUk8cQQS0G+Qws3EU7I74z8KaUfqmO/5ROrXLS50cKC9CODO0 -UFY8FbJDGzS5cFSBlqXYLeQvaOMg0LsV6wZLu6brxEsRYjSpwM8yBFO4bMcTxt4P -VYtinNZ+6ude8mMz6BK/0/XbAL6rc5jwO2xj7GTCFNRTWOa8IGtwqg3qnAiHcg/V -bTBQCOmzMujHBXLnZu6vg79BwzE7Ikq634D6HEwi1bC3XuVz+7NqdUQAGPSapwUo -+0wC5DVwdjhe1zWcf2Zc45HWsx0HaGW28x/tBrw78fgwrSSyV2xunbxGpVaaysTy -Oini8V70uLofn1SHtxvEQCm5Ag0EUjpaLAEQAKV7FnaAcxkzDa7zjrAgLRho44KM -+lBt28+5KO3Jye1Lpf2+4aspu0PXkGW2Twv2tBQNZYs2CWF+vnHNUDuU8TkSpPt+ -2PRSZrQ0K+IpQF/qY3Wf+LYWFNXk5/wHJLGiQv/008svtupng6Ov39JwCNQ1iG3d -nSWfnqHwQULyE7JcZf1It94G43+6NBvKakstOdK7d40dVhmRIKDdJkWhN3MKrGab -FGFAF2Nb57IugQ9QO6Ve/BnjKZmJg7TyUZk27LVTC0aUQgGgDOvsF2Iw95IplCZ/ -jVbwdBGjeCStvI3c0DB+E2xwJ0g2Wf/CBLvmU9GKOW0toBfRUXFbfzNTJfW8kglt -pDuELsVY5vHHxgujdDInHuTW1930zUw0cNA2+ai3sf+UGejh0e3nGfy1uOK3YQ6H -2YWgqXlOkri9pMlE0NJo/3PW9QDu0YRplGl65k+GtHD2La1akq5V5Et0VNaOypBP -OqnUM08LofAS126Kerm7uBSUQDDV6t1VTOBgPW5cJF9I8kdp04pzj4qb/3fuOuGc -kBRfmO/Vkug8U81w/TnxX6EYGy5fyA4JFBJl++waPS/9dXhVnA0qXEivzw9gNQvC -uXYcM3nm4yUrOouC/OlC1cS+6Wxjrx6qn3NnsVzMCtefNK93+TdheZ0cJrMhJKkW -v+qttOzPIleqvDK9ABEBAAGJAh8EGAEKAAkFAlI6WiwCGwwACgkQIIsKsdYwEcdN -tQ/+L8cw9Z9tfrqovO1fGFQwCSaomShsbjoUb5AR3Hj3OuPGwXd8J62mrw+RnGN+ -0w2RyTz52izYvcoB1jmMFQwqi7vM5KCbw6KA8oRX58WSqiWCIwpbUuTODvJrSXjX -pz/J/d+PVZi8T1HAu5HxDqNC1XR+eUd1xA9Pgnmmw99+0rmzES7xexWADXo/RRPH -mDCxGK3UKMHDYJLTx8D3MacMitzQulxVo9xWwH1C7ioL3o5zCv2mfIl32WNjqwpD -h4gNpnAGRthizeYTgyJM9nCrSWgeE+izGZ9F0g5uXzhyk1f6jlUmXiwjMu/XOcJO -5Rr1e42bWITuP49nB2QbdSqVvVscwCd5TEpOnQtVNZGsss/wQHXDmGSVrYYUQwO/ -cUrU+hTti1IJXgyFi7F1oxde+LCUxXmizKGoY96dVN+TYH5c17ub1/4/DYpOmcly -tsQ2TOV0BqK4rgKLGfg2mA4zIFOdqXeGefLQVAF5fFzjFKKDi0ewp3sqy+ed6mKY -1M/HmRX/YzIouFZ3ChFPIpeY23XxJC0BXkWR4pS7qxnelrWBZ+UbleNr9uHat5rC -B77712dCT9zz85b380DnuMkrgz4HCnHuTcbHXIF1J604lars6ZrjtBvX+OsRHt7V -f72qKJufP+n01xliW68LP4v93auM8nuE4kkEJ8ncHyuDq/Q= -=fM0q ------END PGP PUBLIC KEY BLOCK----- +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=l4Ry +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tomcat.spec b/tomcat.spec index 016cfff..7b86632 100644 --- a/tomcat.spec +++ b/tomcat.spec @@ -22,7 +22,7 @@ %define elspec 3.0 %define major_version 9 %define minor_version 0 -%define micro_version 43 +%define micro_version 75 %define packdname apache-tomcat-%{version}-src # FHS 2.3 compliant tree structure - http://www.pathname.com/fhs/2.3/ %global basedir /srv/%{name} @@ -77,23 +77,11 @@ Patch2: %{name}-%{major_version}.%{minor_version}-sle.catalina.policy.pa Patch3: %{name}-%{major_version}.%{minor_version}-javadoc.patch # PATCH-FIX-OPENSUSE: include all necessary aqute-bnd jars Patch4: tomcat-9.0-osgi-build.patch -# PATCH-FIX-OPENSUSE: cast ByteBuffer to Buffer in cases where there is a risk of using Java 9+ apis -Patch5: tomcat-9.0.43-java8compat.patch +Patch5: %{name}-%{major_version}.%{minor_version}-jdt.patch # PATCH-FIX-OPENSUSE: set ajp connector secreteRequired to false by default to avoid tomcat not starting -Patch6: tomcat-9.0.31-secretRequired-default.patch -Patch7: tomcat-9.0-CVE-2021-41079.patch -Patch8: tomcat-9.0-CVE-2021-33037.patch -Patch9: tomcat-9.0-CVE-2021-30640.patch -Patch10: tomcat-9.0-NPE-JNDIRealm.patch -Patch11: tomcat-9.0-CVE-2022-23181.patch -Patch12: tomcat-9.0-hardening_getResources.patch -Patch13: tomcat-9.0.43-CVE-2021-43980.patch -Patch14: tomcat-9.0.43-CVE-2022-42252.patch +Patch6: tomcat-9.0.75-secretRequired-default.patch Patch15: tomcat-9.0-fix_catalina.patch Patch16: tomcat-9.0-logrotate_everything.patch -Patch17: tomcat-9.0.43-CVE-2023-24998.patch -Patch18: tomcat-9.0.43-CVE-2023-28708.patch -Patch19: tomcat-9.0.43-CVE-2022-45143.patch BuildRequires: ant >= 1.8.1 BuildRequires: ant-antlr @@ -266,19 +254,8 @@ find . -type f \( -name "*.bat" -o -name "*.class" -o -name Thumbs.db -o -name " %patch4 -p1 %patch5 -p1 %patch6 -p1 -%patch7 -p1 -%patch8 -p1 -%patch9 -p1 -%patch10 -p1 -%patch11 -p1 -%patch12 -p1 -%patch13 -p1 -%patch14 -p1 %patch15 -p1 %patch16 -p1 -%patch17 -p1 -%patch18 -p1 -%patch19 -p1 # remove date from docs sed -i -e '/build-date/ d' webapps/docs/tomcat-docs.xsl