Echando código: Como automatizar los "Ping Manuales" de VeneBlogs, usando Java y Ethereal

Ya como había comentando antes en este Blog, les decia que Ethereal puede ser muy útil no sólo con fines de seguridad sino también como una herramienta de desarrollo de aplicaciones. Por ejemplo, suponga que usted decide hacer una clase en Java la cual le hace el «Ping manual» a VeneBlogs. Dado que aún no se ha prestado para abusos, el colocar los datos allí es muy simple ya que sólo se exige el usuario y la clave para poder hacer el ping usando una forma en HTML que usa el método POST.

Podemos usar Ethereal para capturar todo el tráfico desde el principio, así que con ello primero obtenemos el HTML de la forma a disecar:

VeneBlogs HTML Form

Sin embargo esta parte de la conversación es trivial, ya que podemos usar un navegador como Mozilla para ver el código HTML de la forma; ¿Pero y que hay de lo que realmente se envia por el cable hacia el servidor? Bueno, siguiendo las instrucciones de el tutorial anterior, podemos capturar el resto de la conversación y ver lo siguiente:

  • Contenido de la forma POST (cabeceras HTTP, contenido de la forma, Cookies)
  • Respuesta de retorno de el servidor

VeneBlogs captura de datos

Por cierto, ¿ya vió el password en el URL (si, esa no es mi verdadera clave :))?. Es una lastima que VeneBlogs no utilice SSL + HTTP para proteger a sus usuarios de este tipo de problemas.

Mi primer intento de hacer un ping a VeneBlogs desde Java fué el siguiente programa:

   1:package com.blogspot.elangelnegro;
