Revision c6ccba7e

b/Makefile.am
245 245
	tools/sanitize-config
246 246

  
247 247
pkglib_python_scripts = \
248
	daemons/import-export
248
	daemons/import-export \
249
	tools/check-cert-expired
249 250

  
250 251
pkglib_SCRIPTS = \
251 252
	daemons/daemon-util \
......
366 367
dist_TESTS = \
367 368
	test/daemon-util_unittest.bash \
368 369
	test/import-export_unittest.bash \
370
	test/check-cert-expired_unittest.bash \
369 371
	$(python_tests)
370 372

  
371 373
nodist_TESTS =
b/daemons/ganeti-cleaner.in
32 32
  xargs -r0 rm -vf
33 33
}
34 34

  
35
cleanup_node() {
36
  # Return if directory for crypto keys doesn't exist
37
  [[ -d $CRYPTO_DIR ]] || return 0
38

  
39
  find $CRYPTO_DIR -mindepth 1 -maxdepth 1 -type d | \
40
  while read dir; do
41
    if $CHECK_CERT_EXPIRED $dir/cert; then
42
      rm -vf $dir/{cert,key}
43
      rmdir -v --ignore-fail-on-non-empty $dir
44
    fi
45
  done
46
}
47

  
35 48
DATA_DIR=@LOCALSTATEDIR@/lib/ganeti
36 49
CLEANER_LOG_DIR=@LOCALSTATEDIR@/log/ganeti/cleaner
37 50
QUEUE_ARCHIVE_DIR=$DATA_DIR/queue/archive
51
CRYPTO_DIR=@LOCALSTATEDIR@/run/ganeti/crypto
52
CHECK_CERT_EXPIRED=@PKGLIBDIR@/check-cert-expired
38 53

  
39 54
# Define how many days archived jobs should be left alone
40 55
REMOVE_AFTER=21
......
58 73
xargs -r rm -vf
59 74

  
60 75
cleanup_master
76
cleanup_node
61 77

  
62 78
exit 0
b/man/ganeti-cleaner.sgml
2 2

  
3 3
  <!-- Fill in your name for FIRSTNAME and SURNAME. -->
4 4
  <!-- Please adjust the date whenever revising the manpage. -->
5
  <!ENTITY dhdate      "<date>February 11, 2009</date>">
5
  <!ENTITY dhdate      "<date>May 17, 2010</date>">
6 6
  <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
7 7
       allowed: see man(7), man(1). -->
8 8
  <!ENTITY dhsection   "<manvolnum>8</manvolnum>">
......
19 19
  <refentryinfo>
20 20
    <copyright>
21 21
      <year>2009</year>
22
      <year>2010</year>
22 23
      <holder>Google Inc.</holder>
23 24
    </copyright>
24 25
    &dhdate;
......
45 46

  
46 47
    <para>
47 48
      The <command>&dhpackage;</command> is a periodically run script to clean
48
      old job files from the job queue archive.
49
      old job files from the job queue archive and to remove expired X509
50
      certificates and keys.
49 51
    </para>
50 52

  
51 53
    <para>
52 54
      <command>&dhpackage;</command> automatically removes all files older than
53 55
      21 days from
54
      <filename>@LOCALSTATEDIR@/lib/ganeti/queue/archive</filename>.
56
      <filename>@LOCALSTATEDIR@/lib/ganeti/queue/archive</filename> and all
57
      expired certificates and keys from
58
      <filename>@LOCALSTATEDIR@/run/ganeti/crypto</filename>
55 59
    </para>
56 60

  
57 61
  </refsect1>
b/test/check-cert-expired_unittest.bash
1
#!/bin/bash
2
#
3

  
4
# Copyright (C) 2010 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
set -e
22
set -o pipefail
23

  
24
export PYTHON=${PYTHON:=python}
25

  
26
CCE=tools/check-cert-expired
27

  
28
err() {
29
  echo "$@"
30
  echo 'Aborting'
31
  exit 1
32
}
33

  
34
impexpd_helper() {
35
  $PYTHON "${TOP_SRCDIR:-.}/test/import-export_unittest-helper" "$@"
36
}
37

  
38
$CCE 2>/dev/null && err 'Accepted empty argument list'
39
$CCE foo bar 2>/dev/null && err 'Accepted more than one argument'
40
$CCE foo bar baz 2>/dev/null && err 'Accepted more than one argument'
41

  
42
tmpdir=$(mktemp -d)
43
trap "rm -rf $tmpdir" EXIT
44

  
45
[[ -f "$tmpdir/cert-not" ]] && err 'File existed when it should not'
46
$CCE $tmpdir/cert-not 2>/dev/null && err 'Accepted non-existent file'
47

  
48
VALIDITY=1 impexpd_helper $tmpdir/cert-valid gencert
49
$CCE $tmpdir/cert-valid 2>/dev/null && \
50
  err 'Reported valid certificate as expired'
51

  
52
VALIDITY=-50 impexpd_helper $tmpdir/cert-expired gencert
53
$CCE $tmpdir/cert-expired 2>/dev/null || \
54
  err 'Reported expired certificate as valid'
55

  
56
echo > $tmpdir/cert-invalid
57
$CCE $tmpdir/cert-invalid 2>/dev/null && \
58
  err 'Reported invalid certificate as expired'
59

  
60
echo 'Hello World' > $tmpdir/cert-invalid2
61
$CCE $tmpdir/cert-invalid2 2>/dev/null && \
62
  err 'Reported invalid certificate as expired'
63

  
64
exit 0
b/test/import-export_unittest-helper
33 33

  
34 34
RETRY_INTERVAL = 0.1
35 35
TIMEOUT = int(os.getenv("TIMEOUT", 10))
36
VALIDITY = int(os.getenv("VALIDITY", 1))
36 37

  
37 38

  
38 39
def _GetImportExportData(filename):
......
68 69
  elif what == "connected":
69 70
    WaitForConnected(filename)
70 71
  elif what == "gencert":
71
    utils.GenerateSelfSignedSslCert(filename, validity=1)
72
    utils.GenerateSelfSignedSslCert(filename, validity=VALIDITY)
72 73
  else:
73 74
    raise Exception("Unknown command '%s'" % what)
74 75

  
b/tools/check-cert-expired
1
#!/usr/bin/python
2
#
3

  
4
# Copyright (C) 2010 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
"""Tool to detect expired X509 certificates.
22

  
23
"""
24

  
25
# pylint: disable-msg=C0103
26
# C0103: Invalid name check-cert-expired
27

  
28
import os.path
29
import sys
30
import OpenSSL
31

  
32
from ganeti import constants
33
from ganeti import cli
34
from ganeti import utils
35

  
36

  
37
def main():
38
  """Main routine.
39

  
40
  """
41
  program = os.path.basename(sys.argv[0])
42

  
43
  if len(sys.argv) != 2:
44
    cli.ToStderr("Usage: %s <certificate-path>", program)
45
    sys.exit(constants.EXIT_FAILURE)
46

  
47
  filename = sys.argv[1]
48

  
49
  # Read certificate
50
  try:
51
    cert_pem = utils.ReadFile(filename)
52
  except EnvironmentError, err:
53
    cli.ToStderr("Unable to read %s: %s", filename, err)
54
    sys.exit(constants.EXIT_FAILURE)
55

  
56
  # Check validity
57
  try:
58
    cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
59
                                           cert_pem)
60

  
61
    (errcode, msg) = utils.VerifyX509Certificate(cert, None, None)
62
    if msg:
63
      cli.ToStderr("%s: %s", filename, msg)
64
    if errcode == utils.CERT_ERROR:
65
      sys.exit(constants.EXIT_SUCCESS)
66

  
67
  except (KeyboardInterrupt, SystemExit):
68
    raise
69
  except Exception, err: # pylint: disable-msg=W0703
70
    cli.ToStderr("Unable to check %s: %s", filename, err)
71

  
72
  sys.exit(constants.EXIT_FAILURE)
73

  
74

  
75
if __name__ == "__main__":
76
  main()

Also available in: Unified diff