Monday, August 31, 2009

Serving up applets on Pluto

The problem is, if I write a simple html page with a simple applet I can display it in apache2 no problem:

import java.awt.Graphics;
public class HelloWorld extends java.applet.Applet {
    public void init() {
 resize(150,25);
    }
    public void paint(Graphics g) {
 g.drawString("Hello world!", 50, 25);
    }
}

And the view.html is:

<html>
<body>
<applet code="HelloWorld" width="450" height="250">
</applet>
</body>
</html>

Now that works, but if you put this into Pluto and serve the page up, with the HelloWorld.class in the same folder as the view.html file you get this error:

java.lang.ClassFormatError: Incompatible magic value 168430090 in class file HelloWorld
 at java.lang.ClassLoader.defineClass1(Native Method)
 at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
 at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
 at sun.plugin2.applet.Applet2ClassLoader.findClass(Applet2ClassLoader.java:140)

which tells me that the class loader tried to load HelloWorld.class and it received a magic hex number of 0A0A0A0A, not CAFEBABE which begins every class file in Java. And the reason is that it received a 404 not found message from the tomcat server, and presumably the 404 HTTP header begins with 4 new line characters.

So there are two possible reasons:

  1. The HelloWorld.class file should be somewhere else
  2. The HelloWorld file needs to be served manually by Tomcat, in the same way that image files are served. But this should happen by default, so I'm going to try option 1 first.

It turns out that the hello world example (once I removed the ".class" from the name) could be served if I specified the full web url: /monitor/jsp as the codebase of the applet. Doh! Another Homer Simpson moment. Time for a slice of delicious Floor-Pie.

OK, I applied the above strategy to the monitor applet and it worked. Only I had to also specify the archive attribute as applet.jar. Now to add an edit page to the portlet so I can change the parameters of the applet.

Setting up Maven2 behind a password-protected NTLM proxy

The nice Maven people suggest that you might be able to get this configuration working, but don't say how. The Jetty people, however, suggest using CNTLM. I tried installing CNTLM (using synaptic package manager) and managed to configure the conf file in /etc/cntlm.conf which now reads in pertinent part:

Username jbloggs
Domain myorg
Password secret
Proxy 192.168.100.1:3128

OK, these aren't real values, but you get the idea. The proxy pointed to here is the REAL proxy. The "domain" is the local domain, not the long full domain-name, but maybe that also works. CNTLM is a proxy to the proxy and runs on localhost. Then I started the cntlm service thus:

sudo service cntlm start

I also had to tinker with my maven setings in ~/.m2/settings.xml:

<settings>
  <proxies>
   <proxy>
      <active>true</active>
      <protocol>http</protocol>
      <host>127.0.0.1</host>
      <port>3128</port>
    </proxy>
  </proxies>
</settings>

Note that I point maven to the cntlm proxy, which contacts the NTLM proxy via the cntlm.conf file. One nice consequence of this is that if I now change my general web proxy also to the localhost CNTLM one then ALL my requests get relayed through cntlm, so I don't have to keep telling the NTLM proxy who I am every five minutes. Whew!

And, hey presto, maven works.

One proviso: On the cntlm website it suggests testing cntlm on the commandline, and if you do that it responds with something to the effect that there was no user specified. What this means is that when running on the commandline cntlm does NOT look in /etc/cntlm.conf. So you have to supply that information as options. That threw me for a while until I just tested the service and was surprised to find it was running beautifully.

Saturday, August 29, 2009

Hello World on Pluto

I'm going to use the manual method of constructing a portlet because people don't like Maven and they may not be able to get it to work behind an NTLM proxy (but I managed that in the end).

First write yourself a basic HelloWorldPortlet. It doesn't do much, which is good. Because you want to understand it:

package examples.portlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

public class HelloWorldPortlet extends GenericPortlet 
{
 protected void doEdit(RenderRequest request, RenderResponse response) 
          throws PortletException, IOException 
 {
         response.setContentType("text/html");  
         PrintWriter writer = new PrintWriter(response.getWriter());
         writer.println("You're now in Edit mode.");  
 }
 protected void doHelp(RenderRequest request, RenderResponse response) 
          throws PortletException, IOException 
 {
         response.setContentType("text/html");  
         PrintWriter writer = new PrintWriter(response.getWriter());
         writer.println("You're now in Help mode."); 
 }
 protected void doView(RenderRequest request, RenderResponse response) 
          throws PortletException, IOException 
 {
         response.setContentType("text/html");
         PrintWriter writer = new PrintWriter(response.getWriter());
         writer.println("Hello world! You're in View mode.");
    }
}

