Python Training: DynDNS auto-login
It's been a while, I know. For one reason or another I haven't been getting round to updating the blog lately. Worst thing is I do have a bunch of stuff to post, so I hope to keep it coming in the near future. Anyway, I've been trying to polish my python skills a little bit, because I have to admit, it has to be one of the sweetest scripting languages out there: tons of support, and libraries, really doesn't have a steep learning curve at all, object oriented (if you wish).... there's really nothing much I can say in the negative aspect.
For this second lil' script I figured we could do something helpful once again. Many of you might host a little web server at home, or like ssh access to your machine, but keep forgetting you static ip, or even worst, get a dynamic ip from you ISP. I use DynDNS to help me get around these small IP troubles. And as helpful as it is, it also comes with one fairly annoying string attached, when you get yourself the free account, you need to login once a month to avoid your name address from expiring. I just want a name for my IP, and I tend to keep forgetting to do these things. So every month or so, two if I was lucky, I'd find my name address gone. Python script to the rescue. You can add this script to your crontab, and it will login automatically for you with the username and password provided to the script. Not rocket science, but definitely helpful.
The most relevant stuff here is the use of urllib and urllib2, which allow us to encode parameters for an HTTP POST request, and perform the actual page requests. The whole login process also uses a cookie, which made us have to use the cookielib to set up a cookiejar. Before you login, you are given a cookie, which you need to store for the process to succeed. Once you have that sorted, you can submit that form together with the right parameters (including a hidden one you need to parse from the HTML output). I figured out my explanation isn't too clarifying, so without further ado, here's the script:
#!/usr/bin/python
import urllib
import urllib2
import cookielib
import getopt
import sys
def getRandHTMLResponse(response):
target = "<form id=\'login"
targetresponse = "<div id=\'loginbox\'"
response = response[response.find(targetresponse):len(response)]
return response[response.find(target)+len(target):response.find(target)+len(target):response.find(target)+len(target)+4]
def getHiddenRandHTMLResponse(response):
target = "<input type=\'hidden\' name=\'multiform\' value=\'"
targetresponse = "<div id=\'loginbox\'"
parsedres = response[response.find(targetresponse):len(response)]
return parsedres[parsedres.find(target)+len(target):parsedres.find(target)+len(target)+34]
def checkLogin(response):
target = "<title>DynDNS.com - My Account</title>"
if response.find(target) == -1:
return False
return True
class HTMLSession:
cj = None
opener = None
txHeaders = None
def __init__(self, txHeaders):
#The CookieJar will hold any cookies necessary throughout the login process.
self.cj = cookielib.MozillaCookieJar()
self.txHeaders = txHeaders
self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(self.cj))
urllib2.install_opener(self.opener)
def setHeaders(self, txheaders):
self.txHeaders = txHeaders
def getHeaders(self):
return self.txHeaders
def openURI(self, uri, txdata):
try:
req = urllib2.Request(uri, txdata, self.txHeaders)
# create a request object
handle = urllib2.urlopen(req)
# and open it to return a handle on the url
except IOError as e:
print \'we failed to open "%s".\' % uri
if hasattr(e, \'code\'):
print \'We failed with error code - %s.\' % e.code
elif hasattr(e, \'reason\'):
print "The error object has the following \'reason\' attribute :"
print e.reason
print "This usually means the server doesn\'t exist,\'"
print "is down, or we don\'t have an internet connection."
return None
return handle.read()
def main(argv):
username = ""
password = ""
hiddenval = ""
theurl = "https://www.dyndns.com/account/entrance/"
thelogouturl = "https://www.dyndns.com/account/entrance/?__logout=1"
txdata = None
txheaders = {\'User-agent\' : \'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)\'}
# fake a user agent, some websites (like google) don\'t like automated exploration
try:
opts, args = getopt.getopt(argv, "hu:p:", ["help", "username=","password="])
except getopt.GetoptError:
usage()
exit(2)
for opt, arg in opts:
if opt in ("-h", "--help"):
usage()
exit(2)
elif opt in ("-u", "--username"):
username = arg
elif opt in ("-p", "--password"):
password = arg
myhtmlsession = HTMLSession(txheaders)
response = myhtmlsession.openURI(theurl, None)
if response == None:
sys.exit(0)
hiddenval = getHiddenRandHTMLResponse(response)
txdata = urllib.urlencode({\'username\':username, \'password\':password, \'multiform\':hiddenval, \'submit\': "Log in"})
response = myhtmlsession.openURI(theurl, txdata)
if response == None:
sys.exit(0)
#we should sleep here for about 10 seconds.
if checkLogin(response):
print(\'We have succesfully logged into DynDNS.\')
response = myhtmlsession.openURI(thelogouturl, None)
if response == None:
sys.exit(0)
if __name__ == "__main__":
main(sys.argv[1:])