Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  postscreen_tests.c

  Sprache: C
 

/*++
/* NAME
/* postscreen_tests 3
/* SUMMARY
/* postscreen tests timestamp/flag bulk support
/* SYNOPSIS
/* #include <postscreen.h>
/*
/* void PSC_INIT_TESTS(state)
/* PSC_STATE *state;
/*
/* void psc_new_tests(state)
/* PSC_STATE *state;
/*
/* void psc_parse_tests(state, stamp_text, time_value)
/* PSC_STATE *state;
/* const char *stamp_text;
/* time_t time_value;
/*
/* void psc_todo_tests(state, time_value)
/* PSC_STATE *state;
/* const char *stamp_text;
/* time_t time_value;
/*
/* char *psc_print_tests(buffer, state)
/* VSTRING *buffer;
/* PSC_STATE *state;
/*
/* char *psc_print_grey_key(buffer, client, helo, sender, rcpt)
/* VSTRING *buffer;
/* const char *client;
/* const char *helo;
/* const char *sender;
/* const char *rcpt;
/*
/* const char *psc_test_name(tindx)
/* int tindx;
/* DESCRIPTION
/* The functions in this module overwrite the per-test expiration
/* time stamps and all flags bits.  Some functions are implemented
/* as unsafe macros, meaning they evaluate one or more arguments
/* multiple times.
/*
/* PSC_INIT_TESTS() is an unsafe macro that sets the per-test
/* expiration time stamps to PSC_TIME_STAMP_INVALID, and that
/* zeroes all the flags bits. These values are not meant to
/* be stored into the postscreen(8) cache.
/*
/* PSC_INIT_TEST_FLAGS_ONLY() zeroes all the flag bits.  It
/* should be used when the time stamps are already initialized.
/*
/* psc_new_tests() sets all test expiration time stamps to
/* PSC_TIME_STAMP_NEW, and invokes psc_todo_tests().
/*
/* psc_parse_tests() parses a cache file record and invokes
/* psc_todo_tests().
/*
/* psc_todo_tests() overwrites all per-session flag bits, and
/* populates the flags based on test expiration time stamp
/* information.  Tests are considered "expired" when they
/* would be expired at the specified time value. Only enabled
/* tests are flagged as "expired"; the object is flagged as
/* "new" if some enabled tests have "new" time stamps.
/*
/* psc_print_tests() creates a cache file record for the
/* specified flags and per-test expiration time stamps.
/* This may modify the time stamps for disabled tests.
/*
/* psc_print_grey_key() prints a greylist lookup key.
/*
/* psc_test_name() returns the name for the specified text
/* index.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/


/* System library. */

#include <sys_defs.h>
#include <stdio.h>   /* sscanf */

/* Utility library. */

#include <msg.h>
#include <name_code.h>
#include <sane_strtol.h>

/* Global library. */

#include <mail_params.h>

/* Application-specific. */

#include <postscreen.h>

 /*
  * Kludge to detect if some test is enabled.
  */

#define PSC_PREGR_TEST_ENABLE() (*var_psc_pregr_banner != 0)
#define PSC_DNSBL_TEST_ENABLE() (*var_psc_dnsbl_sites != 0)

 /*
  * Format of a persistent cache entry (which is almost but not quite the
  * same as the in-memory representation).
  * 
  * Each cache entry has one time stamp for each test.
  * 
  * - A time stamp of PSC_TIME_STAMP_INVALID must never appear in the cache. It
  * is reserved for in-memory objects that are still being initialized.
  * 
  * - A time stamp of PSC_TIME_STAMP_NEW indicates that the test never passed.
  * Postscreen will log the client with "pass new" when it passes the final
  * test.
  * 
  * - A time stamp of PSC_TIME_STAMP_DISABLED indicates that the test never
  * passed, and that the test was disabled when the cache entry was written.
  * 
  * - Otherwise, the test was passed, and the time stamp indicates when that
  * test result expires.
  * 
  * A cache entry is expired when the time stamps of all passed tests are
  * expired.
  */


/* psc_new_tests - initialize new test results from scratch */

