certbot-dns-directadmin 0.0.3__zip

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (12) hide show
  1. Storage/OneDrive/OneDrive - WHS/Projects/certbot-dns-directadmin/.venv/Lib/site-packages/certbot_dns_directadmin/__init__.py +1 -0
  2. Storage/OneDrive/OneDrive - WHS/Projects/certbot-dns-directadmin/.venv/Lib/site-packages/certbot_dns_directadmin/__pycache__/__init__.cpython-37.pyc +0 -0
  3. Storage/OneDrive/OneDrive - WHS/Projects/certbot-dns-directadmin/.venv/Lib/site-packages/certbot_dns_directadmin/__pycache__/directadmin.cpython-37.pyc +0 -0
  4. Storage/OneDrive/OneDrive - WHS/Projects/certbot-dns-directadmin/.venv/Lib/site-packages/certbot_dns_directadmin/__pycache__/dns_directadmin.cpython-37.pyc +0 -0
  5. Storage/OneDrive/OneDrive - WHS/Projects/certbot-dns-directadmin/.venv/Lib/site-packages/certbot_dns_directadmin/directadmin.py +142 -0
  6. Storage/OneDrive/OneDrive - WHS/Projects/certbot-dns-directadmin/.venv/Lib/site-packages/certbot_dns_directadmin/dns_directadmin.py +132 -0
  7. Storage/OneDrive/OneDrive - WHS/Projects/certbot-dns-directadmin/.venv/Lib/site-packages/certbot_dns_directadmin-0.0.3-py3.7.egg-info/PKG-INFO +84 -0
  8. Storage/OneDrive/OneDrive - WHS/Projects/certbot-dns-directadmin/.venv/Lib/site-packages/certbot_dns_directadmin-0.0.3-py3.7.egg-info/SOURCES.txt +12 -0
  9. Storage/OneDrive/OneDrive - WHS/Projects/certbot-dns-directadmin/.venv/Lib/site-packages/certbot_dns_directadmin-0.0.3-py3.7.egg-info/dependency_links.txt +1 -0
  10. Storage/OneDrive/OneDrive - WHS/Projects/certbot-dns-directadmin/.venv/Lib/site-packages/certbot_dns_directadmin-0.0.3-py3.7.egg-info/entry_points.txt +3 -0
  11. Storage/OneDrive/OneDrive - WHS/Projects/certbot-dns-directadmin/.venv/Lib/site-packages/certbot_dns_directadmin-0.0.3-py3.7.egg-info/requires.txt +3 -0
  12. Storage/OneDrive/OneDrive - WHS/Projects/certbot-dns-directadmin/.venv/Lib/site-packages/certbot_dns_directadmin-0.0.3-py3.7.egg-info/top_level.txt +1 -0
