Compare commits
3 Commits
pyopenssl+
...
sendmail
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
861ff0c910 | ||
|
|
643a5bb48f | ||
|
|
6f51198394 |
216
certbot-sendmail/LICENSE.txt
Normal file
216
certbot-sendmail/LICENSE.txt
Normal file
@@ -0,0 +1,216 @@
|
||||
Copyright 2018 Electronic Frontier Foundation and others
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
Incorporating code from nginxparser
|
||||
Copyright 2014 Fatih Erikli
|
||||
Licensed MIT
|
||||
|
||||
|
||||
Text of Apache License
|
||||
======================
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Text of MIT License
|
||||
===================
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
2
certbot-sendmail/MANIFEST.in
Normal file
2
certbot-sendmail/MANIFEST.in
Normal file
@@ -0,0 +1,2 @@
|
||||
include LICENSE.txt
|
||||
include README.rst
|
||||
1
certbot-sendmail/README.rst
Normal file
1
certbot-sendmail/README.rst
Normal file
@@ -0,0 +1 @@
|
||||
Sendmail plugin for Certbot
|
||||
1
certbot-sendmail/certbot_sendmail/__init__.py
Normal file
1
certbot-sendmail/certbot_sendmail/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""Certbot sendmail plugin."""
|
||||
255
certbot-sendmail/certbot_sendmail/configurator.py
Normal file
255
certbot-sendmail/certbot_sendmail/configurator.py
Normal file
@@ -0,0 +1,255 @@
|
||||
"""Sendmail Configuration"""
|
||||
import sys
|
||||
import logging
|
||||
import os
|
||||
import difflib
|
||||
import re
|
||||
import socket
|
||||
import subprocess
|
||||
import tempfile
|
||||
import time
|
||||
|
||||
import OpenSSL
|
||||
import six
|
||||
import zope.component
|
||||
import zope.interface
|
||||
|
||||
from certbot import constants as core_constants
|
||||
from certbot import crypto_util
|
||||
from certbot import errors
|
||||
from certbot import interfaces
|
||||
from certbot import util
|
||||
|
||||
from certbot.plugins import common
|
||||
|
||||
from certbot_sendmail import constants
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FileChanges(object):
|
||||
def __init__(self, filepath):
|
||||
self._filepath = filepath
|
||||
self._lines = []
|
||||
self._append = []
|
||||
if not os.path.isfile(filepath):
|
||||
open(filepath, "a").close()
|
||||
with open(filepath) as f:
|
||||
self._lines = f.readlines()
|
||||
self._diff = {} # line number: new line
|
||||
|
||||
def replace_first(self, regex_find_line, replace_value, full_replace):
|
||||
""" regex to match line, new line to replace it with."""
|
||||
p = re.compile(regex_find_line)
|
||||
for i, line in enumerate(self._lines):
|
||||
result = re.search(p, line)
|
||||
if not result or not result.group("value"):
|
||||
continue
|
||||
if result.group("value") == replace_value:
|
||||
return # already set correctly
|
||||
start, end = result.span("value")
|
||||
self._diff[i] = line[0:start] + replace_value + line[end:]
|
||||
return
|
||||
self._append.append(full_replace)
|
||||
|
||||
def flush(self, diff_file=None):
|
||||
""" print diff """
|
||||
new_filelines = []
|
||||
for i, line in enumerate(self._lines):
|
||||
to_append = line
|
||||
if i in self._diff:
|
||||
to_append = self._diff[i]
|
||||
new_filelines.append(to_append)
|
||||
new_filelines.extend(self._append)
|
||||
|
||||
diff = "".join(difflib.unified_diff(self._lines, new_filelines))
|
||||
pause = True
|
||||
if len(self._append) == 0 and len(self._diff) == 0:
|
||||
message = "Your config files are already up-to-date!\n"
|
||||
pause = False
|
||||
elif diff_file:
|
||||
with open(diff_file, "w") as f:
|
||||
f.write(diff)
|
||||
message = ("The appropriate diff has been written to {diff_file}.\n"
|
||||
"Review these changes, then apply them with:\n\n"
|
||||
" patch -b {tls_file} -i {diff_file}\n\n"
|
||||
"This should also create a backup of the original file at {tls_file}.orig\n").format(
|
||||
diff_file=diff_file, tls_file=self._filepath)
|
||||
else:
|
||||
message = ("Review and apply the following diff to {tls_file}.\n"
|
||||
"Continue when finished:\n\n{content}\n\n".format(
|
||||
tls_file=self._filepath, content=diff))
|
||||
zope.component.getUtility(interfaces.IDisplay).notification(message, pause=True)
|
||||
|
||||
@zope.interface.implementer(interfaces.IInstaller)
|
||||
@zope.interface.provider(interfaces.IPluginFactory)
|
||||
class SendmailConfigurator(common.Installer):
|
||||
# pylint: disable=too-many-instance-attributes,too-many-public-methods
|
||||
"""Sendmail configurator.
|
||||
|
||||
.. todo:: Add proper support for comments in the config. Currently,
|
||||
config files modified by the configurator will lose all their comments.
|
||||
|
||||
:ivar config: Configuration.
|
||||
:type config: :class:`~certbot.interfaces.IConfig`
|
||||
|
||||
:ivar str save_notes: Human-readable config change notes
|
||||
|
||||
:ivar reverter: saves and reverts checkpoints
|
||||
:type reverter: :class:`certbot.reverter.Reverter`
|
||||
|
||||
"""
|
||||
|
||||
description = "Sendmail Web Server plugin - Alpha"
|
||||
|
||||
@classmethod
|
||||
def add_parser_arguments(cls, add):
|
||||
add("server-root", default=constants.CLI_DEFAULTS["server_root"],
|
||||
help="Sendmail server root directory.")
|
||||
add("tls-config-file", default=constants.CLI_DEFAULTS["tls_config_file"],
|
||||
help="Filename for the relevant TLS options.")
|
||||
add("diff-file", default=constants.CLI_DEFAULTS["diff_file"],
|
||||
help="Optional output file for diff. If specified diff will be written"
|
||||
"to file rather than stdout.")
|
||||
|
||||
@property
|
||||
def tls_config_file(self):
|
||||
"""Sendmail TLS config file."""
|
||||
# TODO (sydli): check if there's an intermediate "TLS" directory; if so, drop
|
||||
# it there.
|
||||
return os.path.join(self.conf("server_root"), self.conf("tls-config-file"))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
"""Initialize an Sendmail Configurator. """
|
||||
super(SendmailConfigurator, self).__init__(*args, **kwargs)
|
||||
|
||||
# Files to save
|
||||
self.save_notes = ""
|
||||
self.reverter.recovery_routine()
|
||||
self.changes = None
|
||||
self._keypath = None
|
||||
|
||||
# This is called in determine_authenticator and determine_installer
|
||||
def prepare(self):
|
||||
"""Prepare the authenticator/installer.
|
||||
|
||||
:raises .errors.NoInstallationError: If Sendmail ctl cannot be found
|
||||
:raises .errors.MisconfigurationError: If Sendmail is misconfigured
|
||||
"""
|
||||
# Prevent two Sendmail plugins from modifying a config at once
|
||||
try:
|
||||
util.lock_dir_until_exit(self.conf("server-root"))
|
||||
except (OSError, errors.LockError):
|
||||
logger.debug("Encountered error:", exc_info=True)
|
||||
raise errors.PluginError(
|
||||
"Unable to lock %s", self.conf("server-root"))
|
||||
self.changes = FileChanges(self.tls_config_file)
|
||||
|
||||
# Entry point in main.py for installing cert
|
||||
def deploy_cert(self, domain, cert_path, key_path,
|
||||
chain_path=None, fullchain_path=None):
|
||||
# pylint: disable=unused-argument
|
||||
"""Deploys certificate to specified virtual host.
|
||||
"""
|
||||
fullchain_dir, _ = os.path.split(fullchain_path)
|
||||
regex_metapattern = r"define\(`conf{param}',\s*`(?P<value>.+)'\)"
|
||||
full_string = "define(`conf{param}', `{value}')dnl\n"
|
||||
# TODO: Instead of setting CACERT_PATH to the live/ dir,
|
||||
# We should really just ensure that Let's Encrypt's cert
|
||||
# is trusted.
|
||||
config_params = {
|
||||
"CACERT_PATH": fullchain_dir,
|
||||
"CACERT": fullchain_path,
|
||||
"SERVER_CERT": cert_path,
|
||||
"SERVER_KEY": key_path,
|
||||
"CLIENT_CERT": cert_path,
|
||||
"CLIENT_KEY": key_path,
|
||||
}
|
||||
for param in config_params:
|
||||
yay_for_regex_parsing = regex_metapattern.format(param=param)
|
||||
self.changes.replace_first(yay_for_regex_parsing,
|
||||
config_params[param],
|
||||
full_string.format(param=param, value=config_params[param]))
|
||||
self._keypath = key_path
|
||||
|
||||
##################################
|
||||
# enhancement methods (IInstaller)
|
||||
##################################
|
||||
def supported_enhancements(self): # pylint: disable=no-self-use
|
||||
"""Returns currently supported enhancements."""
|
||||
return []
|
||||
|
||||
def enhance(self, domain, enhancement, options=None):
|
||||
"""Enhance configuration.
|
||||
|
||||
:param str domain: domain to enhance
|
||||
:param str enhancement: enhancement type defined in
|
||||
:const:`~certbot.constants.ENHANCEMENTS`
|
||||
:param options: options for the enhancement
|
||||
See :const:`~certbot.constants.ENHANCEMENTS`
|
||||
documentation for appropriate parameter.
|
||||
|
||||
"""
|
||||
raise NotImplemented("The Sendmail plugin does not support any enhancements")
|
||||
|
||||
######################################
|
||||
# Sendmail management (IInstaller)
|
||||
######################################
|
||||
def restart(self):
|
||||
"""Restarts sendmail. Not implemented. """
|
||||
if self._keypath:
|
||||
os.chmod(self._keypath, 0o640)
|
||||
try:
|
||||
proc = subprocess.Popen(["make", "-C", self.conf("server_root")])
|
||||
out, err = proc.communicate()
|
||||
proc = subprocess.Popen(["make", "install", "-C", self.conf("server_root")])
|
||||
out, err = proc.communicate()
|
||||
proc = subprocess.Popen(["service", "sendmail", "restart"])
|
||||
out, err = proc.communicate()
|
||||
except (OSError, ValueError):
|
||||
raise errors.MisconfigurationError("nginx restart failed")
|
||||
|
||||
|
||||
def config_test(self): # pylint: disable=no-self-use
|
||||
"""Check the configuration of Sendmail for errors.
|
||||
"""
|
||||
pass
|
||||
|
||||
def more_info(self):
|
||||
"""Human-readable string to help understand the module"""
|
||||
return (
|
||||
"Configures Sendmail to install STARTTLS with a valid cert.{0}"
|
||||
"Server root: {root}{0}".format(
|
||||
os.linesep, root=self.parser.config_root))
|
||||
|
||||
###################################################
|
||||
# Wrapper functions for Reverter class (IInstaller)
|
||||
###################################################
|
||||
def save(self, title=None, temporary=False):
|
||||
"""Saves all changes to the configuration files.
|
||||
|
||||
:param str title: The title of the save. If a title is given, the
|
||||
configuration will be saved as a new checkpoint and put in a
|
||||
timestamped directory.
|
||||
|
||||
:param bool temporary: Indicates whether the changes made will
|
||||
be quickly reversed in the future (ie. challenges)
|
||||
|
||||
:raises .errors.PluginError: If there was an error in
|
||||
an attempt to save the configuration, or an error creating a
|
||||
checkpoint
|
||||
|
||||
"""
|
||||
self.changes.flush(self.conf("diff_file"))
|
||||
|
||||
def rollback_checkpoints(self, rollback=1):
|
||||
pass
|
||||
|
||||
def recovery_routine(self):
|
||||
pass
|
||||
|
||||
def get_all_names(self):
|
||||
"""Returns all names that may be authenticated.
|
||||
"""
|
||||
return []
|
||||
9
certbot-sendmail/certbot_sendmail/constants.py
Normal file
9
certbot-sendmail/certbot_sendmail/constants.py
Normal file
@@ -0,0 +1,9 @@
|
||||
"""sendmail plugin constants."""
|
||||
import pkg_resources
|
||||
|
||||
CLI_DEFAULTS = dict(
|
||||
server_root="/etc/mail",
|
||||
tls_config_file="starttls.m4",
|
||||
diff_file=None,
|
||||
)
|
||||
"""CLI defaults."""
|
||||
11
certbot-sendmail/certbot_sendmail/options-ssl-dovecot.conf
Normal file
11
certbot-sendmail/certbot_sendmail/options-ssl-dovecot.conf
Normal file
@@ -0,0 +1,11 @@
|
||||
# This file contains important security parameters. If you modify this file
|
||||
# manually, Certbot will be unable to automatically provide future security
|
||||
# updates. Instead, Certbot will print and log an error message with a path to
|
||||
# the up-to-date file that you will need to refer to when manually updating
|
||||
# this file.
|
||||
|
||||
ssl_protocols = !SSLv3 !SSLv2
|
||||
ssl_prefer_server_ciphers = yes
|
||||
|
||||
ssl_cipher_list = "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS"
|
||||
ssl_dh_parameters_length = 2048
|
||||
1
certbot-sendmail/certbot_sendmail/tests/__init__.py
Normal file
1
certbot-sendmail/certbot_sendmail/tests/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""Certbot Sendmail Tests"""
|
||||
80
certbot-sendmail/certbot_sendmail/tests/configurator_test.py
Normal file
80
certbot-sendmail/certbot_sendmail/tests/configurator_test.py
Normal file
@@ -0,0 +1,80 @@
|
||||
"""Test for certbot_sendmail.configurator."""
|
||||
import unittest
|
||||
import mock
|
||||
import os
|
||||
import subprocess
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
from certbot import errors
|
||||
from certbot.tests import util as certbot_test_util
|
||||
|
||||
from certbot.plugins import common
|
||||
from certbot_sendmail import configurator
|
||||
|
||||
class SendmailConfiguratorTest(unittest.TestCase):
|
||||
"""Test a semi complex vhost configuration."""
|
||||
def setUp(self):
|
||||
super(SendmailConfiguratorTest, self).setUp()
|
||||
|
||||
def test_prepare(self):
|
||||
config, _ = get_configurator()
|
||||
config.prepare()
|
||||
|
||||
@certbot_test_util.patch_get_utility()
|
||||
def test_deploy(self, mock_getutility):
|
||||
mock_utility = mock_getutility()
|
||||
mock_utility.notification = mock.MagicMock(return_value=True)
|
||||
config, _ = get_configurator()
|
||||
config.prepare()
|
||||
config.deploy_cert("example.com", "path/cert123.pem", "path/ultrasecret123.pem",
|
||||
"path/one_chain.pem", "path/full_chain.pem")
|
||||
config.save()
|
||||
|
||||
@certbot_test_util.patch_get_utility()
|
||||
def test_configure_empty(self, mock_getutility):
|
||||
mock_utility = mock_getutility()
|
||||
mock_utility.notification = mock.MagicMock(return_value=True)
|
||||
config, tempdir = get_configurator(tls_filename="nonexistant.m4", output_diff="output.diff")
|
||||
config.prepare()
|
||||
config.deploy_cert("example.com", "path/cert123.pem", "path/ultrasecret123.pem",
|
||||
"path/one_chain.pem", "path/full_chain.pem")
|
||||
config.save()
|
||||
with open(os.path.join(tempdir, "output.diff")) as f:
|
||||
actual = f.readlines()
|
||||
expected = [
|
||||
"--- \n", "+++ \n", "@@ -0,0 +1,6 @@\n",
|
||||
"+define(`confSERVER_CERT', `path/cert123.pem')dnl\n",
|
||||
"+define(`confCACERT_PATH', `path')dnl\n",
|
||||
"+define(`confSERVER_KEY', `path/ultrasecret123.pem')dnl\n",
|
||||
"+define(`confCACERT', `path/full_chain.pem')dnl\n",
|
||||
"+define(`confCLIENT_CERT', `path/cert123.pem')dnl\n",
|
||||
"+define(`confCLIENT_KEY', `path/ultrasecret123.pem')dnl\n",
|
||||
]
|
||||
self.assertEqual(tuple(expected), tuple(actual))
|
||||
|
||||
def get_configurator(tls_filename="starttls.m4", write_tls_data=None, output_diff=None):
|
||||
tempdir, _, _ = common.dir_setup(
|
||||
"etc_mail", "certbot_sendmail.tests")
|
||||
backups = os.path.join(tempdir, "backups")
|
||||
config_path = os.path.join(tempdir, "etc_mail")
|
||||
if write_tls_data:
|
||||
tls_path = os.path.join(config_path, tls_filename)
|
||||
with open(tls_path, 'w') as f:
|
||||
f.write(write_tls_data)
|
||||
diff_file = None
|
||||
if output_diff:
|
||||
diff_file = os.path.join(tempdir, output_diff)
|
||||
return configurator.SendmailConfigurator(
|
||||
config=mock.MagicMock(
|
||||
backup_dir=backups,
|
||||
temp_checkpoint_dir=os.path.join(backups, "temp_checkpoints"),
|
||||
in_progress_dir=os.path.join(backups, "IN_PROGRESS"),
|
||||
sendmail_server_root=config_path,
|
||||
sendmail_tls_config_file=tls_filename,
|
||||
sendmail_diff_file=diff_file,
|
||||
), name="sendmail"), tempdir
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main() # pragma: no cover
|
||||
55
certbot-sendmail/certbot_sendmail/tests/testdata/etc_mail/starttls.m4
vendored
Executable file
55
certbot-sendmail/certbot_sendmail/tests/testdata/etc_mail/starttls.m4
vendored
Executable file
@@ -0,0 +1,55 @@
|
||||
divert(-1)dnl
|
||||
####################################################################
|
||||
####################################################################
|
||||
divert(0)dnl
|
||||
VERSIONID(`$Id: starttls.m4,v 8.15.2-10 2018-01-13 23:43:05 cowboy Exp $')
|
||||
dnl #
|
||||
dnl #---------------------------------------------------------------------
|
||||
dnl # Bring in Autoconf results
|
||||
dnl #---------------------------------------------------------------------
|
||||
ifdef(`sm_version', `dnl',
|
||||
`include(`/usr/share/sendmail/cf/debian/autoconf.m4')dnl')
|
||||
dnl #
|
||||
dnl # Check to see if inclusion is valid (version >= 8.11.0, tls enabled)
|
||||
ifelse(eval(sm_version_math >= 527104), `1', `dnl
|
||||
ifelse(sm_enable_tls, `yes', `dnl
|
||||
dnl #
|
||||
dnl # To support shared keyfiles, we need them to be group readable
|
||||
dnl #
|
||||
define(`confDONT_BLAME_SENDMAIL',dnl
|
||||
defn(`confDONT_BLAME_SENDMAIL')`,GroupReadableKeyFile')dnl
|
||||
dnl #
|
||||
dnl # ...Do not touch anything above this line...
|
||||
dnl #
|
||||
dnl # Set a more reasonable timeout on negotiation
|
||||
dnl #
|
||||
define(`confTO_STARTTLS', `2m')dnl # <= EDIT
|
||||
dnl #
|
||||
dnl # CA directory - CA certs should be herein
|
||||
define(`confCACERT_PATH', `/etc/ssl/certs')dnl # <= EDIT
|
||||
dnl #
|
||||
dnl # CA file (may be the same as client/server certificate)
|
||||
define(`confCACERT', `/etc/mail/tls/sendmail-server.crt')dnl # <= EDIT
|
||||
dnl #
|
||||
dnl # Certificate Revocation List
|
||||
define(`confCRL', `')dnl # <= EDIT
|
||||
dnl # CRL not found... do not issue warnings on it!
|
||||
undefine(`confCRL')dnl
|
||||
dnl #
|
||||
dnl # Server certificate/key (can be in the same file, and shared w/client)
|
||||
dnl # NOTE: The key must *NOT* be encrypted !!!
|
||||
define(`confSERVER_CERT', `/etc/mail/tls/sendmail-server.crt')dnl # <= EDIT
|
||||
define(`confSERVER_KEY', `/etc/mail/tls/sendmail-common.key')dnl # <= EDIT
|
||||
dnl #
|
||||
dnl # Client certificate/key (can be in the same file, and shared w/server)
|
||||
dnl # NOTE: The key must *NOT* be encrypted !!!
|
||||
define(`confCLIENT_CERT', `/etc/mail/tls/sendmail-client.crt')dnl # <= EDIT
|
||||
define(`confCLIENT_KEY', `/etc/mail/tls/sendmail-common.key')dnl # <= EDIT
|
||||
dnl #
|
||||
dnl # DH parameters
|
||||
define(`confDH_PARAMETERS', `/etc/mail/tls/sendmail-common.prm')dnl # <= EDIT
|
||||
dnl #
|
||||
dnl # Optional settings
|
||||
define(`confTLS_SRV_OPTIONS', `V')dnl # <= EDIT
|
||||
dnl #
|
||||
')')dnl
|
||||
2
certbot-sendmail/setup.cfg
Normal file
2
certbot-sendmail/setup.cfg
Normal file
@@ -0,0 +1,2 @@
|
||||
[bdist_wheel]
|
||||
universal = 1
|
||||
70
certbot-sendmail/setup.py
Normal file
70
certbot-sendmail/setup.py
Normal file
@@ -0,0 +1,70 @@
|
||||
import sys
|
||||
|
||||
from setuptools import setup
|
||||
from setuptools import find_packages
|
||||
|
||||
|
||||
version = '0.28.0.dev0'
|
||||
|
||||
# Please update tox.ini when modifying dependency version requirements
|
||||
install_requires = [
|
||||
'acme=={0}'.format(version),
|
||||
'certbot=={0}'.format(version),
|
||||
'mock',
|
||||
'PyOpenSSL',
|
||||
'pyparsing>=1.5.5', # Python3 support; perhaps unnecessary?
|
||||
# For pkg_resources. >=1.0 so pip resolves it to a version cryptography
|
||||
# will tolerate; see #2599:
|
||||
'setuptools>=1.0',
|
||||
'zope.interface',
|
||||
]
|
||||
|
||||
docs_extras = [
|
||||
'Sphinx>=1.0', # autodoc_member_order = 'bysource', autodoc_default_flags
|
||||
'sphinx_rtd_theme',
|
||||
]
|
||||
|
||||
setup(
|
||||
name='certbot-sendmail',
|
||||
version=version,
|
||||
description="Sendmail plugin for Certbot",
|
||||
url='https://github.com/letsencrypt/letsencrypt',
|
||||
author="Certbot Project",
|
||||
author_email='client-dev@letsencrypt.org',
|
||||
license='Apache License 2.0',
|
||||
classifiers=[
|
||||
'Development Status :: 3 - Alpha',
|
||||
'Environment :: Plugins',
|
||||
'Intended Audience :: System Administrators',
|
||||
'License :: OSI Approved :: Apache Software License',
|
||||
'Operating System :: POSIX :: Linux',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Topic :: Internet :: WWW/HTTP',
|
||||
'Topic :: Security',
|
||||
'Topic :: System :: Installation/Setup',
|
||||
'Topic :: System :: Networking',
|
||||
'Topic :: System :: Systems Administration',
|
||||
'Topic :: Utilities',
|
||||
],
|
||||
|
||||
packages=find_packages(),
|
||||
include_package_data=True,
|
||||
install_requires=install_requires,
|
||||
extras_require={
|
||||
'docs': docs_extras,
|
||||
},
|
||||
entry_points={
|
||||
'certbot.plugins': [
|
||||
'sendmail = certbot_sendmail.configurator:SendmailConfigurator',
|
||||
],
|
||||
},
|
||||
test_suite='certbot_sendmail',
|
||||
)
|
||||
@@ -41,6 +41,7 @@ class PluginEntryPoint(object):
|
||||
"certbot-dns-sakuracloud",
|
||||
"certbot-nginx",
|
||||
"certbot-postfix",
|
||||
"certbot-sendmail",
|
||||
]
|
||||
"""Distributions for which prefix will be omitted."""
|
||||
|
||||
|
||||
@@ -30,5 +30,6 @@ fi
|
||||
-e certbot-dns-sakuracloud \
|
||||
-e certbot-nginx \
|
||||
-e certbot-postfix \
|
||||
-e certbot-sendmail \
|
||||
-e letshelp-certbot \
|
||||
-e certbot-compatibility-test
|
||||
|
||||
@@ -29,5 +29,6 @@ fi
|
||||
-e certbot-dns-sakuracloud \
|
||||
-e certbot-nginx \
|
||||
-e certbot-postfix \
|
||||
-e certbot-sendmail \
|
||||
-e letshelp-certbot \
|
||||
-e certbot-compatibility-test
|
||||
|
||||
Reference in New Issue
Block a user