postfix.py 3.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. # This file is part of acme-updater, written by Helmut Pozimski 2016-2017.
  2. #
  3. # stov is free software: you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation, version 2 of the License.
  6. #
  7. # stov is distributed in the hope that it will be useful,
  8. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. # GNU General Public License for more details.
  11. #
  12. # You should have received a copy of the GNU General Public License
  13. # along with stov. If not, see <http://www.gnu.org/licenses/>.
  14. # -*- coding: utf8 -*-
  15. """ Contains the postfix module which manages certificates for the postfix
  16. mail server.
  17. """
  18. import logging
  19. import socket
  20. import os
  21. import subprocess
  22. from amulib import helpers
  23. import OpenSSL
  24. LOGGER = logging.getLogger("acme_tlsa_mail")
  25. def run(config=None, acme_dir="/var/lib/acme",
  26. named_key_path="/run/named/session.key"):
  27. hostname = socket.gethostname()
  28. fqdn = socket.getfqdn()
  29. if config:
  30. certificate_path = config["certificate_path"]
  31. key_path = config["key_path"]
  32. tlsa = config["tlsa"]
  33. tlsa_ports = config["tlsa_ports"]
  34. else:
  35. certificate_path = "/etc/postfix/%s.crt" % hostname
  36. key_path = "/etc/postfix/%s.key" % hostname
  37. tlsa = True
  38. tlsa_ports = [25, 465, 587]
  39. try:
  40. with open(certificate_path, "r") as cert_file:
  41. cert_text = cert_file.read()
  42. except IOError:
  43. LOGGER.error("Error while opening the postfix certificate")
  44. else:
  45. current_cert = OpenSSL.crypto.load_certificate(
  46. OpenSSL.crypto.FILETYPE_PEM, cert_text
  47. )
  48. acme_cert_path = os.path.join(acme_dir, "live", fqdn,
  49. "cert")
  50. acme_fullchain_path = os.path.join(acme_dir, "live", fqdn,
  51. "fullchain")
  52. if helpers.check_renewal(current_cert, acme_cert_path):
  53. try:
  54. with open(acme_cert_path, "r") as acme_cert_file:
  55. acme_cert_text = acme_cert_file.read()
  56. except IOError:
  57. LOGGER.error("Error while opening new postfix "
  58. "certificate file")
  59. else:
  60. acme_cert = OpenSSL.crypto.load_certificate(
  61. OpenSSL.crypto.FILETYPE_PEM, acme_cert_text
  62. )
  63. if tlsa:
  64. for port in tlsa_ports:
  65. helpers.create_tlsa_records(fqdn, port, acme_cert,
  66. named_key_path)
  67. if helpers.copy_file(acme_fullchain_path, certificate_path):
  68. newkey_path = os.path.join(acme_dir, "live",
  69. fqdn, "privkey")
  70. if helpers.copy_file(newkey_path, key_path):
  71. LOGGER.info("Certificate for postfix successfully "
  72. "renewed, restarting service.")
  73. subprocess.call(["/etc/init.d/postfix", "restart"])
  74. else:
  75. LOGGER.error("Renewal of cert for postfix failed, "
  76. "please clean up manually and "
  77. "check the backup files!")
  78. else:
  79. LOGGER.error("Renewal of cert for postfix failed, "
  80. "please clean up manually and "
  81. "check the backup files!")