Sorting document collections in LotusScript

Another option to the function in NotesDatabase was to use the FTSearch() method in NotesView but this method behaves different depending on whether the database is full-text indexed or not. Apparently the sorting of the view is only honored for the search results if the database is NOT full-text indexed. Why this distinction? Why not give me the option?

Anyways… The solution was to use the FTSearch() method in NotesDatabase as I started out doing and then using a function I found via Lotus Developer Domain that can sort a NotesDocumentCollection based on field names.

The function is written by Max Flodén and is available from http://www.tjitjing.com.

Force Domino to output XHTML to allow parsing as XML

In an application I did recently I needed to easily be able to fetch valid XML documents for a lot of documents from the Domino application. This isn’t really a challenge you will say and you’re right… The challenge was that I would like to reuse the HTML that Domino would generate for me for rich text fields etc.

This is a problem since the HTML Domino generates isn’t XHTML so I would get an error when supplying the retrieved page to my JavaScript XML parser. The browser would also complain that the page wasn’t valid XML.

The solution was an undocumented Domino URL argument. When adding the URL argument &OutputFormat=xhtml to the URL Domino will generate valid XHTML and this solved my problem.

Now I could have my cake and eat it too… Now the retrieved page could be supplied to my XML parser and the “embedded” HTML generated by Domino could be extracted and easily shown in a <div> tag using JavaScript. Sweet.

The documents are looked up through a special view using a form formula to make sure the documents are displayed using my special form. The entire form is passthrough HTML and all the contents is wrapped in a CDATA section to be safe.

Using this approach I could reuse the Domino HTML for rich text fields and easily extend the presentation.

Using Regular Expressions from LotusScript

Visual Basic Script (VBScript) version 5 and later (current version is 5.6) has a very powerful RegExp engine that is accessible through COM. The engine supports all the bells and whistles of regular expressions incl. grouping, backreferences etc.

Having regular expressions available from LotusScript is great since it allows you to use it for validation on the client etc. Another great thing is that the VBScript component is installed by default (at least on Windows XP) so there’s no need to touch client machines.

The VBScript RegExp engine is accessed from LotusScript using COM using the CreateObject() method:

Dim regexp As Variant
Set regexp = CreateObject("VBScript.RegExp")

Once you have a RegExp object you will normally use a code snippet like the following to do simple pattern matching:

'declarations
Dim regexp As Variant
Dim rc As Integer

'create object
Set regexp = CreateObject("VBScript.RegExp")

'make pattern matching case insensitive
regexp.IgnoreCase = True

'set pattern
regexp.Pattern = |[1-9]+[0-9]* Failed|

'test pattern
rc = regexp.Test(|Backup job XYZ: 2 Failed, 0 Succeeded.|)
If rc = -1 Then
   MsgBox "Match - backup failed..."
Else
   MsgBox "No match - backup suceeded..."
End If

Further reading

Freetime WebService

Just saw a little download on the Domino 7 download page on Passport Advantage. The download is called “Free Time Web Service database 7.0 (C8525NA)” and contains a Notes database with a web service allowing you to do freetime searches over SOAP. Pretty nice and a good example on how to do web services in Notes 7 in LotusScript.

Sametime 7 Connect for Browsers

Well not exactly the certificate signer you would expect to find on a product like Sametime… I would have expected a certificate that was somewhat more “official” and closer to IBM “home”.

Set the “Prompt for location at startup” User Preference from LotusScript

In Notes 5.x the selections made in the User Preferences dialog box (FilePreferencesUser Preferences) are stored in the notes.ini file as a decimal number in Preferences setting. This setting may be manipulated using binary operations if need be.

Please note: I would think that this is no way a Lotus supported way of doing this… 🙂

The “Prompt for location at startup” User Preferences is set using the 25th bit (1 000 000 000 000 000 000 000 000) which is 16777216 in decimal. Setting the flag can be accomplished using the binary OR operation.

Sub Initialize
   Dim session As New NotesSession
   Dim notes_ini_value As Long
   Dim notes_ini_value2 As Long
   notes_ini_value = Clng(session.GetEnvironmentString("Preferences", True))
   notes_ini_value2 = notes_ini_value Or 16777216
   Call session.SetEnvironmentVar("Preferences", Cstr(notes_ini_value2), True)
End Sub

If you need to toggle the flag you should use the XOR operation.

Configuring site-2-site VPN on Cisco PIX 506

The Cisco PIX firewall series of products are very nice and range from the little entry-level PIX 501 to larger gigabit enterprise ready solutions. We normally use the PIX 501 and PIX 506 with 3DES and/or AES due to their cheap price and superior functionality and built-in VPN capability.

