You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by ge...@apache.org on 2024/03/01 13:38:19 UTC

(solr) branch branch_9x updated: SOLR-17183: Tweak PKI Auth logging (#2312)

This is an automated email from the ASF dual-hosted git repository.

gerlowskija pushed a commit to branch branch_9x
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/branch_9x by this push:
     new b695853142f SOLR-17183: Tweak PKI Auth logging (#2312)
b695853142f is described below

commit b695853142fdc6d5a50a166189f6dd5911643323
Author: Jason Gerlowski <ge...@apache.org>
AuthorDate: Fri Mar 1 08:25:45 2024 -0500

    SOLR-17183: Tweak PKI Auth logging (#2312)
    
    Clarifies one or two messages, includes cryptographic exception messages
    in logging, and introduces a new message in the case where a public-key
    cannot be fetched because the relevant node isn't in `/live_nodes`
---
 .../solr/security/PKIAuthenticationPlugin.java     | 60 ++++++++++++++--------
 .../solr/security/TestPKIAuthenticationPlugin.java |  4 +-
 2 files changed, 41 insertions(+), 23 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java b/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java
index a57c636a386..0b966e5419a 100644
--- a/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java
+++ b/solr/core/src/java/org/apache/solr/security/PKIAuthenticationPlugin.java
@@ -153,7 +153,9 @@ public class PKIAuthenticationPlugin extends AuthenticationPlugin
     PKIHeaderData headerData = null;
     String headerV2 = request.getHeader(HEADER_V2);
     String headerV1 = request.getHeader(HEADER);
-    if (headerV2 != null) {
+    if (headerV1 == null && headerV2 == null) {
+      return sendError(response, true, "No PKI auth header was provided");
+    } else if (headerV2 != null) {
       // Try V2 first
       int nodeNameEnd = headerV2.indexOf(' ');
       if (nodeNameEnd <= 0) {
@@ -172,7 +174,7 @@ public class PKIAuthenticationPlugin extends AuthenticationPlugin
     }
 
     if (headerData == null) {
-      return sendError(response, true, "Could not load principal from SolrAuthV2 header.");
+      return sendError(response, true, "Could not validate PKI header.");
     }
     long elapsed = receivedTime - headerData.timestamp;
     if (elapsed > MAX_VALIDITY) {
@@ -218,14 +220,20 @@ public class PKIAuthenticationPlugin extends AuthenticationPlugin
     }
   }
 
-  private PKIHeaderData decipherHeaderV2(String header, String nodeName) {
+  private PublicKey getOrFetchPublicKey(String nodeName) {
     PublicKey key = keyCache.get(nodeName);
     if (key == null) {
       log.debug("No key available for node: {} fetching now ", nodeName);
-      key = getRemotePublicKey(nodeName);
+      key = fetchPublicKeyFromRemote(nodeName);
       log.debug("public key obtained {} ", key);
     }
 
+    return key;
+  }
+
+  private PKIHeaderData decipherHeaderV2(String header, String nodeName) {
+    PublicKey key = getOrFetchPublicKey(nodeName);
+
     int sigStart = header.lastIndexOf(' ');
 
     String data = header.substring(0, sigStart);
@@ -233,7 +241,7 @@ public class PKIAuthenticationPlugin extends AuthenticationPlugin
     PKIHeaderData rv = validateSignature(data, sig, key, false);
     if (rv == null) {
       log.warn("Failed to verify signature, trying after refreshing the key ");
-      key = getRemotePublicKey(nodeName);
+      key = fetchPublicKeyFromRemote(nodeName);
       rv = validateSignature(data, sig, key, true);
     }
 
@@ -241,6 +249,11 @@ public class PKIAuthenticationPlugin extends AuthenticationPlugin
   }
 
   private PKIHeaderData validateSignature(String data, byte[] sig, PublicKey key, boolean isRetry) {
+    if (key == null) {
+      log.warn("Key is null when attempting to validate signature; skipping...");
+      return null;
+    }
+
     try {
       if (CryptoKeys.verifySha256(data.getBytes(UTF_8), sig, key)) {
         int timestampStart = data.lastIndexOf(' ');
@@ -259,27 +272,23 @@ public class PKIAuthenticationPlugin extends AuthenticationPlugin
         return null;
       }
     } catch (InvalidKeyException | SignatureException e) {
+      final String excMessage = e.getMessage();
       if (isRetry) {
-        log.error("Signature validation on retry failed, likely key error");
+        log.error("Signature validation on retry failed, likely key error: {}", excMessage);
       } else {
-        log.info("Signature validation failed first attempt, likely key error");
+        log.info("Signature validation failed first attempt, likely key error: {}", excMessage);
       }
       return null;
     }
   }
 
   private PKIHeaderData decipherHeader(String nodeName, String cipherBase64) {
-    PublicKey key = keyCache.get(nodeName);
-    if (key == null) {
-      log.debug("No key available for node: {} fetching now ", nodeName);
-      key = getRemotePublicKey(nodeName);
-      log.debug("public key obtained {} ", key);
-    }
+    PublicKey key = getOrFetchPublicKey(nodeName);
 
     PKIHeaderData header = parseCipher(cipherBase64, key, false);
     if (header == null) {
       log.warn("Failed to decrypt header, trying after refreshing the key ");
-      key = getRemotePublicKey(nodeName);
+      key = fetchPublicKeyFromRemote(nodeName);
       return parseCipher(cipherBase64, key, true);
     } else {
       return header;
@@ -320,6 +329,15 @@ public class PKIAuthenticationPlugin extends AuthenticationPlugin
     }
   }
 
+  private boolean isInLiveNodes(String nodeName) {
+    return cores
+        .getZkController()
+        .getZkStateReader()
+        .getClusterState()
+        .getLiveNodes()
+        .contains(nodeName);
+  }
+
   /**
    * Fetch the public key for a remote Solr node and store it in our key cache, replacing any
    * existing entries.
@@ -327,13 +345,13 @@ public class PKIAuthenticationPlugin extends AuthenticationPlugin
    * @param nodename the node to fetch a key from
    * @return the public key
    */
-  PublicKey getRemotePublicKey(String nodename) {
-    if (!cores
-        .getZkController()
-        .getZkStateReader()
-        .getClusterState()
-        .getLiveNodes()
-        .contains(nodename)) return null;
+  PublicKey fetchPublicKeyFromRemote(String nodename) {
+    if (!isInLiveNodes(nodename)) {
+      log.warn(
+          "Unable to fetch public key for {} as it does not appear to be a Solr 'live node'",
+          nodename);
+      return null;
+    }
     String url = cores.getZkController().getZkStateReader().getBaseUrlForNodeName(nodename);
     HttpEntity entity = null;
     try {
diff --git a/solr/core/src/test/org/apache/solr/security/TestPKIAuthenticationPlugin.java b/solr/core/src/test/org/apache/solr/security/TestPKIAuthenticationPlugin.java
index eb2bb2808d3..5c2cdd39c92 100644
--- a/solr/core/src/test/org/apache/solr/security/TestPKIAuthenticationPlugin.java
+++ b/solr/core/src/test/org/apache/solr/security/TestPKIAuthenticationPlugin.java
@@ -64,7 +64,7 @@ public class TestPKIAuthenticationPlugin extends SolrTestCaseJ4 {
     }
 
     @Override
-    PublicKey getRemotePublicKey(String ignored) {
+    PublicKey fetchPublicKeyFromRemote(String ignored) {
       return myKey;
     }
 
@@ -153,7 +153,7 @@ public class TestPKIAuthenticationPlugin extends SolrTestCaseJ4 {
           boolean firstCall = true;
 
           @Override
-          PublicKey getRemotePublicKey(String ignored) {
+          PublicKey fetchPublicKeyFromRemote(String ignored) {
             try {
               return firstCall ? myKey : mock.myKey;
             } finally {