Restrict access to Tomcat URL to select IP addresses

One of our customer applications has been plagued by massive amounts of requests from external IP adresses that really shouldn’t be using the URL’s. The connections caused the connection pool in the Tomcat instance behind Apache to deplete and hence no connections were available to legitimate users. Since the URL cannot be password protected we needed another way to restrict the access.

The solution is quite simple and only involved a couple of lines in the VirtualHost section of httpd.conf. The below RewriteRules restrict the access to the /search URL to the XX.YYY.ZZ.WW1, XX.YYY.ZZ.WW2 and XX.YYY.ZZ.WW3 addresses. All other URLs are available as normal. If you try to access the URL from another IP address than the ones specified you’ll get a 403 Forbidden HTTP response code back.

RewriteEngine    on
RewriteLog       /usr/local/apache2/logs/rewrite.log
RewriteLogLevel  0

# allow access to search only from select addresses
RewriteCond   %{REMOTE_ADDR}  XX.YYY.ZZ.WW1                        [OR]
RewriteCond   %{REMOTE_ADDR}  XX.YYY.ZZ.WW2                        [OR]
RewriteCond   %{REMOTE_ADDR}  XX.YYY.ZZ.WW3
RewriteRule   ^(/search.*)    $1                                   [PT,L]

# deny access to search from all other addresses
RewriteRule   ^/search.*      -                                    [F]

The real beautiful thing is that Tomcat is totally oblivious to the change and not a single line of code needed to be changed hence no need for software tests.

Beware of changing Domino Directory ACL

Be aware when changing the ACL of the Domino Directory since it may affect your users and the deployment of policies. Pay special attention when messing with the PolicyCreator and PolicyModifier roles or you may encounter the “The signer of the note must have Editor access and the PolicyCreator or PolicyModifier role to the Domino Directory” error message.

More information: SPR #TBOO5QNNDM.

DWA working in Firefox 1.5.0.2 (was: “Domino Web Access broken in Firefox 1.5?”)

As previously reported Domino Web Access seemed to have some problems running under Firefox 1.5 and I was not alone in having the issue. I just tried again today using Firefox 1.5.0.2 (the newest version from Mozilla) against Domino 7.0.1 (on Win32) and it was just fine. Don’t know if it’s the Firefox version or after upgradering from Domino 7.0 to Domino 7.0.1.

Anyone else experiencing the same thing?

Java in Notes/Domino Explained: Casting 101


To discuss and understand casting you must know that when you instantiate an object in Java you create an object on the heap and a reference to the object on the stack. In your Java agents you only have direct access to what’s on the stack which means that what you manipulate in your code are the references. Since you do not work with the objects on the heap directly the reference on the stack must tell the JVM which type of object is at the memory location pointed to on the heap.

Casting means taking an existing object reference and making it of another type. When most Java developers talk about casting they refer to “casting objects” which strictly speaking is wrong. It is however one of those things you learn to live with… 🙂

A simple example

As you might know every class in Java ultimatively inherits from java.lang.Object which means that a java.lang.Object reference can point to anything (much like a Variant in LotusScript). This means that you can always cast an object to java.lang.Object since it is a more generic type.

However you cannot store a java.lang.Object reference in a java.lang.String reference without casting since String is more specific than Object. As you can see I have to cast the obj reference to a String reference in line 3. If I don’t the code wont compile.

String sample1 = "This is my string..."; // create a String
Object obj     = sample1;                // store String in java.Object reference
String sample2 = (String)obj;            // we must cast to store an Object in a String
                                         // reference

To sum up you need to cast when refering to an object with a more specific reference than the current reference.

When casting references you may encounter the java.lang.ClassCastException which is an unchecked exception. This exception is the way the JVM can signal that you are doing an illegal cast for example casting a lotus.domino.Document to a lotus.domino.Database.

Knowing when it’s okay to cast

