|
 |
|
 |
» Logging into a Password Protected Site by technobard |
|
(Login to remove green text ads)
Java has a rich network api that makes it possible to connect to URLs and
retrieve information and/or submit information without requiring user
intervention. Occasionally a site requires a username and password.
Providing that information programmatically is the purpose of this article.
For demonstrative purposes, we'll take a look at a program for updating a
dynamic DNS service (www.zonedit.com). The author uses a slightly modified
version of the original program as an aid in running a website from his DSL
connection. Within 10 minutes of the IP address changing, the new address is
used to update an account at Zonedit.
THE PARTS:
==========
1. One of the big guns in java's networking arsenal is the Authenticator
class. Everything else, at least for the purposes of this article, is just
window dressing. The Authenticator class contains a
getPasswordAuthentication method that automatically returns a username and
password when a password-protected site is encountered. This method is
implemented by the developer when creating his own class.
2. Another important component is the getIP method. getIP is a custom method
that gets the IP address assigned by the ISP.
3. A third component is the updateDNS method. Just as it sounds, this method
is used to update the dynamic DNS service with the changed IP address.
The latter two methods are part of the RouterIP2 program example and not part
of the Authenticator class.
There are a few other helper methods in the program. Most will be left to the
reader to explore on his or her own.
THE PROGRAM LOGIC:
==================
The first thing we do in our class (RouterIP2) is to declare variable myAuth
as type MyAuthenticator. myAuthenticator is a class that extends
Authenticator. We'll take a look at MyAuthenticator in a minute. For now,
take a look at the RouterIP2 constructor. A new instance of MyAuthenticator
is created using a username and password as parameters. Next, myAuth is made
the default Authenticator for the program which basically means that whenever
you connect to a URL that requires authentication, myAuth will be used
automatically.
Code:
import java.net.*;
import java.io.*;
public class RouterIP2 {
MyAuthenticator myAuth;
/** Creates new RouterIP2 */
public RouterIP2() {
myAuth = new MyAuthenticator("admin","password");
Authenticator.setDefault (myAuth); //set Authenticator for popup
login
}
The above code represents the most important part of using the Authenticator.
Any program you write will need to do something similar. Now let's take a
look at the MyAuthenticator class definition.
Code:
class MyAuthenticator extends Authenticator {
String uname;
String pass;
public MyAuthenticator(String uname, String pass) {
super();
this.uname = uname;
this.pass = pass;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
protected PasswordAuthentication getPasswordAuthentication() {
String user = getUname();
String pw = getPass();
return (new PasswordAuthentication (user, pw.toCharArray()));
}
}
There really isn't much to it. The getXXX and setXXX methods were added for
flexibility. For example, if your program connects to multiple sites
requiring authentication, the same myAuth can be used simply by changing the
username and password before connecting to the new URL. Likewise, the
constructor takes a username and password. Note: super() is used to call the
constructor of the base class (i.e. Authenticator).
The getPasswordAuthentication method is the only required method. The only
thing to note here is that the password (pw) has to be submitted as a
character array.
If your only interest is the Authenticator, your journey has ended. The
remaining portion of this article refers to the specifics of getting your IP
address (using http://www.whatismyip.com ), storing the information, and
finally updating your DNS record to reflect changes.
THE getIP METHOD:
=================
In the original version of this program, I connect to the status page of my
router and extract the IP address by parsing the contents of the HTML page.
The parsing mechanism depends strongly on the format of the page which will
likely vary from one router manufacturer to another. As a more universal
version, I use the www.whatismyip.com website. The danger, of course, is that
the site may go offline at some point leaving you high and dry.
Okay. Enough philosophizing. Let's look at some code.
Code:
public String getIP(String url) throws Exception {
URL sourceURL = new URL(url);
//Get a character input stream for the URL
BufferedReader in = new BufferedReader(new
InputStreamReader(sourceURL.openStream()));
//Read the URL and parse for Internet IP
String buffer = ""; // buffer to store lines
String ipstr = ""; // string to hold ip address
int pos = 0;
int firstpos = 0;
boolean near = false;
while (!(null == (buffer=in.readLine()))) {
// System.out.println(buffer);
if (!(near) && ((pos = buffer.indexOf("Your ip is ")) > -1)) {
//start looking for ip
near = true;
}
if (near) {
// check for three periods in current line (buffer)
if ((pos = buffer.indexOf(".")) > -1) {
firstpos = pos;
if ((pos = buffer.indexOf(".",pos)) > -1) {
if ((pos = buffer.indexOf(".",pos)) > -1) {
break; //break out of while
}
}
}
} // end of "near" if
} // end of while
buffer = buffer.substring(firstpos - 3,firstpos + 11); //get
substring covering ip address
ipstr = filter(buffer, "0123456789."); //filter out unwanted
characters
return ipstr;
} //end of getIP
In a nutshell, the getIP method creates a URL object called sourceURL, opens a
stream to read from it, then searches for a line containing "Your ip is ".
Once it fines this magical line, it looks for a string with three periods
(i.e. an ip address). The method then substrings for the appropriate length
and just for kicks, filters out any unwanted characters using the handy-dandy
filter method.
Note: Java purists may tsk, tsk the use of strings instead of Stringbuffer in
the code. There are certainly good reasons to do so both in terms of memory
use and performance. In reality, any program this small with only a single
user, etc., won't notice the difference.
STORING THE INFORMATION:
========================
There are a pair of methods, getOldIP and setOldIP, that use java's file i/o
to retrieve and store the IP address. The basic logic in "main" is to get the
current IP address from the router, get the old IP address from a text file,
then compare the two. When the IP addresses are different call the update
routine and set the old ip address in the text file. An exploration of how
these two methods work is left up to the reader. If you're familiar with file
i/o, there is nothing new here.
THE updateDNS METHOD:
=====================
The updateDNS method might look slightly confusing at first. Like the getIP
method, updateDNS connects to a URL (in this case targetURL). It then opens a
stream and reads from the connection. This doesn't seem like an update at
all. In actuality, the URL contains a name/value pair that transmits the
domain name(s) of the sites being updated. The values read back are the
results -success or failure - of the URL connection.
ip.updateDNS("http://dynamic.zoneedit.com/auth/dynamic.html?host=www.yourdomai
n.com,yourdomain.com");
Code:
public boolean updateDNS(String url) {
String buffer = "";
boolean stat = false;
URL targetURL;
try {
targetURL = new URL(url);
//Get a character input stream for the URL
BufferedReader in = new BufferedReader(new
InputStreamReader(targetURL.openStream()));
buffer = in.readLine();
System.out.println("updateDNS result: " + buffer);
stat = true;
} catch (Exception e) {
System.out.println("Failed updateDNS: " + e);
stat = false;
}
return stat;
} // end of updateDNS
FINAL THOUGHTS:
===============
The Authenticator class offers an easy way to connect to a website where a
username and password are required. The example shown, RouterIP2,
demonstrates the basic code requirements, but lacks a professional user
interface. It would be interesting to see a Swing version of the same
program.
The complete source code is listed below:
**** COMPLETE SOURCE CODE FOR ROUTERIP2.JAVA *****
Code:
/*
* RouterIP2.java
*
* Created on March 19, 2002 from RouterIP, 9:03 PM
*/
/**
*
* @author Byron Lee
* @version
*/
/*
http://dynamic.zoneedit.com/auth/dyn...com,wearefam.c
om */
import java.net.*;
import java.io.*;
public class RouterIP2 {
MyAuthenticator myAuth;
/** Creates new RouterIP */
public RouterIP2() {
myAuth = new MyAuthenticator("admin","novap1");
Authenticator.setDefault (myAuth); //set Authenticator for popup
login
}
public String getIP(String url) throws Exception {
URL sourceURL = new URL(url);
//Get a character input stream for the URL
BufferedReader in = new BufferedReader(new
InputStreamReader(sourceURL.openStream()));
//Read the URL and parse for Internet IP
String buffer = ""; // buffer to store lines
String ipstr = ""; // string to hold ip address
int pos = 0;
int firstpos = 0;
boolean near = false;
while (!(null == (buffer=in.readLine()))) {
// System.out.println(buffer);
if (!(near) && ((pos = buffer.indexOf("Your ip is ")) > -1)) {
//start looking for ip
near = true;
}
if (near) {
// check for three periods in current line (buffer)
if ((pos = buffer.indexOf(".")) > -1) {
firstpos = pos;
if ((pos = buffer.indexOf(".",pos)) > -1) {
if ((pos = buffer.indexOf(".",pos)) > -1) {
break; //break out of while
}
}
}
} // end of "near" if
} // end of while
buffer = buffer.substring(firstpos - 3,firstpos + 11); //get
substring covering ip address
ipstr = filter(buffer, "0123456789."); //filter out unwanted
characters
return ipstr;
} //end of getIP
public String filter (String instr, String filstr) {
String outstr = ""; // output string
//compare input string to filter string one char at a time
for (int i=0; i<instr.length(); i++) {
for (int j=0; j<filstr.length();j++) {
if (instr.charAt(i) == filstr.charAt(j)) {
outstr = outstr + instr.charAt(i);
break;
}
}
}
return outstr;
} // end of filter
public boolean updateDNS(String url) {
String buffer = "";
boolean stat = false;
URL targetURL;
try {
targetURL = new URL(url);
//Get a character input stream for the URL
BufferedReader in = new BufferedReader(new
InputStreamReader(targetURL.openStream()));
buffer = in.readLine();
System.out.println("updateDNS result: " + buffer);
stat = true;
} catch (Exception e) {
System.out.println("Failed updateDNS: " + e);
stat = false;
}
return stat;
} // end of updateDNS
public String getOldIP() {
File ipfile = new File("d:\\routerip2\\lastip.txt");
String lastip = "";
BufferedReader in;
BufferedWriter out;
try {
// System.out.println("Got past fileinput stream");
in = new BufferedReader(new FileReader(ipfile.toString()));
if (ipfile.exists()) { //if the file exist
lastip = in.readLine();
lastip = lastip.trim();
in.close();
}
} catch (IOException ioe) {
System.out.println("Failed to read line from " +
ipfile.toString());
System.out.println(ioe);
}
return lastip.trim();
}
public void setOldIP(String ipout) {
BufferedWriter out;
File ipfile = new File("./lastip.txt");
try {
if (ipfile.exists()) { //if the file exist
out = new BufferedWriter(new FileWriter(ipfile.toString(),
false));
out.write(ipout);
out.close();
}
} catch (IOException ioe) {
System.out.println("Failed to write line to " +
ipfile.toString());
System.out.println(ioe);
}
}
public static void main(String[] args) {
RouterIP2 ip = new RouterIP2();
String ipaddr = "";
String oldip = "";
int cnt = 0;
while (true) {
try {
// ip.myAuth.setUname("admin"); -- authentication not
required for whatismyip.com
// ip.myAuth.setPass("noway82"); -- authentication not
required for whatismyip.com
// ipaddr = ip.getIP("http://192.168.1.1/STATUS.HTM"); --
used for my router
ipaddr = ip.getIP("http://www.whatismyip.com");
oldip = ip.getOldIP();
System.out.println("Current IP: " + ipaddr);
if(oldip.equals(ipaddr)) {
cnt++;
} else {
oldip = ipaddr;
ip.setOldIP(oldip);
ip.myAuth.setUname("admin");
ip.myAuth.setPass("noway82");
ip.updateDNS("http://dynamic.zoneedit.com/auth/dynamic.html?host=www.yourdomai
n.com,yourdomain.com");
}
} catch (Exception e) {
System.out.println("Failed for some reason" + e);
}
try {
Thread.sleep(600000L); //sleep (in milliseconds) for 10
minutes
} catch (InterruptedException e) {
System.out.println("Couldn't fall asleep " + e);
}
}
}
class MyAuthenticator extends Authenticator {
String uname;
String pass;
public MyAuthenticator(String uname, String pass) {
super();
this.uname = uname;
this.pass = pass;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
protected PasswordAuthentication getPasswordAuthentication() {
String user = getUname();
String pw = getPass();
return (new PasswordAuthentication (user, pw.toCharArray()));
}
} // end of MyAuthenticator class
} // end of RouterIP2 class
***** end of article *****
|
|
Copyright © 2000-2006, Milano Interactive
Web Hosting provided by Portal 360 Web Hosting
Open Circle
|
 |
|