This is an automated email from the ASF dual-hosted git repository. jlmonteiro pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomee.git
The following commit(s) were added to refs/heads/main by this push: new b4e20cafcc Cleanup Santuario, WSS4J dependencies and patch CXF WSS4J Interceptor so we can upgrade WSS4J + Use BouncyCastle jdk15to18 instead of jdk15on b4e20cafcc is described below commit b4e20cafcc765e544ee98725a2a0311c18d5ee30 Author: Jean-Louis Monteiro <jlmonte...@tomitribe.com> AuthorDate: Tue Nov 15 21:50:20 2022 +0100 Cleanup Santuario, WSS4J dependencies and patch CXF WSS4J Interceptor so we can upgrade WSS4J + Use BouncyCastle jdk15to18 instead of jdk15on --- boms/tomee-microprofile/pom.xml | 11 + boms/tomee-plume/pom.xml | 11 + boms/tomee-plus/pom.xml | 13 +- boms/tomee-webprofile/pom.xml | 2 +- deps/cxf-shade/pom.xml | 11 + .../java/org/apache/cxf/common/jaxb/JAXBUtils.java | 1180 ++++++++++++++++++++ .../security/wss4j/AbstractWSS4JInterceptor.java | 228 ++++ pom.xml | 3 +- server/openejb-client/pom.xml | 4 +- server/openejb-cxf/pom.xml | 4 +- server/openejb-ssh/pom.xml | 4 +- tomee/tomee-embedded/pom.xml | 6 +- 12 files changed, 1465 insertions(+), 12 deletions(-) diff --git a/boms/tomee-microprofile/pom.xml b/boms/tomee-microprofile/pom.xml index 59b0a548e6..96ef39888f 100644 --- a/boms/tomee-microprofile/pom.xml +++ b/boms/tomee-microprofile/pom.xml @@ -1679,6 +1679,17 @@ </exclusion> </exclusions> </dependency> + <dependency> + <groupId>org.bouncycastle</groupId> + <artifactId>bcprov-jdk15to18</artifactId> + <version>1.70</version> + <exclusions> + <exclusion> + <artifactId>*</artifactId> + <groupId>*</groupId> + </exclusion> + </exclusions> + </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk18on</artifactId> diff --git a/boms/tomee-plume/pom.xml b/boms/tomee-plume/pom.xml index 0c85b7d6d4..852332a6fb 100644 --- a/boms/tomee-plume/pom.xml +++ b/boms/tomee-plume/pom.xml @@ -1790,6 +1790,17 @@ </exclusion> </exclusions> </dependency> + <dependency> + <groupId>org.bouncycastle</groupId> + <artifactId>bcprov-jdk15to18</artifactId> + <version>1.70</version> + <exclusions> + <exclusion> + <artifactId>*</artifactId> + <groupId>*</groupId> + </exclusion> + </exclusions> + </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk18on</artifactId> diff --git a/boms/tomee-plus/pom.xml b/boms/tomee-plus/pom.xml index ca9c5d777f..f372efe9d9 100644 --- a/boms/tomee-plus/pom.xml +++ b/boms/tomee-plus/pom.xml @@ -913,7 +913,7 @@ <dependency> <groupId>org.apache.santuario</groupId> <artifactId>xmlsec</artifactId> - <version>2.2.3</version> + <version>3.0.1</version> <exclusions> <exclusion> <artifactId>*</artifactId> @@ -1823,6 +1823,17 @@ </exclusion> </exclusions> </dependency> + <dependency> + <groupId>org.bouncycastle</groupId> + <artifactId>bcprov-jdk15to18</artifactId> + <version>1.70</version> + <exclusions> + <exclusion> + <artifactId>*</artifactId> + <groupId>*</groupId> + </exclusion> + </exclusions> + </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk18on</artifactId> diff --git a/boms/tomee-webprofile/pom.xml b/boms/tomee-webprofile/pom.xml index c4dac6e3b6..37c1077950 100644 --- a/boms/tomee-webprofile/pom.xml +++ b/boms/tomee-webprofile/pom.xml @@ -1197,7 +1197,7 @@ </dependency> <dependency> <groupId>org.bouncycastle</groupId> - <artifactId>bcprov-jdk15on</artifactId> + <artifactId>bcprov-jdk15to18</artifactId> <version>1.70</version> <exclusions> <exclusion> diff --git a/deps/cxf-shade/pom.xml b/deps/cxf-shade/pom.xml index d394b0cb0f..60bc93a1ba 100644 --- a/deps/cxf-shade/pom.xml +++ b/deps/cxf-shade/pom.xml @@ -117,6 +117,7 @@ <artifactId>cxf-rt-transports-http</artifactId> <version>${cxf.version}</version> </dependency> + <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-ws-security</artifactId> @@ -127,6 +128,12 @@ <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> </exclusion> + + <!-- we need this so it compiles the patch for the interceptor --> + <exclusion> + <groupId>org.apache.wss4j</groupId> + <artifactId>wss4j-ws-security-dom</artifactId> + </exclusion> </exclusions> </dependency> <dependency> @@ -368,6 +375,10 @@ <dependency>org.springframework:spring-context:jar:5.3.6</dependency> <dependency>org.springframework:spring-core:jar:5.3.6</dependency> <dependency>org.springframework:spring-webmvc:jar:5.3.6</dependency> + + <!-- We patch the interceptor so it's compliant with WSS4J 3.0.0 which is picked up in openejb-cxf --> + <!-- adding here because we don't want to shade it in cxf-shade jar --> + <dependency>org.apache.wss4j:wss4j-ws-security-dom:jar:3.0.0</dependency> </dependencies> </configuration> <executions> diff --git a/deps/cxf-shade/src/patch/java/org/apache/cxf/common/jaxb/JAXBUtils.java b/deps/cxf-shade/src/patch/java/org/apache/cxf/common/jaxb/JAXBUtils.java new file mode 100644 index 0000000000..d538a030af --- /dev/null +++ b/deps/cxf-shade/src/patch/java/org/apache/cxf/common/jaxb/JAXBUtils.java @@ -0,0 +1,1180 @@ +/** + * 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.cxf.common.jaxb; + + +import java.io.BufferedReader; +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Target; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.lang.reflect.Type; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.charset.StandardCharsets; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.StringTokenizer; +import java.util.logging.Level; +import java.util.logging.Logger; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBElement; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import jakarta.xml.bind.PropertyException; +import jakarta.xml.bind.SchemaOutputResolver; +import jakarta.xml.bind.Unmarshaller; +import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.attachment.AttachmentMarshaller; +import jakarta.xml.bind.attachment.AttachmentUnmarshaller; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; + +import org.xml.sax.EntityResolver; +import org.xml.sax.InputSource; + +import org.apache.cxf.Bus; +import org.apache.cxf.common.classloader.ClassLoaderUtils; +import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.common.spi.ClassLoaderService; +import org.apache.cxf.common.util.CachedClass; +import org.apache.cxf.common.util.PackageUtils; +import org.apache.cxf.common.util.ProxyHelper; +import org.apache.cxf.common.util.ReflectionInvokationHandler; +import org.apache.cxf.common.util.ReflectionInvokationHandler.WrapReturn; +import org.apache.cxf.common.util.ReflectionUtil; +import org.apache.cxf.common.util.StringUtils; +import org.apache.cxf.common.util.SystemPropertyAction; +import org.apache.cxf.common.xmlschema.SchemaCollection; +import org.apache.cxf.helpers.JavaUtils; + +public final class JAXBUtils { + public static final String JAXB_URI = "http://java.sun.com/xml/ns/jaxb"; + + private static final Logger LOG = LogUtils.getL7dLogger(JAXBUtils.class); + + public enum IdentifierType { + CLASS, + INTERFACE, + GETTER, + SETTER, + VARIABLE, + CONSTANT + }; + + private static final char[] XML_NAME_PUNCTUATION_CHARS = new char[] { + /* hyphen */ '\u002D', + /* period */ '\u002E', + /* colon */'\u003A', + /* dot */ '\u00B7', + /* greek ano teleia */ '\u0387', + /* arabic end of ayah */ '\u06DD', + /* arabic start of rub el hizb */'\u06DE', + /* underscore */ '\u005F', + }; + + private static final String XML_NAME_PUNCTUATION_STRING = new String(XML_NAME_PUNCTUATION_CHARS); + + private static final Map<String, String> BUILTIN_DATATYPES_MAP; + private static final Map<String, Class<?>> HOLDER_TYPES_MAP; + private static ClassLoader jaxbXjcLoader; + private static volatile Optional<Object> jaxbMinimumEscapeHandler; + private static volatile Optional<Object> jaxbNoEscapeHandler; + + static { + BUILTIN_DATATYPES_MAP = new HashMap<>(); + BUILTIN_DATATYPES_MAP.put("string", "java.lang.String"); + BUILTIN_DATATYPES_MAP.put("integer", "java.math.BigInteger"); + BUILTIN_DATATYPES_MAP.put("int", "int"); + BUILTIN_DATATYPES_MAP.put("long", "long"); + BUILTIN_DATATYPES_MAP.put("short", "short"); + BUILTIN_DATATYPES_MAP.put("decimal", "java.math.BigDecimal"); + BUILTIN_DATATYPES_MAP.put("float", "float"); + BUILTIN_DATATYPES_MAP.put("double", "double"); + BUILTIN_DATATYPES_MAP.put("boolean", "boolean"); + BUILTIN_DATATYPES_MAP.put("byte", "byte"); + BUILTIN_DATATYPES_MAP.put("QName", "javax.xml.namespace.QName"); + BUILTIN_DATATYPES_MAP.put("dateTime", "javax.xml.datatype.XMLGregorianCalendar"); + BUILTIN_DATATYPES_MAP.put("base64Binary", "byte[]"); + BUILTIN_DATATYPES_MAP.put("hexBinary", "byte[]"); + BUILTIN_DATATYPES_MAP.put("unsignedInt", "long"); + BUILTIN_DATATYPES_MAP.put("unsignedShort", "short"); + BUILTIN_DATATYPES_MAP.put("unsignedByte", "byte"); + BUILTIN_DATATYPES_MAP.put("time", "javax.xml.datatype.XMLGregorianCalendar"); + BUILTIN_DATATYPES_MAP.put("date", "javax.xml.datatype.XMLGregorianCalendar"); + BUILTIN_DATATYPES_MAP.put("gYear", "javax.xml.datatype.XMLGregorianCalendar"); + BUILTIN_DATATYPES_MAP.put("gYearMonth", "javax.xml.datatype.XMLGregorianCalendar"); + BUILTIN_DATATYPES_MAP.put("gMonth", "javax.xml.datatype.XMLGregorianCalendar"); + BUILTIN_DATATYPES_MAP.put("gMonthDay", "javax.xml.datatype.XMLGregorianCalendar"); + BUILTIN_DATATYPES_MAP.put("gDay", "javax.xml.datatype.XMLGregorianCalendar"); + BUILTIN_DATATYPES_MAP.put("duration", "javax.xml.datatype.Duration"); + BUILTIN_DATATYPES_MAP.put("NOTATION", "javax.xml.namespace.QName"); + + HOLDER_TYPES_MAP = new HashMap<>(); + HOLDER_TYPES_MAP.put("int", java.lang.Integer.class); + HOLDER_TYPES_MAP.put("long", java.lang.Long.class); + HOLDER_TYPES_MAP.put("short", java.lang.Short.class); + HOLDER_TYPES_MAP.put("float", java.lang.Float.class); + HOLDER_TYPES_MAP.put("double", java.lang.Double.class); + HOLDER_TYPES_MAP.put("boolean", java.lang.Boolean.class); + HOLDER_TYPES_MAP.put("byte", java.lang.Byte.class); + } + + + /** + * prevents instantiation + * + */ + private JAXBUtils() { + } + + public static void closeUnmarshaller(Unmarshaller u) { + if (u instanceof Closeable) { + //need to do this to clear the ThreadLocal cache + //see https://java.net/jira/browse/JAXB-1000 + + try { + ((Closeable)u).close(); + } catch (IOException e) { + //ignore + } + } + } + public static Object unmarshall(JAXBContext c, Element e) throws JAXBException { + Unmarshaller u = c.createUnmarshaller(); + try { + u.setEventHandler(null); + return u.unmarshal(e); + } finally { + closeUnmarshaller(u); + } + } + public static <T> JAXBElement<T> unmarshall(JAXBContext c, Element e, Class<T> cls) throws JAXBException { + Unmarshaller u = c.createUnmarshaller(); + try { + u.setEventHandler(null); + return u.unmarshal(e, cls); + } finally { + closeUnmarshaller(u); + } + } + public static Object unmarshall(JAXBContext c, Source s) throws JAXBException { + Unmarshaller u = c.createUnmarshaller(); + try { + u.setEventHandler(null); + return u.unmarshal(s); + } finally { + closeUnmarshaller(u); + } + } + public static <T> JAXBElement<T> unmarshall(JAXBContext c, + XMLStreamReader reader, + Class<T> cls) throws JAXBException { + Unmarshaller u = c.createUnmarshaller(); + try { + u.setEventHandler(null); + return u.unmarshal(reader, cls); + } finally { + closeUnmarshaller(u); + } + } + public static Object unmarshall(JAXBContext c, + XMLStreamReader reader) throws JAXBException { + Unmarshaller u = c.createUnmarshaller(); + try { + u.setEventHandler(null); + return u.unmarshal(reader); + } finally { + closeUnmarshaller(u); + } + } + + public static String builtInTypeToJavaType(String type) { + return BUILTIN_DATATYPES_MAP.get(type); + } + + public static Class<?> holderClass(String type) { + return HOLDER_TYPES_MAP.get(type); + } + + /** + * Checks if the specified word is a Java keyword (as defined in JavaUtils). + * + * @param word the word to check. + * @return true if the word is a keyword. + * @see org.apache.cxf.helpers.JavaUtils + */ + protected static boolean isJavaKeyword(String word) { + return JavaUtils.isJavaKeyword(word); + } + + /** + * Generates a Java package name from a URI according to the + * algorithm outlined in JAXB 2.0. + * + * @param namespaceURI the namespace URI. + * @return the package name. + */ + public static String namespaceURIToPackage(String namespaceURI) { + try { + return nameSpaceURIToPackage(new URI(namespaceURI)); + } catch (URISyntaxException ex) { + return null; + } + } + + /** + * Generates a Java package name from a URI according to the + * algorithm outlined in Appendix D of JAXB (2.0+). + * + * @param uri the namespace URI. + * @return the package name. + */ + public static String nameSpaceURIToPackage(URI uri) { + + StringBuilder packageName = new StringBuilder(); + String authority = uri.getAuthority(); + String scheme = uri.getScheme(); + if (authority == null && "urn".equals(scheme)) { + authority = uri.getSchemeSpecificPart(); + } + + if (null != authority && !"".equals(authority)) { + if ("urn".equals(scheme)) { + packageName.append(authority); + /* JAXB 2.2 D.5.1, Rule #5 */ + for (int i = 0; i < packageName.length(); i++) { + if (packageName.charAt(i) == '-') { + packageName.setCharAt(i, '.'); + } + } + authority = packageName.toString(); + packageName.setLength(0); + + StringTokenizer st = new StringTokenizer(authority, ":"); + while (st.hasMoreTokens()) { + String token = st.nextToken(); + if (packageName.length() > 0) { + packageName.insert(0, '.'); + packageName.insert(0, normalizePackageNamePart(token)); + } else { + packageName.insert(0, token); + } + } + authority = packageName.toString(); + packageName.setLength(0); + + } + + StringTokenizer st = new StringTokenizer(authority, "."); + if (st.hasMoreTokens()) { + while (st.hasMoreTokens()) { + String token = st.nextToken(); + if (packageName.length() == 0) { + if ("www".equals(token)) { + continue; + } + } else { + packageName.insert(0, '.'); + } + packageName.insert(0, normalizePackageNamePart(token)); + } + } + + if (!("http".equalsIgnoreCase(scheme) || "urn".equalsIgnoreCase(scheme))) { + packageName.insert(0, '.'); + packageName.insert(0, normalizePackageNamePart(scheme)); + } + + } + + String path = uri.getPath(); + if (path == null) { + path = ""; + } + /* JAXB 2.2 D.5.1 Rule 2 - remove trailing .??, .???, or .html only. */ + int index = path.lastIndexOf('.'); + if (index < 0) { + index = path.length(); + } else { + String ending = path.substring(index + 1); + if (ending.length() < 2 || (ending.length() > 3 + && !"html".equalsIgnoreCase(ending))) { + index = path.length(); + } + } + StringTokenizer st = new StringTokenizer(path.substring(0, index), "/"); + while (st.hasMoreTokens()) { + String token = st.nextToken(); + if (packageName.length() > 0) { + packageName.append('.'); + } + packageName.append(normalizePackageNamePart(token)); + } + return packageName.toString(); + } + + private static String normalizePackageNamePart(String name) { + StringBuilder sname = new StringBuilder(name.toLowerCase()); + + for (int i = 0; i < sname.length(); i++) { + sname.setCharAt(i, Character.toLowerCase(sname.charAt(i))); + } + + for (int i = 0; i < sname.length(); i++) { + if (!Character.isJavaIdentifierPart(sname.charAt(i))) { + sname.setCharAt(i, '_'); + } + } + + if (isJavaKeyword(sname.toString())) { + sname.insert(0, '_'); + } + + if (!Character.isJavaIdentifierStart(sname.charAt(0))) { + sname.insert(0, '_'); + } + + return sname.toString(); + } + + + /** + * Converts an XML name to a Java identifier according to the mapping + * algorithm outlined in the JAXB specification + * + * @param name the XML name + * @return the Java identifier + */ + public static String nameToIdentifier(String name, IdentifierType type) { + + if (null == name || name.length() == 0) { + return name; + } + + // algorithm will not change an XML name that is already a legal and + // conventional (!) Java class, method, or constant identifier + + StringBuilder buf = new StringBuilder(name); + boolean hasUnderscore = false; + boolean legalIdentifier = Character.isJavaIdentifierStart(buf.charAt(0)); + + for (int i = 1; i < name.length() && legalIdentifier; i++) { + legalIdentifier &= Character.isJavaIdentifierPart(buf.charAt(i)); + hasUnderscore |= '_' == buf.charAt(i); + } + + boolean conventionalIdentifier = isConventionalIdentifier(buf, type); + if (legalIdentifier && conventionalIdentifier) { + if (JAXBUtils.isJavaKeyword(name) && type == IdentifierType.VARIABLE) { + name = normalizePackageNamePart(name); + } + if (!hasUnderscore || IdentifierType.CLASS != type) { + return name; + } + } + + // split into words + + List<String> words = new ArrayList<>(); + + StringTokenizer st = new StringTokenizer(name, XML_NAME_PUNCTUATION_STRING); + while (st.hasMoreTokens()) { + words.add(st.nextToken()); + } + + for (int i = 0; i < words.size(); i++) { + splitWord(words, i); + } + + return makeConventionalIdentifier(words, type); + } + + private static void splitWord(List<String> words, int listIndex) { + String word = words.get(listIndex); + if (word.length() <= 1) { + return; + } + int index = listIndex + 1; + StringBuilder sword = new StringBuilder(word); + int first = 0; + char firstChar = sword.charAt(first); + if (Character.isLowerCase(firstChar)) { + sword.setCharAt(first, Character.toUpperCase(firstChar)); + } + int i = 1; + + while (i < sword.length()) { + if (Character.isDigit(firstChar)) { + while (i < sword.length() && Character.isDigit(sword.charAt(i))) { + i++; + } + } else if (isCasedLetter(firstChar)) { + boolean previousIsLower = Character.isLowerCase(firstChar); + while (i < sword.length() && isCasedLetter(sword.charAt(i))) { + if (Character.isUpperCase(sword.charAt(i)) && previousIsLower) { + break; + } + previousIsLower = Character.isLowerCase(sword.charAt(i)); + i++; + } + } else { + // first must be a mark or an uncased letter + while (i < sword.length() && (isMark(sword.charAt(i)) || !isCasedLetter(sword.charAt(i)))) { + i++; + } + } + + // characters from first to i are all either + // * digits + // * upper or lower case letters, with only the first one an upper + // * uncased letters or marks + + + String newWord = sword.substring(first, i); + words.add(index, newWord); + index++; + if (i >= sword.length()) { + break; + } + first = i; + firstChar = sword.charAt(first); + } + + if (index > (listIndex + 1)) { + words.remove(listIndex); + } + } + + private static boolean isMark(char c) { + return Character.isJavaIdentifierPart(c) && !Character.isLetter(c) && !Character.isDigit(c); + } + + private static boolean isCasedLetter(char c) { + return Character.isUpperCase(c) || Character.isLowerCase(c); + } + + private static boolean isConventionalIdentifier(StringBuilder buf, IdentifierType type) { + if (null == buf || buf.length() == 0) { + return false; + } + final boolean result; + if (IdentifierType.CONSTANT == type) { + for (int i = 0; i < buf.length(); i++) { + if (Character.isLowerCase(buf.charAt(i))) { + return false; + } + } + result = true; + } else if (IdentifierType.VARIABLE == type) { + result = Character.isLowerCase(buf.charAt(0)); + } else { + int pos = 3; + if (IdentifierType.GETTER == type + && !(buf.length() >= pos + && "get".equals(buf.subSequence(0, 3)))) { + return false; + } else if (IdentifierType.SETTER == type + && !(buf.length() >= pos && "set".equals(buf.subSequence(0, 3)))) { + return false; + } else { + pos = 0; + } + result = Character.isUpperCase(buf.charAt(pos)); + } + return result; + } + + private static String makeConventionalIdentifier(List<String> words, IdentifierType type) { + StringBuilder buf = new StringBuilder(); + boolean firstWord = true; + if (IdentifierType.GETTER == type) { + buf.append("get"); + } else if (IdentifierType.SETTER == type) { + buf.append("set"); + } + for (String w : words) { + int l = buf.length(); + if (l > 0 && IdentifierType.CONSTANT == type) { + buf.append('_'); + l++; + } + buf.append(w); + if (IdentifierType.CONSTANT == type) { + for (int i = l; i < buf.length(); i++) { + if (Character.isLowerCase(buf.charAt(i))) { + buf.setCharAt(i, Character.toUpperCase(buf.charAt(i))); + } + } + } else if (IdentifierType.VARIABLE == type) { + if (firstWord && Character.isUpperCase(buf.charAt(l))) { + buf.setCharAt(l, Character.toLowerCase(buf.charAt(l))); + } + } else { + if (firstWord && Character.isLowerCase(buf.charAt(l))) { + buf.setCharAt(l, Character.toUpperCase(buf.charAt(l))); + } + } + firstWord = false; + } + return buf.toString(); + } + + public static Class<?> getValidClass(Class<?> cls) { + if (cls.isEnum() || cls.isArray()) { + return cls; + } + + if (cls == Object.class || cls == String.class || cls.isPrimitive() || cls.isAnnotation() + || "jakarta.xml.ws.Holder".equals(cls.getName())) { + return null; + } else if (cls.isInterface() + || "jakarta.xml.ws.wsaddressing.W3CEndpointReference".equals(cls.getName())) { + return cls; + } + + Constructor<?> cons = ReflectionUtil.getDeclaredConstructor(cls); + if (cons == null) { + cons = ReflectionUtil.getConstructor(cls); + if (cons == null) { + return null; + } + } + return cls; + } + + private static synchronized ClassLoader getXJCClassLoader() { + if (jaxbXjcLoader == null) { + try { + Class.forName("com.sun.tools.internal.xjc.api.XJC"); + jaxbXjcLoader = ClassLoader.getSystemClassLoader(); + } catch (Exception t2) { + //couldn't find either, probably cause tools.jar isn't on + //the classpath. Let's see if we can find the tools jar + String s = SystemPropertyAction.getProperty("java.home"); + if (!StringUtils.isEmpty(s)) { + File home = new File(s); + File jar = new File(home, "lib/tools.jar"); + if (!jar.exists()) { + jar = new File(home, "../lib/tools.jar"); + } + if (jar.exists()) { + try { + jaxbXjcLoader = new URLClassLoader(new URL[] {jar.toURI().toURL()}); + Class.forName("com.sun.tools.internal.xjc.api.XJC", false, jaxbXjcLoader); + } catch (Exception e) { + jaxbXjcLoader = null; + } + } + } + } + } + return jaxbXjcLoader; + } + + public static Object setNamespaceMapper(Bus bus, final Map<String, String> nspref, + Marshaller marshaller) throws PropertyException { + ClassLoaderService classLoaderService = bus.getExtension(ClassLoaderService.class); + Object mapper = classLoaderService.createNamespaceWrapperInstance(marshaller.getClass(), nspref); + if (mapper != null) { + if (marshaller.getClass().getName().contains(".internal.")) { + marshaller.setProperty("com.sun.xml.internal.bind.namespacePrefixMapper", + mapper); + } else if (marshaller.getClass().getName().contains("com.sun")) { + marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", + mapper); + } else if (marshaller.getClass().getName().contains("eclipse")) { + marshaller.setProperty("eclipselink.namespace-prefix-mapper", + mapper); + } + } + return mapper; + } + public static BridgeWrapper createBridge(Set<Class<?>> ctxClasses, + QName qname, + Class<?> refcls, + Annotation[] anns) throws JAXBException { + try { + Class<?> cls; + Class<?> refClass; + String pkg = "com.sun.xml.bind."; + try { + cls = Class.forName("com.sun.xml.bind.api.JAXBRIContext"); + refClass = Class.forName(pkg + "api.TypeReference"); + } catch (ClassNotFoundException e) { + cls = Class.forName("com.sun.xml.internal.bind.api.JAXBRIContext", true, getXJCClassLoader()); + pkg = "com.sun.xml.internal.bind."; + refClass = Class.forName(pkg + "api.TypeReference", true, getXJCClassLoader()); + } + Object ref = refClass.getConstructor(QName.class, + Type.class, + anns.getClass()).newInstance(qname, refcls, anns); + List<Object> typeRefs = new ArrayList<>(); + typeRefs.add(ref); + List<Class<?>> clses = new ArrayList<>(ctxClasses); + clses.add(refClass.getField("type").get(ref).getClass()); + if (!refcls.isInterface()) { + clses.add(refcls); + } + + Object ctx = null; + for (Method m : cls.getDeclaredMethods()) { + if ("newInstance".equals(m.getName()) + && m.getParameterTypes().length == 6) { + ctx = m.invoke(null, clses.toArray(new Class<?>[0]), + typeRefs, null, null, true, null); + + } + } + + if (ctx == null) { + throw new JAXBException("No ctx found"); + } + + Object bridge = ctx.getClass().getMethod("createBridge", refClass).invoke(ctx, ref); + return ReflectionInvokationHandler.createProxyWrapper(bridge, + BridgeWrapper.class); + } catch (Exception ex) { + throw new JAXBException(ex); + } + } + public interface BridgeWrapper { + + Object unmarshal(XMLStreamReader source, AttachmentUnmarshaller am) throws JAXBException; + + Object unmarshal(InputStream source) throws JAXBException; + + Object unmarshal(Node source, AttachmentUnmarshaller am) throws JAXBException; + + void marshal(Object elValue, XMLStreamWriter source, AttachmentMarshaller m) throws JAXBException; + + void marshal(Object elValue, StreamResult s1) throws JAXBException; + + void marshal(Object elValue, Node source, AttachmentMarshaller am) throws JAXBException; + } + + + public static SchemaCompiler createSchemaCompiler() throws JAXBException { + try { + Class<?> cls; + Object sc; + try { + cls = Class.forName("com.sun.tools.xjc.api.XJC"); + sc = cls.getMethod("createSchemaCompiler").invoke(null); + } catch (Throwable e) { + cls = Class.forName("com.sun.tools.internal.xjc.api.XJC", true, getXJCClassLoader()); + sc = cls.getMethod("createSchemaCompiler").invoke(null); + } + + return ReflectionInvokationHandler.createProxyWrapper(sc, + SchemaCompiler.class); + } catch (Exception ex) { + throw new JAXBException(ex); + } + } + + public static SchemaCompiler createSchemaCompilerWithDefaultAllocator(Set<String> allocatorSet) { + + try { + SchemaCompiler compiler = JAXBUtils.createSchemaCompiler(); + Object allocator = ReflectionInvokationHandler + .createProxyWrapper(new DefaultClassNameAllocator(allocatorSet), + JAXBUtils.getParamClass(compiler, "setClassNameAllocator")); + + compiler.setClassNameAllocator(allocator); + return compiler; + } catch (JAXBException e1) { + throw new IllegalStateException("Unable to create schema compiler", e1); + } + + } + + public static void logGeneratedClassNames(Logger logger, JCodeModel codeModel) { + if (!logger.isLoggable(Level.FINE)) { + return; + } + + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (Iterator<JPackage> itr = codeModel.packages(); itr.hasNext();) { + JPackage package1 = itr.next(); + + for (Iterator<JDefinedClass> citr = package1.classes(); citr.hasNext();) { + if (!first) { + sb.append(", "); + } else { + first = false; + } + sb.append(citr.next().fullName()); + } + } + + logger.log(Level.FINE, "Created classes: " + sb.toString()); + } + + public static List<String> getGeneratedClassNames(JCodeModel codeModel) { + List<String> classes = new ArrayList<>(); + for (Iterator<JPackage> itr = codeModel.packages(); itr.hasNext();) { + JPackage package1 = itr.next(); + + for (Iterator<JDefinedClass> citr = package1.classes(); citr.hasNext();) { + classes.add(citr.next().fullName()); + } + } + return classes; + } + public static Object createFileCodeWriter(File f) throws JAXBException { + return createFileCodeWriter(f, StandardCharsets.UTF_8.name()); + } + public static Object createFileCodeWriter(File f, String encoding) throws JAXBException { + try { + Class<?> cls; + try { + cls = Class.forName("com.sun.codemodel.writer.FileCodeWriter"); + } catch (ClassNotFoundException e) { + cls = Class.forName("com.sun.codemodel.internal.writer.FileCodeWriter", + true, getXJCClassLoader()); + } + if (encoding != null) { + try { + return cls.getConstructor(File.class, String.class) + .newInstance(f, encoding); + } catch (Exception ex) { + // try a single argument constructor + } + } + return cls.getConstructor(File.class).newInstance(f); + } catch (Exception ex) { + throw new JAXBException(ex); + } + } + + public static Class<?> getParamClass(SchemaCompiler sc, String method) { + Object o = ((ReflectionInvokationHandler)Proxy.getInvocationHandler(sc)).getTarget(); + for (Method m : o.getClass().getMethods()) { + if (m.getName().equals(method) && m.getParameterTypes().length == 1) { + return m.getParameterTypes()[0]; + } + } + return null; + } + + + public static List<DOMResult> generateJaxbSchemas( + JAXBContext context, final Map<String, DOMResult> builtIns) throws IOException { + final List<DOMResult> results = new ArrayList<>(); + + context.generateSchema(new SchemaOutputResolver() { + @Override + public Result createOutput(String ns, String file) throws IOException { + DOMResult result = new DOMResult(); + + if (builtIns.containsKey(ns)) { + DOMResult dr = builtIns.get(ns); + result.setSystemId(dr.getSystemId()); + results.add(dr); + return result; + } + result.setSystemId(file); + results.add(result); + return result; + } + }); + return results; + } + + public static String getPackageNamespace(Class<?> cls) { + Package p = cls.getPackage(); + if (p != null) { + jakarta.xml.bind.annotation.XmlSchema schemaAnn = + p.getAnnotation(jakarta.xml.bind.annotation.XmlSchema.class); + if (schemaAnn != null) { + return schemaAnn.namespace(); + } + } + return null; + } + + public static void scanPackages(Set<Class<?>> classes, + Map<Package, CachedClass> objectFactoryCache) { + scanPackages(classes, null, objectFactoryCache); + } + public static void scanPackages(Set<Class<?>> classes, + Class<?>[] extraClass, + Map<Package, CachedClass> objectFactoryCache) { + + // add user extra class into jaxb context + if (extraClass != null && extraClass.length > 0) { + for (Class<?> clz : extraClass) { + classes.add(clz); + } + } + + // try and read any jaxb.index files that are with the other classes. + // This should + // allow loading of extra classes (such as subclasses for inheritance + // reasons) + // that are in the same package. Also check for ObjectFactory classes + Map<String, InputStream> packages = new HashMap<>(); + Map<String, ClassLoader> packageLoaders = new HashMap<>(); + Set<Class<?>> objectFactories = new HashSet<>(); + for (Class<?> jcls : classes) { + String pkgName = PackageUtils.getPackageName(jcls); + if (!packages.containsKey(pkgName)) { + Package pkg = jcls.getPackage(); + + packages.put(pkgName, jcls.getResourceAsStream("jaxb.index")); + packageLoaders.put(pkgName, getClassLoader(jcls)); + String objectFactoryClassName = pkgName + "." + "ObjectFactory"; + Class<?> ofactory = null; + CachedClass cachedFactory = null; + if (pkg != null && objectFactoryCache != null) { + synchronized (objectFactoryCache) { + cachedFactory = objectFactoryCache.get(pkg); + } + } + if (cachedFactory != null) { + ofactory = cachedFactory.getCachedClass(); + } + if (ofactory == null) { + try { + ofactory = Class.forName(objectFactoryClassName, false, getClassLoader(jcls)); + objectFactories.add(ofactory); + addToObjectFactoryCache(pkg, ofactory, objectFactoryCache); + } catch (ClassNotFoundException e) { + addToObjectFactoryCache(pkg, null, objectFactoryCache); + } + } else { + objectFactories.add(ofactory); + } + } + } + for (Map.Entry<String, InputStream> entry : packages.entrySet()) { + if (entry.getValue() != null) { + try (BufferedReader reader = new BufferedReader( + new InputStreamReader(entry.getValue(), StandardCharsets.UTF_8))) { + String pkg = entry.getKey(); + ClassLoader loader = packageLoaders.get(pkg); + if (!StringUtils.isEmpty(pkg)) { + pkg += "."; + } + + String line = reader.readLine(); + while (line != null) { + line = line.trim(); + if (line.indexOf('#') != -1) { + line = line.substring(0, line.indexOf('#')); + } + if (!StringUtils.isEmpty(line)) { + try { + Class<?> ncls = Class.forName(pkg + line, false, loader); + classes.add(ncls); + } catch (Exception e) { + // ignore + } + } + line = reader.readLine(); + } + } catch (IOException e) { + // ignore + } finally { + try { + entry.getValue().close(); + } catch (IOException e) { + // ignore + } + } + } + } + classes.addAll(objectFactories); + } + + private static ClassLoader getClassLoader(final Class<?> clazz) { + final SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { + @Override + public ClassLoader run() { + return clazz.getClassLoader(); + } + }); + } + return clazz.getClassLoader(); + } + + private static void addToObjectFactoryCache(Package objectFactoryPkg, + Class<?> ofactory, + Map<Package, CachedClass> objectFactoryCache) { + if (objectFactoryPkg == null || objectFactoryCache == null) { + return; + } + synchronized (objectFactoryCache) { + objectFactoryCache.put(objectFactoryPkg, + new CachedClass(ofactory)); + } + } + + public static class DefaultClassNameAllocator { + private final Set<String> typesClassNames; + + public DefaultClassNameAllocator() { + this(new HashSet<>()); + } + + public DefaultClassNameAllocator(Set<String> set) { + typesClassNames = set; + } + + public String assignClassName(String packageName, String className) { + String fullClassName = className; + String fullPckClass = packageName + "." + fullClassName; + int cnt = 0; + while (typesClassNames.contains(fullPckClass)) { + cnt++; + fullClassName = className + cnt; + fullPckClass = packageName + "." + fullClassName; + } + typesClassNames.add(fullPckClass); + return fullClassName; + } + + } + + public interface SchemaCompiler { + void setEntityResolver(EntityResolver entityResolver); + + void setErrorListener(Object elForRun); + + void setClassNameAllocator(Object allocator); + + @WrapReturn(S2JJAXBModel.class) + S2JJAXBModel bind(); + + void parseSchema(InputSource source); + + void parseSchema(String key, Element el); + void parseSchema(String key, XMLStreamReader el); + + @WrapReturn(Options.class) + Options getOptions(); + } + public interface S2JJAXBModel { + + @WrapReturn(JCodeModel.class) + JCodeModel generateCode(Object object, Object elForRun); + + @WrapReturn(Mapping.class) + Mapping get(QName qn); + + @WrapReturn(TypeAndAnnotation.class) + TypeAndAnnotation getJavaType(QName typeQName); + } + public interface Mapping { + @WrapReturn(TypeAndAnnotation.class) + TypeAndAnnotation getType(); + } + public interface TypeAndAnnotation { + @WrapReturn(JType.class) + JType getTypeClass(); + } + public interface JType { + boolean isArray(); + + @WrapReturn(JType.class) + JType elementType(); + + boolean isPrimitive(); + + String binaryName(); + + String fullName(); + + String name(); + + @WrapReturn(value = JType.class, iterator = true) + Iterator<JType> classes(); + } + public interface Options { + + void addGrammar(InputSource is); + + void addBindFile(InputSource is); + + void parseArguments(String[] args); + + String getBuildID(); + } + public interface JCodeModel { + + void build(Object writer) throws IOException; + + @WrapReturn(value = JPackage.class, iterator = true) + Iterator<JPackage> packages(); + } + public interface JPackage { + + String name(); + + @WrapReturn(value = JDefinedClass.class, iterator = true) + Iterator<JDefinedClass> classes(); + } + public interface JDefinedClass { + String name(); + + String fullName(); + } + + public static boolean isJAXB22() { + Target t = XmlElement.class.getAnnotation(Target.class); + //JAXB 2.2 allows XmlElement on params. + for (ElementType et : t.value()) { + if (et == ElementType.PARAMETER) { + return true; + } + } + return false; + } + + public static JAXBContextProxy createJAXBContextProxy(final JAXBContext ctx) { + return createJAXBContextProxy(ctx, null, null); + } + public static JAXBContextProxy createJAXBContextProxy(final JAXBContext ctx, + final SchemaCollection collection, + final String defaultNs) { + if (ctx.getClass().getName().contains("com.sun.") + || collection == null) { + return ReflectionInvokationHandler.createProxyWrapper(ctx, JAXBContextProxy.class); + } + return new SchemaCollectionContextProxy(ctx, collection, defaultNs); + } + public static JAXBBeanInfo getBeanInfo(JAXBContextProxy context, Class<?> cls) { + Object o = context.getBeanInfo(cls); + if (o == null) { + return null; + } + if (o instanceof JAXBBeanInfo) { + return (JAXBBeanInfo)o; + } + return ReflectionInvokationHandler.createProxyWrapper(o, JAXBBeanInfo.class); + } + + private static String getPostfix(Class<?> cls) { + String className = cls.getName(); + if (className.contains("com.sun.xml.internal") + || className.contains("eclipse")) { + //eclipse moxy accepts sun package CharacterEscapeHandler + return ".internal"; + } else if (className.contains("com.sun.xml.bind") + || className.startsWith("com.ibm.xml")) { + return ""; + } + return null; + } + + public static void setMinimumEscapeHandler(Marshaller marshaller) { + if (jaxbMinimumEscapeHandler == null) { + jaxbMinimumEscapeHandler = Optional.ofNullable(createMininumEscapeHandler(marshaller.getClass())); + } + jaxbMinimumEscapeHandler.ifPresent(p -> setEscapeHandler(marshaller, p)); + } + + public static void setNoEscapeHandler(final Marshaller marshaller) { + if (jaxbNoEscapeHandler == null) { + jaxbNoEscapeHandler = Optional.ofNullable(createNoEscapeHandler(marshaller.getClass())); + } + jaxbNoEscapeHandler.ifPresent(p -> setEscapeHandler(marshaller, p)); + } + + public static void setEscapeHandler(Marshaller marshaller, Object escapeHandler) { + try { + String postFix = getPostfix(marshaller.getClass()); + if (postFix != null && escapeHandler != null) { + marshaller.setProperty("com.sun.xml" + postFix + ".bind.characterEscapeHandler", escapeHandler); + } + } catch (PropertyException e) { + LOG.log(Level.INFO, "Failed to set MinumEscapeHandler to jaxb marshaller", e); + } + } + + public static Object createMininumEscapeHandler(Class<?> cls) { + return createEscapeHandler(cls, "MinimumEscapeHandler"); + } + + public static Object createNoEscapeHandler(Class<?> cls) { + return createEscapeHandler(cls, "NoEscapeHandler"); + } + + private static Object createEscapeHandler(Class<?> cls, String simpleClassName) { + try { + String postFix = getPostfix(cls); + if (postFix == null) { + LOG.log(Level.WARNING, "Failed to create" + simpleClassName + " for unknown jaxb class:" + + cls); + return null; + } + Class<?> handlerClass = ClassLoaderUtils.loadClass("com.sun.xml" + postFix + + ".bind.marshaller." + simpleClassName, + cls); + Class<?> handlerInterface = ClassLoaderUtils + .loadClass("com.sun.xml" + postFix + ".bind.marshaller.CharacterEscapeHandler", + cls); + Object targetHandler = ReflectionUtil.getDeclaredField(handlerClass, "theInstance").get(null); + return ProxyHelper.getProxy(cls.getClassLoader(), + new Class[] {handlerInterface}, + new EscapeHandlerInvocationHandler(targetHandler)); + } catch (Exception e) { + if ("NoEscapeHandler".equals(simpleClassName)) { + //this class doesn't exist in JAXB 2.2 so expected + LOG.log(Level.FINER, "Failed to create " + simpleClassName); + } else { + LOG.log(Level.INFO, "Failed to create " + simpleClassName); + } + } + return null; + } + + +} diff --git a/deps/cxf-shade/src/patch/java/org/apache/cxf/security/wss4j/AbstractWSS4JInterceptor.java b/deps/cxf-shade/src/patch/java/org/apache/cxf/security/wss4j/AbstractWSS4JInterceptor.java new file mode 100644 index 0000000000..ad6bec5b23 --- /dev/null +++ b/deps/cxf-shade/src/patch/java/org/apache/cxf/security/wss4j/AbstractWSS4JInterceptor.java @@ -0,0 +1,228 @@ +/** + * 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.cxf.ws.security.wss4j; + +import java.net.URI; +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import javax.xml.namespace.QName; + +import org.apache.cxf.binding.soap.SoapMessage; +import org.apache.cxf.binding.soap.interceptor.SoapInterceptor; +import org.apache.cxf.interceptor.Fault; +import org.apache.cxf.message.Message; +import org.apache.cxf.message.MessageUtils; +import org.apache.cxf.phase.PhaseInterceptor; +import org.apache.cxf.rt.security.utils.SecurityUtils; +import org.apache.cxf.ws.security.SecurityConstants; +import org.apache.wss4j.common.ConfigurationConstants; +import org.apache.wss4j.common.WSS4JConstants; +import org.apache.wss4j.common.crypto.Crypto; +import org.apache.wss4j.common.crypto.PasswordEncryptor; +import org.apache.wss4j.common.ext.WSSecurityException; +import org.apache.wss4j.dom.handler.RequestData; +import org.apache.wss4j.dom.handler.WSHandler; + +public abstract class AbstractWSS4JInterceptor extends WSHandler implements SoapInterceptor, + PhaseInterceptor<SoapMessage> { + + private static final Set<QName> HEADERS = new HashSet<>(); + + static { + HEADERS.add(new QName(WSS4JConstants.WSSE_NS, "Security")); + HEADERS.add(new QName(WSS4JConstants.ENC_NS, "EncryptedData")); + HEADERS.add(new QName(WSS4JConstants.WSSE11_NS, "EncryptedHeader")); + } + + private Map<String, Object> properties = new ConcurrentHashMap<>(); + private final Set<String> before = new HashSet<>(); + private final Set<String> after = new HashSet<>(); + private String phase; + private String id; + + public AbstractWSS4JInterceptor() { + super(); + id = getClass().getName(); + } + + public Set<URI> getRoles() { + return null; + } + + public void handleFault(SoapMessage message) { + } + + public void postHandleMessage(SoapMessage message) throws Fault { + } + public Collection<PhaseInterceptor<? extends Message>> getAdditionalInterceptors() { + return null; + } + + public String getPhase() { + return phase; + } + + public void setPhase(String phase) { + this.phase = phase; + } + + public Object getOption(String key) { + return properties.get(key); + } + + public void setProperty(String key, String value) { + properties.put(key, value); + } + + public String getPassword(Object msgContext) { + return (String)((Message)msgContext).getContextualProperty("password"); + } + + public Object getProperty(Object msgContext, String key) { + if (msgContext == null) { + return null; + } + + Object obj = SecurityUtils.getSecurityPropertyValue(key, (Message)msgContext); + if (obj == null) { + obj = getOption(key); + } + return obj; + } + + public void setPassword(Object msgContext, String password) { + ((Message)msgContext).put("password", password); + } + + public void setProperty(Object msgContext, String key, Object value) { + ((Message)msgContext).put(key, value); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Set<QName> getUnderstoodHeaders() { + return HEADERS; + } + + public Map<String, Object> getProperties() { + return properties; + } + + public void setProperties(Map<String, Object> properties) { + this.properties = properties; + } + + public Set<String> getAfter() { + return after; + } + + public Set<String> getBefore() { + return before; + } + + protected boolean isRequestor(SoapMessage message) { + return MessageUtils.isRequestor(message); + } + + protected void translateProperties(SoapMessage msg) { + String bspCompliant = (String)msg.getContextualProperty(SecurityConstants.IS_BSP_COMPLIANT); + if (bspCompliant != null) { + msg.put(ConfigurationConstants.IS_BSP_COMPLIANT, bspCompliant); + } + String futureTTL = + (String)msg.getContextualProperty(SecurityConstants.TIMESTAMP_FUTURE_TTL); + if (futureTTL != null) { + msg.put(ConfigurationConstants.TTL_FUTURE_TIMESTAMP, futureTTL); + } + String ttl = + (String)msg.getContextualProperty(SecurityConstants.TIMESTAMP_TTL); + if (ttl != null) { + msg.put(ConfigurationConstants.TTL_TIMESTAMP, ttl); + } + + String utFutureTTL = + (String)msg.getContextualProperty(SecurityConstants.USERNAMETOKEN_FUTURE_TTL); + if (utFutureTTL != null) { + msg.put(ConfigurationConstants.TTL_FUTURE_USERNAMETOKEN, utFutureTTL); + } + String utTTL = + (String)msg.getContextualProperty(SecurityConstants.USERNAMETOKEN_TTL); + if (utTTL != null) { + msg.put(ConfigurationConstants.TTL_USERNAMETOKEN, utTTL); + } + + String certConstraints = + (String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SUBJECT_CERT_CONSTRAINTS, msg); + if (certConstraints != null) { + msg.put(ConfigurationConstants.SIG_SUBJECT_CERT_CONSTRAINTS, certConstraints); + } + + String certConstraintsSeparator = + (String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.CERT_CONSTRAINTS_SEPARATOR, msg); + if (certConstraintsSeparator != null && !certConstraintsSeparator.isEmpty()) { + msg.put(ConfigurationConstants.SIG_CERT_CONSTRAINTS_SEPARATOR, certConstraintsSeparator); + } + + // Now set SAML SenderVouches + Holder Of Key requirements + String valSAMLSubjectConf = + (String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.VALIDATE_SAML_SUBJECT_CONFIRMATION, + msg); + boolean validateSAMLSubjectConf = true; + if (valSAMLSubjectConf != null) { + validateSAMLSubjectConf = Boolean.parseBoolean(valSAMLSubjectConf); + } + msg.put( + ConfigurationConstants.VALIDATE_SAML_SUBJECT_CONFIRMATION, + Boolean.toString(validateSAMLSubjectConf) + ); + + PasswordEncryptor passwordEncryptor = + (PasswordEncryptor)msg.getContextualProperty(SecurityConstants.PASSWORD_ENCRYPTOR_INSTANCE); + if (passwordEncryptor != null) { + msg.put(ConfigurationConstants.PASSWORD_ENCRYPTOR_INSTANCE, passwordEncryptor); + } + } + + @Override + protected Crypto loadCryptoFromPropertiesFile( + String propFilename, + RequestData reqData + ) throws WSSecurityException { + Message message = (Message)reqData.getMsgContext(); + // Not compatible with version WSS4J 3 + // ClassLoader classLoader = this.getClassLoader(reqData.getMsgContext()); + ClassLoader classLoader = this.getClassLoader(); + PasswordEncryptor passwordEncryptor = getPasswordEncryptor(reqData); + return + WSS4JUtils.loadCryptoFromPropertiesFile( + message, propFilename, classLoader, passwordEncryptor + ); + } + +} diff --git a/pom.xml b/pom.xml index 65cc55487c..2676429872 100644 --- a/pom.xml +++ b/pom.xml @@ -230,6 +230,7 @@ <version.openjpa>3.2.2</version.openjpa> <openwebbeans.version>2.0.27</openwebbeans.version> <wss4j.version>3.0.0</wss4j.version> + <santuario-xmlsec.version>3.0.1</santuario-xmlsec.version> <!-- org.eclipse --> <version.eclipselink>3.0.3</version.eclipselink> <!-- org.glassfish --> @@ -1441,7 +1442,7 @@ <dependency> <artifactId>xmlsec</artifactId> <groupId>org.apache.santuario</groupId> - <version>2.2.3</version> + <version>${santuario-xmlsec.version}</version> </dependency> <dependency> <groupId>wsdl4j</groupId> diff --git a/server/openejb-client/pom.xml b/server/openejb-client/pom.xml index 3494f5f34f..caa8a77639 100644 --- a/server/openejb-client/pom.xml +++ b/server/openejb-client/pom.xml @@ -154,8 +154,8 @@ </dependency> <dependency> <groupId>org.bouncycastle</groupId> - <artifactId>bcmail-jdk15on</artifactId> - <version>1.60</version> + <artifactId>bcmail-jdk15to18</artifactId> + <version>1.70</version> <scope>test</scope> </dependency> diff --git a/server/openejb-cxf/pom.xml b/server/openejb-cxf/pom.xml index fad54c9b1e..d301858cc6 100644 --- a/server/openejb-cxf/pom.xml +++ b/server/openejb-cxf/pom.xml @@ -69,7 +69,7 @@ <dependency> <groupId>org.apache.santuario</groupId> <artifactId>xmlsec</artifactId> - <version>3.0.1</version> + <version>${santuario-xmlsec.version}</version> <exclusions> <exclusion> <groupId>com.fasterxml.woodstox</groupId> @@ -124,7 +124,7 @@ <!-- Override the bcprov from the previous artifact --> <dependency> <groupId>org.bouncycastle</groupId> - <artifactId>bcprov-jdk15on</artifactId> + <artifactId>bcprov-jdk15to18</artifactId> <version>1.70</version> </dependency> <dependency> diff --git a/server/openejb-ssh/pom.xml b/server/openejb-ssh/pom.xml index 385b7fcff3..a9257b1a32 100644 --- a/server/openejb-ssh/pom.xml +++ b/server/openejb-ssh/pom.xml @@ -67,8 +67,8 @@ <dependency> <groupId>org.bouncycastle</groupId> - <artifactId>bcpkix-jdk15on</artifactId> - <version>1.60</version> + <artifactId>bcpkix-jdk15to18</artifactId> + <version>1.70</version> <scope>test</scope> </dependency> </dependencies> diff --git a/tomee/tomee-embedded/pom.xml b/tomee/tomee-embedded/pom.xml index c72e479fc6..1d70658fc9 100644 --- a/tomee/tomee-embedded/pom.xml +++ b/tomee/tomee-embedded/pom.xml @@ -111,7 +111,7 @@ <exclude>org.jasypt:*</exclude> <exclude>net.shibboleth.utilities:java-support</exclude> <exclude>org.cryptacular:cryptacular</exclude> - <exclude>org.bouncycastle:bcprov-jdk15on</exclude> + <exclude>org.bouncycastle:bcprov-jdk15to18</exclude> <exclude>org.apache.neethi:neethi</exclude> <exclude>org.apache.cxf:cxf-rt-frontend-jaxws</exclude> <exclude>org.apache.cxf:cxf-rt-bindings-soap</exclude> @@ -511,8 +511,8 @@ </dependency> <dependency> <groupId>org.bouncycastle</groupId> - <artifactId>bcmail-jdk15on</artifactId> - <version>1.60</version> + <artifactId>bcmail-jdk15to18</artifactId> + <version>1.70</version> <scope>test</scope> </dependency>