2:import java.util.ResourceBundle;
3:import java.io.IOException;
4:import java.io.InputStreamReader;
5:import java.io.BufferedReader;
6:import java.io.LineNumberReader;
7:import java.io.DataOutputStream;
8:import java.net.URL;
9:import java.net.URLConnection;
10:import java.net.HttpURLConnection;
11:import java.net.URLEncoder;
12:import java.net.MalformedURLException;
13:
14:/**
15: * This program connects to the VeneBlogs.com manual ping page and sends a ping to it, using the POST method.
16: * <b>License:</b> LGPL.
17: * Write a Resource Bundle file with contents similar to this one (change only the appropriate parts):
18: * <pre>
19: * # URL used to connect to Veneblogs
20: * com.blogspot.elangelnegro.ManualPing.url=http://www.veneblogs.com/ping/prlogin.php
21: * com.blogspot.elangelnegro.ManualPing.referer=http://www.veneblogs.com/ping/pingmanual.php
22: * com.blogspot.elangelnegro.ManualPing.username=PPPP@domain.com
23: * com.blogspot.elangelnegro.ManualPing.password=XXXX
24: * </pre>
25: * @author Jose V Nunez Zuleta
26: * @version 0.1 - 01/10/2005
27: * @see http://www.javaworld.com/javaworld/javatips/jw-javatip34.html
28: * @see http://elangelnegro.blogspot.com
29: */
30:public final class VeneBlogsManualPing {
31: private static final ResourceBundle BUNDLE =
32: ResourceBundle.getBundle(VeneBlogsManualPing.class.getName());
33: public static final String VERSION = "1.0";
34: /**
35: * Command line processing
36: * @param args Command line arguments, currently ignored
37: * @throws IOException if there is an error communicating with the website
38: * @since 0.1
39: */
40: public static final void main(String [] args) throws IOException {
41: if (BUNDLE.getString("com.blogspot.elangelnegro.VeneBlogsManualPing.url") == null) {
42: throw new IllegalArgumentException();
43: }
44: URL url = null;
45: LineNumberReader reader = null;
46: DataOutputStream out = null;
47: try {
48: url = new
49: URL(BUNDLE.getString("com.blogspot.elangelnegro.VeneBlogsManualPing.url"));
50: URLConnection con = url.openConnection();
51: con.setDoInput(true);
52: con.setDoOutput(true);
53: con.setUseCaches (false);
54: con.setRequestProperty("User-Agent",
55: VeneBlogsManualPing.class.getName() + "/" +
56: VERSION + " El Angel Negro");
57: con.setRequestProperty("Accept",
58: "text/xml,text/plain,text/html");
59: con.setRequestProperty("Content-Type",
60: "application/x-www-form-urlencoded");
61: con.setRequestProperty("Referer",
62: BUNDLE.getString("com.blogspot.elangelnegro.VeneBlogsManualPing.referer"));
63: ((HttpURLConnection) con).setRequestMethod("POST");
64: ((HttpURLConnection) con).setInstanceFollowRedirects(true);
65: // Write the form to the Website using POST
66: out = new DataOutputStream(con.getOutputStream());
67: // Append the operands in the same order, we don't know if they process them by name...
68: StringBuffer postData = new StringBuffer();
69: postData.append("username=" +
70: URLEncoder.encode(
71: BUNDLE.getString("com.blogspot.elangelnegro.VeneBlogsManualPing.username"))
72: + "&");
73: postData.append("operation=in&");
74: postData.append("password=" +
75: URLEncoder.encode(
76: BUNDLE.getString("com.blogspot.elangelnegro.VeneBlogsManualPing.password"))
77: + "&");
78: // They have it all this empty spaces, don't ask me why! :)
79: postData.append("submit=" +
80: URLEncoder.encode(" Enviar "));
81: out.writeBytes(postData.toString());
82: postData.setLength(0);
83: out.flush();
84: out.close();
85: // Read the response
86: reader = new LineNumberReader(
87: new BufferedReader(new InputStreamReader(con.getInputStream())));
88: for (String line = reader.readLine(); line != null; line = reader.readLine()) {
89: System.out.println(line);
90: }
91: } catch (MalformedURLException malExp) {
92: throw new IllegalArgumentException(malExp.toString());
93: } catch (IOException ioExp) {
94: throw ioExp;
95: } finally {
96: try {
97: if (reader != null) {
98: reader.close();
99: }
100: } catch (IOException ignore) {};
101: try {
102: if (out != null) {
103: out.close();
104: }
105: } catch (IOException ignore) {};
106: }
107: }
108:}

Por alguna razón no funcionó nunca bien y por ello me decidí a comenzar un pequeño pequeño proyecto llamado ‘Pingo‘. Con Pingo espero no tener que llamar 3 sitios web (VeneBlogs, Bitacoras, Technorrati) para notificar que mi bitacora está actualizada (Blogger no lo hace), sino que todo se hará desde un solo programa:

Project Information
-------------------

1. Submitter: josevnz

2. Project UNIX Name: pingo

3. Project Descriptive Name: Pingo, the Blog manual ping tool

4. License: GNU General Public License (GPL)

License other:

5. Project Description: Pingo is a program that can be used to "manual
ping" Blogs directories that doesn't support such automatic feature.
Inittial support is planned for VeneBlogs.com, Bitacoras.com and
Technorati.com

6. Registration Description: Pingo is a program that can be used to
"manual ping" Blogs directories that doesn't support such automatic
feature. Inittial support is planned for VeneBlogs.com, Bitacoras.com and
Technorati.com.

If the project gains interest, then other blog directories will be
added (for that to happen an extensible arquitecture is planned from the
beginning, at least for blogs that require communication in plain HTTP or
XML-RPC).

Pingo will use Open Source libraries like Jakarta XML-RPC and will be
written in Java (Swing for the user interface) in order to guarantee
that it can be executed on any machine with support for a Java Virtual
machine.

inittial supported languajes are English and Spanish.

[end]

Vamos a ver si me lo aprueban. Por cierto, si está interesado en colaborar, tiene tiempo libre y sabe echar código entonces sea usted bienvenido :).