1 /* $NetBSD: smtpd_state.c,v 1.2 2020/03/18 19:05:20 christos Exp $ */ 2 3 /*++ 4 /* NAME 5 /* smtpd_state 3 6 /* SUMMARY 7 /* Postfix SMTP server 8 /* SYNOPSIS 9 /* #include "smtpd.h" 10 /* 11 /* void smtpd_state_init(state, stream, service) 12 /* SMTPD_STATE *state; 13 /* VSTREAM *stream; 14 /* const char *service; 15 /* 16 /* void smtpd_state_reset(state) 17 /* SMTPD_STATE *state; 18 /* DESCRIPTION 19 /* smtpd_state_init() initializes session context. 20 /* 21 /* smtpd_state_reset() cleans up session context. 22 /* 23 /* Arguments: 24 /* .IP state 25 /* Session context. 26 /* .IP stream 27 /* Stream connected to peer. The stream is not copied. 28 /* DIAGNOSTICS 29 /* All errors are fatal. 30 /* LICENSE 31 /* .ad 32 /* .fi 33 /* The Secure Mailer license must be distributed with this software. 34 /* AUTHOR(S) 35 /* Wietse Venema 36 /* IBM T.J. Watson Research 37 /* P.O. Box 704 38 /* Yorktown Heights, NY 10598, USA 39 /* 40 /* Wietse Venema 41 /* Google, Inc. 42 /* 111 8th Avenue 43 /* New York, NY 10011, USA 44 /* 45 /* TLS support originally by: 46 /* Lutz Jaenicke 47 /* BTU Cottbus 48 /* Allgemeine Elektrotechnik 49 /* Universitaetsplatz 3-4 50 /* D-03044 Cottbus, Germany 51 /*--*/ 52 53 /* System library. */ 54 55 #include <sys_defs.h> 56 57 /* Utility library. */ 58 59 #include <events.h> 60 #include <mymalloc.h> 61 #include <vstream.h> 62 #include <name_mask.h> 63 #include <msg.h> 64 65 /* Global library. */ 66 67 #include <cleanup_user.h> 68 #include <mail_params.h> 69 #include <mail_error.h> 70 #include <mail_proto.h> 71 72 /* Application-specific. */ 73 74 #include "smtpd.h" 75 #include "smtpd_chat.h" 76 #include "smtpd_sasl_glue.h" 77 78 /* smtpd_state_init - initialize after connection establishment */ 79 80 void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream, 81 const char *service) 82 { 83 84 /* 85 * Initialize the state information for this connection, and fill in the 86 * connection-specific fields. 87 */ 88 state->flags = 0; 89 state->err = CLEANUP_STAT_OK; 90 state->client = stream; 91 state->service = mystrdup(service); 92 state->buffer = vstring_alloc(100); 93 state->addr_buf = vstring_alloc(100); 94 state->conn_count = state->conn_rate = 0; 95 state->error_count = 0; 96 state->error_mask = 0; 97 state->notify_mask = name_mask(VAR_NOTIFY_CLASSES, mail_error_masks, 98 var_notify_classes); 99 state->helo_name = 0; 100 state->queue_id = 0; 101 state->cleanup = 0; 102 state->dest = 0; 103 state->rcpt_count = 0; 104 state->access_denied = 0; 105 state->history = 0; 106 state->reason = 0; 107 state->sender = 0; 108 state->verp_delims = 0; 109 state->recipient = 0; 110 state->etrn_name = 0; 111 state->protocol = mystrdup(MAIL_PROTO_SMTP); 112 state->where = SMTPD_AFTER_CONNECT; 113 state->recursion = 0; 114 state->msg_size = 0; 115 state->act_size = 0; 116 state->junk_cmds = 0; 117 state->rcpt_overshoot = 0; 118 state->defer_if_permit_client = 0; 119 state->defer_if_permit_helo = 0; 120 state->defer_if_permit_sender = 0; 121 state->defer_if_reject.dsn = 0; 122 state->defer_if_reject.reason = 0; 123 state->defer_if_permit.dsn = 0; 124 state->defer_if_permit.reason = 0; 125 state->discard = 0; 126 state->expand_buf = 0; 127 state->prepend = 0; 128 state->proxy = 0; 129 state->proxy_mail = 0; 130 state->saved_filter = 0; 131 state->saved_redirect = 0; 132 state->saved_bcc = 0; 133 state->saved_flags = 0; 134 #ifdef DELAY_ACTION 135 state->saved_delay = 0; 136 #endif 137 state->instance = vstring_alloc(10); 138 state->seqno = 0; 139 state->rewrite_context = 0; 140 #if 0 141 state->ehlo_discard_mask = ~0; 142 #else 143 state->ehlo_discard_mask = 0; 144 #endif 145 state->dsn_envid = 0; 146 state->dsn_buf = vstring_alloc(100); 147 state->dsn_orcpt_buf = vstring_alloc(100); 148 #ifdef USE_TLS 149 #ifdef USE_TLSPROXY 150 state->tlsproxy = 0; 151 #endif 152 state->tls_context = 0; 153 #endif 154 155 /* 156 * Minimal initialization to support external authentication (e.g., 157 * XCLIENT) without having to enable SASL in main.cf. 158 */ 159 #ifdef USE_SASL_AUTH 160 if (SMTPD_STAND_ALONE(state)) 161 var_smtpd_sasl_enable = 0; 162 smtpd_sasl_set_inactive(state); 163 smtpd_sasl_state_init(state); 164 #endif 165 166 state->milter_argv = 0; 167 state->milter_argc = 0; 168 state->milters = 0; 169 170 /* 171 * Initialize peer information. 172 */ 173 smtpd_peer_init(state); 174 175 /* 176 * Initialize xforward information. 177 */ 178 smtpd_xforward_init(state); 179 180 /* 181 * Initialize the conversation history. 182 */ 183 smtpd_chat_reset(state); 184 185 state->ehlo_argv = 0; 186 state->ehlo_buf = 0; 187 188 /* 189 * BDAT. 190 */ 191 state->bdat_state = SMTPD_BDAT_STAT_NONE; 192 state->bdat_get_stream = 0; 193 state->bdat_get_buffer = 0; 194 } 195 196 /* smtpd_state_reset - cleanup after disconnect */ 197 198 void smtpd_state_reset(SMTPD_STATE *state) 199 { 200 201 /* 202 * When cleaning up, touch only those fields that smtpd_state_init() 203 * filled in. The other fields are taken care of by their own 204 * "destructor" functions. 205 */ 206 if (state->service) 207 myfree(state->service); 208 if (state->buffer) 209 vstring_free(state->buffer); 210 if (state->addr_buf) 211 vstring_free(state->addr_buf); 212 if (state->access_denied) 213 myfree(state->access_denied); 214 if (state->protocol) 215 myfree(state->protocol); 216 smtpd_peer_reset(state); 217 218 /* 219 * Buffers that are created on the fly and that may be shared among mail 220 * deliveries within the same SMTP session. 221 */ 222 if (state->defer_if_permit.dsn) 223 vstring_free(state->defer_if_permit.dsn); 224 if (state->defer_if_permit.reason) 225 vstring_free(state->defer_if_permit.reason); 226 if (state->defer_if_reject.dsn) 227 vstring_free(state->defer_if_reject.dsn); 228 if (state->defer_if_reject.reason) 229 vstring_free(state->defer_if_reject.reason); 230 if (state->expand_buf) 231 vstring_free(state->expand_buf); 232 if (state->instance) 233 vstring_free(state->instance); 234 if (state->dsn_buf) 235 vstring_free(state->dsn_buf); 236 if (state->dsn_orcpt_buf) 237 vstring_free(state->dsn_orcpt_buf); 238 #if (defined(USE_TLS) && defined(USE_TLSPROXY)) 239 if (state->tlsproxy) /* still open after longjmp */ 240 vstream_fclose(state->tlsproxy); 241 #endif 242 243 /* 244 * BDAT. 245 */ 246 if (state->bdat_get_stream) 247 (void) vstream_fclose(state->bdat_get_stream); 248 if (state->bdat_get_buffer) 249 vstring_free(state->bdat_get_buffer); 250 } 251