Example #1
0
  def get_text_stanza_header(self):

    title = underlined_text("Fingerprint validation report", '=')
    title_target_server = underlined_text("Target server")
    title_target_certificate = underlined_text("SSL/TLS X.509 certificate")

    # ADDITION: Print information about the connection from which the
    # certificate was received.

    s = """{}

Date and time: {}

Validation of SSL/TLS X.509 certificate received from the target host using the Convergence protocol.

{}

	* Host          : '{}'
	* Listening port: {}

{}

	* SHA1 fingerprint: {}
""".format(
      title,
      self.creation.strftime('%Y-%m-%d, %H:%M:%S'),
      title_target_server,
      self.host,
      self.port,
      title_target_certificate,
      self.fingerprint
    )

    return s
Example #2
0
  def action_delete_cache_entry(self):

    if self.args['host_target']['host'] is None:
      print('The target host needs to be specified through the --server \
argument.')
      return False

    rows = self.client.delete_cache_entry(
        self.args['host_target']['host'],
        self.args['host_target']['port']
    )

    print("""\
{}
""".format(underlined_text("Deleted Fingerprint Cache Entry")))

    if len(rows) < 1:
      print('No cached entries.')
      return True

    for row in rows:
      host, port, fp, expiration, timestamp = row
      timestamp = timestamp.strftime('%Y-%m-%d, %H.%M.%S')

      if expiration is None:
        expiration = '-'
      else:
        expiration = expiration.strftime('%Y-%m-%d, %H.%M.%S')

      print('{}, Exp: {}, {}:{}\t{}'.format(
        timestamp, expiration, host, port, fp
      ))

    return True
Example #3
0
  def action_list_notaries(self):
    """List notary entities known in the database."""

    notaries = self.client.get_notaries()

    print("""\
{}
""".format(underlined_text("Notaries in the Cuivre database")))

    for n in notaries.values():

      if n.enabled:
        enabled = 'Enabled'
      else:
        enabled = 'Disabled'

      if n.region is None:
        region = 'not specified'
      else:
        region = "'{}'".format(n.region)

      print("Id: {}, Name: '{}', Region: {}, Status: {}\n".format(
          str(n.id), n.name, region, enabled
        )
      )

      for j in n.hosts.values():
        print("    Host: '{}', HTTP port: {}, SSL port: {}".format(
          j.host, str(j.http_port), str(j.ssl_port)))

      print("")

    return True
Example #4
0
  def action_show_cache(self):

    print("""\
{}
""".format(underlined_text("Fingerprints Cache")))

    db_rows = self.client.get_fingerprints_cache()

    rows = []
    max_length = 0

    # Create intermediate list

    for row in db_rows:
      host, port, fp, expiration, timestamp = row

      timestamp = timestamp.strftime('%Y-%m-%d, %H.%M.%S')

      if expiration is None:
        expiration = '-'
      else:
        expiration = expiration.strftime('%Y-%m-%d, %H.%M.%S')

      host_port = host + ":" + unicode(port)
      rows.append((timestamp, expiration, host_port, fp))

      host_port_len = len(host_port)

      if host_port_len > max_length:
        max_length = host_port_len

    # Now print it

    for row in rows:
      timestamp, expiration, host_port, fp = row

      tabs_number = 1 + int(math.ceil((max_length - len(host_port)) / 8.0))

      print('{}, Exp: {}, {}{}{}'.format(
        timestamp, expiration, host_port, '\t' * tabs_number, fp
      ))

    return True
Example #5
0
  def action_update_notaries(self):
    """List notary entities known in the database."""

    # Disable callback printing connections to notaries.
    self.set_client_cb(CB_NOTARY_CONNECTION_START, None)

    notaries = self.client.database.get_notary_entities()

    print("""\
{}
""".format(underlined_text("Updating Notaries")))

    for n in notaries:

      print("Id: {}, Name: '{}'...".format(str(n.id), n.name))
      self.client.update_notary(n.id, n.bundle_location)

    print("")

    # Re-enable callback printing connections to notaries.
    self.set_client_cb(CB_NOTARY_CONNECTION_START, cb_notary_connection_start)

    return True
