From add5e6a3798c2f10ab5e99c45255f022b5f4dd32 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Sat, 28 Sep 2013 20:35:30 +0200 Subject: [PATCH] implemented update api (still without checking the DB), misc. cleanups --- nsupdate/api/views.py | 54 ++++++++++++++++++++++++++++++++++- nsupdate/main/dnstools.py | 4 +-- nsupdate/main/urls.py | 3 +- nsupdate/nsupdate/settings.py | 6 ++-- 4 files changed, 61 insertions(+), 6 deletions(-) diff --git a/nsupdate/api/views.py b/nsupdate/api/views.py index f69abd2..d3d94f2 100644 --- a/nsupdate/api/views.py +++ b/nsupdate/api/views.py @@ -4,9 +4,13 @@ from django.conf import settings from main.forms import * import dns.inet +from main.dnstools import update, SameIpError + + def MyIpView(request): return HttpResponse(request.META['REMOTE_ADDR'], content_type="text/plain") + def UpdateIpView(request): ipaddr = request.META['REMOTE_ADDR'] af = dns.inet.af_for_address(ipaddr) @@ -14,4 +18,52 @@ def UpdateIpView(request): request.session['ipv4'] = ipaddr else: request.session['ipv6'] = ipaddr - return HttpResponse('OK', content_type="text/plain") \ No newline at end of file + return HttpResponse('OK', content_type="text/plain") + + +def basic_challenge(realm): + response = HttpResponse('Authorization Required', content_type="text/plain") + response['WWW-Authenticate'] = 'Basic realm="%s"' % (realm, ) + response.status_code = 401 + return response + + +def basic_authenticate(auth): + authmeth, auth = auth.split(' ', 1) + if authmeth.lower() != 'basic': + return + auth = auth.strip().decode('base64') + username, password = auth.split(':', 1) + return username, password + + +def check_auth(username, password): + return password == 'pass' # FIXME + + +def Response(content, logmsg=None): + return HttpResponse(content, content_type='text/plain') + + +def NicUpdateView(request): + agent = request.META.get('HTTP_USER_AGENT') + if agent in settings.BAD_AGENTS: + return Response('badagent') + auth = request.META.get('HTTP_AUTHORIZATION') + if auth is None: + return basic_challenge("authenticate to update DNS") + username, password = basic_authenticate(auth) + if not check_auth(username, password): + return Response('badauth') + # as we use update_username == hostname, we can fall back to that: + hostname = request.GET.get('hostname', username) + # XXX when do we return Response('badhost') ? + ipaddr = request.GET.get('myip') + if ipaddr is None: + ipaddr = request.META.get('REMOTE_ADDR') + ipaddr = str(ipaddr) # XXX bug in dnspython: crashes if ipaddr is unicode, wants a str! + try: + update(hostname, ipaddr) + return Response('good %s' % ipaddr) + except SameIpError: + return Response('nochg %s' % ipaddr) diff --git a/nsupdate/main/dnstools.py b/nsupdate/main/dnstools.py index 9a84a78..78ff67e 100644 --- a/nsupdate/main/dnstools.py +++ b/nsupdate/main/dnstools.py @@ -13,7 +13,7 @@ import dns.tsig import dns.tsigkeyring -SERVER = settings.SERVER # ns1.thinkmo.de (master / dynamic upd server for nsupdate.info) +SERVER = settings.SERVER BASEDOMAIN = settings.BASEDOMAIN NONEXISTING_HOST = settings.NONEXISTING_HOST @@ -23,7 +23,7 @@ WWW_IPV6_HOST = settings.WWW_IPV6_HOST WWW_IPV4_IP = settings.WWW_IPV4_IP WWW_IPV6_IP = settings.WWW_IPV6_IP -UPDATE_ALGO = dns.tsig.HMAC_SHA512 +UPDATE_ALGO = settings.UPDATE_ALGO UPDATE_KEY = settings.UPDATE_KEY diff --git a/nsupdate/main/urls.py b/nsupdate/main/urls.py index a56707f..284bf9d 100644 --- a/nsupdate/main/urls.py +++ b/nsupdate/main/urls.py @@ -3,7 +3,7 @@ from main.views import ( HomeView, OverviewView ) from api.views import ( - MyIpView, UpdateIpView + MyIpView, UpdateIpView, NicUpdateView ) urlpatterns = patterns('', @@ -11,4 +11,5 @@ urlpatterns = patterns('', url(r'^overview/', OverviewView.as_view(), name="overview"), url(r'^myip$', MyIpView), url(r'^updateip$', UpdateIpView), + url(r'^nic/update$', NicUpdateView), ) diff --git a/nsupdate/nsupdate/settings.py b/nsupdate/nsupdate/settings.py index f83499a..cf7382b 100644 --- a/nsupdate/nsupdate/settings.py +++ b/nsupdate/nsupdate/settings.py @@ -1,5 +1,6 @@ # Django settings for nsupdate project. import django.conf.global_settings as DEFAULT_SETTINGS +import dns.tsig DEBUG = True TEMPLATE_DEBUG = DEBUG @@ -32,8 +33,9 @@ WWW_IPV6_HOST = 'www.ipv6.' + BASEDOMAIN WWW_IPV4_IP = '178.32.221.14' WWW_IPV6_IP = '2001:41d0:8:e00e::1' -#not implemented here. not sure waht to do with it -#UPDATE_ALGO = dns.tsig.HMAC_SHA512 +BAD_AGENTS = set() # useragent blacklist for /nic/update service + +UPDATE_ALGO = dns.tsig.HMAC_SHA512 UPDATE_KEY = 'YWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYQ==' # Hosts/domain names that are valid for this site; required if DEBUG is False