		DNSSEC extension to libspf2-1.0.4: Developer Guide
		==================================================
			         (Version 0.1)

Introduction
------------

The DNSSEC extension to libspf2 provides DNSSEC validation to DNS
queries in libspf2.

This document describes the changes to libspf2 to provide the DNSSEC
validation.  It is intended as a guide to developers who want to use this
functionality offered by libspf2.


Additions to libspf2
--------------------

The layered DNS architecture in libspf2 is amenable to adding DNSSEC
validation.

The 'resolv' DNS layer in libspf2-1.0.4 has been extended to allow
for a flag to indicate whether DNSSEC validation should be performed.

The following functions have been added for creating and destroying the
(secure) resolv layer to allow for DNSSEC validation:

SPF_dns_config_t SPF_dns_create_config_sresolv( SPF_dns_config_t layer_below,
	 				        int debug, int dodnssec);

void SPF_dns_reset_config_sresolv( SPF_dns_config_t spfdc );
void SPF_dns_destroy_config_sresolv( SPF_dns_config_t spfdc );

These functions are described in detail in the next section.

The following header and source files have been modified:
    
    src/include/spf.h:		    Additional error codes for
				    DNSSEC validation failure.

    src/include/spf_dns.h:	    Additional error codes for
				    DNSSEC validation failure.

    src/libspf2/spf_get_spf.c:	    Return appropriate errors
				    for DNSSEC validation failure.

    src/libspf2/spf_result.c:	    Return appropriate errors
				    for DNSSEC validation failure.

    src/include/spf_dns_resolv.h
    src/libspf2/spf_dns_resolv.c:   Additional functions for creation
				    of the secure resolv layer to
				    perform DNSSEC validation.

    src/libspf2/spf_eval_id.c:	    Return appropriate errors
				    for DNSSEC validation failure.

    src/libspf2/spf_strerror.c:	    Compose error string for
				    DNSSEC validation failure.

Additional return values from functions:
The SPF_get_spf function can now return an additional error value, if
DNSSEC validation fails:

    SPF_E_DNSSEC_FAILURE

API for Applications
--------------------

The following function is available for applications to add
DNSSEC validation to their use of libspf2:

(1)SPF_dns_config_t SPF_dns_create_config_sresolv(SPF_dns_config_t layer_below,
					          int debug, int dodnssec);

This function is used to create the dnssec-aware resolv layer.

If the value of the 'dodnssec' parameter is 1, DNSSEC validation will be
performed.  If the value is 0, DNSSEC validation will not be performed.

The 'layer_below' parameter specifies the DNS layer below the dnssec layer.
If dodnssec is '1', the layer_below will not be consulted.

The 'debug' parameter gives the debug level:
    0: Don't output debug or error statements
    1: Debug level 1.  Output error conditions.
    2: Debug level 2.  Output error conditions and debug statements.

This function returns a handle to the dnssec layer.
      
(2) void SPF_dns_reset_config_sresolv ( SPF_dns_config_t spfdc );
This function resets the resolv layer.

(3) void SPF_dns_destroy_config_sresolv ( SPF_dns_config_t spfdc );
This function frees up the memory allocated by the resolv layer.

The dnssec-aware secure resolver layers must be the bottom-most layer if
DNSSEC validation is to be performed.

If previously the layers were:

      dns-caching layer
      dns-resolver layer

Then, the new layers will be:

      dns-caching layer
      dnssec-aware dns-resolver layer

in that order.

The err_msg field in the output from the SPF_result() function in libspf2
now contains additional information about DNSSEC validation failure.  The
application can use this to inform the user of the application about dnssec
validation failure.


Example: Use of dnssec-extensions to libspf2-1.0.4 in spfmilter-1.0.8
---------------------------------------------------------------------

The resolvers[] array in spfmilter-1.0.8 is used to store the libspf2
DNS layers.  The dnssec-aware resolv layer can be added as follows:
(Error checking has not been shown for clarity.)

    if (!resolvers[r].initialized) {
        resolvers[r].spfdcid_r = SPF_dns_create_config_sresolv(NULL, debug, 1);
	resolvers[r].spfdcid_c = SPF_dns_create_config_cache (
				     resolvers[r].spfdcid_r,
				     cache_size,
				     debug);
	resolvers[r].initialized = 1;
    }

spfmilter-1.0.8 calls the SPF_result() function in libspf2 to perform the SPF
lookup.

    ld->output = SPF_result (ld->spfcid, resolvers[r].spfdcid_c);

The SPF_result function returns a pointer to an SPF_output_t structure.
The SPF_output_t structure contains five fields of interest:

    SPF_result_t	   result
    SPF_err_t		   err
    char *		   err_msg
    int			   num_errs
    char **		   err_msgs

If dodnssec flag is set (to a value of 1) and a DNSSEC validation failure
occurs, the values of these fields are as follows:

        result   = <result-value depending on other processing>
	err      = <err-value depending on other processing>
	err_msg  = "DNSSEC Validation of SPF record failed." (or similar)
	           or other value depending on other processing
	num_errs > 0
	err_msgs != NULL (It will contain the message
		          "DNSSEC Validation of SPF record failed." (or
			  similar) as one of its messages).

These output fields can be used by the client of this library
(say spfmilter) to inform the user about the error, or reject the
email.

The DNS layers are destroyed as follows:

    if ( resolvers[r].initialized ) {
	SPF_dns_destroy_config_cache   ( resolvers[r].spfdcid_c );
	SPF_dns_destroy_config_sresolv ( resolvers[r].spfdcid_r );
    }

If spfmilter is operating in the 'warn' mode, a message similar to the
following will be added to the Received-SPF mail-header as a "x-dnssec" field:

	     x-dnssec="fail (DNSSEC validation failed.)";

If spfmilter is operating in the 'warn' or 'reject' modes, and
DNSSEC validation succeeds, the Received-SPF mail-header will contain
the following:

	     x-dnssec="pass";

If spfmilter is operating in the 'ignore' mode, or if the SPF (TXT) record is
not present, DNSSEC validation is not performed.  The Received-SPF mail-header
will show:

	     x-dnssec="none";
==============================================================================