So how do you check if a cast is legal? Well apart from knowing which references you are dealing with you can use the instanceof keyword. The below example checks that the object really does inherit from lotus.domino.RichTextItem before casting:

// declarations
RichTextItem rt = null;
Item item = null;

// get document
Document doc = db.getDocumentByUnid("<some unid>");

// loop all items and put them into an ArrayList
Vector items = doc.getItems();
for (int i=0; i<items.size(); i++) {
   // get next element from the Vector (returns java.lang.Object)
   Object obj = items.elementAt(i);

   // is the item a RichTextItem?
   if (obj instanceof RichTextItem) {
      // yes it is - cast it as such
      rt = (RichTextItem)obj;
   } else {
      // nope - cast it as an Item
      item = (Item)obj;
   }
}

The above example is equivalent to the below code exept that I use the ClassCastException to find out that the cast is invalid.

// declarations
RichTextItem rt = null;
Item item = null;

// get document
Document doc = db.getDocumentByUnid("<some unid>");

// loop all items and put them into an ArrayList
Vector items = doc.getItems();
for (int i=0; i<items.size(); i++) {
   // get next element from the Vector (returns java.lang.Object)
   Object obj = items.elementAt(i);

   try {
      // try to cast as RichTextItem
      rt = (RichTextItem)obj;

      // coming here means that the item is a RichTextItem
      ...
   } catch (ClassCastException e) {
      // not a RichTextItem - cast it as an Item
      item = (Item)obj);
   }
}

Java in Notes/Domino Explained: The difference between a class, an abstract class and an interface


Normal, or concrete, classes in Java can be instantiated using the new keyword. Concrete classes both define the functionality, that is what the class does, and the interface, that is what methods are available for you to call. Most of the classes you write will be concrete classes like the one below.

public class MyConcreteClass {
   public void perform() {
      ...
   }
}

At the other end of the spectrum we have an interface which only defines which methods we can call on it – there is no functionality in there. The interface in the example below specifies that a class implementing the interface will at least have the 4 listed methods. Notice that there is no method bodies (the compiler will enforce this).

public interface Car {
   public void increaseSpeed();
   public void decreaseSpeed();
   public void turnRight();
   public void turnLeft();
}

By creating a class and inserting the keyword “abstract” after the class visibility modifier (public, private, “friendly”) makes the class into an abstract class. An abstract class is somewhere in between an interface and a class, that is a class where some of the functionality is specified but not all. Think of an abstract class as a class with some blanks that needs to be filled in by any, non-abstract, class that extends it. An abstract class cannot be instantiated using the new keyword.

public abstract class MyAbstractClass {
   public class perform() {
      this.doStuff();
   }
   public abstract void doStuff();
}

How do I use an interface?

To use an interface you have your class implement it. Implementing an interface means making sure that the class specifies method bodies for all the methods in the interface. If you do not implement all the methods in the interface the compiler will make you mark the class as abstract.

public class Ford implements Car {
   public void increaseSpeed() {
      ...
   }
   public void decreaseSpeed() {
      ...
   }
   public void turnRight() {
      ...
   }
   public void turnLeft() {
      ...
   }
}

How do I use an abstract class?

An abstact class cannot be instantiated because some of the functionality (for example the doStuff() method in the example above) isn’t implemented. To use the class we need to extend it and implement any missing, abstract, methods.

public class MyClass extends MyAbstractClass {
   public void doStuff() {
      ...
   }
}

So when should I use which?

Well the real answer is it depends…

An abstract class is a good choice when you do most of the programming in the abstract class and leave only one or a couple of methods to sub-classes. An example could be a class that reads data from a file. The abstract class defines the actual reading and processing of the file and concrete sub-classes define how to get the file (from the local disk, via HTTP, via FTP etc.):

public abstract class FileProcessor {
   // declarations
   private File file = null;

