Worm with Glasses

Coding • DevOps • Personal

Dec 2, 2005

Wormbytes::CGI::Application

I’ve done a lot of CGI application programming. Over the years I’ve developed a CGI::Application base class that I derive my applications from. I’ve called my Perl module WormBytes::CGI::Application since it derives from CGI::Application. It brings in all the modules I normally use in my CGI programming.

In addition to the required modules, I’ve extended the class to handle session management. There is also rudimentary support for user management in the base code. Nothing fancy, but enough to do simple log-in style applications. It can be easily extended in sub-classes if needed.

The session management code uses a UUID numbering system. The idea is that each session ID needs a unique ID, but the IDs do not need to be random. Uniqueness is more important. To ensure that sessions can not be hi-jacked, an additional HMAC cookie is included with the session ID cookie. This HMAC includes a random number stored in the session on the server plus a hash of information from the client. The client information is not required, but it does help if the information is present. Because of the random key that’s used in the hash it is impossible to guess what the HMAC will be. It is checked at the beginning of each request and modified at the end of each request. Therefore, the HMAC is constantly changing and is constantly validated. In this, the base class, an invalid session causes the system to log the user out.

There are also certain helper functions like tt_pre_process() that adds certain objects and variables to all templates. cgi_untaint() creates a CGI::Untaint object for later use. Finally, redirect_url() simply redirects the client to a new location.

I find this module to be a great base for all my CGI applications.

Dec 2, 2005

Emacs Lisp

Emacs is my editor of choice, and like most people who use Emacs I have customized it to suite my personal taste. I have included copies of my customizations so that others may build on what I’ve created, or simply have a more pleasant working environment.

Lisp Source

emacs.el

This is my main .emacs file. It contains the bulk of the customizations, but it does include a few other features and functions that other people may find useful. Some of the code is written by me, and other parts I’ve found on the net.

planner-config.el

To help me manage my time and my projects I have turned to the plannel-el (PlannerMode) major mode. Since I have worked as a independent IT consultant, I often need to track the number of hours I work on projects for various clients. I have customized and extended planner-el to allow me to clock in and out of a task. Upon clock-out the system will automatically prompt me for a description of what I did during the clocked-in time, and then write a note on the task page for the project detailing the amount of time I spent, and allowing me to classify the work performed. I then have a separate Perl script that takes the raw task pages and produces an invoice. I think it’s a very slick setup.

pic-asm-mode.el

I have done a lot of firmware programming on various Microchip PIC micro-controllers, and I found that the default asm-mode.el script did not handle the idiosyncrasies of the PIC assembly language very well. Therefore, I created pic-asm-mode.el as an extension to asm-mode.el. It syntax highlights PIC assembly mnemonics and handles formatting correctly.

Nov 30, 2005

Combo Button Lock Quiz Problem

Introduction

Matthias Wandel of Research in Motion (RIM) has a programming challenge posted on his website. The challenge is to write a program that generates all the possible combinations for an N button combination lock. The twist is the multi-button possibilities as well. Read on to see how I solved the problem.

Updated on November 29, 2005: The version described below is the second published version of the code. The first program was 160 lines of code and involved a more complicated way of producing the combinations. It is, however, faster than the current version.

Constraints

Matthias presents the programming challenge while describing the position of an embedded developer. The original code traded memory usage for more complicated code. The new version reverses this decision since the amount of memory consumed is still much lower than a typical 8-bit micro-controller. The other driving constraint is to keep the source to less than 100 lines of code. The current version is at 125, so there is still some room for improvement.

Theory of Operation

The problem can be described as a simple combinatoric (k-of-n) where an increasing number of keys are drawn (starting with one and increasing to a maximum of eight.) After each choice the permutations of the set are generated. Pretty straight forward.

The insight I had for the second version of the program is to pre-compute all the button pair combinations. With only eight possible keys, there are only:


total_pairs = (total_keys * (total_keys - 1)) / 2
            = (8 * (8 - 1)) / 2
            = 28

Therefore, there are 28 pair combinations plus eight single key presses for a total of 36 possible button presses. Now, I can consider the whole single versus pair problem as a simple k-of-36 with k increasing from 1 to 8. This simplifies a lot of the code.

Pairs are stored in a single integer as the upper and lower nibbles of a byte. Single buttons are also stored in an integer, but the upper nibble is zero to differentiate them from the pairs. The display routine uses this information to determine how the output should be handled.

In order to ensure that invalid combinations are not picked a simple bitmask is used to track the keys already used in the current combination. This decision does slow down the program a bit (with my tests showing the current code calculates all the combinations and permutations for eight keys in 4.6 seconds, while the older code could do the same in 2.9 seconds.)

I’m not happy about the slowdown in the execution, but the code is easier to understand, and the change did eliminate 35 lines of source code.

Source Code

The complete source code for combos.c can be compiled into an executable by doing: cc -o combos combos.c

Conclusion

I found the process of writing this application to be fascinating. I had never developed code requiring either permutations or combinations. Even after I wrote a version that solved the problem I still felt compelled to come up with a better version. At 125 lines, this version is closer to meeting the requirements of the challenge, but it’s still not enough. I’ll have to come back to this problem again.

Jun 20, 2005

SpamAssassin Additions

Delivery Scripts

I've written a shell script that handles local delivery of email in a qmail environment.

To use the script you would place it in your .qmail file similar to this:


.qmail:
  |/usr/local/bin/spamassassin.sh

Of course, use the correct path to the script on your system.

I wrote this script (rather than using ifspamh) because I needed a way to delete high scoring messages that could be customized by the end user. In addition, I didn't want to store the full message in memory like ifspamh does.

Required Software

The following packages are required to be installed and working correctly for the spamassassin.sh to work properly:

spam_bounce

The above shell script does rely on one extra program called spam_bounce. This program takes an email address on standard input and returns a numerical limit for that user on standard output. If there is no numerical limit for the supplied email address, it must return 0. The score returned by spam_bounce is used to determine whether to deliver the message or to delete it. Any email messages scored by SpamAssassin higher than the value returned by spam_bounce will be deleted from the user's mailbox. The default bounce score is defined in spamassassin.sh as 13.75.

I separated the spam_bounce functionality out of the main delivery script because different people would have this spam score limit information stored differently. The simplest method would be to have a shell script that looked up the information is a flat text file. On my system, I have a C program that retrieves the information from a MySQL database where all the SpamAssassin user preferences are stored.

Custom Rules

The local rules used by the Flarenet mail server are updated on a daily basis. I'm using a new system where I annotate when each rule was added or modified and why.

Local SpamAssassin Rules

Mar 12, 2005

Additions for Qpsmtpd

Plugins

These plugins are used daily by the Flarenet ISP mail server, but I have not submitted them to the Qpsmtpd maintainers. As always, use these plugins at your own risk. They work for me, but as far as I know I'm the only one using them.

check_badpatterns
Use the existing badmailpatterns and badrcptpatterns control files from the SPAMCONTROL patch.
check_domain_regexp
Compares the reverse DNS (the host/domain name) against a collection of regular expressions.
check_goodrcptto
Allow (or white-list) certain email RCPT TO email addresses or users. This is useful for allowing postmaster and abuse mail through.
rblsmtpd_env
Mimics rblsmtpd functionality with respect to the RBLSMTPD environment variable.

Pending Patches

The following patches have been sent to the Qpsmtpd mailing list, but are not currently part of the Qpsmtpd distribution. The date in brackets is the day I submitted the patch.