url = fields.getvalue('url')
+# Base class for our exceptions
+class DynDnsError(Exception):
+ pass
+
+class AuthError(DynDnsError):
+ returncode = 'badauth'
+
+class UsernameMissing(AuthError):
+ pass
+
+class UsernameInvalid(AuthError):
+ pass
+
+class PasswordMissing(AuthError):
+ pass
+
+class PasswordWrong(AuthError):
+ pass
+
+class HostnameError(DynDnsError):
+ returncode = 'notfqdn'
+
+class HostnameMissing(HostnameError):
+ pass
+
+class PasswordWrong(HostnameError):
+ pass
+
+class IpError(DynDnsError):
+ returncode = 'badip' # not documented at dyn.com
+
+class IpMissing(IpError):
+ pass
+
+class IpInvalid(IpError):
+ pass
+
try:
# check username
- user_info = pwd.getpwnam(username) # returns a key error if the user does not exist
+ if username is None:
+ raise UsernameMissing()
+ try:
+ user_info = pwd.getpwnam(username)
+ except KeyError:
+ raise UsernameInvalid()
if user_info.pw_uid < 1000:
- raise RuntimeError('Invalid user name')
+ raise UsernameInvalid()
# check password
+ if password is None:
+ raise PasswordMissing()
if password != PASSWORD:
- raise RuntimeError('Invalid password')
+ raise PasswordWrong()
# check hostname
+ if hostname is None:
+ raise HostnameMissing()
if re.match(r'[-0-9a-z]+(\.[-0-9a-z]+)*$', hostname) is None:
- raise RuntimeError('Invalid host name')
+ raise HostnameInvalid()
# strip zone
hostname = hostname.strip()
hostname = hostname[:-len(ZONE)]
# check IP address
- ip = ipaddr.IPAddress(myip) # throws axception if the IP address is not valid
+ if myip is None:
+ raise IpMissing()
+ try:
+ ip = ipaddr.IPAddress(myip) # throws an exception if the IP address is not valid
+ except ValueError:
+ raise IpInvalid()
if isinstance(ip, ipaddr.IPv4Address):
- type = 'A'
+ iptype = 'A'
elif isinstance(ip, ipaddr.IPv6Address):
- type = 'AAAA'
+ iptype = 'AAAA'
else:
- raise RuntimeError('Unknown IP address type')
+ raise IpInvalid() # should never happen
# access granted
print "Content-Type: text/html"
print
- call(['sudo', '/usr/local/bin/nsupdate_dyndns', hostname, myip, type])
- print "OK"
+ call(['sudo', '/usr/local/bin/nsupdate_dyndns', hostname, myip, iptype])
+ print "good"
+ # Note: we should return 'nochg' in case the IP has not changed, however we don't know yet.
-except:
- # access denied
+except DynDnsError as error:
print "Content-Type: text/html"
- print "Status: 403 Forbidden"
+ print "Status: 200"
print
- print "Denied"
+ print error.returncode