@@ -0,0 +1,142 @@
1
+ import base64
2
+ from collections import OrderedDict
3
+ import requests
4
+
5
+ try:
6
+ # python 3
7
+ from urllib.request import urlopen, Request
8
+ from urllib.parse import urlencode, parse_qs
9
+ except ImportError:
10
+ # python 2
11
+ from urllib import urlencode
12
+ from urllib2 import urlopen, Request
13
+ from cgi import parse_qs
14
+
15
+
16
+ class DirectAdminClient:
17
+
18
+ def __init__(self, url, username, password):
19
+
20
+ self.version = "0.0.3"
21
+ self.client = requests.session()
22
+ self.headers = {'user-agent': 'pyDirectAdmin/' + str(self.version),
23
+ 'Authorization': 'Basic %s' % base64.b64encode(("%s:%s" %
24
+ (username, password))
25
+ .encode()).decode('utf8'),
26
+ }
27
+ self.url = url
28
+
29
+ def make_request(self, endpoint, data=None):
30
+ response = None # Empty response variable
31
+
32
+ if data is not None:
33
+ # Data is present add the fields to call
34
+ response = urlopen(
35
+ Request(
36
+ "%s?%s" % (self.url + '/{}'.format(endpoint), urlencode(data)),
37
+ headers=self.headers,
38
+ )
39
+ )
40
+ elif data is None:
41
+ # Data is not present so we don't need addition field.
42
+ response = urlopen(
43
+ Request(
44
+ "%s?" % (self.url + '/{}'.format(endpoint)),
45
+ headers=self.headers,
46
+ )
47
+ )
48
+
49
+ return response
50
+
51
+ @staticmethod
52
+ def __process_response__(response):
53
+ if int(response['error'][0]) > 0:
54
+ # There was an error
55
+ raise Exception(response['text'][0])
56
+ elif int(response['error'][0]) == 0:
57
+ # Everything succeeded
58
+ return {'error': response['error'][0],
59
+ 'message': response['text'][0]
60
+ }
61
+
62
+ def get_domain_list(self):
63
+ r = self.make_request('CMD_API_SHOW_DOMAINS')
64
+
65
+ domains = parse_qs(r.read().decode('utf8'),
66
+ keep_blank_values=0,
67
+ strict_parsing=1)
68
+ response = list()
69
+ for domain in domains.values():
70
+ response.append(domain[0])
71
+ return response
72
+
73
+ def get_zone_list(self, domain):
74
+ params = OrderedDict([('domain', domain)])
75
+ r = self.make_request('CMD_API_DNS_CONTROL', params)
76
+
77
+ return r.read()
78
+
79
+ def add_dns_record(self, domain, record_type, record_name, record_value, record_ttl=None):
80
+
81
+ params = OrderedDict([('domain', domain),
82
+ ('action', 'add'),
83
+ ('type', record_type.upper()),
84
+ ('name', record_name),
85
+ ('value', record_value)])
86
+
87
+ if record_ttl is not None:
88
+ params.update({'ttl': record_ttl})
89
+
90
+ response = self.make_request('CMD_API_DNS_CONTROL', data=params)
91
+ response = parse_qs(response.read().decode('utf8'),
92
+ keep_blank_values=0,
93
+ strict_parsing=1)
94
+
95
+ return self.__process_response__(response)
96
+
97
+ def update_dns_record(self, domain, record_type, record_name, record_value_old, record_value_new, record_ttl=None):
98
+
99
+ params = OrderedDict([('domain', domain),
100
+ ('action', 'edit'),
101
+ ('type', record_type.upper()),
102
+ (record_type.lower() + "recs0", 'name={}&value={}'.format(record_name, record_value_old)),
103
+ ('name', record_name),
104
+ ('value', record_value_new)])
105
+
106
+ if record_ttl is not None:
107
+ params.update({'ttl': record_ttl})
108
+
109
+ response = self.make_request('CMD_API_DNS_CONTROL', data=params)
110
+ response = parse_qs(response.read().decode('utf8'),
111
+ keep_blank_values=0,
112
+ strict_parsing=1)
113
+
114
+ return self.__process_response__(response)
115
+
116
+ def delete_dns_record(self, domain, record_type, record_name, record_value):
117
+ params = OrderedDict([('domain', domain),
118
+ ('action', 'select'),
119
+ (record_type.lower() + "recs0", 'name={}&value={}'.format(record_name, record_value))
120
+ ])
121
+
122
+ response = self.make_request('CMD_API_DNS_CONTROL', data=params)
123
+ response = parse_qs(response.read().decode('utf8'),
124
+ keep_blank_values=0,
125
+ strict_parsing=1)
126
+
127
+ return self.__process_response__(response)
128
+
129
+ def override_domain_ttl(self, domain, record_name, ttl):
130
+ params = OrderedDict([('domain', domain),
131
+ ('action', 'ttl'),
132
+ ('ttl_select', 'custom'),
133
+ ('name', record_name),
134
+ ('ttl', ttl)])
135
+
136
+ response = self.make_request('CMD_API_DNS_CONTROL', data=params)
137
+ response = parse_qs(response.read().decode('utf8'),
138
+ keep_blank_values=0,
139
+ strict_parsing=1)
140
+
141
+ return self.__process_response__(response)
142
+
@@ -0,0 +1,132 @@
1
+ """Directadmin dns-01 authenticator plugin"""
2
+ import logging
3
+ import tldextract
4
+
5
+ try:
6
+ # python 3
7
+ from urllib.request import urlopen, Request
8
+ from urllib.parse import urlencode
9
+ except ImportError:
10
+ # python 2
11
+ from urllib import urlencode
12
+ from urllib2 import urlopen, Request
13
+
14
+ import zope.interface
15
+
16
+ from certbot import errors
17
+ from certbot import interfaces
18
+ from certbot.plugins import dns_common
19
+ from certbot_dns_directadmin.directadmin import DirectAdminClient
20
+
21
+ logger = logging.getLogger(__name__)
22
+
23
+
24
+ @zope.interface.implementer(interfaces.IAuthenticator)
25
+ @zope.interface.provider(interfaces.IPluginFactory)
26
+ class Authenticator(dns_common.DNSAuthenticator):
27
+ """directadmin dns-01 authenticator plugin"""
28
+
29
+ description = "Obtain a certificate using a DNS TXT record in directadmin"
30
+ problem = "a"
31
+
32
+ def __init__(self, *args, **kwargs):
33
+ super(Authenticator, self).__init__(*args, **kwargs)
34
+ self.credentials = None
35
+
36
+ @classmethod
37
+ def add_parser_arguments(cls, add): # pylint: disable=arguments-differ
38
+ super(Authenticator, cls).add_parser_arguments(add, default_propagation_seconds=10)
39
+ add("credentials",
40
+ type=str,
41
+ help="The directadmin credentials INI file")
42
+
43
+ def more_info(self): # pylint: disable=missing-docstring
44
+ return self.description
45
+
46
+ def _setup_credentials(self):
47
+ self.credentials = self._configure_credentials(
48
+ 'credentials',
49
+ 'The directadmin credentials INI file',
50
+ {
51
+ 'url': 'directadmin url',
52
+ 'username': 'directadmin username',
53
+ 'password': 'directadmin password'
54
+ }
55
+ )
56
+
57
+ def _perform(self, domain, validation_domain_name, validation):
58
+ self._get_directadmin_client().add_txt_record(validation_domain_name, validation)
59
+
60
+ def _cleanup(self, domain, validation_domain_name, validation):
61
+ self._get_directadmin_client().del_txt_record(validation_domain_name, validation)
62
+
63
+ def _get_directadmin_client(self):
64
+ return _DirectadminClient(
65
+ self.credentials.conf('url'),
66
+ self.credentials.conf('username'),
67
+ self.credentials.conf('password')
68
+ )
69
+
70
+
71
+ class _DirectadminClient:
72
+ """Encapsulate communications with the directadmin API"""
73
+
74
+ def __init__(self, url, username, password):
75
+ self.url = url
76
+ self.client = DirectAdminClient(url, username, password)
77
+
78
+ def add_txt_record(self, record_name, record_content, record_ttl=60):
79
+ """Add a TXT record
80
+ :param str record_name: the domain name to add
81
+ :param str record_content: the content of the TXT record to add
82
+ :param int record_ttl: the TTL of the record to add
83
+ """
84
+ (directadmin_zone, directadmin_name) = self._get_zone_and_name(record_name)
85
+
86
+ try:
87
+ response = self.client.add_dns_record(directadmin_zone,
88
+ 'txt',
89
+ directadmin_name,
90
+ record_value=record_content,
91
+ record_ttl=record_ttl)
92
+
93
+ logger.debug(response)
94
+ if int(response['error']) == 0:
95
+ logger.info("Successfully added TXT record for %s", record_name)
96
+ except Exception as e:
97
+ raise errors.PluginError("Error adding TXT record: %s" % e)
98
+
99
+ def del_txt_record(self, record_name, record_content, record_ttl=60):
100
+ """Remove a TXT record
101
+ :param str record_name: the domain name to remove
102
+ :param str record_content: the content of the TXT record to remove
103
+ :param int record_ttl: the TTL of the record to remove
104
+ """
105
+ (directadmin_zone, directadmin_name) = self._get_zone_and_name(record_name)
106
+
107
+ try:
108
+ response = self.client.delete_dns_record(directadmin_zone, 'txt', directadmin_name, record_content)
109
+ logger.debug(response)
110
+ if int(response['error']) == 0:
111
+ logger.info("Successfully removed TXT record for %s", record_name)
112
+ except Exception as e:
113
+ raise errors.PluginError("Error removing TXT record: %s" % e)
114
+
115
+ def _get_zone_and_name(self, record_domain):
116
+ """Find a suitable zone for a domain
117
+ :param str record_name: the domain name
118
+ :returns: (the zone, the name in the zone)
119
+ :rtype: tuple
120
+ """
121
+ directadmin_zone = ''
122
+ directadmin_name = ''
123
+ logger.debug('Record Domain: ' + record_domain)
124
+ (subdomain, domain, suffix) = tldextract.extract(record_domain)
125
+ logger.debug('Subdomain: ' + subdomain)
126
+ logger.debug('Domain: ' + domain)
127
+ logger.debug('Suffix: ' + suffix)
128
+
129
+ directadmin_zone = ".".join((domain, suffix))
130
+ directadmin_name = subdomain
131
+
132
+ return directadmin_zone, directadmin_name
@@ -0,0 +1,84 @@
1
+ Metadata-Version: 2.1
2
+ Name: certbot-dns-directadmin
3
+ Version: 0.0.3
4
+ Summary: certbot plugin to allow acme dns-01 authentication of a name managed in DirectAdmin.
5
+ Home-page: https://github.com/cybercinch/certbot-dns-directadmin
6
+ Author: Aaron Guise
7
+ Author-email: aaron@guise.net.nz
8
+ License: Apache Licence 2.0
9
+ Description: # certbot-dns-directadmin
10
+
11
+ Plugin to allow acme dns-01 authentication of a name managed in DirectAdmin. Useful for automating and creating a Let's Encrypt certificate (wildcard or not) for a service with a name managed by DirectAdmin, but installed on a server not managed in DirectAdmin.
12
+
13
+ ## How to use
14
+ ### 1. Install
15
+ First, install certbot and the plugin using pip:
16
+ ```
17
+ pip install certbot certbot-dns-directadmin
18
+ ```
19
+ ### 2. Configure
20
+ Download the file `credentials.ini.example` and rename it to `directadmin-credentials.ini`. Edit it to set your DirectAdmin url, username and password.
21
+ ```
22
+ # The url DirectAdmin url
23
+ # include the scheme and the port number (usually 2222)
24
+ certbot_dns_directadmin:directadmin_url = https://directadmin.example.com:2222
25
+ # The DirectAdmin username
26
+ certbot_dns_directadmin:directadmin_username = user
27
+
28
+ # The DirectAdmin password
29
+ certbot_dns_directadmin:directadmin_password = hunter2
30
+ ```
31
+ ### 3. Run
32
+ You can now run certbot using the plugin and feeding the credentials file.
33
+ For example, to get a certificate for example.com and www.example.com:
34
+ ```
35
+ certbot certonly \
36
+ --authenticator certbot-dns-directadmin:directadmin \
37
+ --certbot-dns-directadmin:panel-credentials /path/to/directadmin-credentials.ini \
38
+ -d example.com \
39
+ -d www.example.com
40
+ ```
41
+ To create a wildcard certificate *.example.com and install it on an apache server, the installer plugin must be specified with the `--installer` option.
42
+ You will need to install the apache plugin if it's not already present on your system.
43
+ ```
44
+ pip install certbot-apache
45
+ certbot run \
46
+ --apache \
47
+ --authenticator certbot-dns-directadmin:directadmin \
48
+ --installer apache \
49
+ --certbot-dns-directadmin:directadmin-credentials /path/to/directadmin-credentials.ini \
50
+ -d '*.example.com'
51
+ ```
52
+ The certbot documentation has some additionnal informations about combining authenticator and installer plugins: https://certbot.eff.org/docs/using.html#getting-certificates-and-choosing-plugins
53
+
54
+ ## Docker
55
+ A docker image based on [certbot/certbot](https://hub.docker.com/r/certbot/certbot/) is provided for your convenience:
56
+ ```
57
+ docker run \
58
+ -v /path/to/credentials.ini:/tmp/credentials.ini \
59
+ cybercinch/certbot-dns-directadmin \
60
+ certonly \
61
+ --authenticator certbot-dns-directadmin:directadmin \
62
+ --certbot-dns-cpanel:cpanel-credentials /tmp/directadmin-credentials.ini \
63
+ -d example.com \
64
+ -d www.example.com
65
+ ```
66
+
67
+ ## Additional documentation
68
+ * https://certbot.eff.org/docs/
69
+
70
+ Keywords: certbot letsencrypt directadmin da dns-01 plugin
71
+ Platform: UNKNOWN
72
+ Classifier: Development Status :: 3 - Alpha
73
+ Classifier: Environment :: Plugins
74
+ Classifier: Intended Audience :: System Administrators
75
+ Classifier: License :: OSI Approved :: Apache Software License
76
+ Classifier: Operating System :: POSIX :: Linux
77
+ Classifier: Programming Language :: Python
78
+ Classifier: Topic :: Internet :: WWW/HTTP
79
+ Classifier: Topic :: Security
80
+ Classifier: Topic :: System :: Installation/Setup
81
+ Classifier: Topic :: System :: Networking
82
+ Classifier: Topic :: System :: Systems Administration
83
+ Classifier: Topic :: Utilities
84
+ Description-Content-Type: text/markdown
@@ -0,0 +1,12 @@
1
+ README.md
2
+ setup.cfg
3
+ setup.py
4
+ certbot_dns_directadmin/__init__.py
5
+ certbot_dns_directadmin/directadmin.py
6
+ certbot_dns_directadmin/dns_directadmin.py
7
+ certbot_dns_directadmin.egg-info/PKG-INFO
8
+ certbot_dns_directadmin.egg-info/SOURCES.txt
9
+ certbot_dns_directadmin.egg-info/dependency_links.txt
10
+ certbot_dns_directadmin.egg-info/entry_points.txt
11
+ certbot_dns_directadmin.egg-info/requires.txt
12
+ certbot_dns_directadmin.egg-info/top_level.txt
@@ -0,0 +1,3 @@
1
+ [certbot.plugins]
2
+ directadmin = certbot_dns_directadmin.dns_directadmin:Authenticator
3
+