void    psc_new_tests(PSC_STATE *state)
{
    time_t *expire_time = state->client_info->expire_time;

    /*
     * Give all tests a PSC_TIME_STAMP_NEW time stamp, so that we can later
     * recognize cache entries that haven't passed all enabled tests. When we
     * write a cache entry to the database, any new-but-disabled tests will
     * get a PSC_TIME_STAMP_DISABLED time stamp.
     */

    expire_time[PSC_TINDX_PREGR] = PSC_TIME_STAMP_NEW;
    expire_time[PSC_TINDX_DNSBL] = PSC_TIME_STAMP_NEW;
    expire_time[PSC_TINDX_PIPEL] = PSC_TIME_STAMP_NEW;
    expire_time[PSC_TINDX_NSMTP] = PSC_TIME_STAMP_NEW;
    expire_time[PSC_TINDX_BARLF] = PSC_TIME_STAMP_NEW;

    /*
     * Determine what tests need to be completed.
     */

    psc_todo_tests(state, PSC_TIME_STAMP_NEW + 1);
}

/* psc_parse_tests - parse test results from cache */

void    psc_parse_tests(PSC_STATE *state,
           const char *stamp_str,
           time_t time_value)
{
    const char *start = stamp_str;
    char   *cp;
    time_t *time_stamps = state->client_info->expire_time;
    time_t *sp;

    /*
     * Parse the cache entry, and allow for older postscreen versions that
     * implemented fewer tests. We pretend that the newer tests were disabled
     * at the time that the cache entry was written.
     */

    for (sp = time_stamps; sp < time_stamps + PSC_TINDX_COUNT; sp++) {
 *sp = sane_strtoul(start, &cp, 10);
 if (*start == 0 || (*cp != '\0' && *cp != ';') || errno == ERANGE)
     *sp = PSC_TIME_STAMP_DISABLED;
 if (msg_verbose)
     msg_info("%s -> %lu", start, (unsigned long) *sp);
 if (*cp == ';')
     start = cp + 1;
 else
     start = cp;
    }

    /*
     * Determine what tests need to be completed.
     */

    psc_todo_tests(state, time_value);
}

/* psc_todo_tests - determine what tests to perform */

void    psc_todo_tests(PSC_STATE *state, time_t time_value)
{
    time_t *expire_time = state->client_info->expire_time;
    time_t *sp;

    /*
     * Reset all per-session flags.
     */

    state->flags = 0;

    /*
     * Flag the tests as "new" when the cache entry has fields for all
     * enabled tests, but the remote SMTP client has not yet passed all those
     * tests.
     */

    for (sp = expire_time; sp < expire_time + PSC_TINDX_COUNT; sp++) {
 if (*sp == PSC_TIME_STAMP_NEW)
     state->flags |= PSC_STATE_FLAG_NEW;
    }

    /*
     * Don't flag disabled tests as "todo", because there would be no way to
     * make those bits go away.
     */

    if (PSC_PREGR_TEST_ENABLE() && time_value > expire_time[PSC_TINDX_PREGR])
 state->flags |= PSC_STATE_FLAG_PREGR_TODO;
    if (PSC_DNSBL_TEST_ENABLE() && time_value > expire_time[PSC_TINDX_DNSBL])
 state->flags |= PSC_STATE_FLAG_DNSBL_TODO;
    if (var_psc_pipel_enable && time_value > expire_time[PSC_TINDX_PIPEL])
 state->flags |= PSC_STATE_FLAG_PIPEL_TODO;
    if (var_psc_nsmtp_enable && time_value > expire_time[PSC_TINDX_NSMTP])
 state->flags |= PSC_STATE_FLAG_NSMTP_TODO;
    if (var_psc_barlf_enable && time_value > expire_time[PSC_TINDX_BARLF])
 state->flags |= PSC_STATE_FLAG_BARLF_TODO;

    /*
     * If any test has expired, proactively refresh tests that will expire
     * soon. This can increase the occurrence of client-visible delays, but
     * avoids questions about why a client can pass some test and then fail
     * within seconds. The proactive refresh time is really a surrogate for
     * the user's curiosity level, and therefore hard to choose optimally.
     */

#ifdef VAR_PSC_REFRESH_TIME
    if ((state->flags & PSC_STATE_MASK_ANY_TODO) != 0
 && var_psc_refresh_time > 0) {
 time_t  refresh_time = time_value + var_psc_refresh_time;

 if (PSC_PREGR_TEST_ENABLE() && refresh_time > expire_time[PSC_TINDX_PREGR])
     state->flags |= PSC_STATE_FLAG_PREGR_TODO;
 if (PSC_DNSBL_TEST_ENABLE() && refresh_time > expire_time[PSC_TINDX_DNSBL])
     state->flags |= PSC_STATE_FLAG_DNSBL_TODO;
 if (var_psc_pipel_enable && refresh_time > expire_time[PSC_TINDX_PIPEL])
     state->flags |= PSC_STATE_FLAG_PIPEL_TODO;
 if (var_psc_nsmtp_enable && refresh_time > expire_time[PSC_TINDX_NSMTP])
     state->flags |= PSC_STATE_FLAG_NSMTP_TODO;
 if (var_psc_barlf_enable && refresh_time > expire_time[PSC_TINDX_BARLF])
     state->flags |= PSC_STATE_FLAG_BARLF_TODO;
    }
#endif

    /*
     * Gratuitously make postscreen logging more useful by turning on all
     * enabled pre-handshake tests when any pre-handshake test is turned on.
     * 
     * XXX Don't enable PREGREET gratuitously before the test expires. With a
     * short TTL for DNSBL allowlisting, turning on PREGREET would force a
     * full postscreen_greet_wait too frequently.
     */

#if 0
    if (state->flags & PSC_STATE_MASK_EARLY_TODO) {
 if (PSC_PREGR_TEST_ENABLE())
     state->flags |= PSC_STATE_FLAG_PREGR_TODO;
 if (PSC_DNSBL_TEST_ENABLE())
     state->flags |= PSC_STATE_FLAG_DNSBL_TODO;
    }
#endif
}

/* psc_print_tests - print postscreen cache record */

char   *psc_print_tests(VSTRING *buf, PSC_STATE *state)
{
    const char *myname = "psc_print_tests";
    time_t *expire_time = state->client_info->expire_time;

    /*
     * Sanity check.
     */

    if ((state->flags & PSC_STATE_MASK_ANY_UPDATE) == 0)
 msg_panic("%s: attempt to save a no-update record", myname);

    /*
     * Give disabled tests a dummy time stamp so that we don't log a client
     * with "pass new" when some disabled test becomes enabled at some later
     * time.
     */

    if (PSC_PREGR_TEST_ENABLE() == 0 && expire_time[PSC_TINDX_PREGR] == PSC_TIME_STAMP_NEW)
 expire_time[PSC_TINDX_PREGR] = PSC_TIME_STAMP_DISABLED;
    if (PSC_DNSBL_TEST_ENABLE() == 0 && expire_time[PSC_TINDX_DNSBL] == PSC_TIME_STAMP_NEW)
 expire_time[PSC_TINDX_DNSBL] = PSC_TIME_STAMP_DISABLED;
    if (var_psc_pipel_enable == 0 && expire_time[PSC_TINDX_PIPEL] == PSC_TIME_STAMP_NEW)
 expire_time[PSC_TINDX_PIPEL] = PSC_TIME_STAMP_DISABLED;
    if (var_psc_nsmtp_enable == 0 && expire_time[PSC_TINDX_NSMTP] == PSC_TIME_STAMP_NEW)
 expire_time[PSC_TINDX_NSMTP] = PSC_TIME_STAMP_DISABLED;
    if (var_psc_barlf_enable == 0 && expire_time[PSC_TINDX_BARLF] == PSC_TIME_STAMP_NEW)
 expire_time[PSC_TINDX_BARLF] = PSC_TIME_STAMP_DISABLED;

    vstring_sprintf(buf, "%lu;%lu;%lu;%lu;%lu",
      (unsigned long) expire_time[PSC_TINDX_PREGR],
      (unsigned long) expire_time[PSC_TINDX_DNSBL],
      (unsigned long) expire_time[PSC_TINDX_PIPEL],
      (unsigned long) expire_time[PSC_TINDX_NSMTP],
      (unsigned long) expire_time[PSC_TINDX_BARLF]);
    return (STR(buf));
}

/* psc_print_grey_key - print postscreen cache record */

char   *psc_print_grey_key(VSTRING *buf, const char *client,
              const char *helo, const char *sender,
              const char *rcpt)
{
    return (STR(vstring_sprintf(buf, "%s/%s/%s/%s",
    client, helo, sender, rcpt)));
}

/* psc_test_name - map test index to symbolic name */

const char *psc_test_name(int tindx)
{
    const char *myname = "psc_test_name";
    const NAME_CODE test_name_map[] = {
 PSC_TNAME_PREGR, PSC_TINDX_PREGR,
 PSC_TNAME_DNSBL, PSC_TINDX_DNSBL,
 PSC_TNAME_PIPEL, PSC_TINDX_PIPEL,
 PSC_TNAME_NSMTP, PSC_TINDX_NSMTP,
 PSC_TNAME_BARLF, PSC_TINDX_BARLF,
 0, -1,
    };
    const char *result;

    if ((result = str_name_code(test_name_map, tindx)) == 0)
 msg_panic("%s: bad index %d", myname, tindx);
    return (result);
}

Messung V0.5 in Prozent
C=97 H=100 G=98

¤ Dauer der Verarbeitung: 0.24 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=738142