Revision 24d70417 lib/utils.py

b/lib/utils.py
92 92
_STRUCT_UCRED = "iII"
93 93
_STRUCT_UCRED_SIZE = struct.calcsize(_STRUCT_UCRED)
94 94

  
95
# Certificate verification results
96
(CERT_WARNING,
97
 CERT_ERROR) = range(1, 3)
98

  
95 99

  
96 100
class RunResult(object):
97 101
  """Holds the result of running external programs.
......
2442 2446
  return rows[-lines:]
2443 2447

  
2444 2448

  
2449
def FormatTimestampWithTZ(secs):
2450
  """Formats a Unix timestamp with the local timezone.
2451

  
2452
  """
2453
  return time.strftime("%F %T %Z", time.gmtime(secs))
2454

  
2455

  
2445 2456
def _ParseAsn1Generalizedtime(value):
2446 2457
  """Parses an ASN1 GENERALIZEDTIME timestamp as used by pyOpenSSL.
2447 2458

  
......
2505 2516
  return (not_before, not_after)
2506 2517

  
2507 2518

  
2519
def _VerifyCertificateInner(expired, not_before, not_after, now,
2520
                            warn_days, error_days):
2521
  """Verifies certificate validity.
2522

  
2523
  @type expired: bool
2524
  @param expired: Whether pyOpenSSL considers the certificate as expired
2525
  @type not_before: number or None
2526
  @param not_before: Unix timestamp before which certificate is not valid
2527
  @type not_after: number or None
2528
  @param not_after: Unix timestamp after which certificate is invalid
2529
  @type now: number
2530
  @param now: Current time as Unix timestamp
2531
  @type warn_days: number or None
2532
  @param warn_days: How many days before expiration a warning should be reported
2533
  @type error_days: number or None
2534
  @param error_days: How many days before expiration an error should be reported
2535

  
2536
  """
2537
  if expired:
2538
    msg = "Certificate is expired"
2539

  
2540
    if not_before is not None and not_after is not None:
2541
      msg += (" (valid from %s to %s)" %
2542
              (FormatTimestampWithTZ(not_before),
2543
               FormatTimestampWithTZ(not_after)))
2544
    elif not_before is not None:
2545
      msg += " (valid from %s)" % FormatTimestampWithTZ(not_before)
2546
    elif not_after is not None:
2547
      msg += " (valid until %s)" % FormatTimestampWithTZ(not_after)
2548

  
2549
    return (CERT_ERROR, msg)
2550

  
2551
  elif not_before is not None and not_before > now:
2552
    return (CERT_WARNING,
2553
            "Certificate not yet valid (valid from %s)" %
2554
            FormatTimestampWithTZ(not_before))
2555

  
2556
  elif not_after is not None:
2557
    remaining_days = int((not_after - now) / (24 * 3600))
2558

  
2559
    msg = "Certificate expires in about %d days" % remaining_days
2560

  
2561
    if error_days is not None and remaining_days <= error_days:
2562
      return (CERT_ERROR, msg)
2563

  
2564
    if warn_days is not None and remaining_days <= warn_days:
2565
      return (CERT_WARNING, msg)
2566

  
2567
  return (None, None)
2568

  
2569

  
2570
def VerifyX509Certificate(cert, warn_days, error_days):
2571
  """Verifies a certificate for LUVerifyCluster.
2572

  
2573
  @type cert: OpenSSL.crypto.X509
2574
  @param cert: X509 certificate object
2575
  @type warn_days: number or None
2576
  @param warn_days: How many days before expiration a warning should be reported
2577
  @type error_days: number or None
2578
  @param error_days: How many days before expiration an error should be reported
2579

  
2580
  """
2581
  # Depending on the pyOpenSSL version, this can just return (None, None)
2582
  (not_before, not_after) = GetX509CertValidity(cert)
2583

  
2584
  return _VerifyCertificateInner(cert.has_expired(), not_before, not_after,
2585
                                 time.time(), warn_days, error_days)
2586

  
2587

  
2508 2588
def SignX509Certificate(cert, key, salt):
2509 2589
  """Sign a X509 certificate.
2510 2590

  

Also available in: Unified diff