   public process() {
      // get file
      this.file = this.getFile();

      // open file
      this.openFile();

      // decrypt file
      this.decryptFile();

      // do other stuff with the file
      ...
      ...
   }
   private void openFile() {
      ...
   }
   private void decryptFile() {
      ...
   }
   private abstract File getFile() throws Exception;
}

public class HttpFileProcessor extends FileProcessor {
   private abstract File getFile() throws Exception {
      // get file via HTTP and return it
      ...
   }
}

public class FtpFileProcessor extends FileProcessor {
   private abstract File getFile() throws Exception {
      // get file via FTP and return it
      ...
   }
}

An interface is really nice when all you need to do it define what methods are available but you want to leave the entire implementation up to the implementer. The interface in the example below only describes that a class implementing the interface knows how to process a Document object. You don’t care how the class does it but you know that you can call the process() method supplying the Document that should be processed.

public interface DocumentProcessor {
   public void process(Document doc) throws Exception;
}

Another really neat thing about interfaces is that a class may implement multiple interfaces whereas it can only extend a single class. This means you can use an interface simply to signal something (for an example of this look at the java.lang.Cloneable interface in the JDK).

public class MyCar implements Car, Cloneable, Serializable {
   ...
}

Re: Helping out a fellow blogger getting the actual bytes of an image resource – a lesson in the intricacies of DXL representation

And there you have it… Ben Langhinrichs of Genii Software, CoexEdit and the Midas RichText LSX fame has posted a comment that explains my findings about the structure of an image resource in DXL.

Thanks Ben.

Joel on Software: The Development Abstraction Layer

As always the posts by Joel Spolsky are insightful, funny and with an edge that makes you keep reading. The newest post (The Development Abstraction Layer) is about why programmers can’t run a business by themselves, but what it takes to make them think they can.

“Management’s primary responsibility to create the illusion that a software company can be run by writing code, because that’s what programmers do. And while it would be great to have programmers who are also great at sales, graphic design, system administration, and cooking, it’s unrealistic. Like teaching a pig to sing, it wastes your time and it annoys the pig.”

As a (self-employed) programmer I can only say: “sad but true…” 🙂

Re: Re: How are roaming id-files encrypted?

Dear Mr Heisterberg,

Our development team have released the following information about the encryption method of the ID file.
This is the Text which they sent back to me:

“Double encryption is chosen to securely deliver an ID file to the roaming user. It is a client – server interaction, where the Password the client enters is not necessarily the Password it is used to undisclosed the ID file.

This action can only be fulfilled together with the server. For basic concepts please see “Bellovin-Merritt Encrypted Key Exchange protocol”. It is implemented differently but this will give you an Idea what is going on. Diffi Hellman was choose as an encryption algorithm itself.”

I have also to advise you. The only supported configuration for Roaming Users it to upgrade the users via the information in the Administration help guide.
If a problem arose with Roaming Users where the config used was not done as per Admin help ,we would be unable to provide assistance.

Kind Regards,
Xxxxxx Yyyyyyy
Software Engineer – Lotus EMEA Support –

Apart from the fact that the references to the algorithms in the response are erroneous I guess I have to accept the answer. Just for the record – Diffie-Hellman is not an encryption algorithm but an algorithm to securely establish a session key across an unsecure network.

However after another round of clarifying questions with Lotus Support it is clear that any attempt to automate the process of pre-creating the roaming user databases on the server will be totally unsupported by Lotus. The only way is to manually mark users for roaming which leaves some room for improvement I’m afraid though I understand Lotus’ position.

I guess it’s back to the drawing board now to find a way to automate the migration process to roaming as much as possible and find a way to make it as easy for existing users as possible. During my research I did find the a method in the Notes C API (SECAttachIdFileToDB()) that might be of interest to some – the customer I am researching this for will probably not go so far as to do C API development.

To end on a positive note. Enabling roaming for new users isn’t an issue since it’s simply a matter of checking a box in the registration dialog. That’s easy! 🙂

Further reading: