From 68843d9664b5dcc11fab5cb2a30a6a5cb00153fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Tr=C3=B6ger?= Date: Sat, 25 Jan 2020 19:44:11 +0100 Subject: [PATCH] Add new setting to verify outgoing SSL connections The new setting 'verify_ssl_connections' tells the requests library to verify secured outgoing HTTP connections. Usually verifying is desired and helps to reveal configuration problems. It also disables an ugly warning when HTTPS connections are made without verification. --- powerdnsadmin/lib/utils.py | 9 ++++++--- powerdnsadmin/models/domain.py | 31 +++++++++++++++++++++++-------- powerdnsadmin/models/record.py | 11 +++++++++-- powerdnsadmin/models/server.py | 9 ++++++--- powerdnsadmin/models/setting.py | 1 + powerdnsadmin/routes/admin.py | 2 +- powerdnsadmin/routes/api.py | 6 ++++-- 7 files changed, 50 insertions(+), 19 deletions(-) diff --git a/powerdnsadmin/lib/utils.py b/powerdnsadmin/lib/utils.py index b6e398f..27812ad 100644 --- a/powerdnsadmin/lib/utils.py +++ b/powerdnsadmin/lib/utils.py @@ -24,11 +24,12 @@ def fetch_remote(remote_url, accept=None, params=None, timeout=None, - headers=None): + headers=None, + verify=True): if data is not None and type(data) != str: data = json.dumps(data) - verify = False + verify = bool(verify) # enforce type boolean our_headers = { 'user-agent': 'powerdnsadmin/0', @@ -64,13 +65,15 @@ def fetch_json(remote_url, data=None, params=None, headers=None, - timeout=None): + timeout=None, + verify=True): r = fetch_remote(remote_url, method=method, data=data, params=params, headers=headers, timeout=timeout, + verify=verify, accept='application/json; q=1') if method == "DELETE": diff --git a/powerdnsadmin/models/domain.py b/powerdnsadmin/models/domain.py index 53a122a..8a60406 100644 --- a/powerdnsadmin/models/domain.py +++ b/powerdnsadmin/models/domain.py @@ -81,7 +81,8 @@ class Domain(db.Model): '/servers/localhost/zones/{0}'.format(domain_name)), headers=headers, timeout=int( - Setting().get('pdns_api_timeout'))) + Setting().get('pdns_api_timeout')), + verify=Setting().get('verify_ssl_connections')) return jdata def get_domains(self): @@ -94,7 +95,8 @@ class Domain(db.Model): urljoin(self.PDNS_STATS_URL, self.API_EXTENDED_URL + '/servers/localhost/zones'), headers=headers, - timeout=int(Setting().get('pdns_api_timeout'))) + timeout=int(Setting().get('pdns_api_timeout')), + verify=Setting().get('verify_ssl_connections')) return jdata def get_id_by_name(self, name): @@ -125,7 +127,8 @@ class Domain(db.Model): urljoin(self.PDNS_STATS_URL, self.API_EXTENDED_URL + '/servers/localhost/zones'), headers=headers, - timeout=int(Setting().get('pdns_api_timeout'))) + timeout=int(Setting().get('pdns_api_timeout')), + verify=Setting().get('verify_ssl_connections')) list_jdomain = [d['name'].rstrip('.') for d in jdata] current_app.logger.info( "Found {} entrys in PowerDNS server".format(len(list_jdomain))) @@ -233,6 +236,7 @@ class Domain(db.Model): headers=headers, timeout=int(Setting().get('pdns_api_timeout')), method='POST', + verify=Setting().get('verify_ssl_connections'), data=post_data) if 'error' in jdata.keys(): current_app.logger.error(jdata['error']) @@ -265,7 +269,8 @@ class Domain(db.Model): '/servers/localhost/zones/{0}'.format( domain_dict['name'])), headers=headers, - timeout=int(Setting().get('pdns_api_timeout'))) + timeout=int(Setting().get('pdns_api_timeout')), + verify=Setting().get('verify_ssl_connections')) except Exception as e: current_app.logger.error('Can not read Domain from PDNS') current_app.logger.error(e) @@ -325,6 +330,7 @@ class Domain(db.Model): timeout=int( Setting().get('pdns_api_timeout')), method='PUT', + verify=Setting().get('verify_ssl_connections'), data=post_data) if 'error' in jdata.keys(): current_app.logger.error(jdata['error']) @@ -368,6 +374,7 @@ class Domain(db.Model): timeout=int( Setting().get('pdns_api_timeout')), method='PUT', + verify=Setting().get('verify_ssl_connections'), data=post_data) if 'error' in jdata.keys(): current_app.logger.error(jdata['error']) @@ -494,7 +501,8 @@ class Domain(db.Model): '/servers/localhost/zones/{0}'.format(domain_name)), headers=headers, timeout=int(Setting().get('pdns_api_timeout')), - method='DELETE') + method='DELETE', + verify=Setting().get('verify_ssl_connections')) current_app.logger.info( 'Deleted domain successfully from PowerDNS-Entity: {0}'.format( domain_name)) @@ -587,7 +595,8 @@ class Domain(db.Model): headers=headers, timeout=int( Setting().get('pdns_api_timeout')), - method='PUT') + method='PUT', + verify=Setting().get('verify_ssl_connections')) return {'status': 'ok', 'msg': r.get('result')} except Exception as e: current_app.logger.error( @@ -617,7 +626,8 @@ class Domain(db.Model): domain.name)), headers=headers, timeout=int(Setting().get('pdns_api_timeout')), - method='GET') + method='GET', + verify=Setting().get('verify_ssl_connections')) if 'error' in jdata: return { 'status': 'error', @@ -655,6 +665,7 @@ class Domain(db.Model): headers=headers, timeout=int(Setting().get('pdns_api_timeout')), method='PUT', + verify=Setting().get('verify_ssl_connections'), data=post_data) if 'error' in jdata: return { @@ -674,6 +685,7 @@ class Domain(db.Model): headers=headers, timeout=int(Setting().get('pdns_api_timeout')), method='POST', + verify=Setting().get('verify_ssl_connections'), data=post_data) if 'error' in jdata: return { @@ -719,7 +731,8 @@ class Domain(db.Model): domain.name, key_id)), headers=headers, timeout=int(Setting().get('pdns_api_timeout')), - method='DELETE') + method='DELETE', + verify=Setting().get('verify_ssl_connections')) if jdata != True: return { 'status': @@ -740,6 +753,7 @@ class Domain(db.Model): headers=headers, timeout=int(Setting().get('pdns_api_timeout')), method='PUT', + verify=Setting().get('verify_ssl_connections'), data=post_data) if 'error' in jdata: return { @@ -796,6 +810,7 @@ class Domain(db.Model): timeout=int( Setting().get('pdns_api_timeout')), method='PUT', + verify=Setting().get('verify_ssl_connections'), data=post_data) if 'error' in jdata.keys(): diff --git a/powerdnsadmin/models/record.py b/powerdnsadmin/models/record.py index 97d6f28..9ff95e1 100644 --- a/powerdnsadmin/models/record.py +++ b/powerdnsadmin/models/record.py @@ -52,7 +52,8 @@ class Record(object): '/servers/localhost/zones/{0}'.format(domain)), timeout=int( Setting().get('pdns_api_timeout')), - headers=headers) + headers=headers, + verify=Setting().get('verify_ssl_connections')) except Exception as e: current_app.logger.error( "Cannot fetch domain's record data from remote powerdns api. DETAIL: {0}" @@ -96,6 +97,7 @@ class Record(object): timeout=int( Setting().get('pdns_api_timeout')), method='PATCH', + verify=Setting().get('verify_ssl_connections'), data=rrset) current_app.logger.debug(jdata) return {'status': 'ok', 'msg': 'Record was added successfully'} @@ -281,6 +283,7 @@ class Record(object): '/servers/localhost/zones/{0}'.format(domain_name)), headers=headers, method='PATCH', + verify=Setting().get('verify_ssl_connections'), data=del_rrsets) if 'error' in jdata1.keys(): current_app.logger.error( @@ -300,6 +303,7 @@ class Record(object): headers=headers, timeout=int(Setting().get('pdns_api_timeout')), method='PATCH', + verify=Setting().get('verify_ssl_connections'), data=new_rrsets) if 'error' in jdata2.keys(): current_app.logger.error( @@ -451,6 +455,7 @@ class Record(object): timeout=int( Setting().get('pdns_api_timeout')), method='PATCH', + verify=Setting().get('verify_ssl_connections'), data=data) current_app.logger.debug(jdata) return {'status': 'ok', 'msg': 'Record was removed successfully'} @@ -522,6 +527,7 @@ class Record(object): headers=headers, timeout=int(Setting().get('pdns_api_timeout')), method='PATCH', + verify=Setting().get('verify_ssl_connections'), data=data) current_app.logger.debug("dyndns data: {0}".format(data)) return {'status': 'ok', 'msg': 'Record was updated successfully'} @@ -544,7 +550,8 @@ class Record(object): headers=headers, timeout=int( Setting().get('pdns_api_timeout')), - method='GET') + method='GET', + verify=Setting().get('verify_ssl_connections')) serial = jdata['serial'] domain = Domain.query.filter(Domain.name == domain).first() diff --git a/powerdnsadmin/models/server.py b/powerdnsadmin/models/server.py index 2034168..cdcd6f0 100644 --- a/powerdnsadmin/models/server.py +++ b/powerdnsadmin/models/server.py @@ -33,7 +33,8 @@ class Server(object): '/servers/{0}/config'.format(self.server_id)), headers=headers, timeout=int(Setting().get('pdns_api_timeout')), - method='GET') + method='GET', + verify=Setting().get('verify_ssl_connections')) return jdata except Exception as e: current_app.logger.error( @@ -54,7 +55,8 @@ class Server(object): '/servers/{0}/statistics'.format(self.server_id)), headers=headers, timeout=int(Setting().get('pdns_api_timeout')), - method='GET') + method='GET', + verify=Setting().get('verify_ssl_connections')) return jdata except Exception as e: current_app.logger.error( @@ -77,7 +79,8 @@ class Server(object): headers=headers, timeout=int( Setting().get('pdns_api_timeout')), - method='GET') + method='GET', + verify=Setting().get('verify_ssl_connections')) return jdata except Exception as e: current_app.logger.error( diff --git a/powerdnsadmin/models/setting.py b/powerdnsadmin/models/setting.py index fba9a26..08ba2c0 100644 --- a/powerdnsadmin/models/setting.py +++ b/powerdnsadmin/models/setting.py @@ -32,6 +32,7 @@ class Setting(db.Model): 'pdns_api_key': '', 'pdns_api_timeout': 30, 'pdns_version': '4.1.1', + 'verify_ssl_connections': True, 'local_db_enabled': True, 'signup_enabled': True, 'verify_user_email': False, diff --git a/powerdnsadmin/routes/admin.py b/powerdnsadmin/routes/admin.py index d892a29..5c6f6fe 100644 --- a/powerdnsadmin/routes/admin.py +++ b/powerdnsadmin/routes/admin.py @@ -501,7 +501,7 @@ def setting_basic(): 'pretty_ipv6_ptr', 'dnssec_admins_only', 'allow_user_create_domain', 'bg_domain_updates', 'site_name', 'session_timeout', 'warn_session_timeout', 'ttl_options', - 'pdns_api_timeout', 'verify_user_email' + 'pdns_api_timeout', 'verify_ssl_connections', 'verify_user_email' ] return render_template('admin_setting_basic.html', settings=settings) diff --git a/powerdnsadmin/routes/api.py b/powerdnsadmin/routes/api.py index 81ac886..39534f9 100644 --- a/powerdnsadmin/routes/api.py +++ b/powerdnsadmin/routes/api.py @@ -144,7 +144,8 @@ def api_login_create_zone(): method='POST', data=request.get_json(force=True), headers=headers, - accept='application/json; q=1') + accept='application/json; q=1', + verify=Setting().get('verify_ssl_connections')) except Exception as e: current_app.logger.error("Cannot create domain. Error: {}".format(e)) abort(500) @@ -219,7 +220,8 @@ def api_login_delete_zone(domain_name): resp = utils.fetch_remote(urljoin(pdns_api_url, api_full_uri), method='DELETE', headers=headers, - accept='application/json; q=1') + accept='application/json; q=1', + verify=Setting().get('verify_ssl_connections')) if resp.status_code == 204: current_app.logger.debug("Request to powerdns API successful")