Example #6
0
  def get_text(self):
    if self.from_cache:
      # A cached result is always a successful verification.

      title = underlined_text("Certificate fingerprint validation", "=")

      s = """{}

Validation of SSL/TLS X.509 certificate fingerprint:
  {}

For server host {} on port {}.

Successful certificate verification from result cached on {} UTC.
""".format(
        title,
        self.fingerprint,
        self.server_host,
        self.server_port,
        self.cache_date_time
      )

      return s
Example #7
0
  def get_text_stanza_convergence(self):

    stanza = self.convergence_stanza
    s = ''

    if stanza.anonymization:
      s += """
* Anonymization of queries through relay notary entity: \'{}\'.
""".format(stanza.relay_notary_entity_name)

    for i in stanza.notary_connections:

      notary_entity_name = i

      connections = stanza.notary_connections[i]['connections']

      z = "".join(("Connection to notary '", notary_entity_name, "'"))
      z = underlined_text(z)
      z = "".join(("\n", z, "\n"))

      if not stanza.notary_connections[i]['connection']:
        z += """  No established connections.
"""
        s += z

        continue

      established_connection = \
        connections.pop(stanza.notary_connections[i]['connection'])
      c = established_connection

      z += """
	* Notary host:
		* Hostname: '{}'
		* Port    : {}
""".format(
        c['notary_host']['host'],
        c['notary_host']['port']
      )

      if stanza.anonymization:
        z += """
	* Relay host:
		* Hostname: '{}'
		* Port    : {}
""".format(
          c['relay_host']['host'],
          c['relay_host']['port']
        )

      z += """
	* Connection:
		* Connection Id : {}
		* X.509 certificate SHA1 fingerprint: {}
		* SSL/TLS protocol version          : {}
		* Adopted cipher suite              : {}
""".format(
        stanza.notary_connections[i]['connection'],
        c['notary_host']['notary_fingerprint'],
        c['notary_host']['ssl_protocol'],
        c['notary_host']['ssl_cipher_suite']
      )

      # Response stanza

      status_code = c['notary_host']['response_code']

      if status_code == cuivre.http.HTTP_STATUS_CODE_OK:
        r = '{} fingerprint verified'.format(
          cuivre.http.HTTP_STATUS_CODE_OK)

      elif status_code == cuivre.http.HTTP_STATUS_CODE_CONFLICT:
        r = '{} fingerprint *NOT* verified'.format(
          cuivre.http.HTTP_STATUS_CODE_CONFLICT)

      elif status_code == cuivre.http.HTTP_STATUS_CODE_SEE_OTHER:
        r = '{} cannot verify fingerprint'.format(
          cuivre.http.HTTP_STATUS_CODE_SEE_OTHER)

      elif status_code == cuivre.http.HTTP_STATUS_CODE_BAD_REQUEST:
        r = '{} incomplete verification request'.format(
          cuivre.http.HTTP_STATUS_CODE_BAD_REQUEST)

      elif status_code == cuivre.http.HTTP_STATUS_SERVICE_UNAVAILABLE:
        r = '{} notary internal error'.format(
          cuivre.http.HTTP_STATUS_SERVICE_UNAVAILABLE)

      else:
        r = 'undefined'

      vsign = '*failed* verification'

      if c['notary_host']['signature_verification'] == True:
        vsign = 'verified'

      z += """
	* Response:
		* Notary response                   : {}.
""".format(r)

      if status_code not in (cuivre.http.HTTP_STATUS_CODE_OK,
                             cuivre.http.HTTP_STATUS_CODE_CONFLICT):
        s = '{}{}'.format(s, z)
        continue

      z += """\
		* Observed fingerprint              : {}
		* Response data signature           : {}
""".format(c['notary_host']['observed_fingerprint'], vsign)

      s = '{}{}'.format(s, z)

    # Convergence policy and its application.

    policy_name = 'None'

    if stanza.policy == cuivre.POLICY_ONE:
      policy_name = 'require one notary to agree.'

    elif stanza.policy == cuivre.POLICY_MAJORITY:
      policy_name = 'require notary majority.'

    elif stanza.policy == cuivre.POLICY_UNANIMITY:
      policy_name = 'require unanimity among notaries.'

    validation_msg = 'Failure'
    if stanza.validation == True:
      validation_msg = 'Success'

    s += """
Applied Convergence policy               : {}
Fingerprint validation as per Convergence: {}
""".format(policy_name, validation_msg)

    return s