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.http import HttpResponse
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from main.forms import *
|
from main.forms import *
|
||||||
|
from main.models import Host
|
||||||
import dns.inet
|
import dns.inet
|
||||||
|
|
||||||
from main.dnstools import update, SameIpError
|
from main.dnstools import update, SameIpError
|
||||||
@ -23,14 +24,27 @@ def UpdateIpView(request):
|
|||||||
return HttpResponse('OK', content_type="text/plain")
|
return HttpResponse('OK', content_type="text/plain")
|
||||||
|
|
||||||
|
|
||||||
def basic_challenge(realm):
|
def basic_challenge(realm, content='Authorization Required'):
|
||||||
response = HttpResponse('Authorization Required', content_type="text/plain")
|
"""
|
||||||
|
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['WWW-Authenticate'] = 'Basic realm="%s"' % (realm, )
|
||||||
response.status_code = 401
|
response.status_code = 401
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
def basic_authenticate(auth):
|
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)
|
authmeth, auth = auth.split(' ', 1)
|
||||||
if authmeth.lower() != 'basic':
|
if authmeth.lower() != 'basic':
|
||||||
return
|
return
|
||||||
@ -40,7 +54,17 @@ def basic_authenticate(auth):
|
|||||||
|
|
||||||
|
|
||||||
def check_auth(username, password):
|
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):
|
def Response(content):
|
||||||
@ -48,15 +72,33 @@ def Response(content):
|
|||||||
|
|
||||||
|
|
||||||
def NicUpdateView(request):
|
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')
|
hostname = request.GET.get('hostname')
|
||||||
auth = request.META.get('HTTP_AUTHORIZATION')
|
auth = request.META.get('HTTP_AUTHORIZATION')
|
||||||
if auth is None:
|
if auth is None:
|
||||||
logger.warning('%s - received no auth' % (hostname, ))
|
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)
|
username, password = basic_authenticate(auth)
|
||||||
if not check_auth(username, password):
|
if not check_auth(username, password):
|
||||||
logger.info('%s - received bad credentials, username: %s' % (hostname, username, ))
|
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:
|
if hostname is None:
|
||||||
# as we use update_username == hostname, we can fall back to that:
|
# as we use update_username == hostname, we can fall back to that:
|
||||||
hostname = username
|
hostname = username
|
||||||
|
Loading…
x
Reference in New Issue
Block a user