Normal configuration
The configuration I normally do is the following:

  • Use static to map services from the outside address(es) to the inside address(es).
  • Use an access-list to allow the trafic to pass from the outside interface to the inside interface. Normal services to map through are SMTP, HTTP, HTTPS and Lotus Notes (1352).
  • Use an access-list to restrict users from accessing services other than HTTP, HTTPS and FTP though the firewall. No unwanted filesharing etc.
  • Configure IPSEC VPN from all remote addreses to connect using 3DES and a shared secret. We use RADIUS to authenticate users connecting so they can use their Windows username and password.

The above is normally enough to solve the need of our customers as well as our setup even though there might be more than one site. Internally we have made the concious choice of not configuring VPN tunnels between sites since most users do not need to access services at other sites. The users that need access to other sites use the VPN client and hence know when they could affect other sites.

Site-2-site IPSEC VPN
This time I needed to configure a full site-2-site VPN tunnel that would allow users and servers at each site to transparently access services at the other site. It proved surprisingly easy to configure once I understood the way the PIX uses so-called “crypto maps” and once I got a hold of a good book called Cisco Security Specialists Guide to Pix Firewall.

To configure VPN access we use a dynamic crypto map which allows the PIX to create a crypto map per user once they connect. This is not however the desired setup for site-2-site configuration. Here you would like to know exactly what is going on. The dynamic crypto map should still be there to allow users from accessing the site using VPN.

Before you begin
Below I assume that all exising IPSEC related configuration has been removed such as crypto maps, transform sets and isakmp setup. To see any existing configuration enter enable mode (and configure terminal mode) and use the “sh crypto map”, “sh crypto ipsec transform-set” and “sh isakmp” commands.

The setup
I also assume you have two IP-segments you would like to connect. My IP-segments are the 192.168.1.0/24 segment and the 192.168.2.0/24 segments. Each end has a PIX 506/501 in front and the edge router allows all IP protocols to pass through to the PIX (incl. ESP and AH). Check with your ISP since some connections has these protocols blocked and only allow TCP and UDP traffic.

The configuration I show is the configuration from the 192.168.2.0/24 segment (source) to the 192.168.1.0/24 segment (target). The PIX in the source end has the public IP-address 2.2.2.2 and the public IP-address in the target end is 1.1.1.1 (the addresses are random).

To configure the PIX you need to add the following pieces of configuration.

-- allow IPSEC traffic through to the inside interface of the PIX
-- unfiltered (this is not a security issue)
sysopt connection permit-ipsec

-- create a transform-set which basically means which protocols should we use
crypto ipsec transform-set myset esp-3des esp-md5-hmac

-- create client VPN config using dynamic crypto map referencing the transform-set.
-- The priority is set to 50 to have it be the last of the two maps we end up creating
crypto dynamic-map dynmap 10 set transform-set myset

-- create a crypto map for the client using RADIUS authentication
-- (be sure to also configure an aaa-server for this)
crypto map pix-ny_map 50 ipsec-isakmp dynamic dynmap
crypto map pix-ny_map client configuration address initiate
crypto map pix-ny_map client configuration address respond
crypto map pix-ny_map client authentication RADIUS

-- create a pre-shared key IKE towards the target (1.1.1.1)
isakmp key <shared secret> address 1.1.1.1 netmask 255.255.255.255

-- create an access-list to handle all trafic from 192.168.2.0 --> 192.168.1.0
access-list site2site_vpn permit ip 192.168.2.0 255.255.255.0 192.168.1.0 255.255.255.0

-- exclude NAT'ing the trafic handled by the access-list we just created
nat 0 access-list site2site_vpn

-- create a crypto map to pull everything together
crypto map pix-ny_map 10 ipsec-isakmp

-- add the addresses to match for this crypto map
crypto map pix-ny_map 10 match address site2site_vpn

-- set the peer for the tunnel
crypto map pix-ny_map 10 set peer 1.1.1.1

-- define the transform set (the suite of protocols) to be used for our map
crypto map pix-ny_map 10 set transform-set myset

-- apply the crypto map to the outside interface (there can only be one map per interface)
crypto map pix-ny_map interface outside

-- if you use an access-list to restrict trafic from the internal interface
-- to the outside you must allow the traffic from 192.168.2.0 to pass to 192.168.1.0
access-list inside permit ip 192.168.2.0 255.255.255.0 192.168.1.0 255.255.255.0

Please note: You need to create the same configuration in the target end using the same shared secret! In the target end you need to specify another address for the peer (change 1.1.1.1 to 2.2.2.2) and swap the IP-segments in both the access-list commands (192.168.1.0 / 192.168.2.0).

Final words
Hopefully this will work for you and save you some hours of fustration. Please note though – you really want to read a primer on IPSEC before venturing into stuff like this to understand how IPSEC works. You might as well start at the wikipedia article.