Home | History | Annotate | Line # | Download | only in postscreen
      1 /*	$NetBSD: postscreen.h,v 1.4 2022/10/08 16:12:48 christos Exp $	*/
      2 
      3 /*++
      4 /* NAME
      5 /*	postscreen 3h
      6 /* SUMMARY
      7 /*	postscreen internal interfaces
      8 /* SYNOPSIS
      9 /*	#include <postscreen.h>
     10 /* DESCRIPTION
     11 /* .nf
     12 
     13  /*
     14   * System library.
     15   */
     16 
     17  /*
     18   * Utility library.
     19   */
     20 #include <dict_cache.h>
     21 #include <vstream.h>
     22 #include <vstring.h>
     23 #include <events.h>
     24 #include <htable.h>
     25 #include <myaddrinfo.h>
     26 
     27  /*
     28   * Global library.
     29   */
     30 #include <addr_match_list.h>
     31 #include <string_list.h>
     32 #include <maps.h>
     33 #include <server_acl.h>
     34 
     35  /*
     36   * Preliminary stuff, to be fixed.
     37   */
     38 #define PSC_READ_BUF_SIZE	1024
     39 
     40  /*
     41   * Numeric indices and symbolic names for tests whose time stamps and status
     42   * flags can be accessed by numeric index.
     43   */
     44 #define PSC_TINDX_PREGR	0		/* pregreet */
     45 #define PSC_TINDX_DNSBL	1		/* dnsbl */
     46 #define PSC_TINDX_PIPEL	2		/* pipelining */
     47 #define PSC_TINDX_NSMTP	3		/* non-smtp command */
     48 #define PSC_TINDX_BARLF	4		/* bare newline */
     49 #define PSC_TINDX_COUNT	5		/* number of tests */
     50 
     51 #define PSC_TNAME_PREGR	"pregreet"
     52 #define PSC_TNAME_DNSBL	"dnsbl"
     53 #define PSC_TNAME_PIPEL	"pipelining"
     54 #define PSC_TNAME_NSMTP	"non-smtp command"
     55 #define PSC_TNAME_BARLF	"bare newline"
     56 
     57 #define PSC_TINDX_BYTNAME(tname) (PSC_TINDX_ ## tname)
     58 
     59  /*
     60   * Per-client shared state.
     61   */
     62 typedef struct {
     63     int     concurrency;		/* per-client */
     64     int     pass_new_count;		/* per-client */
     65     time_t  expire_time[PSC_TINDX_COUNT];	/* per-test expiration */
     66 } PSC_CLIENT_INFO;
     67 
     68  /*
     69   * Per-session state.
     70   */
     71 typedef struct {
     72     int     flags;			/* see below */
     73     /* Socket state. */
     74     VSTREAM *smtp_client_stream;	/* remote SMTP client */
     75     int     smtp_server_fd;		/* real SMTP server */
     76     char   *smtp_client_addr;		/* client address */
     77     char   *smtp_client_port;		/* client port */
     78     char   *smtp_server_addr;		/* server address */
     79     char   *smtp_server_port;		/* server port */
     80     const char *final_reply;		/* cause for hanging up */
     81     VSTRING *send_buf;			/* pending output */
     82     /* Test context. */
     83     struct timeval start_time;		/* start of current test */
     84     const char *test_name;		/* name of current test */
     85     PSC_CLIENT_INFO *client_info;	/* shared client state */
     86     VSTRING *dnsbl_reply;		/* dnsbl reject text */
     87     int     dnsbl_score;		/* saved DNSBL score */
     88     int     dnsbl_ttl;			/* saved DNSBL TTL */
     89     const char *dnsbl_name;		/* DNSBL name with largest weight */
     90     int     dnsbl_index;		/* dnsbl request index */
     91     const char *rcpt_reply;		/* how to reject recipients */
     92     int     command_count;		/* error + junk command count */
     93     const char *protocol;		/* SMTP or ESMTP */
     94     char   *helo_name;			/* SMTP helo/ehlo */
     95     char   *sender;			/* MAIL FROM */
     96     VSTRING *cmd_buffer;		/* command read buffer */
     97     int     read_state;			/* command read state machine */
     98     /* smtpd(8) compatibility */
     99     int     ehlo_discard_mask;		/* EHLO filter */
    100     VSTRING *expand_buf;		/* macro expansion */
    101     const char *where;			/* SMTP protocol state */
    102 } PSC_STATE;
    103 
    104  /*
    105   * Special expiration time values.
    106   */
    107 #define PSC_TIME_STAMP_NEW		(0)	/* test was never passed */
    108 #define PSC_TIME_STAMP_DISABLED		(1)	/* never passed but disabled */
    109 #define PSC_TIME_STAMP_INVALID		(-1)	/* must not be cached */
    110 
    111  /*
    112   * Status flags.
    113   */
    114 #define PSC_STATE_FLAG_NOFORWARD	(1<<0)	/* don't forward this session */
    115 #define PSC_STATE_FLAG_USING_TLS	(1<<1)	/* using the TLS proxy */
    116 #define PSC_STATE_FLAG_UNUSED2		(1<<2)	/* use me! */
    117 #define PSC_STATE_FLAG_NEW		(1<<3)	/* some test was never passed */
    118 #define PSC_STATE_FLAG_DNLIST_FAIL	(1<<4)	/* denylisted */
    119 #define PSC_STATE_FLAG_HANGUP		(1<<5)	/* NOT a test failure */
    120 #define PSC_STATE_FLAG_SMTPD_X21	(1<<6)	/* hang up after command */
    121 #define PSC_STATE_FLAG_ALLIST_FAIL	(1<<7)	/* do not allowlist */
    122 #define PSC_STATE_FLAG_TEST_BASE	(8)	/* start of indexable flags */
    123 
    124  /*
    125   * Tests whose flags and expiration time can be accessed by numerical index.
    126   *
    127   * Important: every MUMBLE_TODO flag must have a MUMBLE_PASS flag, such that
    128   * MUMBLE_PASS == PSC_STATE_FLAGS_TODO_TO_PASS(MUMBLE_TODO).
    129   *
    130   * MUMBLE_TODO flags must not be cleared once raised. The _TODO_TO_PASS and
    131   * _TODO_TO_DONE macros depend on this to decide that a group of tests is
    132   * passed or completed.
    133   *
    134   * MUMBLE_DONE flags are used for "early" tests that have final results.
    135   *
    136   * MUMBLE_SKIP flags are used for "deep" tests where the client messed up.
    137   * These flags look like MUMBLE_DONE but they are different. Deep tests can
    138   * tentatively pass, but can still fail later in a session. The "ignore"
    139   * action introduces an additional complication. MUMBLE_PASS indicates
    140   * either that a deep test passed tentatively, or that the test failed but
    141   * the result was ignored. MUMBLE_FAIL, on the other hand, is always final.
    142   * We use MUMBLE_SKIP to indicate that a decision was either "fail" or
    143   * forced "pass".
    144   *
    145   * The difference between DONE and SKIP is in the beholder's eye. These flags
    146   * share the same bit.
    147   */
    148 #define PSC_STATE_FLAGS_TODO_TO_PASS(todo_flags) ((todo_flags) >> 1)
    149 #define PSC_STATE_FLAGS_TODO_TO_DONE(todo_flags) ((todo_flags) << 1)
    150 
    151 #define PSC_STATE_FLAG_SHIFT_FAIL	(0)	/* failed test */
    152 #define PSC_STATE_FLAG_SHIFT_PASS	(1)	/* passed test */
    153 #define PSC_STATE_FLAG_SHIFT_TODO	(2)	/* expired test */
    154 #define PSC_STATE_FLAG_SHIFT_DONE	(3)	/* decision is final */
    155 #define PSC_STATE_FLAG_SHIFT_SKIP	(3)	/* action is already logged */
    156 #define PSC_STATE_FLAG_SHIFT_STRIDE	(4)	/* nr of flags per test */
    157 
    158 #define PSC_STATE_FLAG_SHIFT_BYFNAME(fname) (PSC_STATE_FLAG_SHIFT_ ## fname)
    159 
    160  /*
    161   * Indexable per-test flags. These are used for DNS allowlisting multiple
    162   * tests, without needing per-test ad-hoc code.
    163   */
    164 #define PSC_STATE_FLAG_BYTINDX_FNAME(tindx, fname) \
    165 	(1U << (PSC_STATE_FLAG_TEST_BASE \
    166 	    + PSC_STATE_FLAG_SHIFT_STRIDE * (tindx) \
    167 	    + PSC_STATE_FLAG_SHIFT_BYFNAME(fname)))
    168 
    169 #define PSC_STATE_FLAG_BYTINDX_FAIL(tindx) \
    170 	PSC_STATE_FLAG_BYTINDX_FNAME((tindx), FAIL)
    171 #define PSC_STATE_FLAG_BYTINDX_PASS(tindx) \
    172 	PSC_STATE_FLAG_BYTINDX_FNAME((tindx), PASS)
    173 #define PSC_STATE_FLAG_BYTINDX_TODO(tindx) \
    174 	PSC_STATE_FLAG_BYTINDX_FNAME((tindx), TODO)
    175 #define PSC_STATE_FLAG_BYTINDX_DONE(tindx) \
    176 	PSC_STATE_FLAG_BYTINDX_FNAME((tindx), DONE)
    177 #define PSC_STATE_FLAG_BYTINDX_SKIP(tindx) \
    178 	PSC_STATE_FLAG_BYTINDX_FNAME((tindx), SKIP)
    179 
    180  /*
    181   * Flags with distinct names. These are used in the per-test ad-hoc code.
    182   */
    183 #define PSC_STATE_FLAG_BYTNAME_FNAME(tname, fname) \
    184 	(1U << (PSC_STATE_FLAG_TEST_BASE \
    185 	    + PSC_STATE_FLAG_SHIFT_STRIDE * PSC_TINDX_BYTNAME(tname) \
    186 	    + PSC_STATE_FLAG_SHIFT_BYFNAME(fname)))
    187 
    188 #define PSC_STATE_FLAG_PREGR_FAIL PSC_STATE_FLAG_BYTNAME_FNAME(PREGR, FAIL)
    189 #define PSC_STATE_FLAG_PREGR_PASS PSC_STATE_FLAG_BYTNAME_FNAME(PREGR, PASS)
    190 #define PSC_STATE_FLAG_PREGR_TODO PSC_STATE_FLAG_BYTNAME_FNAME(PREGR, TODO)
    191 #define PSC_STATE_FLAG_PREGR_DONE PSC_STATE_FLAG_BYTNAME_FNAME(PREGR, DONE)
    192 
    193 #define PSC_STATE_FLAG_DNSBL_FAIL PSC_STATE_FLAG_BYTNAME_FNAME(DNSBL, FAIL)
    194 #define PSC_STATE_FLAG_DNSBL_PASS PSC_STATE_FLAG_BYTNAME_FNAME(DNSBL, PASS)
    195 #define PSC_STATE_FLAG_DNSBL_TODO PSC_STATE_FLAG_BYTNAME_FNAME(DNSBL, TODO)
    196 #define PSC_STATE_FLAG_DNSBL_DONE PSC_STATE_FLAG_BYTNAME_FNAME(DNSBL, DONE)
    197 
    198 #define PSC_STATE_FLAG_PIPEL_FAIL PSC_STATE_FLAG_BYTNAME_FNAME(PIPEL, FAIL)
    199 #define PSC_STATE_FLAG_PIPEL_PASS PSC_STATE_FLAG_BYTNAME_FNAME(PIPEL, PASS)
    200 #define PSC_STATE_FLAG_PIPEL_TODO PSC_STATE_FLAG_BYTNAME_FNAME(PIPEL, TODO)
    201 #define PSC_STATE_FLAG_PIPEL_SKIP PSC_STATE_FLAG_BYTNAME_FNAME(PIPEL, SKIP)
    202 
    203 #define PSC_STATE_FLAG_NSMTP_FAIL PSC_STATE_FLAG_BYTNAME_FNAME(NSMTP, FAIL)
    204 #define PSC_STATE_FLAG_NSMTP_PASS PSC_STATE_FLAG_BYTNAME_FNAME(NSMTP, PASS)
    205 #define PSC_STATE_FLAG_NSMTP_TODO PSC_STATE_FLAG_BYTNAME_FNAME(NSMTP, TODO)
    206 #define PSC_STATE_FLAG_NSMTP_SKIP PSC_STATE_FLAG_BYTNAME_FNAME(NSMTP, SKIP)
    207 
    208 #define PSC_STATE_FLAG_BARLF_FAIL PSC_STATE_FLAG_BYTNAME_FNAME(BARLF, FAIL)
    209 #define PSC_STATE_FLAG_BARLF_PASS PSC_STATE_FLAG_BYTNAME_FNAME(BARLF, PASS)
    210 #define PSC_STATE_FLAG_BARLF_TODO PSC_STATE_FLAG_BYTNAME_FNAME(BARLF, TODO)
    211 #define PSC_STATE_FLAG_BARLF_SKIP PSC_STATE_FLAG_BYTNAME_FNAME(BARLF, SKIP)
    212 
    213  /*
    214   * Aggregates for individual tests.
    215   */
    216 #define PSC_STATE_MASK_PREGR_TODO_FAIL \
    217 	(PSC_STATE_FLAG_PREGR_TODO | PSC_STATE_FLAG_PREGR_FAIL)
    218 #define PSC_STATE_MASK_DNSBL_TODO_FAIL \
    219 	(PSC_STATE_FLAG_DNSBL_TODO | PSC_STATE_FLAG_DNSBL_FAIL)
    220 #define PSC_STATE_MASK_PIPEL_TODO_FAIL \
    221 	(PSC_STATE_FLAG_PIPEL_TODO | PSC_STATE_FLAG_PIPEL_FAIL)
    222 #define PSC_STATE_MASK_NSMTP_TODO_FAIL \
    223 	(PSC_STATE_FLAG_NSMTP_TODO | PSC_STATE_FLAG_NSMTP_FAIL)
    224 #define PSC_STATE_MASK_BARLF_TODO_FAIL \
    225 	(PSC_STATE_FLAG_BARLF_TODO | PSC_STATE_FLAG_BARLF_FAIL)
    226 
    227 #define PSC_STATE_MASK_PREGR_TODO_DONE \
    228 	(PSC_STATE_FLAG_PREGR_TODO | PSC_STATE_FLAG_PREGR_DONE)
    229 #define PSC_STATE_MASK_PIPEL_TODO_SKIP \
    230 	(PSC_STATE_FLAG_PIPEL_TODO | PSC_STATE_FLAG_PIPEL_SKIP)
    231 #define PSC_STATE_MASK_NSMTP_TODO_SKIP \
    232 	(PSC_STATE_FLAG_NSMTP_TODO | PSC_STATE_FLAG_NSMTP_SKIP)
    233 #define PSC_STATE_MASK_BARLF_TODO_SKIP \
    234 	(PSC_STATE_FLAG_BARLF_TODO | PSC_STATE_FLAG_BARLF_SKIP)
    235 
    236 #define PSC_STATE_MASK_PREGR_FAIL_DONE \
    237 	(PSC_STATE_FLAG_PREGR_FAIL | PSC_STATE_FLAG_PREGR_DONE)
    238 
    239 #define PSC_STATE_MASK_PIPEL_TODO_PASS_FAIL \
    240 	(PSC_STATE_MASK_PIPEL_TODO_FAIL | PSC_STATE_FLAG_PIPEL_PASS)
    241 #define PSC_STATE_MASK_NSMTP_TODO_PASS_FAIL \
    242 	(PSC_STATE_MASK_NSMTP_TODO_FAIL | PSC_STATE_FLAG_NSMTP_PASS)
    243 #define PSC_STATE_MASK_BARLF_TODO_PASS_FAIL \
    244 	(PSC_STATE_MASK_BARLF_TODO_FAIL | PSC_STATE_FLAG_BARLF_PASS)
    245 
    246  /*
    247   * Separate aggregates for early tests and deep tests.
    248   */
    249 #define PSC_STATE_MASK_EARLY_DONE \
    250 	(PSC_STATE_FLAG_PREGR_DONE | PSC_STATE_FLAG_DNSBL_DONE)
    251 #define PSC_STATE_MASK_EARLY_TODO \
    252 	(PSC_STATE_FLAG_PREGR_TODO | PSC_STATE_FLAG_DNSBL_TODO)
    253 #define PSC_STATE_MASK_EARLY_PASS \
    254 	(PSC_STATE_FLAG_PREGR_PASS | PSC_STATE_FLAG_DNSBL_PASS)
    255 #define PSC_STATE_MASK_EARLY_FAIL \
    256 	(PSC_STATE_FLAG_PREGR_FAIL | PSC_STATE_FLAG_DNSBL_FAIL)
    257 
    258 #define PSC_STATE_MASK_SMTPD_TODO \
    259 	(PSC_STATE_FLAG_PIPEL_TODO | PSC_STATE_FLAG_NSMTP_TODO | \
    260 	PSC_STATE_FLAG_BARLF_TODO)
    261 #define PSC_STATE_MASK_SMTPD_PASS \
    262 	(PSC_STATE_FLAG_PIPEL_PASS | PSC_STATE_FLAG_NSMTP_PASS | \
    263 	PSC_STATE_FLAG_BARLF_PASS)
    264 #define PSC_STATE_MASK_SMTPD_FAIL \
    265 	(PSC_STATE_FLAG_PIPEL_FAIL | PSC_STATE_FLAG_NSMTP_FAIL | \
    266 	PSC_STATE_FLAG_BARLF_FAIL)
    267 
    268  /*
    269   * Super-aggregates for all tests combined.
    270   */
    271 #define PSC_STATE_MASK_ANY_FAIL \
    272 	(PSC_STATE_FLAG_DNLIST_FAIL | \
    273 	PSC_STATE_MASK_EARLY_FAIL | PSC_STATE_MASK_SMTPD_FAIL | \
    274 	PSC_STATE_FLAG_ALLIST_FAIL)
    275 
    276 #define PSC_STATE_MASK_ANY_PASS \
    277 	(PSC_STATE_MASK_EARLY_PASS | PSC_STATE_MASK_SMTPD_PASS)
    278 
    279 #define PSC_STATE_MASK_ANY_TODO \
    280 	(PSC_STATE_MASK_EARLY_TODO | PSC_STATE_MASK_SMTPD_TODO)
    281 
    282 #define PSC_STATE_MASK_ANY_TODO_FAIL \
    283 	(PSC_STATE_MASK_ANY_TODO | PSC_STATE_MASK_ANY_FAIL)
    284 
    285 #define PSC_STATE_MASK_ANY_UPDATE \
    286 	(PSC_STATE_MASK_ANY_PASS)
    287 
    288  /*
    289   * Meta-commands for state->where that reflect the initial command processor
    290   * state and commands that aren't implemented.
    291   */
    292 #define PSC_SMTPD_CMD_CONNECT		"CONNECT"
    293 #define PSC_SMTPD_CMD_UNIMPL		"UNIMPLEMENTED"
    294 
    295  /*
    296   * See log_adhoc.c for discussion.
    297   */
    298 typedef struct {
    299     int     dt_sec;			/* make sure it's signed */
    300     int     dt_usec;			/* make sure it's signed */
    301 } DELTA_TIME;
    302 
    303 #define PSC_CALC_DELTA(x, y, z) \
    304     do { \
    305 	(x).dt_sec = (y).tv_sec - (z).tv_sec; \
    306 	(x).dt_usec = (y).tv_usec - (z).tv_usec; \
    307 	while ((x).dt_usec < 0) { \
    308 	    (x).dt_usec += 1000000; \
    309 	    (x).dt_sec -= 1; \
    310 	} \
    311 	while ((x).dt_usec >= 1000000) { \
    312 	    (x).dt_usec -= 1000000; \
    313 	    (x).dt_sec += 1; \
    314 	} \
    315 	if ((x).dt_sec < 0) \
    316 	    (x).dt_sec = (x).dt_usec = 0; \
    317     } while (0)
    318 
    319 #define SIG_DIGS        2
    320 
    321  /*
    322   * Event management.
    323   */
    324 
    325 /* PSC_READ_EVENT_REQUEST - prepare for transition to next state */
    326 
    327 #define PSC_READ_EVENT_REQUEST(fd, action, context, timeout) do { \
    328 	if (msg_verbose > 1) \
    329 	    msg_info("%s: read-request fd=%d", myname, (fd)); \
    330 	event_enable_read((fd), (action), (context)); \
    331 	event_request_timer((action), (context), (timeout)); \
    332     } while (0)
    333 
    334 #define PSC_READ_EVENT_REQUEST2(fd, read_act, time_act, context, timeout) do { \
    335 	if (msg_verbose > 1) \
    336 	    msg_info("%s: read-request fd=%d", myname, (fd)); \
    337 	event_enable_read((fd), (read_act), (context)); \
    338 	event_request_timer((time_act), (context), (timeout)); \
    339     } while (0)
    340 
    341 /* PSC_CLEAR_EVENT_REQUEST - complete state transition */
    342 
    343 #define PSC_CLEAR_EVENT_REQUEST(fd, time_act, context) do { \
    344 	if (msg_verbose > 1) \
    345 	    msg_info("%s: clear-request fd=%d", myname, (fd)); \
    346 	event_disable_readwrite(fd); \
    347 	event_cancel_timer((time_act), (context)); \
    348     } while (0)
    349 
    350  /*
    351   * Failure enforcement policies.
    352   */
    353 #define PSC_NAME_ACT_DROP	"drop"
    354 #define PSC_NAME_ACT_ENFORCE	"enforce"
    355 #define PSC_NAME_ACT_IGNORE	"ignore"
    356 #define PSC_NAME_ACT_CONT	"continue"
    357 
    358 #define PSC_ACT_DROP		1
    359 #define PSC_ACT_ENFORCE		2
    360 #define PSC_ACT_IGNORE		3
    361 
    362  /*
    363   * Global variables.
    364   */
    365 extern int psc_check_queue_length;	/* connections being checked */
    366 extern int psc_post_queue_length;	/* being sent to real SMTPD */
    367 extern DICT_CACHE *psc_cache_map;	/* cache table handle */
    368 extern VSTRING *psc_temp;		/* scratchpad */
    369 extern char *psc_smtpd_service_name;	/* path to real SMTPD */
    370 extern int psc_pregr_action;		/* PSC_ACT_DROP etc. */
    371 extern int psc_dnsbl_action;		/* PSC_ACT_DROP etc. */
    372 extern int psc_pipel_action;		/* PSC_ACT_DROP etc. */
    373 extern int psc_nsmtp_action;		/* PSC_ACT_DROP etc. */
    374 extern int psc_barlf_action;		/* PSC_ACT_DROP etc. */
    375 extern int psc_min_ttl;			/* Update with new tests! */
    376 extern STRING_LIST *psc_forbid_cmds;	/* CONNECT GET POST */
    377 extern int psc_stress_greet_wait;	/* stressed greet wait */
    378 extern int psc_normal_greet_wait;	/* stressed greet wait */
    379 extern int psc_stress_cmd_time_limit;	/* stressed command limit */
    380 extern int psc_normal_cmd_time_limit;	/* normal command time limit */
    381 extern int psc_stress;			/* stress level */
    382 extern int psc_lowat_check_queue_length;/* stress low-water mark */
    383 extern int psc_hiwat_check_queue_length;/* stress high-water mark */
    384 extern DICT *psc_dnsbl_reply;		/* DNSBL name mapper */
    385 extern HTABLE *psc_client_concurrency;	/* per-client concurrency */
    386 
    387 #define PSC_EFF_GREET_WAIT \
    388 	(psc_stress ? psc_stress_greet_wait : psc_normal_greet_wait)
    389 #define PSC_EFF_CMD_TIME_LIMIT \
    390 	(psc_stress ? psc_stress_cmd_time_limit : psc_normal_cmd_time_limit)
    391 
    392  /*
    393   * String plumbing macros.
    394   */
    395 #define PSC_STRING_UPDATE(str, text) do { \
    396 	if (str) myfree(str); \
    397 	(str) = ((text) ? mystrdup(text) : 0); \
    398     } while (0)
    399 
    400 #define PSC_STRING_RESET(str) do { \
    401 	if (str) { \
    402 	    myfree(str); \
    403 	    (str) = 0; \
    404 	} \
    405     } while (0)
    406 
    407  /*
    408   * SLMs.
    409   */
    410 #define STR(x)  vstring_str(x)
    411 #define LEN(x)  VSTRING_LEN(x)
    412 
    413  /*
    414   * postscreen_state.c
    415   */
    416 #define PSC_CLIENT_ADDR_PORT(state) \
    417 	(state)->smtp_client_addr, (state)->smtp_client_port
    418 
    419 #define PSC_PASS_SESSION_STATE(state, what, bits) do { \
    420 	if (msg_verbose) \
    421 	    msg_info("PASS %s [%s]:%s", (what), PSC_CLIENT_ADDR_PORT(state)); \
    422 	(state)->flags |= (bits); \
    423     } while (0)
    424 #define PSC_FAIL_SESSION_STATE(state, bits) do { \
    425 	if (msg_verbose) \
    426 	    msg_info("FAIL [%s]:%s", PSC_CLIENT_ADDR_PORT(state)); \
    427 	(state)->flags |= (bits); \
    428     } while (0)
    429 #define PSC_SKIP_SESSION_STATE(state, what, bits) do { \
    430 	if (msg_verbose) \
    431 	    msg_info("SKIP %s [%s]:%s", (what), PSC_CLIENT_ADDR_PORT(state)); \
    432 	(state)->flags |= (bits); \
    433     } while (0)
    434 #define PSC_DROP_SESSION_STATE(state, reply) do { \
    435 	if (msg_verbose) \
    436 	    msg_info("DROP [%s]:%s", PSC_CLIENT_ADDR_PORT(state)); \
    437 	(state)->flags |= PSC_STATE_FLAG_NOFORWARD; \
    438 	(state)->final_reply = (reply); \
    439 	psc_conclude(state); \
    440     } while (0)
    441 #define PSC_ENFORCE_SESSION_STATE(state, reply) do { \
    442 	if (msg_verbose) \
    443 	    msg_info("ENFORCE [%s]:%s", PSC_CLIENT_ADDR_PORT(state)); \
    444 	(state)->rcpt_reply = (reply); \
    445 	(state)->flags |= PSC_STATE_FLAG_NOFORWARD; \
    446     } while (0)
    447 #define PSC_UNPASS_SESSION_STATE(state, bits) do { \
    448 	if (msg_verbose) \
    449 	    msg_info("UNPASS [%s]:%s", PSC_CLIENT_ADDR_PORT(state)); \
    450 	(state)->flags &= ~(bits); \
    451     } while (0)
    452 #define PSC_UNFAIL_SESSION_STATE(state, bits) do { \
    453 	if (msg_verbose) \
    454 	    msg_info("UNFAIL [%s]:%s", PSC_CLIENT_ADDR_PORT(state)); \
    455 	(state)->flags &= ~(bits); \
    456     } while (0)
    457 #define PSC_ADD_SERVER_STATE(state, fd) do { \
    458 	(state)->smtp_server_fd = (fd); \
    459 	psc_post_queue_length++; \
    460     } while (0)
    461 #define PSC_DEL_SERVER_STATE(state) do { \
    462 	close((state)->smtp_server_fd); \
    463 	(state)->smtp_server_fd = (-1); \
    464 	psc_post_queue_length--; \
    465     } while (0)
    466 #define PSC_DEL_CLIENT_STATE(state) do { \
    467 	event_server_disconnect((state)->smtp_client_stream); \
    468 	(state)->smtp_client_stream = 0; \
    469 	psc_check_queue_length--; \
    470     } while (0)
    471 extern PSC_STATE *psc_new_session_state(VSTREAM *, const char *, const char *, const char *, const char *);
    472 extern void psc_free_session_state(PSC_STATE *);
    473 extern const char *psc_print_state_flags(int, const char *);
    474 
    475  /*
    476   * postscreen_dict.c
    477   */
    478 extern int psc_addr_match_list_match(ADDR_MATCH_LIST *, const char *);
    479 extern const char *psc_cache_lookup(DICT_CACHE *, const char *);
    480 extern void psc_cache_update(DICT_CACHE *, const char *, const char *);
    481 const char *psc_dict_get(DICT *, const char *);
    482 const char *psc_maps_find(MAPS *, const char *, int);
    483 
    484  /*
    485   * postscreen_dnsbl.c
    486   */
    487 extern void psc_dnsbl_init(void);
    488 extern int psc_dnsbl_retrieve(const char *, const char **, int, int *);
    489 extern int psc_dnsbl_request(const char *, void (*) (int, void *), void *);
    490 
    491  /*
    492   * postscreen_tests.c
    493   */
    494 #define PSC_INIT_TESTS(dst) do { \
    495 	time_t *_it_stamp_p; \
    496 	(dst)->flags = 0; \
    497 	for (_it_stamp_p = (dst)->client_info->expire_time; \
    498 	    _it_stamp_p < (dst)->client_info->expire_time + PSC_TINDX_COUNT; \
    499 	    _it_stamp_p++) \
    500 	    *_it_stamp_p = PSC_TIME_STAMP_INVALID; \
    501     } while (0)
    502 #define PSC_INIT_TEST_FLAGS_ONLY(dst) do { \
    503 	(dst)->flags = 0; \
    504     } while (0)
    505 #define PSC_BEGIN_TESTS(state, name) do { \
    506 	(state)->test_name = (name); \
    507 	GETTIMEOFDAY(&(state)->start_time); \
    508     } while (0)
    509 extern void psc_new_tests(PSC_STATE *);
    510 extern void psc_parse_tests(PSC_STATE *, const char *, time_t);
    511 extern void psc_todo_tests(PSC_STATE *, time_t);
    512 extern char *psc_print_tests(VSTRING *, PSC_STATE *);
    513 extern char *psc_print_grey_key(VSTRING *, const char *, const char *,
    514 				        const char *, const char *);
    515 extern const char *psc_test_name(int);
    516 
    517 #define PSC_MIN(x, y) ((x) < (y) ? (x) : (y))
    518 #define PSC_MAX(x, y) ((x) > (y) ? (x) : (y))
    519 
    520  /*
    521   * postscreen_early.c
    522   */
    523 extern void psc_early_tests(PSC_STATE *);
    524 extern void psc_early_init(void);
    525 
    526  /*
    527   * postscreen_smtpd.c
    528   */
    529 extern void psc_smtpd_tests(PSC_STATE *);
    530 extern void psc_smtpd_init(void);
    531 extern void psc_smtpd_pre_jail_init(void);
    532 
    533 #define PSC_SMTPD_X21(state, reply) do { \
    534 	(state)->flags |= PSC_STATE_FLAG_SMTPD_X21; \
    535 	(state)->final_reply = (reply); \
    536 	psc_smtpd_tests(state); \
    537     } while (0)
    538 
    539  /*
    540   * postscreen_misc.c
    541   */
    542 extern char *psc_format_delta_time(VSTRING *, struct timeval, DELTA_TIME *);
    543 extern void psc_conclude(PSC_STATE *);
    544 extern void psc_hangup_event(PSC_STATE *);
    545 
    546  /*
    547   * postscreen_send.c
    548   */
    549 #define PSC_SEND_REPLY psc_send_reply	/* legacy macro */
    550 extern void pcs_send_pre_jail_init(void);
    551 extern int psc_send_reply(PSC_STATE *, const char *);
    552 extern void psc_send_socket(PSC_STATE *);
    553 
    554  /*
    555   * postscreen_starttls.c
    556   */
    557 extern void psc_starttls_open(PSC_STATE *, EVENT_NOTIFY_FN);
    558 
    559  /*
    560   * postscreen_expand.c
    561   */
    562 extern VSTRING *psc_expand_filter;
    563 extern void psc_expand_init(void);
    564 extern const char *psc_expand_lookup(const char *, int, void *);
    565 
    566  /*
    567   * postscreen_endpt.c
    568   */
    569 typedef void (*PSC_ENDPT_LOOKUP_FN) (int, VSTREAM *,
    570 			             MAI_HOSTADDR_STR *, MAI_SERVPORT_STR *,
    571 			            MAI_HOSTADDR_STR *, MAI_SERVPORT_STR *);
    572 extern void psc_endpt_lookup(VSTREAM *, PSC_ENDPT_LOOKUP_FN);
    573 extern void psc_endpt_local_lookup(VSTREAM *, PSC_ENDPT_LOOKUP_FN);
    574 
    575  /*
    576   * postscreen_access emulation.
    577   */
    578 #define PSC_ACL_ACT_ALLOWLIST	SERVER_ACL_ACT_PERMIT
    579 #define PSC_ACL_ACT_DUNNO	SERVER_ACL_ACT_DUNNO
    580 #define PSC_ACL_ACT_DENYLIST	SERVER_ACL_ACT_REJECT
    581 #define PSC_ACL_ACT_ERROR	SERVER_ACL_ACT_ERROR
    582 
    583 #define psc_acl_pre_jail_init	server_acl_pre_jail_init
    584 #define psc_acl_parse		server_acl_parse
    585 #define psc_acl_eval(s,a,p)	server_acl_eval((s)->smtp_client_addr, (a), (p))
    586 
    587 /* LICENSE
    588 /* .ad
    589 /* .fi
    590 /*	The Secure Mailer license must be distributed with this software.
    591 /* AUTHOR(S)
    592 /*	Wietse Venema
    593 /*	IBM T.J. Watson Research
    594 /*	P.O. Box 704
    595 /*	Yorktown Heights, NY 10598, USA
    596 /*
    597 /*	Wietse Venema
    598 /*	Google, Inc.
    599 /*	111 8th Avenue
    600 /*	New York, NY 10011, USA
    601 /*--*/
    602