Postfix3.3.1
postscreen_misc.c
[詳解]
1 /*++
2 /* NAME
3 /* postscreen_misc 3
4 /* SUMMARY
5 /* postscreen misc routines
6 /* SYNOPSIS
7 /* #include <postscreen.h>
8 /*
9 /* char *psc_format_delta_time(buf, tv, delta)
10 /* VSTRING *buf;
11 /* struct timeval tv;
12 /* DELTA_TIME *delta;
13 /*
14 /* void psc_conclude(state)
15 /* PSC_STATE *state;
16 /*
17 /* void psc_hangup_event(state)
18 /* PSC_STATE *state;
19 /* DESCRIPTION
20 /* psc_format_delta_time() computes the time difference between
21 /* tv (past) and the present, formats the time difference with
22 /* sub-second resolution in a human-readable way, and returns
23 /* the integer time difference in seconds through the delta
24 /* argument.
25 /*
26 /* psc_conclude() logs when a client passes all necessary tests,
27 /* updates the postscreen cache for any testes that were passed,
28 /* and either forwards the connection to a real SMTP server or
29 /* replies with the text in state->error_reply and hangs up the
30 /* connection (by default, state->error_reply is set to a
31 /* default 421 reply).
32 /*
33 /* psc_hangup_event() cleans up after a client connection breaks
34 /* unexpectedly. If logs the test where the break happened,
35 /* and how much time as spent in that test before the connection
36 /* broke.
37 /* LICENSE
38 /* .ad
39 /* .fi
40 /* The Secure Mailer license must be distributed with this software.
41 /* AUTHOR(S)
42 /* Wietse Venema
43 /* IBM T.J. Watson Research
44 /* P.O. Box 704
45 /* Yorktown Heights, NY 10598, USA
46 /*
47 /* Wietse Venema
48 /* Google, Inc.
49 /* 111 8th Avenue
50 /* New York, NY 10011, USA
51 /*--*/
52 
53 /* System library. */
54 
55 #include <sys_defs.h>
56 
57 /* Utility library. */
58 
59 #include <msg.h>
60 #include <vstring.h>
61 #include <iostuff.h>
62 #include <format_tv.h>
63 
64 /* Global library. */
65 
66 #include <mail_params.h>
67 
68 /* Application-specific. */
69 
70 #include <postscreen.h>
71 
72 /* psc_format_delta_time - pretty-formatted delta time */
73 
74 char *psc_format_delta_time(VSTRING *buf, struct timeval tv,
75  DELTA_TIME *delta)
76 {
77  DELTA_TIME pdelay;
78  struct timeval now;
79 
80  GETTIMEOFDAY(&now);
81  PSC_CALC_DELTA(pdelay, now, tv);
82  VSTRING_RESET(buf);
83  format_tv(buf, pdelay.dt_sec, pdelay.dt_usec, SIG_DIGS, var_delay_max_res);
84  *delta = pdelay;
85  return (STR(buf));
86 }
87 
88 /* psc_conclude - bring this session to a conclusion */
89 
90 void psc_conclude(PSC_STATE *state)
91 {
92  const char *myname = "psc_conclude";
93 
94  if (msg_verbose)
95  msg_info("flags for %s: %s",
96  myname, psc_print_state_flags(state->flags, myname));
97 
98  /*
99  * Handle clients that passed at least one test other than permanent
100  * whitelisting, and that didn't fail any test including permanent
101  * blacklisting. There may still be unfinished tests; those tests will
102  * need to be completed when the client returns in a later session.
103  */
104  if (state->flags & PSC_STATE_MASK_ANY_FAIL)
105  state->flags &= ~PSC_STATE_MASK_ANY_PASS;
106 
107  /*
108  * Log our final blessing when all unfinished tests were completed.
109  */
110  if ((state->flags & PSC_STATE_MASK_ANY_PASS) != 0
111  && (state->flags & PSC_STATE_MASK_ANY_PASS) ==
113  msg_info("PASS %s [%s]:%s", (state->flags & PSC_STATE_FLAG_NEW) == 0
114  || state->client_info->pass_new_count++ > 0 ?
115  "OLD" : "NEW", PSC_CLIENT_ADDR_PORT(state));
116 
117  /*
118  * Update the postscreen cache. This still supports a scenario where a
119  * client gets whitelisted in the course of multiple sessions, as long as
120  * that client does not "fail" any test. Don't try to optimize away cache
121  * updates; we want cached information to be up-to-date even if a test
122  * result is renewed during overlapping SMTP sessions, and even if
123  * 'postfix reload' happens in the middle of that.
124  */
125  if ((state->flags & PSC_STATE_MASK_ANY_UPDATE) != 0
126  && psc_cache_map != 0) {
127  psc_print_tests(psc_temp, state);
129  }
130 
131  /*
132  * Either hand off the socket to a real SMTP engine, or say bye-bye.
133  */
134  if ((state->flags & PSC_STATE_FLAG_NOFORWARD) == 0) {
135  psc_send_socket(state);
136  } else {
137  if ((state->flags & PSC_STATE_FLAG_HANGUP) == 0)
138  (void) PSC_SEND_REPLY(state, state->final_reply);
139  msg_info("DISCONNECT [%s]:%s", PSC_CLIENT_ADDR_PORT(state));
140  psc_free_session_state(state);
141  }
142 }
143 
144 /* psc_hangup_event - handle unexpected disconnect */
145 
147 {
148  DELTA_TIME elapsed;
149 
150  /*
151  * Sessions can break at any time, even after the client passes all tests
152  * (some MTAs including Postfix don't send QUIT when connection reuse is
153  * enabled). This must not be treated as a protocol test failure.
154  *
155  * Log the current test phase, and the elapsed time after the start of that
156  * phase.
157  */
158  state->flags |= PSC_STATE_FLAG_HANGUP;
159  msg_info("HANGUP after %s from [%s]:%s in %s",
160  psc_format_delta_time(psc_temp, state->start_time, &elapsed),
161  PSC_CLIENT_ADDR_PORT(state), state->test_name);
163  psc_conclude(state);
164 }
int msg_verbose
Definition: msg.c:177
PSC_CLIENT_INFO * client_info
Definition: postscreen.h:83
char * psc_print_tests(VSTRING *, PSC_STATE *)
#define PSC_STATE_FLAG_NEW
Definition: postscreen.h:115
#define PSC_STATE_MASK_ANY_FAIL
Definition: postscreen.h:269
const char * test_name
Definition: postscreen.h:82
void psc_send_socket(PSC_STATE *)
#define PSC_STATE_MASK_ANY_PASS
Definition: postscreen.h:274
int flags
Definition: postscreen.h:70
#define PSC_STATE_FLAG_HANGUP
Definition: postscreen.h:117
VSTRING * format_tv(VSTRING *buf, long sec, long usec, int sig_dig, int max_dig)
Definition: format_tv.c:65
#define PSC_STATE_MASK_ANY_TODO
Definition: postscreen.h:277
const char * final_reply
Definition: postscreen.h:78
#define PSC_CLIENT_ADDR_PORT(state)
Definition: postscreen.h:414
long dt_usec
Definition: log_adhoc.c:77
char * smtp_client_addr
Definition: postscreen.h:74
#define SIG_DIGS
long dt_sec
Definition: log_adhoc.c:76
#define VSTRING_RESET(vp)
Definition: vstring.h:77
#define STR(x)
Definition: anvil.c:518
#define PSC_STATE_MASK_ANY_UPDATE
Definition: postscreen.h:283
int var_delay_max_res
Definition: mail_params.c:330
#define PSC_STATE_FLAG_NOFORWARD
Definition: postscreen.h:112
VSTRING * psc_temp
Definition: postscreen.c:530
#define PSC_STATE_FLAGS_TODO_TO_PASS(todo_flags)
Definition: postscreen.h:146
char * psc_format_delta_time(VSTRING *buf, struct timeval tv, DELTA_TIME *delta)
DICT_CACHE * psc_cache_map
Definition: postscreen.c:529
void psc_hangup_event(PSC_STATE *state)
void psc_conclude(PSC_STATE *state)
void psc_free_session_state(PSC_STATE *)
void psc_cache_update(DICT_CACHE *, const char *, const char *)
#define PSC_SEND_REPLY
Definition: postscreen.h:542
struct timeval start_time
Definition: postscreen.h:81
#define PSC_CALC_DELTA(x, y, z)
Definition: postscreen.h:301
const char * psc_print_state_flags(int, const char *)
void msg_info(const char *fmt,...)
Definition: msg.c:199