Save that in a file HelloWorldPortlet.java. We'll assemble it later.

Now create a web application description file. Call it web.xml. Here's the one I used:

<?xml version="1.0" encoding="UTF-8"?>>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
 <display-name>HelloWorldPortlet</display-name>
 <servlet>
  <servlet-name>HelloWorldPortlet</servlet-name>
  <servlet-class>
   org.apache.pluto.container.driver.PortletServlet
  </servlet-class>
  <init-param>
   <param-name>portlet-name</param-name>
   <param-value>HelloWorldPortlet</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
  <servlet-name>HelloWorldPortlet</servlet-name>
  <url-pattern>/PlutoInvoker/HelloWorldPortlet</url-pattern>
 </servlet-mapping>
  <security-role>
    <role-name>tomcat</role-name>
  </security-role>
</web-app>

The org.apache.pluto.container.driver.PortletServlet is really important. This is the class inside Pluto that registers your portlet. Without that it won't know it's there.

Now create a portlet app definition file, call it portlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app
    xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
    version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd
                        http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
 <portlet>
    <description>Hello, world! portlet</description>
    <portlet-name>HelloWorldPortlet</portlet-name>
    <display-name>HelloWorldPortlet</display-name>
    <portlet-class>
       examples.portlet.HelloWorldPortlet
    </portlet-class>    
    <supports>
      <mime-type>text/html</mime-type>
      <portlet-mode>VIEW</portlet-mode>
      <portlet-mode>EDIT</portlet-mode>
      <portlet-mode>HELP</portlet-mode>
    </supports>
    <portlet-info>
        <title>Hello, Pluto at last!</title>
    </portlet-info>        
  </portlet>
</portlet-app>

There's only one portlet inside it, but you can have several. In fact you can define all your portlets inside Pluto but that means hacking Pluto, which I don't recommend. It's much better to provide a portlet app with separate portlets, like the testsuite.

Finally you need to create a context-descriptor. It's very simple. Call it hello.xml:

<Context path="/hello" docBase="hello.war" crossContext="true"> </Context>

Now compile the HelloWorldPortlet. You'll need to add the portlet-api_2.0_spec-1.0.jar which is in the lib folder of your Pluto (aka Tomcat 6) installation to the classpath:
javac -cp ~/pluto/lib/portlet-api_2.0_spec-1.0.jar HelloWorldPortlet.java
(assuming that your Pluto installation is in your home directory)

Now create a directory called hello, and populate it as follows:

  • META-INF
    • hello.xml
  • WEB-INF
    • portlet.xml
    • web.xml
    • classes
      • examples
        • portlet
          • HelloWorldPortlet.class

Finally, cd into the hello directory and type:
java cvf hello.war .

Now copy the hello.war file into the webapps directory inside your Pluto installation. Restart Pluto and if you go to Pluto Admin then the hello world portlet will be available for adding to pages. It even works.

Tuesday, August 25, 2009

First Steps on Pluto

Wow, this is heady stuff. I have worked out roughly how Pluto works. It's not too complicated. The basic application is in pluto-portal-2.0.0.war. All this does is run the portal, the pluto page administration and an about box portlet. If you need more functionality you add another .war file, like the testsuite. In order for Pluto to run the other war file, however, you need to:

  1. copy five jars into the shared lib folder of apache-tomcat-6.0.20: pluto-container-api-2.0.0.jar, pluto-container-driver-api-2.0.0.jar, pluto-taglib-2.0.0.jar, portlet-api_2.0_spec-1.0.jar and ccpp-1.0.jar.
  2. copy tomcat-users.xml from the pluto installation into tomcat's conf directory. Or define a role "pluto" and a user "pluto".
  3. Rename pluto-portal-2.0.0.war to pluto.war and pluto-testsuite-2.0.0.war to testsuite.war and copy them from pluto-2.0.0/PlutoDomain to apache-tomcat-6.0.20/webapps.

And that appears to be it. The only drawback is, defining add-on portlets this way means that you have to modify the default tomcat installation. This makes it difficult to use a commercial tomcat server. Hmmm. But otherwise Pluto can't launch the portlets in the other war file.

