Statistics
| Branch: | Tag: | Revision:

root / lib / utils / security.py @ 653bc0f1

History | View | Annotate | Download (4.9 kB)

1 3338a9ce Helga Velroyen
#
2 3338a9ce Helga Velroyen
#
3 3338a9ce Helga Velroyen
4 3338a9ce Helga Velroyen
# Copyright (C) 2013 Google Inc.
5 3338a9ce Helga Velroyen
#
6 3338a9ce Helga Velroyen
# This program is free software; you can redistribute it and/or modify
7 3338a9ce Helga Velroyen
# it under the terms of the GNU General Public License as published by
8 3338a9ce Helga Velroyen
# the Free Software Foundation; either version 2 of the License, or
9 3338a9ce Helga Velroyen
# (at your option) any later version.
10 3338a9ce Helga Velroyen
#
11 3338a9ce Helga Velroyen
# This program is distributed in the hope that it will be useful, but
12 3338a9ce Helga Velroyen
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 3338a9ce Helga Velroyen
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 3338a9ce Helga Velroyen
# General Public License for more details.
15 3338a9ce Helga Velroyen
#
16 3338a9ce Helga Velroyen
# You should have received a copy of the GNU General Public License
17 3338a9ce Helga Velroyen
# along with this program; if not, write to the Free Software
18 3338a9ce Helga Velroyen
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 3338a9ce Helga Velroyen
# 02110-1301, USA.
20 3338a9ce Helga Velroyen
21 3338a9ce Helga Velroyen
"""Utility functions for security features of Ganeti.
22 3338a9ce Helga Velroyen

23 3338a9ce Helga Velroyen
"""
24 3338a9ce Helga Velroyen
25 3338a9ce Helga Velroyen
import logging
26 b544a3c2 Helga Velroyen
import OpenSSL
27 60cc531d Helga Velroyen
import os
28 ab4b1cf2 Helga Velroyen
import uuid as uuid_module
29 b544a3c2 Helga Velroyen
30 b544a3c2 Helga Velroyen
from ganeti.utils import io
31 60cc531d Helga Velroyen
from ganeti.utils import x509
32 a6c43c02 Helga Velroyen
from ganeti import constants
33 a6c43c02 Helga Velroyen
from ganeti import errors
34 b544a3c2 Helga Velroyen
from ganeti import pathutils
35 3338a9ce Helga Velroyen
36 3338a9ce Helga Velroyen
37 ab4b1cf2 Helga Velroyen
def UuidToInt(uuid):
38 ab4b1cf2 Helga Velroyen
  uuid_obj = uuid_module.UUID(uuid)
39 ab4b1cf2 Helga Velroyen
  return uuid_obj.int # pylint: disable=E1101
40 ab4b1cf2 Helga Velroyen
41 ab4b1cf2 Helga Velroyen
42 3338a9ce Helga Velroyen
def AddNodeToCandidateCerts(node_uuid, cert_digest, candidate_certs,
43 3338a9ce Helga Velroyen
                            info_fn=logging.info, warn_fn=logging.warn):
44 3338a9ce Helga Velroyen
  """Adds an entry to the candidate certificate map.
45 3338a9ce Helga Velroyen

46 3338a9ce Helga Velroyen
  @type node_uuid: string
47 3338a9ce Helga Velroyen
  @param node_uuid: the node's UUID
48 3338a9ce Helga Velroyen
  @type cert_digest: string
49 3338a9ce Helga Velroyen
  @param cert_digest: the digest of the node's client SSL certificate
50 3338a9ce Helga Velroyen
  @type candidate_certs: dict of strings to strings
51 3338a9ce Helga Velroyen
  @param candidate_certs: map of node UUIDs to the digests of their client
52 3338a9ce Helga Velroyen
      SSL certificates, will be manipulated in this function
53 3338a9ce Helga Velroyen
  @type info_fn: function
54 3338a9ce Helga Velroyen
  @param info_fn: logging function for information messages
55 3338a9ce Helga Velroyen
  @type warn_fn: function
56 3338a9ce Helga Velroyen
  @param warn_fn: logging function for warning messages
57 3338a9ce Helga Velroyen

58 3338a9ce Helga Velroyen
  """
59 3338a9ce Helga Velroyen
  assert candidate_certs is not None
60 3338a9ce Helga Velroyen
61 3338a9ce Helga Velroyen
  if node_uuid in candidate_certs:
62 3338a9ce Helga Velroyen
    old_cert_digest = candidate_certs[node_uuid]
63 3338a9ce Helga Velroyen
    if old_cert_digest == cert_digest:
64 3338a9ce Helga Velroyen
      info_fn("Certificate digest for node %s already in config."
65 3338a9ce Helga Velroyen
              "Not doing anything." % node_uuid)
66 3338a9ce Helga Velroyen
      return
67 3338a9ce Helga Velroyen
    else:
68 3338a9ce Helga Velroyen
      warn_fn("Overriding differing certificate digest for node %s"
69 3338a9ce Helga Velroyen
              % node_uuid)
70 3338a9ce Helga Velroyen
  candidate_certs[node_uuid] = cert_digest
71 3338a9ce Helga Velroyen
72 3338a9ce Helga Velroyen
73 3338a9ce Helga Velroyen
def RemoveNodeFromCandidateCerts(node_uuid, candidate_certs,
74 3338a9ce Helga Velroyen
                                 warn_fn=logging.warn):
