mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +00:00 
			
		
		
		
	GUACAMOLE-1809: Merge replacement of Spring with "IPAddress" library.
This commit is contained in:
		
							
								
								
									
										8
									
								
								doc/licenses/ipaddress-5.4.0/README
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								doc/licenses/ipaddress-5.4.0/README
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| IPAddress (https://seancfoley.github.io/IPAddress/) | ||||
| --------------------------------------------------- | ||||
|  | ||||
|     Version: 5.4.0 | ||||
|     From: 'Sean C Foley' (https://seancfoley.github.io/) | ||||
|     License(s): | ||||
|         Apache v2.0 | ||||
|  | ||||
							
								
								
									
										1
									
								
								doc/licenses/ipaddress-5.4.0/dep-coordinates.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								doc/licenses/ipaddress-5.4.0/dep-coordinates.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| com.github.seancfoley:ipaddress:jar:5.4.0 | ||||
| @@ -1,8 +0,0 @@ | ||||
| Spring Framework (https://spring.io/projects/spring-framework) | ||||
| -------------------------------------------------------------- | ||||
|  | ||||
|     Version: 5.3.27 | ||||
|     From: 'Spring' (https://spring.io/) | ||||
|     License(s): | ||||
|         Apache v2.0 | ||||
|  | ||||
| @@ -1,7 +0,0 @@ | ||||
| org.springframework:spring-aop:jar:5.3.27 | ||||
| org.springframework:spring-beans:jar:5.3.27 | ||||
| org.springframework:spring-context:jar:5.3.27 | ||||
| org.springframework:spring-core:jar:5.3.27 | ||||
| org.springframework:spring-expression:jar:5.3.27 | ||||
| org.springframework:spring-jcl:jar:5.3.27 | ||||
| org.springframework:spring-web:jar:5.3.27 | ||||
| @@ -1,2 +0,0 @@ | ||||
| This product includes software developed by Spring Security | ||||
| Project (https://www.springframework.org/security). | ||||
| @@ -1,8 +0,0 @@ | ||||
| Spring Security (https://spring.io/projects/spring-security) | ||||
| ------------------------------------------------------------ | ||||
|  | ||||
|     Version: 5.8.3 | ||||
|     From: 'Spring' (https://spring.io/) | ||||
|     License(s): | ||||
|         Apache v2.0 | ||||
|  | ||||
| @@ -1,3 +0,0 @@ | ||||
| org.springframework.security:spring-security-core:jar:5.8.3 | ||||
| org.springframework.security:spring-security-crypto:jar:5.8.3 | ||||
| org.springframework.security:spring-security-web:jar:5.8.3 | ||||
| @@ -73,11 +73,18 @@ | ||||
|             <scope>provided</scope> | ||||
|         </dependency> | ||||
|  | ||||
|         <!-- Spring security library (required for IP address matching) --> | ||||
|         <!-- IPAddress (required for IP address matching) --> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.security</groupId> | ||||
|             <artifactId>spring-security-web</artifactId> | ||||
|             <version>5.8.3</version> | ||||
|             <groupId>com.github.seancfoley</groupId> | ||||
|             <artifactId>ipaddress</artifactId> | ||||
|             <version>5.4.0</version> | ||||
|         </dependency> | ||||
|  | ||||
|         <!-- JUnit --> | ||||
|         <dependency> | ||||
|             <groupId>junit</groupId> | ||||
|             <artifactId>junit</artifactId> | ||||
|             <scope>test</scope> | ||||
|         </dependency> | ||||
|  | ||||
|     </dependencies> | ||||
|   | ||||
| @@ -20,13 +20,13 @@ | ||||
| package org.apache.guacamole.auth.json; | ||||
|  | ||||
| import com.google.inject.Inject; | ||||
| import inet.ipaddr.IPAddressString; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collection; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import org.apache.guacamole.GuacamoleException; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.springframework.security.web.util.matcher.IpAddressMatcher; | ||||
|  | ||||
| /** | ||||
|  * Service for testing the validity of received HTTP requests. | ||||
| @@ -45,6 +45,17 @@ public class RequestValidationService { | ||||
|     @Inject | ||||
|     private ConfigurationService confService; | ||||
|  | ||||
|     /** | ||||
|      * Constructor that enables passing of an instance of | ||||
|      * ConfigurationService. (Only used for unit testing) | ||||
|      * | ||||
|      * @param confService | ||||
|      *     The (mock) instance of ConfigurationService | ||||
|      */ | ||||
|     public RequestValidationService(ConfigurationService confService) { | ||||
|         this.confService = confService; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Returns whether the given request can be used for authentication, taking | ||||
|      * into account restrictions specified within guacamole.properties. | ||||
| @@ -77,16 +88,11 @@ public class RequestValidationService { | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         // Build matchers for each trusted network | ||||
|         Collection<IpAddressMatcher> matchers = new ArrayList<>(trustedNetworks.size()); | ||||
|         for (String network : trustedNetworks) | ||||
|             matchers.add(new IpAddressMatcher(network)); | ||||
|  | ||||
|         // Otherwise ensure at least one subnet matches | ||||
|         for (IpAddressMatcher matcher : matchers) { | ||||
|         // Otherwise ensure that the remote address is part of a trusted network | ||||
|         for (String network : trustedNetworks) { | ||||
|  | ||||
|             // Request is allowed if any subnet matches | ||||
|             if (matcher.matches(request)) { | ||||
|             if (new IPAddressString(network).contains(new IPAddressString(request.getRemoteAddr()))) { | ||||
|                 logger.debug("Authentication request from \"{}\" is ALLOWED (matched subnet).", request.getRemoteAddr()); | ||||
|                 return true; | ||||
|             } | ||||
|   | ||||
| @@ -0,0 +1,452 @@ | ||||
| /* | ||||
|  * 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.guacamole.auth.json; | ||||
|  | ||||
| import java.io.BufferedReader; | ||||
| import java.security.Principal; | ||||
| import java.util.Arrays; | ||||
| import java.util.Collection; | ||||
| import java.util.Collections; | ||||
| import java.util.Enumeration; | ||||
| import java.util.Locale; | ||||
| import java.util.Map; | ||||
| import java.util.regex.Pattern; | ||||
| import javax.servlet.http.Cookie; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpSession; | ||||
| import javax.servlet.ServletInputStream; | ||||
| import javax.servlet.RequestDispatcher; | ||||
| import org.junit.Test; | ||||
| import static org.junit.Assert.*; | ||||
|  | ||||
| /** | ||||
|  * Unit test for RequestValidationService. Verifies that only requests | ||||
|  * from trusted hosts are allowed to authenticate. | ||||
|  */ | ||||
| public class RequestValidationServiceTest { | ||||
|  | ||||
|     /** | ||||
|      * This class is used to mock ConfigurationService. | ||||
|      */ | ||||
|     private class MockConfigurationService extends ConfigurationService { | ||||
|  | ||||
|         /** | ||||
|          * List of networks to be trusted | ||||
|          */ | ||||
|         private Collection<String> trustedNetworks; | ||||
|  | ||||
|         /** | ||||
|          * Constructor that enables passing of a comma-separated list of | ||||
|          * trusted networks. | ||||
|          * | ||||
|          * @param trustedNetworks | ||||
|          *     The comma-separated list of trusted networks | ||||
|          */ | ||||
|         private MockConfigurationService(String trustedNetworks) { | ||||
|             if (trustedNetworks == null || trustedNetworks.isEmpty()) | ||||
|                 this.trustedNetworks = Collections.<String>emptyList(); | ||||
|             else | ||||
|                 this.trustedNetworks = Arrays.asList(Pattern.compile(",\\s*").split(trustedNetworks)); | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public Collection<String> getTrustedNetworks() { | ||||
|             return trustedNetworks; | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The instance of RequestValidationService to be tested. | ||||
|      */ | ||||
|     private RequestValidationService requestService; | ||||
|  | ||||
|     /** | ||||
|      * Method that returns a (mock) HttpServletRequest with the provided | ||||
|      * remote address. | ||||
|      * | ||||
|      * @param remoteAddr | ||||
|      *     The remote address of the request | ||||
|      */ | ||||
|     private static HttpServletRequest mockHttpServletRequest(String remoteAddr) { | ||||
|  | ||||
|         return new HttpServletRequest() { | ||||
|  | ||||
|             @Override | ||||
|             public Object getAttribute(String name) { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public Enumeration<String> getAttributeNames() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getAuthType() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getCharacterEncoding() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public int getContentLength() { | ||||
|                 return 0; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getContentType() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getContextPath() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public Cookie[] getCookies() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public long getDateHeader(String name) { | ||||
|                 return 0; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getHeader(String name) { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public Enumeration<String> getHeaderNames() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public Enumeration<String> getHeaders(String name) { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public ServletInputStream getInputStream() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public int getIntHeader(String name) { | ||||
|                 return 0; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getLocalAddr() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public Locale getLocale() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public Enumeration<Locale> getLocales() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getLocalName() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public int getLocalPort() { | ||||
|                 return 0; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getMethod() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getParameter(String name) { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public Map<String,String[]> getParameterMap() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public Enumeration<String> getParameterNames() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String[] getParameterValues(String name) { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getPathInfo() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getPathTranslated() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getProtocol() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getQueryString() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public BufferedReader getReader() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             @Deprecated | ||||
|             public String getRealPath(String path) { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getRemoteAddr() { | ||||
|                 return remoteAddr; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getRemoteHost() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public int getRemotePort() { | ||||
|                 return 0; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getRemoteUser() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public RequestDispatcher getRequestDispatcher(String path) { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getRequestedSessionId() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getRequestURI() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public StringBuffer getRequestURL() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getScheme() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getServerName() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public int getServerPort() { | ||||
|                 return 0; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public String getServletPath() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public HttpSession getSession() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public HttpSession getSession(boolean create) { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public Principal getUserPrincipal() { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public boolean isRequestedSessionIdFromCookie() { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             @Deprecated | ||||
|             public boolean isRequestedSessionIdFromUrl() { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public boolean isRequestedSessionIdFromURL() { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public boolean isRequestedSessionIdValid() { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public boolean isSecure() { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public boolean isUserInRole(String role) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void removeAttribute(String name) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void setAttribute(String name, Object o) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             @Override | ||||
|             public void setCharacterEncoding(String env) { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|         }; | ||||
|  | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Verifies that all hosts are allowed to authenticate when no | ||||
|      * trusted networks are specified. | ||||
|      */ | ||||
|     @Test | ||||
|     public void testNoTrustedNetwork() { | ||||
|  | ||||
|         requestService = new RequestValidationService(new MockConfigurationService(null)); | ||||
|  | ||||
|         try { | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("1.1.1.1"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("10.10.10.10"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("100.100.100.100"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("1:1:1:1:1:1:1:1"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("10:10:10:10:10:10:10:10"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("100:100:100:100:100:100:100:100"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("1000:1000:1000:1000:1000:1000:1000:1000"))); | ||||
|         } | ||||
|         catch (AssertionError e) { | ||||
|             fail("A network was denied to authenticate even though no trusted networks were specified."); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Verifies that hosts from trusted networks are allowed to | ||||
|      * authenticate: | ||||
|      */ | ||||
|     @Test | ||||
|     public void testTrustedNetwork() { | ||||
|  | ||||
|         requestService = new RequestValidationService(new MockConfigurationService("10.0.0.0/8,127.0.0.0/8,172.16.0.0/12,192.168.0.0/16,1.2.3.4/32,::1/128,fc00::/7")); | ||||
|  | ||||
|         try { | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("10.0.0.0"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("10.255.255.255"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("127.0.0.0"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("127.255.255.255"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("172.16.0.0"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("172.31.255.255"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("192.168.0.0"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("192.168.255.255"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("1.2.3.4"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("::1"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("fc00::"))); | ||||
|             assertTrue(requestService.isAuthenticationAllowed(mockHttpServletRequest("fdff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"))); | ||||
|         } | ||||
|         catch (AssertionError e) { | ||||
|             fail("A trusted network was denied to authenticate."); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Verifies that hosts outside trusted networks are not allowed to | ||||
|      * authenticate. | ||||
|      */ | ||||
|     @Test | ||||
|     public void testUntrustedNetwork() { | ||||
|  | ||||
|         requestService = new RequestValidationService(new MockConfigurationService("10.0.0.0/8,127.0.0.0/8,172.16.0.0/12,192.168.0.0/16,1.2.3.4/32,::1/128,fc00::/7")); | ||||
|  | ||||
|         try { | ||||
|             assertFalse(requestService.isAuthenticationAllowed(mockHttpServletRequest("9.255.255.255"))); | ||||
|             assertFalse(requestService.isAuthenticationAllowed(mockHttpServletRequest("11.0.0.0"))); | ||||
|             assertFalse(requestService.isAuthenticationAllowed(mockHttpServletRequest("126.255.255.255"))); | ||||
|             assertFalse(requestService.isAuthenticationAllowed(mockHttpServletRequest("128.0.0.0"))); | ||||
|             assertFalse(requestService.isAuthenticationAllowed(mockHttpServletRequest("172.15.255.255"))); | ||||
|             assertFalse(requestService.isAuthenticationAllowed(mockHttpServletRequest("172.32.0.0"))); | ||||
|             assertFalse(requestService.isAuthenticationAllowed(mockHttpServletRequest("192.167.255.255"))); | ||||
|             assertFalse(requestService.isAuthenticationAllowed(mockHttpServletRequest("192.169.0.0"))); | ||||
|             assertFalse(requestService.isAuthenticationAllowed(mockHttpServletRequest("1.2.3.3"))); | ||||
|             assertFalse(requestService.isAuthenticationAllowed(mockHttpServletRequest("1.2.3.5"))); | ||||
|             assertFalse(requestService.isAuthenticationAllowed(mockHttpServletRequest("::0"))); | ||||
|             assertFalse(requestService.isAuthenticationAllowed(mockHttpServletRequest("::2"))); | ||||
|             assertFalse(requestService.isAuthenticationAllowed(mockHttpServletRequest("fbff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"))); | ||||
|             assertFalse(requestService.isAuthenticationAllowed(mockHttpServletRequest("fe00::"))); | ||||
|         } | ||||
|         catch (AssertionError e) { | ||||
|             fail("An untrusted network was allowed to authenticate."); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user