Import sendmail 8.14.1
[dragonfly.git] / contrib / sendmail-8.14 / libmilter / engine.c
1 /*
2  *  Copyright (c) 1999-2004, 2006 Sendmail, Inc. and its suppliers.
3  *      All rights reserved.
4  *
5  * By using this file, you agree to the terms and conditions set
6  * forth in the LICENSE file which can be found at the top level of
7  * the sendmail distribution.
8  *
9  */
10
11 #include <sm/gen.h>
12 SM_RCSID("@(#)$Id: engine.c,v 8.157 2007/03/26 18:10:04 ca Exp $")
13
14 #include "libmilter.h"
15
16 #if NETINET || NETINET6
17 # include <arpa/inet.h>
18 #endif /* NETINET || NETINET6 */
19
20 /* generic argument for functions in the command table */
21 struct arg_struct
22 {
23         size_t          a_len;          /* length of buffer */
24         char            *a_buf;         /* argument string */
25         int             a_idx;          /* index for macro array */
26         SMFICTX_PTR     a_ctx;          /* context */
27 };
28
29 typedef struct arg_struct genarg;
30
31 /* structure for commands received from MTA */
32 struct cmdfct_t
33 {
34         char    cm_cmd;                         /* command */
35         int     cm_argt;                        /* type of arguments expected */
36         int     cm_next;                        /* next state */
37         int     cm_todo;                        /* what to do next */
38         int     cm_macros;                      /* index for macros */
39         int     (*cm_fct) __P((genarg *));      /* function to execute */
40 };
41
42 typedef struct cmdfct_t cmdfct;
43
44 /* possible values for cm_argt */
45 #define CM_ARG0 0       /* no args */
46 #define CM_ARG1 1       /* one arg (string) */
47 #define CM_ARG2 2       /* two args (strings) */
48 #define CM_ARGA 4       /* one string and _SOCK_ADDR */
49 #define CM_ARGO 5       /* two integers */
50 #define CM_ARGV 8       /* \0 separated list of args, NULL-terminated */
51 #define CM_ARGN 9       /* \0 separated list of args (strings) */
52
53 /* possible values for cm_todo */
54 #define CT_CONT         0x0000  /* continue reading commands */
55 #define CT_IGNO         0x0001  /* continue even when error  */
56
57 /* not needed right now, done via return code instead */
58 #define CT_KEEP         0x0004  /* keep buffer (contains symbols) */
59 #define CT_END          0x0008  /* last command of session, stop replying */
60
61 /* index in macro array: macros only for these commands */
62 #define CI_NONE         (-1)
63 #define CI_CONN         0
64 #define CI_HELO         1
65 #define CI_MAIL         2
66 #define CI_RCPT         3
67 #define CI_DATA         4
68 #define CI_EOM          5
69 #define CI_EOH          6
70 #define CI_LAST         CI_EOH
71 #if CI_LAST < CI_DATA
72 ERROR: do not compile with CI_LAST < CI_DATA
73 #endif
74 #if CI_LAST < CI_EOM
75 ERROR: do not compile with CI_LAST < CI_EOM
76 #endif
77 #if CI_LAST < CI_EOH
78 ERROR: do not compile with CI_LAST < CI_EOH
79 #endif
80 #if CI_LAST < CI_ENVRCPT
81 ERROR: do not compile with CI_LAST < CI_ENVRCPT
82 #endif
83 #if CI_LAST < CI_ENVFROM
84 ERROR: do not compile with CI_LAST < CI_ENVFROM
85 #endif
86 #if CI_LAST < CI_HELO
87 ERROR: do not compile with CI_LAST < CI_HELO
88 #endif
89 #if CI_LAST < CI_CONNECT
90 ERROR: do not compile with CI_LAST < CI_CONNECT
91 #endif
92 #if CI_LAST >= MAX_MACROS_ENTRIES
93 ERROR: do not compile with CI_LAST >= MAX_MACROS_ENTRIES
94 #endif
95
96 /* function prototypes */
97 static int      st_abortfct __P((genarg *));
98 static int      st_macros __P((genarg *));
99 static int      st_optionneg __P((genarg *));
100 static int      st_bodychunk __P((genarg *));
101 static int      st_connectinfo __P((genarg *));
102 static int      st_bodyend __P((genarg *));
103 static int      st_helo __P((genarg *));
104 static int      st_header __P((genarg *));
105 static int      st_sender __P((genarg *));
106 static int      st_rcpt __P((genarg *));
107 static int      st_unknown __P((genarg *));
108 static int      st_data __P((genarg *));
109 static int      st_eoh __P((genarg *));
110 static int      st_quit __P((genarg *));
111 static int      sendreply __P((sfsistat, socket_t, struct timeval *, SMFICTX_PTR));
112 static void     fix_stm __P((SMFICTX_PTR));
113 static bool     trans_ok __P((int, int));
114 static char     **dec_argv __P((char *, size_t));
115 static int      dec_arg2 __P((char *, size_t, char **, char **));
116
117 #if _FFR_WORKERS_POOL
118 static bool     mi_rd_socket_ready __P((int));
119 #endif /* _FFR_WORKERS_POOL */
120
121 /* states */
122 #define ST_NONE (-1)
123 #define ST_INIT 0       /* initial state */
124 #define ST_OPTS 1       /* option negotiation */
125 #define ST_CONN 2       /* connection info */
126 #define ST_HELO 3       /* helo */
127 #define ST_MAIL 4       /* mail from */
128 #define ST_RCPT 5       /* rcpt to */
129 #define ST_DATA 6       /* data */
130 #define ST_HDRS 7       /* headers */
131 #define ST_EOHS 8       /* end of headers */
132 #define ST_BODY 9       /* body */
133 #define ST_ENDM 10      /* end of message */
134 #define ST_QUIT 11      /* quit */
135 #define ST_ABRT 12      /* abort */
136 #define ST_UNKN 13      /* unknown SMTP command */
137 #define ST_Q_NC 14      /* quit, new connection follows */
138 #define ST_LAST ST_Q_NC /* last valid state */
139 #define ST_SKIP 16      /* not a state but required for the state table */
140
141 /* in a mail transaction? must be before eom according to spec. */
142 #define ST_IN_MAIL(st)  ((st) >= ST_MAIL && (st) < ST_ENDM)
143
144 /*
145 **  set of next states
146 **  each state (ST_*) corresponds to bit in an int value (1 << state)
147 **  each state has a set of allowed transitions ('or' of bits of states)
148 **  so a state transition is valid if the mask of the next state
149 **  is set in the NX_* value
150 **  this function is coded in trans_ok(), see below.
151 */
152
153 #define MI_MASK(x)      (0x0001 << (x)) /* generate a bit "mask" for a state */
154 #define NX_INIT (MI_MASK(ST_OPTS))
155 #define NX_OPTS (MI_MASK(ST_CONN) | MI_MASK(ST_UNKN))
156 #define NX_CONN (MI_MASK(ST_HELO) | MI_MASK(ST_MAIL) | MI_MASK(ST_UNKN))
157 #define NX_HELO (MI_MASK(ST_HELO) | MI_MASK(ST_MAIL) | MI_MASK(ST_UNKN))
158 #define NX_MAIL (MI_MASK(ST_RCPT) | MI_MASK(ST_ABRT) | MI_MASK(ST_UNKN))
159 #define NX_RCPT (MI_MASK(ST_HDRS) | MI_MASK(ST_EOHS) | MI_MASK(ST_DATA) | \
160                  MI_MASK(ST_BODY) | MI_MASK(ST_ENDM) | \
161                  MI_MASK(ST_RCPT) | MI_MASK(ST_ABRT) | MI_MASK(ST_UNKN))
162 #define NX_DATA (MI_MASK(ST_EOHS) | MI_MASK(ST_HDRS) | MI_MASK(ST_ABRT))
163 #define NX_HDRS (MI_MASK(ST_EOHS) | MI_MASK(ST_HDRS) | MI_MASK(ST_ABRT))
164 #define NX_EOHS (MI_MASK(ST_BODY) | MI_MASK(ST_ENDM) | MI_MASK(ST_ABRT))
165 #define NX_BODY (MI_MASK(ST_ENDM) | MI_MASK(ST_BODY) | MI_MASK(ST_ABRT))
166 #define NX_ENDM (MI_MASK(ST_QUIT) | MI_MASK(ST_MAIL) | MI_MASK(ST_UNKN) | \
167                 MI_MASK(ST_Q_NC))
168 #define NX_QUIT 0
169 #define NX_ABRT 0
170 #define NX_UNKN (MI_MASK(ST_HELO) | MI_MASK(ST_MAIL) | \
171                  MI_MASK(ST_RCPT) | MI_MASK(ST_ABRT) | \
172                  MI_MASK(ST_DATA) | \
173                  MI_MASK(ST_BODY) | MI_MASK(ST_UNKN) | \
174                  MI_MASK(ST_ABRT) | MI_MASK(ST_QUIT) | MI_MASK(ST_Q_NC))
175 #define NX_Q_NC (MI_MASK(ST_CONN) | MI_MASK(ST_UNKN))
176 #define NX_SKIP MI_MASK(ST_SKIP)
177
178 static int next_states[] =
179 {
180           NX_INIT
181         , NX_OPTS
182         , NX_CONN
183         , NX_HELO
184         , NX_MAIL
185         , NX_RCPT
186         , NX_DATA
187         , NX_HDRS
188         , NX_EOHS
189         , NX_BODY
190         , NX_ENDM
191         , NX_QUIT
192         , NX_ABRT
193         , NX_UNKN
194         , NX_Q_NC
195 };
196
197 #define SIZE_NEXT_STATES        (sizeof(next_states) / sizeof(next_states[0]))
198
199 /* commands received by milter */
200 static cmdfct cmds[] =
201 {
202   {SMFIC_ABORT, CM_ARG0, ST_ABRT,  CT_CONT,     CI_NONE, st_abortfct    }
203 , {SMFIC_MACRO, CM_ARGV, ST_NONE,  CT_KEEP,     CI_NONE, st_macros      }
204 , {SMFIC_BODY,  CM_ARG1, ST_BODY,  CT_CONT,     CI_NONE, st_bodychunk   }
205 , {SMFIC_CONNECT, CM_ARG2, ST_CONN,  CT_CONT,   CI_CONN, st_connectinfo }
206 , {SMFIC_BODYEOB, CM_ARG1, ST_ENDM,  CT_CONT,   CI_EOM,  st_bodyend     }
207 , {SMFIC_HELO,  CM_ARG1, ST_HELO,  CT_CONT,     CI_HELO, st_helo        }
208 , {SMFIC_HEADER, CM_ARG2, ST_HDRS,  CT_CONT,    CI_NONE, st_header      }
209 , {SMFIC_MAIL,  CM_ARGV, ST_MAIL,  CT_CONT,     CI_MAIL, st_sender      }
210 , {SMFIC_OPTNEG, CM_ARGO, ST_OPTS,  CT_CONT,    CI_NONE, st_optionneg   }
211 , {SMFIC_EOH,   CM_ARG0, ST_EOHS,  CT_CONT,     CI_EOH,  st_eoh         }
212 , {SMFIC_QUIT,  CM_ARG0, ST_QUIT,  CT_END,      CI_NONE, st_quit        }
213 , {SMFIC_DATA,  CM_ARG0, ST_DATA,  CT_CONT,     CI_DATA, st_data        }
214 , {SMFIC_RCPT,  CM_ARGV, ST_RCPT,  CT_IGNO,     CI_RCPT, st_rcpt        }
215 , {SMFIC_UNKNOWN, CM_ARG1, ST_UNKN,  CT_IGNO,   CI_NONE, st_unknown     }
216 , {SMFIC_QUIT_NC, CM_ARG0, ST_Q_NC,  CT_CONT,   CI_NONE, st_quit        }
217 };
218
219 /*
220 **  Additional (internal) reply codes;
221 **  must be coordinated wit libmilter/mfapi.h
222 */
223
224 #define _SMFIS_KEEP     20
225 #define _SMFIS_ABORT    21
226 #define _SMFIS_OPTIONS  22
227 #define _SMFIS_NOREPLY  SMFIS_NOREPLY
228 #define _SMFIS_FAIL     (-1)
229 #define _SMFIS_NONE     (-2)
230
231 /*
232 **  MI_ENGINE -- receive commands and process them
233 **
234 **      Parameters:
235 **              ctx -- context structure
236 **
237 **      Returns:
238 **              MI_FAILURE/MI_SUCCESS
239 */
240
241 int
242 mi_engine(ctx)
243         SMFICTX_PTR ctx;
244 {
245         size_t len;
246         int i;
247         socket_t sd;
248         int ret = MI_SUCCESS;
249         int ncmds = sizeof(cmds) / sizeof(cmdfct);
250         int curstate = ST_INIT;
251         int newstate;
252         bool call_abort;
253         sfsistat r;
254         char cmd;
255         char *buf = NULL;
256         genarg arg;
257         struct timeval timeout;
258         int (*f) __P((genarg *));
259         sfsistat (*fi_abort) __P((SMFICTX *));
260         sfsistat (*fi_close) __P((SMFICTX *));
261
262         arg.a_ctx = ctx;
263         sd = ctx->ctx_sd;
264         fi_abort = ctx->ctx_smfi->xxfi_abort;
265 #if _FFR_WORKERS_POOL
266         curstate = ctx->ctx_state;
267         if (curstate == ST_INIT)
268         {
269                 mi_clr_macros(ctx, 0);
270                 fix_stm(ctx);
271         }
272 #else   /* _FFR_WORKERS_POOL */
273         mi_clr_macros(ctx, 0);
274         fix_stm(ctx);
275 #endif  /* _FFR_WORKERS_POOL */
276         r = _SMFIS_NONE;
277         do
278         {
279                 /* call abort only if in a mail transaction */
280                 call_abort = ST_IN_MAIL(curstate);
281                 timeout.tv_sec = ctx->ctx_timeout;
282                 timeout.tv_usec = 0;
283                 if (mi_stop() == MILTER_ABRT)
284                 {
285                         if (ctx->ctx_dbg > 3)
286                                 sm_dprintf("[%ld] milter_abort\n",
287                                         (long) ctx->ctx_id);
288                         ret = MI_FAILURE;
289                         break;
290                 }
291
292                 /*
293                 **  Notice: buf is allocated by mi_rd_cmd() and it will
294                 **  usually be free()d after it has been used in f().
295                 **  However, if the function returns _SMFIS_KEEP then buf
296                 **  contains macros and will not be free()d.
297                 **  Hence r must be set to _SMFIS_NONE if a new buf is
298                 **  allocated to avoid problem with housekeeping, esp.
299                 **  if the code "break"s out of the loop.
300                 */
301
302 #if _FFR_WORKERS_POOL
303                 /* Is the socket ready to be read ??? */
304                 if (!mi_rd_socket_ready(sd))
305                 {
306                         ret = MI_CONTINUE;
307                         break;
308                 }
309 #endif  /* _FFR_WORKERS_POOL */
310
311                 r = _SMFIS_NONE;
312                 if ((buf = mi_rd_cmd(sd, &timeout, &cmd, &len,
313                                      ctx->ctx_smfi->xxfi_name)) == NULL &&
314                     cmd < SMFIC_VALIDCMD)
315                 {
316                         if (ctx->ctx_dbg > 5)
317                                 sm_dprintf("[%ld] mi_engine: mi_rd_cmd error (%x)\n",
318                                         (long) ctx->ctx_id, (int) cmd);
319
320                         /*
321                         **  eof is currently treated as failure ->
322                         **  abort() instead of close(), otherwise use:
323                         **  if (cmd != SMFIC_EOF)
324                         */
325
326                         ret = MI_FAILURE;
327                         break;
328                 }
329                 if (ctx->ctx_dbg > 4)
330                         sm_dprintf("[%ld] got cmd '%c' len %d\n",
331                                 (long) ctx->ctx_id, cmd, (int) len);
332                 for (i = 0; i < ncmds; i++)
333                 {
334                         if (cmd == cmds[i].cm_cmd)
335                                 break;
336                 }
337                 if (i >= ncmds)
338                 {
339                         /* unknown command */
340                         if (ctx->ctx_dbg > 1)
341                                 sm_dprintf("[%ld] cmd '%c' unknown\n",
342                                         (long) ctx->ctx_id, cmd);
343                         ret = MI_FAILURE;
344                         break;
345                 }
346                 if ((f = cmds[i].cm_fct) == NULL)
347                 {
348                         /* stop for now */
349                         if (ctx->ctx_dbg > 1)
350                                 sm_dprintf("[%ld] cmd '%c' not impl\n",
351                                         (long) ctx->ctx_id, cmd);
352                         ret = MI_FAILURE;
353                         break;
354                 }
355
356                 /* is new state ok? */
357                 newstate = cmds[i].cm_next;
358                 if (ctx->ctx_dbg > 5)
359                         sm_dprintf("[%ld] cur %x new %x nextmask %x\n",
360                                 (long) ctx->ctx_id,
361                                 curstate, newstate, next_states[curstate]);
362
363                 if (newstate != ST_NONE && !trans_ok(curstate, newstate))
364                 {
365                         if (ctx->ctx_dbg > 1)
366                                 sm_dprintf("[%ld] abort: cur %d (%x) new %d (%x) next %x\n",
367                                         (long) ctx->ctx_id,
368                                         curstate, MI_MASK(curstate),
369                                         newstate, MI_MASK(newstate),
370                                         next_states[curstate]);
371
372                         /* call abort only if in a mail transaction */
373                         if (fi_abort != NULL && call_abort)
374                                 (void) (*fi_abort)(ctx);
375
376                         /*
377                         **  try to reach the new state from HELO
378                         **  if it can't be reached, ignore the command.
379                         */
380
381                         curstate = ST_HELO;
382                         if (!trans_ok(curstate, newstate))
383                         {
384                                 if (buf != NULL)
385                                 {
386                                         free(buf);
387                                         buf = NULL;
388                                 }
389                                 continue;
390                         }
391                 }
392                 arg.a_len = len;
393                 arg.a_buf = buf;
394                 if (newstate != ST_NONE)
395                 {
396                         curstate = newstate;
397                         ctx->ctx_state = curstate;
398                 }
399                 arg.a_idx = cmds[i].cm_macros;
400                 call_abort = ST_IN_MAIL(curstate);
401
402                 /* call function to deal with command */
403                 MI_MONITOR_BEGIN(ctx, cmd);
404                 r = (*f)(&arg);
405                 MI_MONITOR_END(ctx, cmd);
406                 if (r != _SMFIS_KEEP && buf != NULL)
407                 {
408                         free(buf);
409                         buf = NULL;
410                 }
411                 if (sendreply(r, sd, &timeout, ctx) != MI_SUCCESS)
412                 {
413                         ret = MI_FAILURE;
414                         break;
415                 }
416
417                 if (r == SMFIS_ACCEPT)
418                 {
419                         /* accept mail, no further actions taken */
420                         curstate = ST_HELO;
421                 }
422                 else if (r == SMFIS_REJECT || r == SMFIS_DISCARD ||
423                          r ==  SMFIS_TEMPFAIL)
424                 {
425                         /*
426                         **  further actions depend on current state
427                         **  if the IGNO bit is set: "ignore" the error,
428                         **  i.e., stay in the current state
429                         */
430                         if (!bitset(CT_IGNO, cmds[i].cm_todo))
431                                 curstate = ST_HELO;
432                 }
433                 else if (r == _SMFIS_ABORT)
434                 {
435                         if (ctx->ctx_dbg > 5)
436                                 sm_dprintf("[%ld] function returned abort\n",
437                                         (long) ctx->ctx_id);
438                         ret = MI_FAILURE;
439                         break;
440                 }
441         } while (!bitset(CT_END, cmds[i].cm_todo));
442
443         ctx->ctx_state = curstate;
444
445         if (ret == MI_FAILURE)
446         {
447                 /* call abort only if in a mail transaction */
448                 if (fi_abort != NULL && call_abort)
449                         (void) (*fi_abort)(ctx);
450         }
451
452         /* has close been called? */
453         if (ctx->ctx_state != ST_QUIT
454 #if _FFR_WORKERS_POOL
455            && ret != MI_CONTINUE
456 #endif /* _FFR_WORKERS_POOL */
457            )
458         {
459                 if ((fi_close = ctx->ctx_smfi->xxfi_close) != NULL)
460                         (void) (*fi_close)(ctx);
461         }
462         if (r != _SMFIS_KEEP && buf != NULL)
463                 free(buf);
464 #if !_FFR_WORKERS_POOL
465         mi_clr_macros(ctx, 0);
466 #endif /* _FFR_WORKERS_POOL */
467         return ret;
468 }
469
470 static size_t milter_addsymlist __P((SMFICTX_PTR, char *, char **));
471
472 static size_t
473 milter_addsymlist(ctx, buf, newbuf)
474         SMFICTX_PTR ctx;
475         char *buf;
476         char **newbuf;
477 {
478         size_t len;
479         int i;
480         mi_int32 v;
481         char *buffer;
482
483         SM_ASSERT(ctx != NULL);
484         SM_ASSERT(buf != NULL);
485         SM_ASSERT(newbuf != NULL);
486         len = 0;
487         for (i = 0; i < MAX_MACROS_ENTRIES; i++)
488         {
489                 if (ctx->ctx_mac_list[i] != NULL)
490                 {
491                         len += strlen(ctx->ctx_mac_list[i]) + 1 +
492                                 MILTER_LEN_BYTES;
493                 }
494         }
495         if (len > 0)
496         {
497                 size_t offset;
498
499                 SM_ASSERT(len + MILTER_OPTLEN > len);
500                 len += MILTER_OPTLEN;
501                 buffer = malloc(len);
502                 if (buffer != NULL)
503                 {
504                         (void) memcpy(buffer, buf, MILTER_OPTLEN);
505                         offset = MILTER_OPTLEN;
506                         for (i = 0; i < MAX_MACROS_ENTRIES; i++)
507                         {
508                                 size_t l;
509
510                                 if (ctx->ctx_mac_list[i] == NULL)
511                                         continue;
512
513                                 SM_ASSERT(offset + MILTER_LEN_BYTES < len);
514                                 v = htonl(i);
515                                 (void) memcpy(buffer + offset, (void *) &v,
516                                                 MILTER_LEN_BYTES);
517                                 offset += MILTER_LEN_BYTES;
518                                 l = strlen(ctx->ctx_mac_list[i]) + 1;
519                                 SM_ASSERT(offset + l <= len);
520                                 (void) memcpy(buffer + offset,
521                                                 ctx->ctx_mac_list[i], l);
522                                 offset += l;
523                         }
524                 }
525                 else
526                 {
527                         /* oops ... */
528                 }
529         }
530         else
531         {
532                 len = MILTER_OPTLEN;
533                 buffer = buf;
534         }
535         *newbuf = buffer;
536         return len;
537 }
538
539 /*
540 **  GET_NR_BIT -- get "no reply" bit matching state
541 **
542 **      Parameters:
543 **              state -- current protocol stage
544 **
545 **      Returns:
546 **              0: no matching bit
547 **              >0: the matching "no reply" bit
548 */
549
550 static unsigned long get_nr_bit __P((int));
551
552 static unsigned long
553 get_nr_bit(state)
554         int state;
555 {
556         unsigned long bit;
557
558         switch (state)
559         {
560           case ST_CONN:
561                 bit = SMFIP_NR_CONN;
562                 break;
563           case ST_HELO:
564                 bit = SMFIP_NR_HELO;
565                 break;
566           case ST_MAIL:
567                 bit = SMFIP_NR_MAIL;
568                 break;
569           case ST_RCPT:
570                 bit = SMFIP_NR_RCPT;
571                 break;
572           case ST_DATA:
573                 bit = SMFIP_NR_DATA;
574                 break;
575           case ST_UNKN:
576                 bit = SMFIP_NR_UNKN;
577                 break;
578           case ST_HDRS:
579                 bit = SMFIP_NR_HDR;
580                 break;
581           case ST_EOHS:
582                 bit = SMFIP_NR_EOH;
583                 break;
584           case ST_BODY:
585                 bit = SMFIP_NR_BODY;
586                 break;
587           default:
588                 bit = 0;
589                 break;
590         }
591         return bit;
592 }
593
594 /*
595 **  SENDREPLY -- send a reply to the MTA
596 **
597 **      Parameters:
598 **              r -- reply code
599 **              sd -- socket descriptor
600 **              timeout_ptr -- (ptr to) timeout to use for sending
601 **              ctx -- context structure
602 **
603 **      Returns:
604 **              MI_SUCCESS/MI_FAILURE
605 */
606
607 static int
608 sendreply(r, sd, timeout_ptr, ctx)
609         sfsistat r;
610         socket_t sd;
611         struct timeval *timeout_ptr;
612         SMFICTX_PTR ctx;
613 {
614         int ret;
615         unsigned long bit;
616
617         ret = MI_SUCCESS;
618
619         bit = get_nr_bit(ctx->ctx_state);
620         if (bit != 0 && (ctx->ctx_pflags & bit) != 0 && r != SMFIS_NOREPLY)
621         {
622                 if (r >= SMFIS_CONTINUE && r < _SMFIS_KEEP)
623                 {
624                         /* milter said it wouldn't reply, but it lied... */
625                         smi_log(SMI_LOG_ERR,
626                                 "%s: milter claimed not to reply in state %d but did anyway %d\n",
627                                 ctx->ctx_smfi->xxfi_name,
628                                 ctx->ctx_state, r);
629
630                 }
631
632                 /*
633                 **  Force specified behavior, otherwise libmilter
634                 **  and MTA will fail to communicate properly.
635                 */
636
637                 switch (r)
638                 {
639                   case SMFIS_CONTINUE:
640                   case SMFIS_TEMPFAIL:
641                   case SMFIS_REJECT:
642                   case SMFIS_DISCARD:
643                   case SMFIS_ACCEPT:
644                   case SMFIS_SKIP:
645                   case _SMFIS_OPTIONS:
646                         r = SMFIS_NOREPLY;
647                         break;
648                 }
649         }
650
651         switch (r)
652         {
653           case SMFIS_CONTINUE:
654                 ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_CONTINUE, NULL, 0);
655                 break;
656           case SMFIS_TEMPFAIL:
657           case SMFIS_REJECT:
658                 if (ctx->ctx_reply != NULL &&
659                     ((r == SMFIS_TEMPFAIL && *ctx->ctx_reply == '4') ||
660                      (r == SMFIS_REJECT && *ctx->ctx_reply == '5')))
661                 {
662                         ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_REPLYCODE,
663                                         ctx->ctx_reply,
664                                         strlen(ctx->ctx_reply) + 1);
665                         free(ctx->ctx_reply);
666                         ctx->ctx_reply = NULL;
667                 }
668                 else
669                 {
670                         ret = mi_wr_cmd(sd, timeout_ptr, r == SMFIS_REJECT ?
671                                         SMFIR_REJECT : SMFIR_TEMPFAIL, NULL, 0);
672                 }
673                 break;
674           case SMFIS_DISCARD:
675                 ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_DISCARD, NULL, 0);
676                 break;
677           case SMFIS_ACCEPT:
678                 ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_ACCEPT, NULL, 0);
679                 break;
680           case SMFIS_SKIP:
681                 ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_SKIP, NULL, 0);
682                 break;
683           case _SMFIS_OPTIONS:
684                 {
685                         mi_int32 v;
686                         size_t len;
687                         char *buffer;
688                         char buf[MILTER_OPTLEN];
689
690                         v = htonl(ctx->ctx_prot_vers2mta);
691                         (void) memcpy(&(buf[0]), (void *) &v,
692                                       MILTER_LEN_BYTES);
693                         v = htonl(ctx->ctx_aflags);
694                         (void) memcpy(&(buf[MILTER_LEN_BYTES]), (void *) &v,
695                                       MILTER_LEN_BYTES);
696                         v = htonl(ctx->ctx_pflags2mta);
697                         (void) memcpy(&(buf[MILTER_LEN_BYTES * 2]),
698                                       (void *) &v, MILTER_LEN_BYTES);
699                         len = milter_addsymlist(ctx, buf, &buffer);
700                         if (buffer != NULL)
701                                 ret = mi_wr_cmd(sd, timeout_ptr, SMFIC_OPTNEG,
702                                                 buffer, len);
703                         else
704                                 ret = MI_FAILURE;
705                 }
706                 break;
707           case SMFIS_NOREPLY:
708                 if (bit != 0 &&
709                     (ctx->ctx_pflags & bit) != 0 &&
710                     (ctx->ctx_mta_pflags & bit) == 0)
711                 {
712                         /*
713                         **  milter doesn't want to send a reply,
714                         **  but the MTA doesn't have that feature: fake it.
715                         */
716
717                         ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_CONTINUE, NULL,
718                                         0);
719                 }
720                 break;
721           default:      /* don't send a reply */
722                 break;
723         }
724         return ret;
725 }
726
727 /*
728 **  CLR_MACROS -- clear set of macros starting from a given index
729 **
730 **      Parameters:
731 **              ctx -- context structure
732 **              m -- index from which to clear all macros
733 **
734 **      Returns:
735 **              None.
736 */
737
738 void
739 mi_clr_macros(ctx, m)
740         SMFICTX_PTR ctx;
741         int m;
742 {
743         int i;
744
745         for (i = m; i < MAX_MACROS_ENTRIES; i++)
746         {
747                 if (ctx->ctx_mac_ptr[i] != NULL)
748                 {
749                         free(ctx->ctx_mac_ptr[i]);
750                         ctx->ctx_mac_ptr[i] = NULL;
751                 }
752                 if (ctx->ctx_mac_buf[i] != NULL)
753                 {
754                         free(ctx->ctx_mac_buf[i]);
755                         ctx->ctx_mac_buf[i] = NULL;
756                 }
757         }
758 }
759
760 /*
761 **  ST_OPTIONNEG -- negotiate options
762 **
763 **      Parameters:
764 **              g -- generic argument structure
765 **
766 **      Returns:
767 **              abort/send options/continue
768 */
769
770 static int
771 st_optionneg(g)
772         genarg *g;
773 {
774         mi_int32 i, v, fake_pflags;
775         SMFICTX_PTR ctx;
776         int (*fi_negotiate) __P((SMFICTX *,
777                                         unsigned long, unsigned long,
778                                         unsigned long, unsigned long,
779                                         unsigned long *, unsigned long *,
780                                         unsigned long *, unsigned long *));
781
782         if (g == NULL || g->a_ctx->ctx_smfi == NULL)
783                 return SMFIS_CONTINUE;
784         ctx = g->a_ctx;
785         mi_clr_macros(ctx, g->a_idx + 1);
786         ctx->ctx_prot_vers = SMFI_PROT_VERSION;
787
788         /* check for minimum length */
789         if (g->a_len < MILTER_OPTLEN)
790         {
791                 smi_log(SMI_LOG_ERR,
792                         "%s: st_optionneg[%ld]: len too short %d < %d",
793                         ctx->ctx_smfi->xxfi_name,
794                         (long) ctx->ctx_id, (int) g->a_len,
795                         MILTER_OPTLEN);
796                 return _SMFIS_ABORT;
797         }
798
799         /* protocol version */
800         (void) memcpy((void *) &i, (void *) &(g->a_buf[0]), MILTER_LEN_BYTES);
801         v = ntohl(i);
802
803 #define SMFI_PROT_VERSION_MIN   2
804
805         /* check for minimum version */
806         if (v < SMFI_PROT_VERSION_MIN)
807         {
808                 smi_log(SMI_LOG_ERR,
809                         "%s: st_optionneg[%ld]: protocol version too old %d < %d",
810                         ctx->ctx_smfi->xxfi_name,
811                         (long) ctx->ctx_id, v, SMFI_PROT_VERSION_MIN);
812                 return _SMFIS_ABORT;
813         }
814         ctx->ctx_mta_prot_vers = v;
815         if (ctx->ctx_prot_vers < ctx->ctx_mta_prot_vers)
816                 ctx->ctx_prot_vers2mta = ctx->ctx_prot_vers;
817         else
818                 ctx->ctx_prot_vers2mta = ctx->ctx_mta_prot_vers;
819
820         (void) memcpy((void *) &i, (void *) &(g->a_buf[MILTER_LEN_BYTES]),
821                       MILTER_LEN_BYTES);
822         v = ntohl(i);
823
824         /* no flags? set to default value for V1 actions */
825         if (v == 0)
826                 v = SMFI_V1_ACTS;
827         ctx->ctx_mta_aflags = v;        /* MTA action flags */
828
829         (void) memcpy((void *) &i, (void *) &(g->a_buf[MILTER_LEN_BYTES * 2]),
830                       MILTER_LEN_BYTES);
831         v = ntohl(i);
832
833         /* no flags? set to default value for V1 protocol */
834         if (v == 0)
835                 v = SMFI_V1_PROT;
836         ctx->ctx_mta_pflags = v;        /* MTA protocol flags */
837
838         /*
839         **  Copy flags from milter struct into libmilter context;
840         **  this variable will be used later on to check whether
841         **  the MTA "actions" can fulfill the milter requirements,
842         **  but it may be overwritten by the negotiate callback.
843         */
844
845         ctx->ctx_aflags = ctx->ctx_smfi->xxfi_flags;
846         fake_pflags = SMFIP_NR_CONN
847                         |SMFIP_NR_HELO
848                         |SMFIP_NR_MAIL
849                         |SMFIP_NR_RCPT
850                         |SMFIP_NR_DATA
851                         |SMFIP_NR_UNKN
852                         |SMFIP_NR_HDR
853                         |SMFIP_NR_EOH
854                         |SMFIP_NR_BODY
855                         ;
856
857         if (g->a_ctx->ctx_smfi != NULL &&
858             (fi_negotiate = g->a_ctx->ctx_smfi->xxfi_negotiate) != NULL)
859         {
860                 int r;
861                 unsigned long m_aflags, m_pflags, m_f2, m_f3;
862
863                 /*
864                 **  let milter decide whether the features offered by the
865                 **  MTA are "good enough".
866                 **  Notes:
867                 **  - libmilter can "fake" some features (e.g., SMFIP_NR_HDR)
868                 **  - m_f2, m_f3 are for future extensions
869                 */
870
871                 m_f2 = m_f3 = 0;
872                 m_aflags = ctx->ctx_mta_aflags;
873                 m_pflags = ctx->ctx_pflags;
874                 if ((SMFIP_SKIP & ctx->ctx_mta_pflags) != 0)
875                         m_pflags |= SMFIP_SKIP;
876                 r = fi_negotiate(g->a_ctx,
877                                 ctx->ctx_mta_aflags,
878                                 ctx->ctx_mta_pflags|fake_pflags,
879                                 0, 0,
880                                 &m_aflags, &m_pflags, &m_f2, &m_f3);
881
882                 /*
883                 **  Types of protocol flags (pflags):
884                 **  1. do NOT send protocol step X
885                 **  2. MTA can do/understand something extra (SKIP,
886                 **      send unknown RCPTs)
887                 **  3. MTA can deal with "no reply" for various protocol steps
888                 **  Note: this mean that it isn't possible to simply set all
889                 **      flags to get "everything":
890                 **      setting a flag of type 1 turns off a step
891                 **              (it should be the other way around:
892                 **              a flag means a protocol step can be sent)
893                 **      setting a flag of type 3 requires that milter
894                 **      never sends a reply for the corresponding step.
895                 **  Summary: the "negation" of protocol flags is causing
896                 **      problems, but at least for type 3 there is no simple
897                 **      solution.
898                 **
899                 **  What should "all options" mean?
900                 **  send all protocol steps _except_ those for which there is
901                 **      no callback (currently registered in ctx_pflags)
902                 **  expect SKIP as return code?         Yes
903                 **  send unknown RCPTs?                 No,
904                 **                              must be explicitly requested?
905                 **  "no reply" for some protocol steps? No,
906                 **                              must be explicitly requested.
907                 */
908
909                 if (SMFIS_ALL_OPTS == r)
910                 {
911                         ctx->ctx_aflags = ctx->ctx_mta_aflags;
912                         ctx->ctx_pflags2mta = ctx->ctx_pflags;
913                         if ((SMFIP_SKIP & ctx->ctx_mta_pflags) != 0)
914                                 ctx->ctx_pflags2mta |= SMFIP_SKIP;
915                 }
916                 else if (r != SMFIS_CONTINUE)
917                 {
918                         smi_log(SMI_LOG_ERR,
919                                 "%s: st_optionneg[%ld]: xxfi_negotiate returned %d (protocol options=0x%lx, actions=0x%lx)",
920                                 ctx->ctx_smfi->xxfi_name,
921                                 (long) ctx->ctx_id, r, ctx->ctx_mta_pflags,
922                                 ctx->ctx_mta_aflags);
923                         return _SMFIS_ABORT;
924                 }
925                 else
926                 {
927                         ctx->ctx_aflags = m_aflags;
928                         ctx->ctx_pflags = m_pflags;
929                         ctx->ctx_pflags2mta = m_pflags;
930                 }
931
932                 /* check whether some flags need to be "faked" */
933                 i = ctx->ctx_pflags2mta;
934                 if ((ctx->ctx_mta_pflags & i) != i)
935                 {
936                         unsigned int idx;
937                         unsigned long b;
938
939                         /*
940                         **  If some behavior can be faked (set in fake_pflags),
941                         **  but the MTA doesn't support it, then unset
942                         **  that flag in the value that is sent to the MTA.
943                         */
944
945                         for (idx = 0; idx < 32; idx++)
946                         {
947                                 b = 1 << idx;
948                                 if ((ctx->ctx_mta_pflags & b) != b &&
949                                     (fake_pflags & b) == b)
950                                         ctx->ctx_pflags2mta &= ~b;
951                         }
952                 }
953         }
954         else
955         {
956                 /*
957                 **  Set the protocol flags based on the values determined
958                 **  in mi_listener() which checked the defined callbacks.
959                 */
960
961                 ctx->ctx_pflags2mta = ctx->ctx_pflags;
962         }
963
964         /* check whether actions and protocol requirements can be satisfied */
965         i = ctx->ctx_aflags;
966         if ((i & ctx->ctx_mta_aflags) != i)
967         {
968                 smi_log(SMI_LOG_ERR,
969                         "%s: st_optionneg[%ld]: 0x%lx does not fulfill action requirements 0x%x",
970                         ctx->ctx_smfi->xxfi_name,
971                         (long) ctx->ctx_id, ctx->ctx_mta_aflags, i);
972                 return _SMFIS_ABORT;
973         }
974
975         i = ctx->ctx_pflags2mta;
976         if ((ctx->ctx_mta_pflags & i) != i)
977         {
978                 /*
979                 **  Older MTAs do not support some protocol steps.
980                 **  As this protocol is a bit "wierd" (it asks for steps
981                 **  NOT to be taken/sent) we have to check whether we
982                 **  should turn off those "negative" requests.
983                 **  Currently these are only SMFIP_NODATA and SMFIP_NOUNKNOWN.
984                 */
985
986                 if (bitset(SMFIP_NODATA, ctx->ctx_pflags2mta) &&
987                     !bitset(SMFIP_NODATA, ctx->ctx_mta_pflags))
988                         ctx->ctx_pflags2mta &= ~SMFIP_NODATA;
989                 if (bitset(SMFIP_NOUNKNOWN, ctx->ctx_pflags2mta) &&
990                     !bitset(SMFIP_NOUNKNOWN, ctx->ctx_mta_pflags))
991                         ctx->ctx_pflags2mta &= ~SMFIP_NOUNKNOWN;
992                 i = ctx->ctx_pflags2mta;
993         }
994
995         if ((ctx->ctx_mta_pflags & i) != i)
996         {
997                 smi_log(SMI_LOG_ERR,
998                         "%s: st_optionneg[%ld]: 0x%lx does not fulfill protocol requirements 0x%x",
999                         ctx->ctx_smfi->xxfi_name,
1000                         (long) ctx->ctx_id, ctx->ctx_mta_pflags, i);
1001                 return _SMFIS_ABORT;
1002         }
1003
1004         if (ctx->ctx_dbg > 3)
1005                 sm_dprintf("[%ld] milter_negotiate:"
1006                         " mta_actions=0x%lx, mta_flags=0x%lx"
1007                         " actions=0x%lx, flags=0x%lx\n"
1008                         , (long) ctx->ctx_id
1009                         , ctx->ctx_mta_aflags, ctx->ctx_mta_pflags
1010                         , ctx->ctx_aflags, ctx->ctx_pflags);
1011
1012         return _SMFIS_OPTIONS;
1013 }
1014
1015 /*
1016 **  ST_CONNECTINFO -- receive connection information
1017 **
1018 **      Parameters:
1019 **              g -- generic argument structure
1020 **
1021 **      Returns:
1022 **              continue or filter-specified value
1023 */
1024
1025 static int
1026 st_connectinfo(g)
1027         genarg *g;
1028 {
1029         size_t l;
1030         size_t i;
1031         char *s, family;
1032         unsigned short port = 0;
1033         _SOCK_ADDR sockaddr;
1034         sfsistat (*fi_connect) __P((SMFICTX *, char *, _SOCK_ADDR *));
1035
1036         if (g == NULL)
1037                 return _SMFIS_ABORT;
1038         mi_clr_macros(g->a_ctx, g->a_idx + 1);
1039         if (g->a_ctx->ctx_smfi == NULL ||
1040             (fi_connect = g->a_ctx->ctx_smfi->xxfi_connect) == NULL)
1041                 return SMFIS_CONTINUE;
1042
1043         s = g->a_buf;
1044         i = 0;
1045         l = g->a_len;
1046         while (s[i] != '\0' && i <= l)
1047                 ++i;
1048         if (i + 1 >= l)
1049                 return _SMFIS_ABORT;
1050
1051         /* Move past trailing \0 in host string */
1052         i++;
1053         family = s[i++];
1054         (void) memset(&sockaddr, '\0', sizeof sockaddr);
1055         if (family != SMFIA_UNKNOWN)
1056         {
1057                 if (i + sizeof port >= l)
1058                 {
1059                         smi_log(SMI_LOG_ERR,
1060                                 "%s: connect[%ld]: wrong len %d >= %d",
1061                                 g->a_ctx->ctx_smfi->xxfi_name,
1062                                 (long) g->a_ctx->ctx_id, (int) i, (int) l);
1063                         return _SMFIS_ABORT;
1064                 }
1065                 (void) memcpy((void *) &port, (void *) (s + i),
1066                               sizeof port);
1067                 i += sizeof port;
1068
1069                 /* make sure string is terminated */
1070                 if (s[l - 1] != '\0')
1071                         return _SMFIS_ABORT;
1072 # if NETINET
1073                 if (family == SMFIA_INET)
1074                 {
1075                         if (inet_aton(s + i, (struct in_addr *) &sockaddr.sin.sin_addr)
1076                             != 1)
1077                         {
1078                                 smi_log(SMI_LOG_ERR,
1079                                         "%s: connect[%ld]: inet_aton failed",
1080                                         g->a_ctx->ctx_smfi->xxfi_name,
1081                                         (long) g->a_ctx->ctx_id);
1082                                 return _SMFIS_ABORT;
1083                         }
1084                         sockaddr.sa.sa_family = AF_INET;
1085                         if (port > 0)
1086                                 sockaddr.sin.sin_port = port;
1087                 }
1088                 else
1089 # endif /* NETINET */
1090 # if NETINET6
1091                 if (family == SMFIA_INET6)
1092                 {
1093                         if (mi_inet_pton(AF_INET6, s + i,
1094                                          &sockaddr.sin6.sin6_addr) != 1)
1095                         {
1096                                 smi_log(SMI_LOG_ERR,
1097                                         "%s: connect[%ld]: mi_inet_pton failed",
1098                                         g->a_ctx->ctx_smfi->xxfi_name,
1099                                         (long) g->a_ctx->ctx_id);
1100                                 return _SMFIS_ABORT;
1101                         }
1102                         sockaddr.sa.sa_family = AF_INET6;
1103                         if (port > 0)
1104                                 sockaddr.sin6.sin6_port = port;
1105                 }
1106                 else
1107 # endif /* NETINET6 */
1108 # if NETUNIX
1109                 if (family == SMFIA_UNIX)
1110                 {
1111                         if (sm_strlcpy(sockaddr.sunix.sun_path, s + i,
1112                             sizeof sockaddr.sunix.sun_path) >=
1113                             sizeof sockaddr.sunix.sun_path)
1114                         {
1115                                 smi_log(SMI_LOG_ERR,
1116                                         "%s: connect[%ld]: path too long",
1117                                         g->a_ctx->ctx_smfi->xxfi_name,
1118                                         (long) g->a_ctx->ctx_id);
1119                                 return _SMFIS_ABORT;
1120                         }
1121                         sockaddr.sunix.sun_family = AF_UNIX;
1122                 }
1123                 else
1124 # endif /* NETUNIX */
1125                 {
1126                         smi_log(SMI_LOG_ERR,
1127                                 "%s: connect[%ld]: unknown family %d",
1128                                 g->a_ctx->ctx_smfi->xxfi_name,
1129                                 (long) g->a_ctx->ctx_id, family);
1130                         return _SMFIS_ABORT;
1131                 }
1132         }
1133         return (*fi_connect)(g->a_ctx, g->a_buf,
1134                              family != SMFIA_UNKNOWN ? &sockaddr : NULL);
1135 }
1136
1137 /*
1138 **  ST_EOH -- end of headers
1139 **
1140 **      Parameters:
1141 **              g -- generic argument structure
1142 **
1143 **      Returns:
1144 **              continue or filter-specified value
1145 */
1146
1147 static int
1148 st_eoh(g)
1149         genarg *g;
1150 {
1151         sfsistat (*fi_eoh) __P((SMFICTX *));
1152
1153         if (g == NULL)
1154                 return _SMFIS_ABORT;
1155         if (g->a_ctx->ctx_smfi != NULL &&
1156             (fi_eoh = g->a_ctx->ctx_smfi->xxfi_eoh) != NULL)
1157                 return (*fi_eoh)(g->a_ctx);
1158         return SMFIS_CONTINUE;
1159 }
1160
1161 /*
1162 **  ST_DATA -- DATA command
1163 **
1164 **      Parameters:
1165 **              g -- generic argument structure
1166 **
1167 **      Returns:
1168 **              continue or filter-specified value
1169 */
1170
1171 static int
1172 st_data(g)
1173         genarg *g;
1174 {
1175         sfsistat (*fi_data) __P((SMFICTX *));
1176
1177         if (g == NULL)
1178                 return _SMFIS_ABORT;
1179         if (g->a_ctx->ctx_smfi != NULL &&
1180             (fi_data = g->a_ctx->ctx_smfi->xxfi_data) != NULL)
1181                 return (*fi_data)(g->a_ctx);
1182         return SMFIS_CONTINUE;
1183 }
1184
1185 /*
1186 **  ST_HELO -- helo/ehlo command
1187 **
1188 **      Parameters:
1189 **              g -- generic argument structure
1190 **
1191 **      Returns:
1192 **              continue or filter-specified value
1193 */
1194
1195 static int
1196 st_helo(g)
1197         genarg *g;
1198 {
1199         sfsistat (*fi_helo) __P((SMFICTX *, char *));
1200
1201         if (g == NULL)
1202                 return _SMFIS_ABORT;
1203         mi_clr_macros(g->a_ctx, g->a_idx + 1);
1204         if (g->a_ctx->ctx_smfi != NULL &&
1205             (fi_helo = g->a_ctx->ctx_smfi->xxfi_helo) != NULL)
1206         {
1207                 /* paranoia: check for terminating '\0' */
1208                 if (g->a_len == 0 || g->a_buf[g->a_len - 1] != '\0')
1209                         return MI_FAILURE;
1210                 return (*fi_helo)(g->a_ctx, g->a_buf);
1211         }
1212         return SMFIS_CONTINUE;
1213 }
1214
1215 /*
1216 **  ST_HEADER -- header line
1217 **
1218 **      Parameters:
1219 **              g -- generic argument structure
1220 **
1221 **      Returns:
1222 **              continue or filter-specified value
1223 */
1224
1225 static int
1226 st_header(g)
1227         genarg *g;
1228 {
1229         char *hf, *hv;
1230         sfsistat (*fi_header) __P((SMFICTX *, char *, char *));
1231
1232         if (g == NULL)
1233                 return _SMFIS_ABORT;
1234         if (g->a_ctx->ctx_smfi == NULL ||
1235             (fi_header = g->a_ctx->ctx_smfi->xxfi_header) == NULL)
1236                 return SMFIS_CONTINUE;
1237         if (dec_arg2(g->a_buf, g->a_len, &hf, &hv) == MI_SUCCESS)
1238                 return (*fi_header)(g->a_ctx, hf, hv);
1239         else
1240                 return _SMFIS_ABORT;
1241 }
1242
1243 #define ARGV_FCT(lf, rf, idx)                                   \
1244         char **argv;                                            \
1245         sfsistat (*lf) __P((SMFICTX *, char **));               \
1246         int r;                                                  \
1247                                                                 \
1248         if (g == NULL)                                          \
1249                 return _SMFIS_ABORT;                            \
1250         mi_clr_macros(g->a_ctx, g->a_idx + 1);                  \
1251         if (g->a_ctx->ctx_smfi == NULL ||                       \
1252             (lf = g->a_ctx->ctx_smfi->rf) == NULL)              \
1253                 return SMFIS_CONTINUE;                          \
1254         if ((argv = dec_argv(g->a_buf, g->a_len)) == NULL)      \
1255                 return _SMFIS_ABORT;                            \
1256         r = (*lf)(g->a_ctx, argv);                              \
1257         free(argv);                                             \
1258         return r;
1259
1260 /*
1261 **  ST_SENDER -- MAIL FROM command
1262 **
1263 **      Parameters:
1264 **              g -- generic argument structure
1265 **
1266 **      Returns:
1267 **              continue or filter-specified value
1268 */
1269
1270 static int
1271 st_sender(g)
1272         genarg *g;
1273 {
1274         ARGV_FCT(fi_envfrom, xxfi_envfrom, CI_MAIL)
1275 }
1276
1277 /*
1278 **  ST_RCPT -- RCPT TO command
1279 **
1280 **      Parameters:
1281 **              g -- generic argument structure
1282 **
1283 **      Returns:
1284 **              continue or filter-specified value
1285 */
1286
1287 static int
1288 st_rcpt(g)
1289         genarg *g;
1290 {
1291         ARGV_FCT(fi_envrcpt, xxfi_envrcpt, CI_RCPT)
1292 }
1293
1294 /*
1295 **  ST_UNKNOWN -- unrecognized or unimplemented command
1296 **
1297 **      Parameters:
1298 **              g -- generic argument structure
1299 **
1300 **      Returns:
1301 **              continue or filter-specified value
1302 */
1303
1304 static int
1305 st_unknown(g)
1306         genarg *g;
1307 {
1308         sfsistat (*fi_unknown) __P((SMFICTX *, const char *));
1309
1310         if (g == NULL)
1311                 return _SMFIS_ABORT;
1312         if (g->a_ctx->ctx_smfi != NULL &&
1313             (fi_unknown = g->a_ctx->ctx_smfi->xxfi_unknown) != NULL)
1314                 return (*fi_unknown)(g->a_ctx, (const char *) g->a_buf);
1315         return SMFIS_CONTINUE;
1316 }
1317
1318 /*
1319 **  ST_MACROS -- deal with macros received from the MTA
1320 **
1321 **      Parameters:
1322 **              g -- generic argument structure
1323 **
1324 **      Returns:
1325 **              continue/keep
1326 **
1327 **      Side effects:
1328 **              set pointer in macro array to current values.
1329 */
1330
1331 static int
1332 st_macros(g)
1333         genarg *g;
1334 {
1335         int i;
1336         char **argv;
1337
1338         if (g == NULL || g->a_len < 1)
1339                 return _SMFIS_FAIL;
1340         if ((argv = dec_argv(g->a_buf + 1, g->a_len - 1)) == NULL)
1341                 return _SMFIS_FAIL;
1342         switch (g->a_buf[0])
1343         {
1344           case SMFIC_CONNECT:
1345                 i = CI_CONN;
1346                 break;
1347           case SMFIC_HELO:
1348                 i = CI_HELO;
1349                 break;
1350           case SMFIC_MAIL:
1351                 i = CI_MAIL;
1352                 break;
1353           case SMFIC_RCPT:
1354                 i = CI_RCPT;
1355                 break;
1356           case SMFIC_DATA:
1357                 i = CI_DATA;
1358                 break;
1359           case SMFIC_BODYEOB:
1360                 i = CI_EOM;
1361                 break;
1362           case SMFIC_EOH:
1363                 i = CI_EOH;
1364                 break;
1365           default:
1366                 free(argv);
1367                 return _SMFIS_FAIL;
1368         }
1369         if (g->a_ctx->ctx_mac_ptr[i] != NULL)
1370                 free(g->a_ctx->ctx_mac_ptr[i]);
1371         if (g->a_ctx->ctx_mac_buf[i] != NULL)
1372                 free(g->a_ctx->ctx_mac_buf[i]);
1373         g->a_ctx->ctx_mac_ptr[i] = argv;
1374         g->a_ctx->ctx_mac_buf[i] = g->a_buf;
1375         return _SMFIS_KEEP;
1376 }
1377
1378 /*
1379 **  ST_QUIT -- quit command
1380 **
1381 **      Parameters:
1382 **              g -- generic argument structure
1383 **
1384 **      Returns:
1385 **              noreply
1386 */
1387
1388 /* ARGSUSED */
1389 static int
1390 st_quit(g)
1391         genarg *g;
1392 {
1393         sfsistat (*fi_close) __P((SMFICTX *));
1394
1395         if (g == NULL)
1396                 return _SMFIS_ABORT;
1397         if (g->a_ctx->ctx_smfi != NULL &&
1398             (fi_close = g->a_ctx->ctx_smfi->xxfi_close) != NULL)
1399                 (void) (*fi_close)(g->a_ctx);
1400         mi_clr_macros(g->a_ctx, 0);
1401         return _SMFIS_NOREPLY;
1402 }
1403
1404 /*
1405 **  ST_BODYCHUNK -- deal with a piece of the mail body
1406 **
1407 **      Parameters:
1408 **              g -- generic argument structure
1409 **
1410 **      Returns:
1411 **              continue or filter-specified value
1412 */
1413
1414 static int
1415 st_bodychunk(g)
1416         genarg *g;
1417 {
1418         sfsistat (*fi_body) __P((SMFICTX *, unsigned char *, size_t));
1419
1420         if (g == NULL)
1421                 return _SMFIS_ABORT;
1422         if (g->a_ctx->ctx_smfi != NULL &&
1423             (fi_body = g->a_ctx->ctx_smfi->xxfi_body) != NULL)
1424                 return (*fi_body)(g->a_ctx, (unsigned char *)g->a_buf,
1425                                   g->a_len);
1426         return SMFIS_CONTINUE;
1427 }
1428
1429 /*
1430 **  ST_BODYEND -- deal with the last piece of the mail body
1431 **
1432 **      Parameters:
1433 **              g -- generic argument structure
1434 **
1435 **      Returns:
1436 **              continue or filter-specified value
1437 **
1438 **      Side effects:
1439 **              sends a reply for the body part (if non-empty).
1440 */
1441
1442 static int
1443 st_bodyend(g)
1444         genarg *g;
1445 {
1446         sfsistat r;
1447         sfsistat (*fi_body) __P((SMFICTX *, unsigned char *, size_t));
1448         sfsistat (*fi_eom) __P((SMFICTX *));
1449
1450         if (g == NULL)
1451                 return _SMFIS_ABORT;
1452         r = SMFIS_CONTINUE;
1453         if (g->a_ctx->ctx_smfi != NULL)
1454         {
1455                 if ((fi_body = g->a_ctx->ctx_smfi->xxfi_body) != NULL &&
1456                     g->a_len > 0)
1457                 {
1458                         socket_t sd;
1459                         struct timeval timeout;
1460
1461                         timeout.tv_sec = g->a_ctx->ctx_timeout;
1462                         timeout.tv_usec = 0;
1463                         sd = g->a_ctx->ctx_sd;
1464                         r = (*fi_body)(g->a_ctx, (unsigned char *)g->a_buf,
1465                                        g->a_len);
1466                         if (r != SMFIS_CONTINUE &&
1467                             sendreply(r, sd, &timeout, g->a_ctx) != MI_SUCCESS)
1468                                 return _SMFIS_ABORT;
1469                 }
1470         }
1471         if (r == SMFIS_CONTINUE &&
1472             (fi_eom = g->a_ctx->ctx_smfi->xxfi_eom) != NULL)
1473                 return (*fi_eom)(g->a_ctx);
1474         return r;
1475 }
1476
1477 /*
1478 **  ST_ABORTFCT -- deal with aborts
1479 **
1480 **      Parameters:
1481 **              g -- generic argument structure
1482 **
1483 **      Returns:
1484 **              abort or filter-specified value
1485 */
1486
1487 static int
1488 st_abortfct(g)
1489         genarg *g;
1490 {
1491         sfsistat (*fi_abort) __P((SMFICTX *));
1492
1493         if (g == NULL)
1494                 return _SMFIS_ABORT;
1495         if (g != NULL && g->a_ctx->ctx_smfi != NULL &&
1496             (fi_abort = g->a_ctx->ctx_smfi->xxfi_abort) != NULL)
1497                 (void) (*fi_abort)(g->a_ctx);
1498         return _SMFIS_NOREPLY;
1499 }
1500
1501 /*
1502 **  TRANS_OK -- is the state transition ok?
1503 **
1504 **      Parameters:
1505 **              old -- old state
1506 **              new -- new state
1507 **
1508 **      Returns:
1509 **              state transition ok
1510 */
1511
1512 static bool
1513 trans_ok(old, new)
1514         int old, new;
1515 {
1516         int s, n;
1517
1518         s = old;
1519         if (s >= SIZE_NEXT_STATES)
1520                 return false;
1521         do
1522         {
1523                 /* is this state transition allowed? */
1524                 if ((MI_MASK(new) & next_states[s]) != 0)
1525                         return true;
1526
1527                 /*
1528                 **  no: try next state;
1529                 **  this works since the relevant states are ordered
1530                 **  strict sequentially
1531                 */
1532
1533                 n = s + 1;
1534                 if (n >= SIZE_NEXT_STATES)
1535                         return false;
1536
1537                 /*
1538                 **  can we actually "skip" this state?
1539                 **  see fix_stm() which sets this bit for those
1540                 **  states which the filter program is not interested in
1541                 */
1542
1543                 if (bitset(NX_SKIP, next_states[n]))
1544                         s = n;
1545                 else
1546                         return false;
1547         } while (s < SIZE_NEXT_STATES);
1548         return false;
1549 }
1550
1551 /*
1552 **  FIX_STM -- add "skip" bits to the state transition table
1553 **
1554 **      Parameters:
1555 **              ctx -- context structure
1556 **
1557 **      Returns:
1558 **              None.
1559 **
1560 **      Side effects:
1561 **              may change state transition table.
1562 */
1563
1564 static void
1565 fix_stm(ctx)
1566         SMFICTX_PTR ctx;
1567 {
1568         unsigned long fl;
1569
1570         if (ctx == NULL || ctx->ctx_smfi == NULL)
1571                 return;
1572         fl = ctx->ctx_pflags;
1573         if (bitset(SMFIP_NOCONNECT, fl))
1574                 next_states[ST_CONN] |= NX_SKIP;
1575         if (bitset(SMFIP_NOHELO, fl))
1576                 next_states[ST_HELO] |= NX_SKIP;
1577         if (bitset(SMFIP_NOMAIL, fl))
1578                 next_states[ST_MAIL] |= NX_SKIP;
1579         if (bitset(SMFIP_NORCPT, fl))
1580                 next_states[ST_RCPT] |= NX_SKIP;
1581         if (bitset(SMFIP_NOHDRS, fl))
1582                 next_states[ST_HDRS] |= NX_SKIP;
1583         if (bitset(SMFIP_NOEOH, fl))
1584                 next_states[ST_EOHS] |= NX_SKIP;
1585         if (bitset(SMFIP_NOBODY, fl))
1586                 next_states[ST_BODY] |= NX_SKIP;
1587         if (bitset(SMFIP_NODATA, fl))
1588                 next_states[ST_DATA] |= NX_SKIP;
1589         if (bitset(SMFIP_NOUNKNOWN, fl))
1590                 next_states[ST_UNKN] |= NX_SKIP;
1591 }
1592
1593 /*
1594 **  DEC_ARGV -- split a buffer into a list of strings, NULL terminated
1595 **
1596 **      Parameters:
1597 **              buf -- buffer with several strings
1598 **              len -- length of buffer
1599 **
1600 **      Returns:
1601 **              array of pointers to the individual strings
1602 */
1603
1604 static char **
1605 dec_argv(buf, len)
1606         char *buf;
1607         size_t len;
1608 {
1609         char **s;
1610         size_t i;
1611         int elem, nelem;
1612
1613         nelem = 0;
1614         for (i = 0; i < len; i++)
1615         {
1616                 if (buf[i] == '\0')
1617                         ++nelem;
1618         }
1619         if (nelem == 0)
1620                 return NULL;
1621
1622         /* last entry is only for the name */
1623         s = (char **)malloc((nelem + 1) * (sizeof *s));
1624         if (s == NULL)
1625                 return NULL;
1626         s[0] = buf;
1627         for (i = 0, elem = 0; i < len && elem < nelem; i++)
1628         {
1629                 if (buf[i] == '\0')
1630                 {
1631                         ++elem;
1632                         if (i + 1 >= len)
1633                                 s[elem] = NULL;
1634                         else
1635                                 s[elem] = &(buf[i + 1]);
1636                 }
1637         }
1638
1639         /* overwrite last entry (already done above, just paranoia) */
1640         s[elem] = NULL;
1641         return s;
1642 }
1643
1644 /*
1645 **  DEC_ARG2 -- split a buffer into two strings
1646 **
1647 **      Parameters:
1648 **              buf -- buffer with two strings
1649 **              len -- length of buffer
1650 **              s1,s2 -- pointer to result strings
1651 **
1652 **      Returns:
1653 **              MI_FAILURE/MI_SUCCESS
1654 */
1655
1656 static int
1657 dec_arg2(buf, len, s1, s2)
1658         char *buf;
1659         size_t len;
1660         char **s1;
1661         char **s2;
1662 {
1663         size_t i;
1664
1665         /* paranoia: check for terminating '\0' */
1666         if (len == 0 || buf[len - 1] != '\0')
1667                 return MI_FAILURE;
1668         *s1 = buf;
1669         for (i = 1; i < len && buf[i] != '\0'; i++)
1670                 continue;
1671         if (i >= len - 1)
1672                 return MI_FAILURE;
1673         *s2 = buf + i + 1;
1674         return MI_SUCCESS;
1675 }
1676
1677 /*
1678 **  SENDOK -- is it ok for the filter to send stuff to the MTA?
1679 **
1680 **      Parameters:
1681 **              ctx -- context structure
1682 **              flag -- flag to check
1683 **
1684 **      Returns:
1685 **              sending allowed (in current state)
1686 */
1687
1688 bool
1689 mi_sendok(ctx, flag)
1690         SMFICTX_PTR ctx;
1691         int flag;
1692 {
1693         if (ctx == NULL || ctx->ctx_smfi == NULL)
1694                 return false;
1695
1696         /* did the milter request this operation? */
1697         if (flag != 0 && !bitset(flag, ctx->ctx_aflags))
1698                 return false;
1699
1700         /* are we in the correct state? It must be "End of Message". */
1701         return ctx->ctx_state == ST_ENDM;
1702 }
1703
1704 #if _FFR_WORKERS_POOL
1705 /*
1706 **  MI_RD_SOCKET_READY - checks if the socket is ready for read(2)
1707 **
1708 **      Parameters:
1709 **              sd -- socket_t
1710 **
1711 **      Returns:
1712 **              true iff socket is ready for read(2)
1713 */
1714
1715 #define MI_RD_CMD_TO  1
1716 #define MI_RD_MAX_ERR 16
1717
1718 static bool
1719 mi_rd_socket_ready (sd)
1720         socket_t sd;
1721 {
1722         int n;
1723         int nerr = 0;
1724 #if SM_CONF_POLL
1725                 struct pollfd pfd;
1726 #else /* SM_CONF_POLL */
1727                 fd_set  rd_set, exc_set;
1728 #endif /* SM_CONF_POLL */
1729
1730         do
1731         {
1732 #if SM_CONF_POLL
1733                 pfd.fd = sd;
1734                 pfd.events = POLLIN;
1735                 pfd.revents = 0;
1736
1737                 n = poll(&pfd, 1, MI_RD_CMD_TO);
1738 #else /* SM_CONF_POLL */
1739                 struct timeval timeout;
1740
1741                 FD_ZERO(&rd_set);
1742                 FD_ZERO(&exc_set);
1743                 FD_SET(sd, &rd_set);
1744                 FD_SET(sd, &exc_set);
1745
1746                 timeout.tv_sec = MI_RD_CMD_TO / 1000;
1747                 timeout.tv_usec = 0;
1748                 n = select(sd + 1, &rd_set, NULL, &exc_set, &timeout);
1749 #endif /* SM_CONF_POLL */
1750
1751                 if (n < 0)
1752                 {
1753                         if (errno == EINTR)
1754                         {
1755                                 nerr++;
1756                                 continue;
1757                         }
1758                         return true;
1759                 }
1760
1761                 if (n == 0)
1762                         return false;
1763                 break;
1764         } while (nerr < MI_RD_MAX_ERR);
1765         if (nerr >= MI_RD_MAX_ERR)
1766                 return false;
1767
1768 #if SM_CONF_POLL
1769         return (pfd.revents != 0);
1770 #else /* SM_CONF_POLL */
1771         return FD_ISSET(sd, &rd_set) || FD_ISSET(sd, &exc_set);
1772 #endif /* SM_CONF_POLL */
1773 }
1774 #endif /* _FFR_WORKERS_POOL */