#!/usr/bin/python
"""Dynamic DNS script. Expects URLs from routers in the form
-http://dyndns.colgarra.priv.at/nic/update?username=<username>&password=<pass>&hostname=<domain>&myip=<ipaddr>
+http://dyndns.colgarra.priv.at/nic/update?hostname=<domain>&myip=<ipaddr>
"""
import os
import re
import cgi
-import pwd
-import base64
from subprocess import call
import ipaddr
# Configuration
-PASSWORD = 'hygCithOrs5'
DEBUG = False
class DynDnsError(Exception):
pass
-class AuthError(DynDnsError):
- returncode = 'badauth'
-
-class CredentialsMissing(AuthError):
- pass
-
-class UsernameMissing(AuthError):
- pass
-
-class UsernameInvalid(AuthError):
- pass
-
-class PasswordMissing(AuthError):
- pass
-
-class PasswordWrong(AuthError):
- pass
-
-class AuthWrongMethod(AuthError):
- returncode = 'wrongauthmethod' # not documented at dyn.com
-
-class AuthBasicError(AuthError):
- returncode = 'authbasicerror' # not documented at dyn.com
-
class HostnameError(DynDnsError):
returncode = 'notfqdn'
# the following fields are supported by most dyndns providers
# if a parameter is not provided, the .getvalue method returns None
-username = fields.getvalue('username')
-password = fields.getvalue('password')
hostname = fields.getvalue('hostname')
myip = fields.getvalue('myip')
wildcard = fields.getvalue('wildcard')
try:
- # Optional Auth Basic
- auth = os.environ.get('HTTP_AUTHORIZATION') # auth == 'Basic cGhpbGlwcDpka2ZhamRrZg=='
- if auth: # empty string if HTTP_AUTHORIZATION not present
- auth_parts = auth.split(' ')
- auth_method = 'Basic'
- if len(auth_parts) != 2 or auth_parts[0] != auth_method:
- raise AuthWrongMethod()
- try:
- auth_decoded = base64.b64decode(auth_parts[1]) # auth_decoded == 'philipp:dkfajdkf'
- except TypeError:
- raise AuthBasicError()
- auth_decoded_parts = auth_decoded.split(':')
- if len(auth_decoded_parts) != 2:
- raise AuthBasicError()
- username, password = auth_decoded_parts
-
- # check username and password
- if username is None and password is None:
- raise CredentialsMissing()
-
- # check username
- if username is None:
- raise UsernameMissing()
- try:
- user_info = pwd.getpwnam(username)
- except KeyError:
- raise UsernameInvalid()
- if user_info.pw_uid < 1000:
- raise UsernameInvalid()
-
- # check password
- if password is None:
- raise PasswordMissing()
- if password != PASSWORD:
- raise PasswordWrong()
-
# check hostname
if hostname is None:
raise HostnameMissing()
# Note: we should return 'nochg' in case the IP has not changed, however we don't know yet.
-except CredentialsMissing as error:
- print "Content-Type: text/html"
- print "Status: 401 Unauthorized"
- print "WWW-Authenticate: Basic realm='tdyndns'"
- print
-
except DynDnsError as error:
print "Content-Type: text/html"
print "Status: 200 OK"