75 3338a9ce Helga Velroyen
  """Removes the entry of the given node in the certificate map.
76 3338a9ce Helga Velroyen

77 3338a9ce Helga Velroyen
  @type node_uuid: string
78 3338a9ce Helga Velroyen
  @param node_uuid: the node's UUID
79 3338a9ce Helga Velroyen
  @type candidate_certs: dict of strings to strings
80 3338a9ce Helga Velroyen
  @param candidate_certs: map of node UUIDs to the digests of their client
81 3338a9ce Helga Velroyen
      SSL certificates, will be manipulated in this function
82 3338a9ce Helga Velroyen
  @type warn_fn: function
83 3338a9ce Helga Velroyen
  @param warn_fn: logging function for warning messages
84 3338a9ce Helga Velroyen

85 3338a9ce Helga Velroyen
  """
86 3338a9ce Helga Velroyen
  if node_uuid not in candidate_certs:
87 3338a9ce Helga Velroyen
    warn_fn("Cannot remove certifcate for node %s, because it's not in the"
88 3338a9ce Helga Velroyen
            "candidate map." % node_uuid)
89 3338a9ce Helga Velroyen
    return
90 3338a9ce Helga Velroyen
  del candidate_certs[node_uuid]
91 b544a3c2 Helga Velroyen
92 b544a3c2 Helga Velroyen
93 b3cc1646 Helga Velroyen
def GetCertificateDigest(cert_filename=pathutils.NODED_CLIENT_CERT_FILE):
94 b544a3c2 Helga Velroyen
  """Reads the SSL certificate and returns the sha1 digest.
95 b544a3c2 Helga Velroyen

96 b544a3c2 Helga Velroyen
  """
97 b544a3c2 Helga Velroyen
  cert_plain = io.ReadFile(cert_filename)
98 b544a3c2 Helga Velroyen
  cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
99 b544a3c2 Helga Velroyen
                                         cert_plain)
100 b544a3c2 Helga Velroyen
  return cert.digest("sha1")
101 60cc531d Helga Velroyen
102 60cc531d Helga Velroyen
103 ab4b1cf2 Helga Velroyen
def GenerateNewSslCert(new_cert, cert_filename, serial_no, log_msg):
104 60cc531d Helga Velroyen
  """Creates a new SSL certificate and backups the old one.
105 60cc531d Helga Velroyen

106 60cc531d Helga Velroyen
  @type new_cert: boolean
107 60cc531d Helga Velroyen
  @param new_cert: whether a new certificate should be created
108 60cc531d Helga Velroyen
  @type cert_filename: string
109 60cc531d Helga Velroyen
  @param cert_filename: filename of the certificate file
110 ab4b1cf2 Helga Velroyen
  @type serial_no: int
111 ab4b1cf2 Helga Velroyen
  @param serial_no: serial number of the certificate
112 60cc531d Helga Velroyen
  @type log_msg: string
113 60cc531d Helga Velroyen
  @param log_msg: log message to be written on certificate creation
114 60cc531d Helga Velroyen

115 60cc531d Helga Velroyen
  """
116 60cc531d Helga Velroyen
  cert_exists = os.path.exists(cert_filename)
117 60cc531d Helga Velroyen
  if new_cert or not cert_exists:
118 60cc531d Helga Velroyen
    if cert_exists:
119 60cc531d Helga Velroyen
      io.CreateBackup(cert_filename)
120 60cc531d Helga Velroyen
121 60cc531d Helga Velroyen
    logging.debug(log_msg)
122 ab4b1cf2 Helga Velroyen
    x509.GenerateSelfSignedSslCert(cert_filename, serial_no)
123 a6c43c02 Helga Velroyen
124 a6c43c02 Helga Velroyen
125 a6c43c02 Helga Velroyen
def VerifyCertificate(filename):
126 a6c43c02 Helga Velroyen
  """Verifies a SSL certificate.
127 a6c43c02 Helga Velroyen

128 a6c43c02 Helga Velroyen
  @type filename: string
129 a6c43c02 Helga Velroyen
  @param filename: Path to PEM file
130 a6c43c02 Helga Velroyen

131 a6c43c02 Helga Velroyen
  """
132 a6c43c02 Helga Velroyen
  try:
133 a6c43c02 Helga Velroyen
    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
134 a6c43c02 Helga Velroyen
                                           io.ReadFile(filename))
135 a6c43c02 Helga Velroyen
  except Exception, err: # pylint: disable=W0703
136 a6c43c02 Helga Velroyen
    return (constants.CV_ERROR,
137 a6c43c02 Helga Velroyen
            "Failed to load X509 certificate %s: %s" % (filename, err))
138 a6c43c02 Helga Velroyen
139 a6c43c02 Helga Velroyen
  (errcode, msg) = \
140 a6c43c02 Helga Velroyen
    x509.VerifyX509Certificate(cert, constants.SSL_CERT_EXPIRATION_WARN,
141 a6c43c02 Helga Velroyen
                                constants.SSL_CERT_EXPIRATION_ERROR)
142 a6c43c02 Helga Velroyen
143 a6c43c02 Helga Velroyen
  if msg:
144 a6c43c02 Helga Velroyen
    fnamemsg = "While verifying %s: %s" % (filename, msg)
145 a6c43c02 Helga Velroyen
  else:
146 a6c43c02 Helga Velroyen
    fnamemsg = None
147 a6c43c02 Helga Velroyen
148 a6c43c02 Helga Velroyen
  if errcode is None:
149 a6c43c02 Helga Velroyen
    return (None, fnamemsg)
150 a6c43c02 Helga Velroyen
  elif errcode == x509.CERT_WARNING:
151 a6c43c02 Helga Velroyen
    return (constants.CV_WARNING, fnamemsg)
152 a6c43c02 Helga Velroyen
  elif errcode == x509.CERT_ERROR:
153 a6c43c02 Helga Velroyen
    return (constants.CV_ERROR, fnamemsg)
154 a6c43c02 Helga Velroyen
155 a6c43c02 Helga Velroyen
  raise errors.ProgrammerError("Unhandled certificate error code %r" % errcode)