The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Mail::Address::Tagged - construct and validate email addresses with HMAC verification

SYNOPSIS

 #---------------------------------------------------------------------------
 # methods to use when constructing an address
 #---------------------------------------------------------------------------

 my $tag = Mail::Address::Tagged->new(key   => $key,
                                      email => 'foo@bar.com');

 my $seconds = $tag->set_valid_for($period);
 my $keyword = $tag->set_keyword('wibble');

 my $tag = Mail::Address::Tagged->new(key       => $key,
                                      user      => 'foo',
                                      host      => 'bar.com',
                                      valid_for => '10d',
                                      keyword   => 'wibble');

 $my $address = $tag->make_confirm(time    => $unix_time,
                                   pid     => $pid,
                                   keyword => $keyword);

 $my $address = $tag->make_confirm({time    => $unix_time,
                                    pid     => $pid,});

 $my $address = $tag->make_dated;
 $my $address = $tag->make_sender($address_to_receive_from);


 #---------------------------------------------------------------------------
 # methods to use when validating an address
 #---------------------------------------------------------------------------

 my $tag = Mail::Address::Tagged->for_received(key      => $key,
                                               received => $address,
                                               sender   => $sender,);

 if ($tag->valid) {
   ...
 }

 my $still_valid = ! $tag->expired;


 #---------------------------------------------------------------------------
 # Methods for accessing the objects internals (these will probably
 # be mainly used internally)
 #---------------------------------------------------------------------------

 my $email   = $tag->key;
 my $address = $tag->email;
 my $user    = $tag->user;
 my $host    = $tag->host;
 my $seconds = $tag->valid_for;
 my $keyword = $tag->keyword
 my $address = $tag->wrap('text_to_wrap');

 my $hmac = $tag->conf_mac(time => $time,
                           pid  => $pid);

 my $hmac = $tag->conf_mac(time    => $time,
                           pid     => $pid,
                           keyword => $value);

 my $hmac = $tag->single_value_mac($date);
 my $hmac = $tag->single_value_mac($sender);


 # only set by for_received

 my $received_time = $tag->candidate_time
 my $received_pid  = $tag->candidate_pid
 my $received_HMAC = $tag->candidate_mac
 my $address_type  = $tag->type
 my $correspondent = $tag->sender

DESCRIPTION

This module implements an object that can generate and validate tagged email addresses. These are designed to be used primarily in anti-spam applications.

The addresses generated all carry extra information, such as the date when they expire, who may use them to send you mail etc. A cryptocraphic hash of this extra information is also included in in the address. This Hashed Message Authenticaion Code (HMAC RFC 2104) is your guarantee that the information contained in the address has not been tampered with.

This module can generate and validate three different types of tagged address. They are all extensions of a users normal email address and are constructed in a similar manner. Where the normal address is user@host.com, the tagged address takes the form user-tagtype-tag@host.com.

The three supported address types are confirm, dated and sender.

Confirm addresses must contain a time (in unixtime) and the process id of the process that generated them, they may also optionally contain a keyword. They include the time and process id so that the system can deal with more than one message a second. Addresses of this type are used to request verification that a message should be delivered. The point being that automated mailers are unlikely to be able to respond in this way so spam will not get through. If a persistant spammer does reach your mailbox, then you can always black list the address. The keyword when it is supplied is the type of confirmation being asked for. All three bits of information are combined and a cryptographic hash is taken of the result, these bits of info are then combined like this.

  user-confirm-keyword.time.pid.HMAC@host.com

When mail like this is received, the bits can be separated out and a new HMAC generated, if it matches the one in the address, then this is a valid address.

Dated addresses have an expiry time and are used to accept mail up to a given time. They end up in the format

  user-dated-time.HMAC@host.com

and are validated in the same manner

The third type of supported address is sender, this takes the form

  user-sender-HMAC@host.com

the address that this will be accepted from is included in the HMAC generation. When mail of this form comes in the sending address can be checked against the HMAC if they don't match then appropriate action can be taken (disposal or confirmation request etc.).

FACTORY METHODS

new

  my $tag = Mail::Address::Tagged->new(key   => $key,
                                       email => 'foo@bar.com');

  my $tag = Mail::Address::Tagged->new(key       => $key,
                                       user      => 'foo',
                                       host      => 'bar.com',
                                       valid_for => '10d',
                                       keyword   => 'wibble');

