Statistics
| Branch: | Tag: | Revision:

root / lib / utils / security.py @ 60cc531d

History | View | Annotate | Download (3.9 kB)

1
#
2
#
3

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

    
21
"""Utility functions for security features of Ganeti.
22

23
"""
24

    
25
import logging
26
import OpenSSL
27
import os
28

    
29
from ganeti.utils import io
30
from ganeti.utils import x509
31
from ganeti import pathutils
32

    
33

    
34
def AddNodeToCandidateCerts(node_uuid, cert_digest, candidate_certs,
35
                            info_fn=logging.info, warn_fn=logging.warn):
36
  """Adds an entry to the candidate certificate map.
37

38
  @type node_uuid: string
39
  @param node_uuid: the node's UUID
40
  @type cert_digest: string
41
  @param cert_digest: the digest of the node's client SSL certificate
42
  @type candidate_certs: dict of strings to strings
43
  @param candidate_certs: map of node UUIDs to the digests of their client
44
      SSL certificates, will be manipulated in this function
45
  @type info_fn: function
46
  @param info_fn: logging function for information messages
47
  @type warn_fn: function
48
  @param warn_fn: logging function for warning messages
49

50
  """
51
  assert candidate_certs is not None
52

    
53
  if node_uuid in candidate_certs:
54
    old_cert_digest = candidate_certs[node_uuid]
55
    if old_cert_digest == cert_digest:
56
      info_fn("Certificate digest for node %s already in config."
57
              "Not doing anything." % node_uuid)
58
      return
59
    else:
60
      warn_fn("Overriding differing certificate digest for node %s"
61
              % node_uuid)
62
  candidate_certs[node_uuid] = cert_digest
63

    
64

    
65
def RemoveNodeFromCandidateCerts(node_uuid, candidate_certs,
66
                                 warn_fn=logging.warn):
67
  """Removes the entry of the given node in the certificate map.
68

69
  @type node_uuid: string
70
  @param node_uuid: the node's UUID
71
  @type candidate_certs: dict of strings to strings
72
  @param candidate_certs: map of node UUIDs to the digests of their client
73
      SSL certificates, will be manipulated in this function
74
  @type warn_fn: function
75
  @param warn_fn: logging function for warning messages
76

77
  """
78
  if node_uuid not in candidate_certs:
79
    warn_fn("Cannot remove certifcate for node %s, because it's not in the"
80
            "candidate map." % node_uuid)
81
    return
82
  del candidate_certs[node_uuid]
83

    
84

    
85
def GetClientCertificateDigest(cert_filename=pathutils.NODED_CERT_FILE):
86
  """Reads the SSL certificate and returns the sha1 digest.
87

88
  """
89
  # FIXME: This is supposed to read the client certificate, but
90
  # in this stage of the patch series there is no client certificate
91
  # yet, so we return the digest of the server certificate to get
92
  # the rest of the key management infrastructure running.
93
  cert_plain = io.ReadFile(cert_filename)
94
  cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
95
                                         cert_plain)
96
  return cert.digest("sha1")
97

    
98

    
99
def GenerateNewSslCert(new_cert, cert_filename, log_msg):
100
  """Creates a new SSL certificate and backups the old one.
101

102
  @type new_cert: boolean
103
  @param new_cert: whether a new certificate should be created
104
  @type cert_filename: string
105
  @param cert_filename: filename of the certificate file
106
  @type log_msg: string
107
  @param log_msg: log message to be written on certificate creation
108

109
  """
110
  cert_exists = os.path.exists(cert_filename)
111
  if new_cert or not cert_exists:
112
    if cert_exists:
113
      io.CreateBackup(cert_filename)
114

    
115
    logging.debug(log_msg)
116
    x509.GenerateSelfSignedSslCert(cert_filename)