Added system and url parameters.
[toast/tdyndns.git] / cgi-bin / dyndns.py
1 #!/usr/bin/python2.7
2 """Dynamic DNS script. Expects URLs from routers in the form
3 https://info.colgarra.priv.at/dyndns/dyndns.py?username=<username>&password=<pass>&hostname=<domain>&myip=<ipaddr>
4 """
5
6 import re
7 import cgi
8 import pwd
9 from subprocess import call
10 import ipaddr
11
12
13 # Configuration
14 PASSWORD = 'hygCithOrs5'
15 ZONE = '.dyn.colgarra.priv.at'
16 DEBUG = False
17
18
19 # Just for debugging:
20 if DEBUG:
21         import cgitb
22         cgitb.enable()
23
24
25 fields = cgi.FieldStorage()
26
27 # the following fields are supported by most dyndns providers
28 # if a parameter is not provided, the .getvalue method returns None
29 username = fields.getvalue('username')
30 password = fields.getvalue('password')
31 hostname = fields.getvalue('hostname')
32 myip     = fields.getvalue('myip')
33 wildcard = fields.getvalue('wildcard')
34 mx       = fields.getvalue('mx')
35 backmx   = fields.getvalue('backmx')
36 offline  = fields.getvalue('offline')
37 system   = fields.getvalue('system')
38 url      = fields.getvalue('url')
39
40
41 try:
42         # check username
43         user_info = pwd.getpwnam(username) # returns a key error if the user does not exist
44         if user_info.pw_uid < 1000:
45                 raise RuntimeError('Invalid user name')
46
47         # check password
48         if password != PASSWORD:
49                 raise RuntimeError('Invalid password')
50
51         # check hostname
52         if re.match(r'[-0-9a-z]+(\.[-0-9a-z]+)*$', hostname) is None:
53                 raise RuntimeError('Invalid host name')
54
55         # strip zone
56         hostname = hostname.strip()
57         if hostname.endswith(ZONE):
58                 hostname = hostname[:-len(ZONE)]
59
60         # check IP address
61         ip = ipaddr.IPAddress(myip) # throws axception if the IP address is not valid
62         if isinstance(ip, ipaddr.IPv4Address):
63                 type = 'A'
64         elif isinstance(ip, ipaddr.IPv6Address):
65                 type = 'AAAA'
66         else:
67                 raise RuntimeError('Unknown IP address type')
68
69         # access granted
70         print "Content-Type: text/html"
71         print
72         call(['sudo', '/usr/local/bin/nsupdate_dyndns', hostname, myip, type])
73         print "OK"
74
75
76 except:
77         # access denied
78         print "Content-Type: text/html"
79         print "Status: 403 Forbidden"
80         print
81         print "Denied"
82