[java-sp-server] branch main updated: Move client address checking into service activator.

Scott Cantor cantor.2 at osu.edu
Thu May 19 20:06:11 UTC 2022


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch main
in repository java-sp-server.

View the commit online:
http://git.shibboleth.net/view/?p=java-sp-server.git;a=commit;h=7be727b5500daa5d2306ad46d028bf54fabe863c

The following commit(s) were added to refs/heads/main by this push:
     new 7be727b  Move client address checking into service activator.
7be727b is described below

commit 7be727b5500daa5d2306ad46d028bf54fabe863c
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Thu May 19 16:06:08 2022 -0400

    Move client address checking into service activator.
---
 .../net/shibboleth/sp/conf/integration.xml         | 15 ++++--
 sp-conf/src/main/resources/conf/sp.properties      |  2 +-
 .../sp/remoting/impl/RequestProcessor.java         | 59 +++++++++++++++++++---
 3 files changed, 65 insertions(+), 11 deletions(-)

diff --git a/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/integration.xml b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/integration.xml
index ea633ad..f117714 100644
--- a/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/integration.xml
+++ b/sp-conf-impl/src/main/resources/net/shibboleth/sp/conf/integration.xml
@@ -30,6 +30,10 @@
     <bean id="ByteArrayCrLfSerializer"
         class="org.springframework.integration.ip.tcp.serializer.ByteArrayCrLfSerializer" />
 
+    <!--
+    This worked funtionally but didn't manage to allow blocked message exceptions to be raised against
+    the error channel.
+    
     <bean id="shibboleth.TCPInterceptorFactory"
             class="org.springframework.integration.ip.tcp.connection.TcpConnectionInterceptorFactoryChain">
         <property name="interceptors">
@@ -43,15 +47,17 @@
             </array>
         </property>
     </bean>
-
+    
+    interceptor-factory-chain="shibboleth.TCPInterceptorFactory"
+    -->
+    
 	<int-ip:tcp-connection-factory id="shibboleth.IntegrationConnectionFactory"
         type="server"
         lookup-host="false"
         local-address="%{sp.service.address:127.0.0.1}"
         port="%{sp.service.port:1600}"
         serializer="#{%{sp.service.prefixLength:false} ? 'ByteArrayLengthHeaderSerializer' : 'ByteArrayCrLfSerializer'}"
-        deserializer="#{%{sp.service.prefixLength:false} ? 'ByteArrayLengthHeaderSerializer' : 'ByteArrayCrLfSerializer'}"
-        interceptor-factory-chain="shibboleth.TCPInterceptorFactory" />
+        deserializer="#{%{sp.service.prefixLength:false} ? 'ByteArrayLengthHeaderSerializer' : 'ByteArrayCrLfSerializer'}" />
 
 	<int-ip:tcp-inbound-gateway id="shibboleth.IntegrationGateway"
         connection-factory="shibboleth.IntegrationConnectionFactory"
@@ -76,6 +82,7 @@
 
 	<bean id="shibboleth.RequestProcessor" class="net.shibboleth.sp.remoting.impl.RequestProcessor"
         depends-on="shibboleth.LoggingService"
-        p:endpointManager-ref="shibboleth.ServiceProvider" />
+        p:endpointManager-ref="shibboleth.ServiceProvider"
+        p:allowedRanges="#{'%{sp.service.allowedRanges:127.0.0.1/32,::0/128}'.trim()}" />
     
 </beans>
diff --git a/sp-conf/src/main/resources/conf/sp.properties b/sp-conf/src/main/resources/conf/sp.properties
index 99605de..b8f630c 100644
--- a/sp-conf/src/main/resources/conf/sp.properties
+++ b/sp-conf/src/main/resources/conf/sp.properties
@@ -8,7 +8,7 @@ sp.additionalProperties = /credentials/secrets.properties
 # Networking settings for service.
 #sp.service.address = 127.0.0.1
 #sp.service.port = 1600
-sp.service.allowedRanges = 1.2.3.4/32
+#sp.service.allowedRanges = 127.0.0.1/32, ::1/128
 # Set to true for better performance.
 #sp.service.prefixLength = false
 
