verify username (fqdn) and password (update secret) against the database, improve docstrings
This commit is contained in:
parent
a92e691161
commit
ec3869c9d0
@ -6,6 +6,7 @@ logger = logging.getLogger(__name__)
|
||||
from django.http import HttpResponse
|
||||
from django.conf import settings
|
||||
from main.forms import *
|
||||
from main.models import Host
|
||||
import dns.inet
|
||||
|
||||
from main.dnstools import update, SameIpError
|
||||
@ -23,14 +24,27 @@ def UpdateIpView(request):
|
||||
return HttpResponse('OK', content_type="text/plain")
|
||||
|
||||
|
||||
def basic_challenge(realm):
|
||||
response = HttpResponse('Authorization Required', content_type="text/plain")
|
||||
def basic_challenge(realm, content='Authorization Required'):
|
||||
"""
|
||||
Construct a 401 response requesting http basic auth.
|
||||
|
||||
:param realm: realm string (displayed by the browser)
|
||||
:param content: request body content
|
||||
:return: HttpResponse object
|
||||
"""
|
||||
response = HttpResponse(content, content_type="text/plain")
|
||||
response['WWW-Authenticate'] = 'Basic realm="%s"' % (realm, )
|
||||
response.status_code = 401
|
||||
return response
|
||||
|
||||
|
||||
def basic_authenticate(auth):
|
||||
"""
|
||||
Get username and password from http basic auth string.
|
||||
|
||||
:param auth: http basic auth string
|
||||
:return: username, password
|
||||
"""
|
||||
authmeth, auth = auth.split(' ', 1)
|
||||
if authmeth.lower() != 'basic':
|
||||
return
|
||||
@ -40,7 +54,17 @@ def basic_authenticate(auth):
|
||||
|
||||
|
||||
def check_auth(username, password):
|
||||
return password == 'pass' # FIXME
|
||||
"""
|
||||
Check username and password against our database.
|
||||
|
||||
:param username: http basic auth username (== fqdn)
|
||||
:param password: update password
|
||||
:return: True if authenticated, False otherwise.
|
||||
"""
|
||||
# in our case username == fqdn
|
||||
hosts = Host.objects.filter(fqdn=username, update_secret=password)
|
||||
assert len(hosts) < 2
|
||||
return bool(hosts)
|
||||
|
||||
|
||||
def Response(content):
|
||||
@ -48,15 +72,33 @@ def Response(content):
|
||||
|
||||
|
||||
def NicUpdateView(request):
|
||||
"""
|
||||
dyndns2 compatible /nic/update API.
|
||||
|
||||
Example URLs:
|
||||
|
||||
Will request username (fqdn) and password (secret) from user,
|
||||
for interactive testing / updating:
|
||||
https://nsupdate.info/nic/update
|
||||
|
||||
You can put it also into the url, so the browser will automatically
|
||||
send the http basic auth with the request:
|
||||
https://fqdn:secret@nsupdate.info/nic/update
|
||||
|
||||
If the request does not come from the correct IP, you can give it as
|
||||
a query parameter, you can also give the hostname (then it won't use
|
||||
the username from http basic auth as the fqdn:
|
||||
https://fqdn:secret@nsupdate.info/nic/update?hostname=fqdn&myip=1.2.3.4
|
||||
"""
|
||||
hostname = request.GET.get('hostname')
|
||||
auth = request.META.get('HTTP_AUTHORIZATION')
|
||||
if auth is None:
|
||||
logger.warning('%s - received no auth' % (hostname, ))
|
||||
return basic_challenge("authenticate to update DNS")
|
||||
return basic_challenge("authenticate to update DNS", 'noauth')
|
||||
username, password = basic_authenticate(auth)
|
||||
if not check_auth(username, password):
|
||||
logger.info('%s - received bad credentials, username: %s' % (hostname, username, ))
|
||||
return Response('badauth')
|
||||
return basic_challenge("authenticate to update DNS", 'badauth')
|
||||
if hostname is None:
|
||||
# as we use update_username == hostname, we can fall back to that:
|
||||
hostname = username
|
||||
|
Loading…
x
Reference in New Issue
Block a user