vyommani commented on code in PR #665:
URL: https://github.com/apache/ranger/pull/665#discussion_r2352119839


##########
plugin-nifi-registry/src/test/java/org/apache/ranger/services/nifi/registry/client/TestNiFiRegistryClient.java:
##########
@@ -126,26 +148,228 @@ public void testConnectionTestSuccess() {
     }
 
     @Test
-    public void testConnectionTestFailure() {
+    public void testConnectionTestFailure() throws NoSuchAlgorithmException, 
KeyManagementException {
         final String errorMsg = "unknown error";
-        registryClient = new MockNiFiRegistryClient(errorMsg, 
Response.Status.BAD_REQUEST.getStatusCode());
+        registryClient = new MockNiFiRegistryClient(errorMsg, 
Response.Status.BAD_REQUEST.getStatusCode(), false, null);
 
         HashMap<String, Object> ret = registryClient.connectionTest();
         Assert.assertNotNull(ret);
         Assert.assertEquals(NiFiRegistryClient.FAILURE_MSG, 
ret.get("message"));
     }
 
+    @Test
+    public void testHostnameVerifierMatch() throws NoSuchAlgorithmException, 
KeyManagementException, CertificateParsingException, SSLPeerUnverifiedException 
{
+        MockNiFiRegistryClient sslClient = new MockNiFiRegistryClient("", 200, 
true, HOSTNAME);
+        sslClient.setupSSLMock(HOSTNAME);
+        sslClient.getResponse(sslClient.getWebResource(), "application/json");
+        verify(sslClient.hostnameVerifierSpy).verify(eq(HOSTNAME), 
any(SSLSession.class));
+        Assert.assertTrue(sslClient.lastVerifyResult);
+    }
+
+    @Test
+    public void testHostnameVerifierNoMatch() throws NoSuchAlgorithmException, 
KeyManagementException, CertificateParsingException, SSLPeerUnverifiedException 
{
+        MockNiFiRegistryClient sslClient = new MockNiFiRegistryClient("", 200, 
true, HOSTNAME);
+        sslClient.setupSSLMock("other.com");
+        sslClient.getResponse(sslClient.getWebResource(), "application/json");
+        verify(sslClient.hostnameVerifierSpy).verify(eq(HOSTNAME), 
any(SSLSession.class));
+        Assert.assertFalse(sslClient.lastVerifyResult);
+    }
+
+    @Test
+    public void testHostnameVerifierNoCerts() throws NoSuchAlgorithmException, 
KeyManagementException, SSLPeerUnverifiedException {
+        MockNiFiRegistryClient sslClient = new MockNiFiRegistryClient("", 200, 
true, HOSTNAME);
+        sslClient.setupSSLMockWithNoCerts();
+        sslClient.getResponse(sslClient.getWebResource(), "application/json");
+        Assert.assertFalse(sslClient.lastVerifyResult);
+    }
+
+    @Test
+    public void testHostnameVerifierEmptyCerts() throws 
NoSuchAlgorithmException, KeyManagementException, SSLPeerUnverifiedException {
+        MockNiFiRegistryClient sslClient = new MockNiFiRegistryClient("", 200, 
true, HOSTNAME);
+        sslClient.setupSSLMockWithEmptyCerts();
+        sslClient.getResponse(sslClient.getWebResource(), "application/json");
+        Assert.assertFalse(sslClient.lastVerifyResult);
+    }
+
+    @Test
+    public void testHostnameVerifierSanInIntermediateCertsFails() throws 
NoSuchAlgorithmException, KeyManagementException, CertificateParsingException, 
SSLPeerUnverifiedException {
+        MockNiFiRegistryClient sslClient = new MockNiFiRegistryClient("", 200, 
true, HOSTNAME);
+        sslClient.setupSSLMockWithSanInIntermediate();
+        sslClient.getResponse(sslClient.getWebResource(), "application/json");
+        verify(sslClient.hostnameVerifierSpy).verify(eq(HOSTNAME), 
any(SSLSession.class));
+        Assert.assertFalse(sslClient.lastVerifyResult);
+    }
+
     /**
      * Extend NiFiRegistryClient to return mock responses.
      */
     private static final class MockNiFiRegistryClient extends 
NiFiRegistryClient {
-        private int    statusCode;
-        private String responseEntity;
+        private final int statusCode;
+        private final String responseEntity;
+        private final boolean useSSL;
+        private final String hostname;
+        private HostnameVerifier hostnameVerifierSpy;
+        private boolean lastVerifyResult;
+        private SSLSession mockSession;
 
-        private MockNiFiRegistryClient(String responseEntity, int statusCode) {
-            
super("http://localhost:18080/nifi-registry-api/policiesresources";, null);
-            this.statusCode     = statusCode;
+        private MockNiFiRegistryClient(String responseEntity, int statusCode, 
boolean useSSL, String hostname) throws NoSuchAlgorithmException, 
KeyManagementException {
+            super(useSSL ? ("https://"; + (hostname != null ? hostname : 
"localhost") + ":443") : POLICIES_RESOURCES,
+                    useSSL ? createInitializedSSLContext() : null);
+            this.statusCode = statusCode;
             this.responseEntity = responseEntity;
+            this.useSSL = useSSL;
+            this.hostname = hostname;
+        }
+
+        private static SSLContext createInitializedSSLContext() throws 
NoSuchAlgorithmException, KeyManagementException {
+            SSLContext sslContext = SSLContext.getInstance("TLS");
+            sslContext.init(null, null, null);
+            return sslContext;
+        }
+
+        void setupSSLMock(String sanHostname) throws 
CertificateParsingException, SSLPeerUnverifiedException {
+            if (!useSSL) {
+                throw new IllegalStateException("SSL setup not supported for 
non-SSL mock");
+            }
+            hostnameVerifierSpy = spy(getHostnameVerifier());
+            mockSession = Mockito.mock(SSLSession.class);
+            SSLSessionContext mockContext = 
Mockito.mock(SSLSessionContext.class);
+            doReturn(mockContext).when(mockSession).getSessionContext();
+
+            X509Certificate mockCert = Mockito.mock(X509Certificate.class);
+            Certificate[] certs = {mockCert};
+            doReturn(certs).when(mockSession).getPeerCertificates();
+
+            Collection<?> altNames = Mockito.mock(Collection.class);
+            List<?> generalName = Mockito.mock(List.class);
+            doReturn(2).when(generalName).size();
+            doReturn(2).when(generalName).get(0);
+            doReturn(sanHostname.toLowerCase()).when(generalName).get(1);
+            
doReturn(java.util.Collections.singletonList(generalName).iterator()).when(altNames).iterator();
+            doReturn(altNames).when(mockCert).getSubjectAlternativeNames();
+
+            doAnswer(invocation -> {
+                String calledHostname = invocation.getArgument(0);
+                SSLSession calledSession = invocation.getArgument(1);
+                try {
+                    Certificate[] certificates = 
calledSession.getPeerCertificates();
+                    if (certificates == null || certificates.length == 0) {
+                        lastVerifyResult = false;
+                        return false;
+                    }
+                    final X509Certificate x509Cert = (X509Certificate) 
certificates[0];
+                    final Collection<List<?>> sanCollection = 
x509Cert.getSubjectAlternativeNames();
+                    if (sanCollection == null) {
+                        lastVerifyResult = false;
+                        return false;
+                    }
+                    boolean match = false;
+                    for (final List<?> generalNameEntry : sanCollection) {
+                        if (generalNameEntry.size() > 1) {
+                            final Object value = generalNameEntry.get(1);
+                            if (value instanceof String) {
+                                if (calledHostname.equalsIgnoreCase(((String) 
value))) {
+                                    match = true;
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                    lastVerifyResult = match;
+                    return match;
+                } catch (final SSLPeerUnverifiedException | 
CertificateParsingException ex) {
+                    lastVerifyResult = false;
+                    return false;
+                }
+            }).when(hostnameVerifierSpy).verify(any(String.class), 
any(SSLSession.class));

Review Comment:
   done, removed the duplicate code.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to