Pass this your key and email address it will constrct an object for making tagged addresses. The email address may be complete e.g. foo@bar.com or supplied as user and host.

There are also various optional parametes that may be supplied to new.

You may pass the valid_for attribute to control how long dated address will be active for, if not supplied it defaults to 5 days (see set_valid_for documentation)

The keyword parameter is used when generating dated addresses. It is included in the string and allows for the generation of addresses like this:

name-confirm-keyword.12344556.123.ABCDEF@host.org

If not supplied it defaults to the empty string.

for_received

  my $tag = Mail::Address::Tagged->for_received(key      => $key,
                                                received => $address,
                                                sender   => $sender,);

This constructs an object based on the received address. It will break it down into it's component parts, these may then be queried and checked for validity.

INSTANCE METHODS - Construction

set_valid_for

  my $seconds = $tag->set_valid_for($period);

This allows one to set the time period that dated addresses will be valid for. Times periods are specified as a string which consists of a positive integer folowed by a period modifier. Valid modifiers are:

Y year
M month
w week
d day
h hours
s seconds

set_keyword

  my $keyword = $tag->set_keyword('wibble');

Set the keyword of this object. Returns the new keyword.

make_confirm

  $my $address = $tag->make_confirm(time    => $unix_time,
                                    pid     => $pid,
                                    keyword => $keyword);

  $my $address = $tag->make_confirm({time    => $unix_time,
                                     pid     => $pid,});

Return an address that will be used to confirm an email from an untrusted source. You must pass time and processid, you may also optionally pass a keyword.

make_dated

  $my $address = $tag->make_dated;

Return an address that will be allowed to send us mail for the default period of time from now.

make_sender

  $my $address = $tag->make_sender($address_to_receive_from);

Return an address that will only accept mail if it is sent from one particular sender address.

INSTANCE METHODS - querying

These methods are only useful on objects constructed with the for_received method. They will tell you whether the address is genuine and whether it has expired (for dated addresses).

valid

  if ($tag->valid) {
   ...
  }

This will tell you whether the HMAC matches the details of the address.

expired

  my $still_valid = ! $tag->expired;

This will tell you whether dated addresses have expired.

VALIDATION METHODS (mostly only for internal use)

conf_mac

  my $hmac = $tag->conf_mac(time => $time,
                            pid  => $pid);

  my $hmac = $tag->conf_mac(time    => $time,
                            pid     => $pid,
                            keyword => $value);

Return the HMAC for the time and pid passed in. The method may also take an optional keyword -> value pairing and if provided this will also be included in the HMAC generation.

single_value_mac

  my $hmac = $tag->single_value_mac($date);

  my $hmac = $tag->single_value_mac($sender);

Return the HMAC for the value passed in.

key

  my $email = $tag->key;

Return the cryptographic key that this address is using.

email

  my $address = $tag->email;

This returns the unaltered email address that this object is manipulating.

user

  my $user = $tag->user;

This returns the user portion of the email address that this object is manipulating.

host

  my $host = $tag->host;

This returns the host portion of the email address that this object is manipulating.

valid_for

  my $seconds = $tag->valid_for;

The number of seconds that a dated email address will be valid for.

keyword

  my $keyword = $tag->keyword

If a keyword was supplied to the constructor, this method returns its value.

wrap

  my $address = $hmac->wrap('text_to_wrap');

When you call this method it constructs an email address of the form

  nametext_to_wrap@host

that is it wraps its argument in the user and host

candidate_time

  my $time = $tag->candidate_time

The time in the address. This is only valid when an address of type confirm or dated is being validated. In all other cases it will return undef.

candidate_pid

  my $received_pid = $tag->candidate_pid

the pid in the address. this is only valid when a confirmation address is bing validated. it will return undef at all other times.

candidate_mac

  my $tag->candidate_mac

The HMAC of the address used to construct this object, this will only being valid for objects that have been instantiated to validate an address, it returns undef at all other times.

type

  $tag->type

The type of mail address used to create this object, it is only valid when this object is being used for validation, it will return undef at all other times.

sender

  $tag->sender

The sender argument passed to for_address when constructing an object to validate an address. If the object was not constructed to validate an addrss it will return undef.

BUGS

Nothing Known

TODO

Nothing Known