Apart from the obvious fields we need to send back (username, password...), you can see by the highlighted sections there are 2 hidden fields. Thankfully the first one (iov1) is not necessary for a login - this field is rather complexly generated by javascript and does not render except in a browser. This means we are only interested in the "multiform" hidden field which we need to send back in our request.
That sorts out the fields we need to populate: username, password, submit and multiform. What about cookies? Yes there are cookies but that is easily captured in the header request message (set-cookie) and we can simply attach the same cookie back into our response header unmodified.
I have since setup a cron job on Google App Engine that runs my code once every month. This should help alleviate the headache of logging in manually every month. Here is the code if anyone wants to use it:
URL url = new URL("https://account.dyn.com/entrance/"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); //Spoof as if from a web browser con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31"); con.setDoOutput(true); con.connect(); // give it 15 seconds to respond con.setReadTimeout(15 * 1000); //Get cookie id String headerName = null; String cookie = null; for(int i = 1; (headerName = con.getHeaderFieldKey(i)) != null; i++) { if (headerName.equalsIgnoreCase("Set-Cookie")) { cookie = con.getHeaderField(i); break; } } //Read the website into a string so we can parse with Jsoup BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream())); String temp = ""; String line = null; while((line = reader.readLine()) != null) { temp += line + "\r\n"; } reader.close(); Document doc = Jsoup.parse(temp); Elements els = doc.getElementsByTag("input"); String multiform = null; for(Element e : els) { String name = e.attr("name"); String value = e.attr("value"); //Get the hidden field required for login if(name.equalsIgnoreCase("multiform")) { multiform = value; break; } } //Open the connection again with the correct headers con = (HttpURLConnection) url.openConnection(); con.setRequestProperty("Cookie", cookie); con.setRequestProperty("Host", "account.dyn.com"); con.setRequestProperty("Origin", "https://account.dyn.com"); con.setRequestProperty("Referer", "https://account.dyn.com/entrance/"); con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31"); con.setRequestMethod("POST"); con.setDoOutput(true); String username = "your_username_here"; String password = "your_password_here"; //Set the login fields OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream()); String data = URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode(username, "UTF-8"); data += "&" + URLEncoder.encode("password", "UTF-8") + "=" + URLEncoder.encode(password, "UTF-8"); data += "&" + URLEncoder.encode("submit", "UTF-8") + "=" + URLEncoder.encode("Log in", "UTF-8"); data += "&" + URLEncoder.encode("multiform", "UTF-8") + "=" + URLEncoder.encode(multiform, "UTF-8"); out.write(data); out.flush(); out.close(); //Read the response message reader = new BufferedReader(new InputStreamReader(con.getInputStream())); boolean success = false; while((line = reader.readLine()) != null) { //If the title says we are logged in everything worked if(line.contains("My Dyn Account ")) { success = true; break; } } if(success) { System.out.println("Succesfully logged in!"); } else { System.out.println("Login failed!"); } reader.close();
Looks like a great solution! I am not much of a coder, but would love to implement something like this. Do you have thoughts on how I could run that as a local CRON job?
ReplyDeleteThanks for the comment. Are you referring to a local cron job in a unix OS? If so I am not too familiar with setting that up. However to be able to invoke this Java code locally would require a JVM which your computer should have and possibly adding the code to a self-executing JAR file, which you then invoke periodically.
DeleteHi, many thanks for your solution. To run it on a local machine you must compile it as a regular java file, with class headers and footers, import declarations, and have a correct classpath with jsoup.
DeleteHere are some instructions to adapt your script to run it on a local machine : http://www.lprp.fr/wiki/doku.php/dyndns_autologin
Remi,
DeleteException in thread "main" java.lang.UnsupportedClassVersionError: DynDnsAutoLogin : Unsupported major.minor version 51.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:321)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
Could not find the main class: DynDnsAutoLogin. Program will exit.
Hi David, please check your java environnement, and that your jdk and jre have the same version number (javac -version and java -version)
DeleteCheers Remi, I would assume some knowledge of Java for those that would want to use it. I simply use Eclipse to compile and load the correct imports for me.
DeleteHi Remi
DeleteIs that website on vacation for Bastille Day?? - it doesn't respond
or
Is it only available at certain times of the day, it responds to ping and tracert finds it ok but it won't open
This comment has been removed by the author.
ReplyDeleteHi.
ReplyDeleteThis looks very good indeed. However I have no clue about java, and have been trying to get it to do something. But so far no luck.
Would it not be possible to just make a compiled file where you can pass username and password as arguments?
Many more would be able to use the script then I believe.
Have a look at Rémi Peyronnet posts above who has made a working example of the above script. You can visit his link to see how to run it step by step.
DeleteCreated a new spreadsheet in Drive,
ReplyDeleteAdded a new blank script with a simple function skeleton.
Pasted your code with my username/password, but I keep getting a syntax error on the very first line of code after the function. If I comment that line out... same syntax error appears on the very next line... any ideas? The file is called "code.gs"
Missing ; before statement. (line 2, file "Code")Dismiss
Nevermind... I managed with the standalone solution running as a cron job on my web host.
ReplyDeleteThanks anyways
Hi. I created a Python version with gmail(smtp) notify on failed login attempt: https://github.com/evrenesat/logindyn/
ReplyDelete