diff --git a/sp-server-impl/src/main/java/net/shibboleth/sp/remoting/impl/RequestProcessor.java b/sp-server-impl/src/main/java/net/shibboleth/sp/remoting/impl/RequestProcessor.java
index 3adced6..4bc7b68 100644
--- a/sp-server-impl/src/main/java/net/shibboleth/sp/remoting/impl/RequestProcessor.java
+++ b/sp-server-impl/src/main/java/net/shibboleth/sp/remoting/impl/RequestProcessor.java
@@ -14,20 +14,31 @@
 
 package net.shibboleth.sp.remoting.impl;
 
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.integration.ip.IpHeaders;
+import org.springframework.messaging.Message;
 
 import net.shibboleth.sp.remoting.RemoteProcessingException;
 import net.shibboleth.sp.remoting.Endpoint;
 import net.shibboleth.sp.remoting.EndpointManager;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.utilities.java.support.annotation.constraint.NonnullElements;
 import net.shibboleth.utilities.java.support.component.AbstractIdentifiableInitializableComponent;
 import net.shibboleth.utilities.java.support.component.ComponentInitializationException;
 import net.shibboleth.utilities.java.support.component.ComponentSupport;
 import net.shibboleth.utilities.java.support.ddf.DDF;
 import net.shibboleth.utilities.java.support.logic.Constraint;
+import net.shibboleth.utilities.java.support.net.IPRange;
 import net.shibboleth.utilities.java.support.service.ReloadableService;
 import net.shibboleth.utilities.java.support.service.ServiceableComponent;
 
@@ -41,6 +52,9 @@ public class RequestProcessor extends AbstractIdentifiableInitializableComponent
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(RequestProcessor.class);
     
+    /** List of CIDR blocks allowed to access connections. */
+    @Nonnull @NonnullElements private Collection<IPRange> allowedRanges;
+    
     /** Address lookup service. */
     @NonnullAfterInit ReloadableService<EndpointManager> service;
 
@@ -55,6 +69,21 @@ public class RequestProcessor extends AbstractIdentifiableInitializableComponent
         service = Constraint.isNotNull(svc, "EndpointManager service cannot be null");
     }
     
+    /**
+     * Sets the allowed client address ranges.
+     *
+     * @param ranges allowed ranges for client connection enforcement
+     */
+    public void setAllowedRanges(@Nullable @NonnullElements final Collection<IPRange> ranges) {
+        ComponentSupport.ifInitializedThrowUnmodifiabledComponentException(this);
+        
+        if (ranges != null) {
+            allowedRanges = List.copyOf(ranges);
+        } else {
+            allowedRanges = Collections.emptyList();
+        }
+    }
+    
     /** {@inheritDoc} */
     @Override
     protected void doInitialize() throws ComponentInitializationException {
@@ -62,25 +91,43 @@ public class RequestProcessor extends AbstractIdentifiableInitializableComponent
         
         if (service == null) {
             throw new ComponentInitializationException("EndpointManager service cannot be null");
+        } else if (allowedRanges.isEmpty()) {
+            throw new ComponentInitializationException("At least one IPRange must be permitted");
         }
     }
-    
-
-
 
     /**
      * Execute a remote request.
      * 
-     * @param input input data object
+     * @param message input message
      * 
      * @return output data object
      * 
      * @throws RemoteProcessingException if an error is raised by the destination of the message 
      */
-	@Nonnull public DDF execute(@Nonnull final DDF input) throws RemoteProcessingException {
+	@Nonnull public DDF execute(@Nonnull final Message<DDF> message) throws RemoteProcessingException {
         ComponentSupport.ifNotInitializedThrowUninitializedComponentException(this);
         
-	    Constraint.isNotNull(input, "Input object cannot be null");
+        final Object address = message.getHeaders().get(IpHeaders.IP_ADDRESS);
+        if (address instanceof String) {
+            final InetAddress parsedAddress;
+            try {
+                parsedAddress = InetAddress.getByName((String) address);
+            } catch (final UnknownHostException e) {
+                log.warn("Unable to parse client address {}", address, e);
+                throw new RemoteProcessingException("Unable to parse client address", e);
+            }
+            if (!allowedRanges.stream().anyMatch(range -> range.contains(parsedAddress))) {
+                log.warn("Blocked request from unauthorized client address {}", address);
+                throw new RemoteProcessingException("Blocked request from unauthorized client address");
+            }
+        } else {
+            throw new RemoteProcessingException("Save my walrus! ip_address header was not a String?");
+        }
+        
+	    Constraint.isNotNull(message.getPayload(), "Input object cannot be null");
+	    
+	    final DDF input = message.getPayload();
 	    
 	    log.trace("Input message: {}", input.toString());
 	    

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list