And I still haven't worked out how to add portlets to the testsuite, or rather how to replace them with my own. But compared to Jetspeed it's as clean as a whistle. It's so nice that the portlets you add are all in a separate webapp.

Tomorrow I'm going to try to replace the testsuite with my own webapp of portlets defined in Eclipse. No fr***in Maven!!!

Monday, August 24, 2009

Including Javascript in XSL

No one tells you how to do this. If you add Javascript to HTML you end up with some left and right angle brackets and ampersands in your javascript, which you can't have in XML, before it is transformed into HTML. The thing about Xalan is that it first interprets all entity references to &amp; and &lt; before it transforms it and then puts them back again afterwards. You can disable the afterwards transformation by enclosing the script in a <xsl:text disable-output-escaping="yes"> ... </xsl:text> pair of tags. But you have to encode your angle brackets and ampersands as entities too, otherwise you'll get a syntax error. So &amp; gets transformed into & and &lt; into < during the input phase, then you get a literal angle bracket etc in your transformed Javascript. Cool.

That took me an hour and a half to work out again (I forgot how to do it) so I thought I would write it down this time.

Monday, August 17, 2009

Testbed Status portlet

I thought a good way to start off my portal would be to write a simple HTML type of report using the DOS test suite I developed. This tests the network looking for machines exposed on the monitoring AND attack networks, and also detects routers and switches, firewalls etc. A HTML readout of the testbed setup would be a good place to start building and would be easy enough to get me started on porting all my code to the portal.

In fact, why not turn it into a fully-fledged topology view? Rather than just list computers and routers using text, why not draw them using icons? Then use colours to indicate their status. We could write out the network status in XML then view it using an interactive applet.

Sunday, August 16, 2009

Possible Extensions to dosTF

There are a few possible directions to continue development of the testing framework. I would like to start using the GUI for real now, not the various components. So I see the tasks ahead as:

  1. Add logging to applet
  2. Enhance scenario-editing GUI
  3. Add a repertoire of real DOS attacks, compiled for each machine architecture, and ready to deploy.

Sunday, August 2, 2009

Enabling snmp on Ubuntu

I thought I'd write down the recipe for enabling snmp on Ubuntu. Much the same instructions also work for RedHat.

First ensure that the packages snmp and snmpd are both installed. Login as root via ssh to the machine you need to configure, and then:

apt-get install snmp and
apt-get install snmpd

Follow the usual prompts to get it installed then

  1. Type snmpconf
  2. From the text-menus choose to load "none" of the existing snmpd.conf files.
  3. Choose option 1: snmpd.conf as the file to create
  4. Select the option "Access Control Setup" (the number varies)
  5. Choose option 3: "a SNMPv1/SNMPv2c read-only access community name"
  6. In answer to the first prompt type "public".
  7. In response to the request to specify a host address to accept this community name just hit return
  8. In response to the OID request just hit return.
  9. Then type "finished", "finished" and "quit"
  10. Copy the resulting snmpd.conf in the current directory to /etc/snmp/, overwriting what is there.
  11. Edit the file /etc/default/snmpd. At the end of the line saying SNMPDOPTS remove the " 127.0.0.1". This step is not required on RedHat.
  12. Save the file and restart the snmp daemon: service snmpd restart. If you haven't got the service command install the sysvconfig package or just type: /etc/init.d/snmpd restart (same thing)
  13. Test the snmp service: snmpwalk -c public -v2c localhost. You should get a sizeable chunk of responses, several pages worth. If only one page then your snmpd.conf file is not installed or mucked up or overridden by something else.
  14. Also test from another machine that can access the snmp server you just set up. snmpwalk -c public -v2c <snmp-host-ip-address>. You should get the same output. If it hangs, then you failed to remove the "127.0.0.1" from the snmpd file above.

snmpd glitch

Oh the joys of overcoming poor software design! You'd have thought that an application like snmpd, which allows you to configure who can access the SNMP information on a server and from which ip-addresses, could be configured as such. Not a bit. That'd be too easy. The default Ubuntu installation screws it up very nicely by launching the snmp daemon with an argument '127.0.0.1' i.e. localhost, which secretly overrides whatever you specify in the snmpd.conf file. You can only access from localhost, even if you used snmpconf to specify access for all. To fix the problem you have to edit the /etc/default/snmpd file and delete the '127.0.0.1' from the end of the line that starts with 'SNMPDOPTS'. Then it works.