class_docstr: Implementation of ZAP authentication for zmq connections.
  
  Note:
  
  - libzmq provides four levels of security: default NULL (which the Authenticator does
    not see), and authenticated NULL, PLAIN, CURVE, and GSSAPI, which the Authenticator can see.
  - until you add policies, all incoming NULL connections are allowed.
    (classic ZeroMQ behavior), and all PLAIN and CURVE connections are denied.
  - GSSAPI requires no configuration.
docstr: CURVE ZAP authentication
docstr_tok: ["CURVE","ZAP","authentication"]
code: def _authenticate_curve(self, domain, client_key):
      """CURVE ZAP authentication"""
      allowed = False
      reason = b""
      if self.allow_any:
          allowed = True
          reason = b"OK"
          self.log.debug("ALLOWED (CURVE allow any client)")
      elif self.credentials_providers != {}:
          # If no explicit domain is specified then use the default domain
          if not domain:
              domain = "*"
  
          if domain in self.credentials_providers:
              z85_client_key = z85.encode(client_key)
              # Callback to check if key is Allowed
              if self.credentials_providers[domain].callback(
                  domain, z85_client_key
              ):
                  allowed = True
                  reason = b"OK"
              else:
                  reason = b"Unknown key"
  
              status = "ALLOWED" if allowed else "DENIED"
              self.log.debug(
                  "%s (CURVE auth_callback) domain=%s client_key=%s",
                  status,
                  domain,
                  z85_client_key,
              )
          else:
              reason = b"Unknown domain"
      else:
          # If no explicit domain is specified then use the default domain
          if not domain:
              domain = "*"
  
          if domain in self.certs:
              # The certs dict stores keys in z85 format, convert binary key to z85 bytes
              z85_client_key = z85.encode(client_key)
              if self.certs[domain].get(z85_client_key):
                  allowed = True
                  reason = b"OK"
              else:
                  reason = b"Unknown key"
  
              status = "ALLOWED" if allowed else "DENIED"
              self.log.debug(
                  "%s (CURVE) domain=%s client_key=%s",
                  status,
                  domain,
                  z85_client_key,
              )
          else:
              reason = b"Unknown domain"
  
      return allowed, reason
  
imports: import logging
  import zmq
  from zmq.utils import z85
  from zmq.utils.strtypes import bytes, unicode, b, u
  from zmq.error import _check_version
  from .certs import load_certificates
label_desc: Use image node_id 13 for calling the Authenticator obj's underlying member method code with example usage: obj._authenticate_curve(domain, client_key) and returns: allowed,  reason