Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
* Encapsulation of version-specific WS-Addressing constants.
*/
public class AddressingConstants {
private static final ResourceBundle BUNDLE =
static final ResourceBundle BUNDLE =
BundleUtils.getBundle(AddressingConstants.class);


Expand Down
119 changes: 104 additions & 15 deletions core/src/main/java/org/apache/cxf/ws/addressing/ContextUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
Expand Down Expand Up @@ -330,7 +331,7 @@ public static RelatesToType getRelatesTo(String uri) {
relatesTo.setValue(uri);
return relatesTo;
}

private static boolean startsWith(String value, String ref) {
if (StringUtils.isEmpty(value)) {
return false;
Expand Down Expand Up @@ -637,6 +638,106 @@ public static boolean isDecoupledDestinationAllowed(String uri) {
return isDecoupledDestinationSchemeAllowed(uri);
}

/**
* Log a message after {@link #isDecoupledDestinationAllowed(String)} returned {@code false}.
*
* @param logger the {@link Logger} to pass the message to
* @param level log {@link Level} on which the message should be logged
* @param destinationUri the URI banned due to the configuration
*/
public static void logDisallowedDecoupledDestinationScheme(Logger logger, Level level, String destinationUri) {
logger.logrb(level,
AddressingConstants.BUNDLE,
"DISALLOWED_DECOUPLED_DESTINATION_SCHEME",
new Object[] {
destinationUri,
ALLOWED_DECOUPLED_DEST_SCHEMES_PROPERTY
});
}

/**
* Log a message after {@link #isDecoupledDestinationAllowed(String)} returned {@code false}
* for messages having {@value #DECOUPLED_DESTINATION_APPROVED_PROPERTY} set to {@code true}.
*
* @param logger the {@link Logger} to pass the message to
* @param level log {@link Level} on which the message should be logged
* @param destinationUri the URI banned due to the configuration
*/
public static void logRejectedDecoupledDestination(Logger logger, Level level, String destinationUri) {
logger.logrb(level,
AddressingConstants.BUNDLE,
"REJECTED_DECOUPLED_DESTINATION",
new Object[] {
destinationUri,
WS_ADDRESSING_DECOUPLED_ENABLED_PROPERTY,
ALLOWED_DECOUPLED_DEST_SCHEMES_PROPERTY
});
}

/**
* Log a message after {@link #isDecoupledDestinationSchemeAllowed(String)} returned {@code false}
* for messages having {@value #DECOUPLED_DESTINATION_APPROVED_PROPERTY} set to {@code true}.
*
* @param logger the {@link Logger} to pass the message to
* @param level log {@link Level} on which the message should be logged
* @param destinationUri the URI banned due to the configuration
*/
public static void logDecoupledFaultToSchemeNotAllowed(Logger logger, Level level, String destinationUri) {
logger.logrb(level,
AddressingConstants.BUNDLE,
"DECOUPLED_FAULT_TO_SCHEME_NOT_ALLOWED",
new Object[] {
destinationUri,
ALLOWED_DECOUPLED_DEST_SCHEMES_PROPERTY
});
}

/**
* Log a message after {@link #isDecoupledDestinationAllowed(String)} returned {@code false}
* for {@code FaultTo} URI.
*
* @param logger the {@link Logger} to pass the message to
* @param level log {@link Level} on which the message should be logged
* @param destinationUri the URI banned due to the configuration
*/
public static void logDecoupledFaultToNotAllowed(Logger logger, Level level, String destinationUri) {
logger.logrb(level,
AddressingConstants.BUNDLE,
"DECOUPLED_FAULT_TO_NOT_ALLOWED",
new Object[] {
destinationUri,
WS_ADDRESSING_DECOUPLED_ENABLED_PROPERTY,
ALLOWED_DECOUPLED_DEST_SCHEMES_PROPERTY
});
}

/**
* Create a SOAP Fault reason after {@link #isDecoupledDestinationAllowed(String)} returned {@code false}.
*
* @param destinationUri the URI banned due to the configuration
* @return a formatted message
*/
public static String formatDecoupledReplyToNotPermittedMessage(String destinationUri) {
return MessageFormat.format(
AddressingConstants.BUNDLE.getString("DECOUPLED_REPLY_TO_NOT_PERMITTED"),
destinationUri,
WS_ADDRESSING_DECOUPLED_ENABLED_PROPERTY,
ALLOWED_DECOUPLED_DEST_SCHEMES_PROPERTY);
}

/**
* Create a SOAP Fault reason after {@link #isDecoupledDestinationSchemeAllowed(String)} returned {@code false}.
*
* @param destinationUri the URI banned due to the configuration
* @return a formatted message
*/
public static String formatDecoupledReplyToSchemeNotPermittedMessage(String destinationUri) {
return MessageFormat.format(
AddressingConstants.BUNDLE.getString("DECOUPLED_REPLY_TO_SCHEME_NOT_PERMITTED"),
destinationUri,
ALLOWED_DECOUPLED_DEST_SCHEMES_PROPERTY);
}

/**
* Validates the URI scheme for {@link #isDecoupledDestinationAllowed}.
*/
Expand Down Expand Up @@ -697,23 +798,11 @@ public Conduit getBackChannel(Message inMessage) throws IOException {
// Higher-level protocol (e.g. WS-RM) pre-approved decoupled addressing
// for this exchange; still enforce the scheme allowlist.
if (!isDecoupledDestinationSchemeAllowed(destinationUri)) {
LOG.log(Level.WARNING,
"Rejected pre-approved decoupled destination with disallowed scheme: {0}. "
+ "Configure permitted URI schemes with system property {1}",
new Object[] {destinationUri, ALLOWED_DECOUPLED_DEST_SCHEMES_PROPERTY});
logDisallowedDecoupledDestinationScheme(LOG, Level.WARNING, destinationUri);
return null;
}
} else if (!isDecoupledDestinationAllowed(destinationUri)) {
LOG.log(Level.WARNING,
"Rejected wsa:ReplyTo/FaultTo decoupled destination: {0}. "
+ "Decoupled WS-Addressing is disabled by default; "
+ "enable with system property {1}=true, "
+ "or configure permitted URI schemes with {2}",
new Object[] {
destinationUri,
WS_ADDRESSING_DECOUPLED_ENABLED_PROPERTY,
ALLOWED_DECOUPLED_DEST_SCHEMES_PROPERTY
});
logRejectedDecoupledDestination(LOG, Level.WARNING, destinationUri);
return null;
}
Bus bus = inMessage.getExchange().getBus();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# under the License.
#
#
BUILDER_CLASS_NOT_FOUND_MSG = WS-Addressing builder class {0} not found
BUILDER_CLASS_NOT_FOUND_MSG = WS-Addressing builder class {0} not found
BUILDER_INSTANTIATION_FAILED_MSG = WS-Addressing builder {0} could not be instantiated:
MAPS_RETRIEVAL_FAILURE_MSG = WS-Addressing - failed to retrieve Message Addressing Properties from context
ACTION_NOT_SUPPORTED_MSG = Action {0} not supported
Expand All @@ -29,4 +29,19 @@ MAP_REQUIRED_MSG = Message Addressing Property {0} required
DUPLICATE_MESSAGE_ID_MSG = Duplicate Message ID {0}
INVALID_ADDRESSING_PROPERTY_MESSAGE = A header representing a Message Addressing Property is not valid and the message cannot be processed
MISSING_ACTION_MESSAGE = A required header representing a Message Addressing Property is not present
REPLYTO_NOT_SUPPORTED_MSG = ReplyTo {0} is not supported for request-response MEP
REPLYTO_NOT_SUPPORTED_MSG = ReplyTo {0} is not supported for request-response MEP
DISALLOWED_DECOUPLED_DESTINATION_SCHEME = Rejected pre-approved decoupled destination with disallowed scheme: {0}. \
Configure permitted URI schemes with system property {1}
REJECTED_DECOUPLED_DESTINATION = Rejected wsa:ReplyTo/FaultTo decoupled destination: {0}. \
Decoupled WS-Addressing is disabled by default; enable with system property {1}=true, \
or configure permitted URI schemes with {2}
DECOUPLED_REPLY_TO_NOT_PERMITTED = Decoupled WS-Addressing ReplyTo ({0}) is not permitted by this server. Enable with system property {1}=true, \
or configure permitted URI schemes with {2}
DECOUPLED_REPLY_TO_SCHEME_NOT_PERMITTED = Decoupled WS-Addressing ReplyTo ({0}) is not permitted by this server: URI scheme is not allowed. \
Configure permitted schemes with system property {1}
DECOUPLED_FAULT_TO_SCHEME_NOT_ALLOWED = Decoupled pre-approved FaultTo ({0}) is not permitted: URI scheme is not allowed. \
Fault will be delivered to ReplyTo instead. Configure permitted schemes with {1}
DECOUPLED_FAULT_TO_NOT_ALLOWED = Fault will be delivered to ReplyTo instead. Configure permitted schemes with {1} \
Decoupled WS-Addressing FaultTo ({0}) is not permitted; \
fault will be delivered to ReplyTo instead. \
Enable with system property {1}=true, or configure permitted URI schemes with {2}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,14 @@

package org.apache.cxf.ws.addressing;

import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Random;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import java.util.logging.StreamHandler;

import org.apache.cxf.message.ExchangeImpl;
import org.apache.cxf.message.Message;
Expand Down Expand Up @@ -213,4 +220,78 @@ public void testHasEmptyAddress() {
assertThat(hasEmptyAction(maps), is(false));
assertThat(maps.getAction(), notNullValue());
}

@Test
public void formatMessages() {
assertThat(
ContextUtils.formatDecoupledReplyToNotPermittedMessage("http://localhost:1234/decoupled"),
is("Decoupled WS-Addressing ReplyTo (http://localhost:1234/decoupled) is not permitted by this server."
+ " Enable with system property org.apache.cxf.ws.addressing.decoupled.enabled=true,"
+ " or configure permitted URI schemes with"
+ " org.apache.cxf.ws.addressing.decoupled.allowedSchemes"));
assertThat(
ContextUtils.formatDecoupledReplyToSchemeNotPermittedMessage("http://localhost:1234/decoupled"),
is("Decoupled WS-Addressing ReplyTo (http://localhost:1234/decoupled) is not permitted by this server:"
+ " URI scheme is not allowed."
+ " Configure permitted schemes with system property"
+ " org.apache.cxf.ws.addressing.decoupled.allowedSchemes"));
}

@Test
public void logMessages() {
assertLogMessage(log -> ContextUtils.logDisallowedDecoupledDestinationScheme(
log,
Level.WARNING,
"http://localhost:1234/decoupled"),
"Rejected pre-approved decoupled destination with disallowed scheme: http://localhost:1234/decoupled."
+ " Configure permitted URI schemes with system property "
+ ContextUtils.ALLOWED_DECOUPLED_DEST_SCHEMES_PROPERTY);
assertLogMessage(
log -> ContextUtils.logRejectedDecoupledDestination(
log,
Level.WARNING,
"http://localhost:1234/decoupled"),
"Rejected wsa:ReplyTo/FaultTo decoupled destination: http://localhost:1234/decoupled."
+ " Decoupled WS-Addressing is disabled by default;"
+ " enable with system property org.apache.cxf.ws.addressing.decoupled.enabled=true,"
+ " or configure permitted URI schemes with"
+ " org.apache.cxf.ws.addressing.decoupled.allowedSchemes");
assertLogMessage(
log -> ContextUtils.logDecoupledFaultToSchemeNotAllowed(
log,
Level.WARNING,
"http://localhost:1234/decoupled"),
"Decoupled pre-approved FaultTo (http://localhost:1234/decoupled) is not permitted:"
+ " URI scheme is not allowed. Fault will be delivered to ReplyTo instead."
+ " Configure permitted schemes with org.apache.cxf.ws.addressing.decoupled.allowedSchemes");
assertLogMessage(
log -> ContextUtils.logDecoupledFaultToNotAllowed(
log,
Level.WARNING,
"http://localhost:1234/decoupled"),
"Fault will be delivered to ReplyTo instead. Configure permitted schemes with"
+ " org.apache.cxf.ws.addressing.decoupled.enabled Decoupled WS-Addressing FaultTo"
+ " (http://localhost:1234/decoupled) is not permitted; fault will be delivered to ReplyTo"
+ " instead. Enable with system property org.apache.cxf.ws.addressing.decoupled.enabled=true,"
+ " or configure permitted URI schemes with"
+ " org.apache.cxf.ws.addressing.decoupled.allowedSchemes");
}

static void assertLogMessage(Consumer<Logger> logMethod, String expected) {
Logger log = Logger.getLogger("test" + logMethod.toString());
log.setLevel(Level.FINEST);
log.setUseParentHandlers(false);
ByteArrayOutputStream out = new ByteArrayOutputStream();
StreamHandler handler = new StreamHandler(out, new SimpleFormatter());
handler.setLevel(Level.FINEST);
log.addHandler(handler);
logMethod.accept(log);
handler.flush();
String logOutput = out.toString(StandardCharsets.UTF_8);
assertThat(
logOutput,
org.hamcrest.Matchers.containsString("WARNING: " + expected));
log.removeHandler(handler);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -99,23 +99,11 @@ public Conduit getBackChannel(Message inMessage) throws IOException {
inMessage.getExchange().get(ContextUtils.DECOUPLED_DESTINATION_APPROVED_PROPERTY));
if (approved) {
if (!ContextUtils.isDecoupledDestinationSchemeAllowed(destinationUri)) {
LOG.log(Level.WARNING,
"Rejected pre-approved decoupled destination with disallowed scheme: {0}. "
+ "Configure permitted URI schemes with system property {1}",
new Object[] {destinationUri, ContextUtils.ALLOWED_DECOUPLED_DEST_SCHEMES_PROPERTY});
ContextUtils.logDisallowedDecoupledDestinationScheme(LOG, Level.WARNING, destinationUri);
return null;
}
} else if (!ContextUtils.isDecoupledDestinationAllowed(destinationUri)) {
LOG.log(Level.WARNING,
"Rejected wsa:ReplyTo/FaultTo decoupled destination: {0}. "
+ "Decoupled WS-Addressing is disabled by default; "
+ "enable with system property {1}=true, "
+ "and/or configure permitted URI schemes with {2}",
new Object[] {
destinationUri,
ContextUtils.WS_ADDRESSING_DECOUPLED_ENABLED_PROPERTY,
ContextUtils.ALLOWED_DECOUPLED_DEST_SCHEMES_PROPERTY
});
ContextUtils.logRejectedDecoupledDestination(LOG, Level.WARNING, destinationUri);
return null;
}
Bus bus = inMessage.getExchange().getBus();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1235,10 +1235,7 @@ private void assertDecoupledReplyToAllowed(Message message, AddressingProperties
if (ContextUtils.isDecoupledDestinationSchemeAllowed(uri)) {
return;
}
final String reason = "Decoupled WS-Addressing ReplyTo (" + uri
+ ") is not permitted by this server: URI scheme is not allowed. "
+ "Configure permitted schemes with system property "
+ ContextUtils.ALLOWED_DECOUPLED_DEST_SCHEMES_PROPERTY;
final String reason = ContextUtils.formatDecoupledReplyToSchemeNotPermittedMessage(uri);
if (isSOAP12(message)) {
SoapFault f = new SoapFault(reason, Soap12.getInstance().getSender());
f.setSubCode(Names.DESTINATION_UNREACHABLE_QNAME);
Expand All @@ -1250,9 +1247,7 @@ private void assertDecoupledReplyToAllowed(Message message, AddressingProperties
if (ContextUtils.isDecoupledDestinationAllowed(uri)) {
return;
}
final String reason = "Decoupled WS-Addressing ReplyTo (" + uri
+ ") is not permitted by this server. Enable with system property "
+ ContextUtils.WS_ADDRESSING_DECOUPLED_ENABLED_PROPERTY + "=true";
final String reason = ContextUtils.formatDecoupledReplyToNotPermittedMessage(uri);
if (isSOAP12(message)) {
SoapFault f = new SoapFault(reason, Soap12.getInstance().getSender());
f.setSubCode(Names.DESTINATION_UNREACHABLE_QNAME);
Expand Down Expand Up @@ -1284,22 +1279,14 @@ private void rebaseOrFallbackFaultTo(Message message,
m.getExchange().setDestination(destination);
return;
}
LOG.log(Level.WARNING,
"Decoupled pre-approved FaultTo ({0}) is not permitted: URI scheme is not allowed. "
+ "Fault will be delivered to ReplyTo instead. Configure permitted schemes with {1}",
new Object[]{faultToUri, ContextUtils.ALLOWED_DECOUPLED_DEST_SCHEMES_PROPERTY});
ContextUtils.logDecoupledFaultToSchemeNotAllowed(LOG, Level.WARNING, faultToUri);
if (inMAPs.getReplyTo() != null) {
maps.setTo(inMAPs.getReplyTo());
}
return;
}
if (!ContextUtils.isDecoupledDestinationAllowed(faultToUri)) {
LOG.log(Level.WARNING,
"Decoupled WS-Addressing FaultTo ({0}) is not permitted; "
+ "fault will be delivered to ReplyTo instead. "
+ "Enable with system property {1}=true",
new Object[]{faultToUri,
ContextUtils.WS_ADDRESSING_DECOUPLED_ENABLED_PROPERTY});
ContextUtils.logDecoupledFaultToNotAllowed(LOG, Level.WARNING, faultToUri);
if (inMAPs.getReplyTo() != null) {
maps.setTo(inMAPs.getReplyTo());
}
Expand Down
Loading