NAME
    Mail::SRS - Interface to Sender Rewriting Scheme

SYNOPSIS
            use Mail::SRS;
            my $srs = new Mail::SRS(
                    Secret    => [ .... ],    # scalar or array
                    MaxAge    => 49,          # days
                            );
            my $srsaddress = $srs->forward($sender, $alias);
            my $sender = $srs->reverse($srsaddress);

DESCRIPTION
    The Sender Rewriting Scheme preserves .forward functionality in an
    SPF-compliant world.

    SPF requires the SMTP client IP to match the envelope sender
    (return-path). When a message is forwarded through an intermediate
    server, that intermediate server may need to rewrite the return-path to
    remain SPF compliant. If the message bounces, that intermediate server
    needs to validate the bounce and forward the bounce to the original
    sender.

    SRS provides a convention for return-path rewriting which allows
    multiple forwarding servers to compact the return-path. SRS also
    provides an authentication mechanism to ensure that purported bounces
    are not arbitrarily forwarded.

    SRS is documented at http://spf.pobox.com/srs.html and many points about
    the scheme are discussed at http://www.anarres.org/projects/srs/

    For a better understanding of this code and how it functions, please run
    the interactive walkthrough in eg/simple.pl in this distribution. To run
    this from the build directory, type "make teach".

WARNING
    This API is now a release candidate and should remain stable.

    There have been INTERFACE CHANGES since Mail::SRS version 0.10.

    This code has been written by Shevek <shevek@cpan.org> to emulate the
    functionality (but not the exact behaviour) of Mail::SRS-0.10 from CPAN.
    The original documentation for Mail::SRS version 0.10 is included for
    posterity in the files OLD-DOCS and README.pobox in this distribution.

    Implementors please note the warning about the adjustment of the HMAC
    hash below.

EXTENDING Mail::SRS
    Write a subclass. If people mail me asking for callbacks with the hash
    data from the standard subclasses, I will provide them. Callback hooks
    have not been provided in this release candidate.

    $srs = new Mail::SRS(...)
    Construct a new Mail::SRS object and return it. Available parameters
    are:

    Secret
        A key for the cryptographic algorithms. This may be an array or a
        single string. A string is promoted into an array of one element.

    MaxAge
        The maximum number of days for which a timestamp is considered
        valid. After this time, the timestamp is invalid.

    Some subclasses require other parameters. See their documentation for
    details.

METHODS
    $srsaddress = $srs->forward($sender, $alias)
    Map a sender address into a new sender and a cryptographic cookie.
    Returns an SRS address to use as the new sender.

    There are alternative subclasses, some of which will return SRS
    compliant addresses, some will simply return non-SRS but valid RFC821
    addresses. See the interactive walkthrough for more information on this
    ("make teach").

    $sender = $srs->reverse($srsaddress)
    Reverse the mapping to get back the original address. Validates all
    cryptographic and timestamp information. Returns the original sender
    address.

    $srs->compile($sendhost, $senduser)
    This method, designed to be overridden by subclasses, takes as
    parameters the original host and user and must compile a new username
    for the SRS transformed address. It is expected that this new username
    will be joined on $self->separator, and will contain a hash generated
    from $self->hash_create(...), and possibly a timestamp generated by
    $self->timestamp_create().

    $srs->parse($srsuser)
    This method, designed to be overridden by subclasses, takes an
    SRS-transformed username as an argument, and must reverse the
    transformation produced by compile(). It is required to verify any hash
    and timestamp in the parsed data, using $self->hash_verify($hash, ...)
    and $self->timestamp_check($timestamp).

    $srs->timestamp_create([$time])
    Return a two character timestamp representing 'today', or $time if
    given. $time is a Unix timestamp (seconds since the aeon).

    $srs->timestamp_check($timestamp)
    Return 1 if a timestamp is valid, undef otherwise. There are 65536
    possible timestamps, used in a cycle. At any time, $srs->{MaxAge}
    timestamps in this cycle are valid, the last one being today. A
    timestamp from the future is not valid, neither is a timestamp from too
    far into the past. Of course if you go far enough into the future, the
    cycle wraps around, and there are valid timestamps again, but the
    likelihood of a random timestamp being valid is 65536/$srs->{MaxAge},
    which is usually quite small: 1 in 2114 by default.

    $srs->time_check($time)
    Similar to $srs->timestamp_check($timestamp), but takes a Unix time, and
    checks that an alias created at that Unix time is still valid. This is
    designed for use by subclasses with storage backends.

    $srs->hash_create(@data)
    Returns a cryptographic hash of all data in @data. Any piece of data
    encoded into an address which must remain inviolate should be hashed, so
    that when the address is reversed, we can check that this data has not
    been tampered with. You must provide at least one piece of data to this
    method (otherwise this system is both cryptographically weak and there
    may be collision problems with sender addresses).

    WARNING: The digest is slightly modified: Digest::HMAC_MD5 uses + as one
    of the base64 characters. We cannot allow that since we use + as our SRS
    separator. So we replace every + with a - and reverse this text
    transformation in hash_verify(). Our base64 character set is therefore
    'A-Za-z0-9=/' instead of 'A-Za-z0-9+/'

    $srs->hash_verify($hash, @data)
    Verify that @data has not been tampered with, given the cryptographic
    hash previously output by $srs->hash_create(); Returns 1 or undef. All
    known secrets are tried in order to see if the hash was created with an
    old secret.

    $srs->set_secret($new, @old)
    Add a new secret to the rewriter. When an address is returned, all
    secrets are tried to see if the hash can be validated. Don't use "foo".

    $srs->get_secret()
    Return the list of secrets. These are secret. Don't publish them.

SEE ALSO
    Mail::SRS::DB, Mail::SRS::Reversable, "make teach", eg/*

AUTHOR
            Shevek
            CPAN ID: SHEVEK
            cpan@anarres.org
            http://www.anarres.org/projects/

COPYRIGHT
    Copyright (c) 2004 Shevek. All rights reserved.

    This program is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

