Import sendmail 8.14.2
[dragonfly.git] / contrib / sendmail-8.14 / libmilter / engine.c
1 /*
2  *  Copyright (c) 1999-2004, 2006, 2007 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.159 2007/04/23 22:22:50 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             g->a_ctx->ctx_smfi->xxfi_version > 4 &&
859             (fi_negotiate = g->a_ctx->ctx_smfi->xxfi_negotiate) != NULL)
860         {
861                 int r;
862                 unsigned long m_aflags, m_pflags, m_f2, m_f3;
863
864                 /*
865                 **  let milter decide whether the features offered by the
866                 **  MTA are "good enough".
867                 **  Notes:
868                 **  - libmilter can "fake" some features (e.g., SMFIP_NR_HDR)
869                 **  - m_f2, m_f3 are for future extensions
870                 */
871
872                 m_f2 = m_f3 = 0;
873                 m_aflags = ctx->ctx_mta_aflags;
874                 m_pflags = ctx->ctx_pflags;
875                 if ((SMFIP_SKIP & ctx->ctx_mta_pflags) != 0)
876                         m_pflags |= SMFIP_SKIP;
877                 r = fi_negotiate(g->a_ctx,
878                                 ctx->ctx_mta_aflags,
879                                 ctx->ctx_mta_pflags|fake_pflags,
880                                 0, 0,
881                                 &m_aflags, &m_pflags, &m_f2, &m_f3);
882
883                 /*
884                 **  Types of protocol flags (pflags):
885                 **  1. do NOT send protocol step X
886                 **  2. MTA can do/understand something extra (SKIP,
887                 **      send unknown RCPTs)
888                 **  3. MTA can deal with "no reply" for various protocol steps
889                 **  Note: this mean that it isn't possible to simply set all
890                 **      flags to get "everything":
891                 **      setting a flag of type 1 turns off a step
892                 **              (it should be the other way around:
893                 **              a flag means a protocol step can be sent)
894                 **      setting a flag of type 3 requires that milter
895                 **      never sends a reply for the corresponding step.
896                 **  Summary: the "negation" of protocol flags is causing
897                 **      problems, but at least for type 3 there is no simple
898                 **      solution.
899                 **
900                 **  What should "all options" mean?
901                 **  send all protocol steps _except_ those for which there is
902                 **      no callback (currently registered in ctx_pflags)
903                 **  expect SKIP as return code?         Yes
904                 **  send unknown RCPTs?                 No,
905                 **                              must be explicitly requested?
906                 **  "no reply" for some protocol steps? No,
907                 **                              must be explicitly requested.
908                 */
909
910                 if (SMFIS_ALL_OPTS == r)
911                 {
912                         ctx->ctx_aflags = ctx->ctx_mta_aflags;
913                         ctx->ctx_pflags2mta = ctx->ctx_pflags;
914                         if ((SMFIP_SKIP & ctx->ctx_mta_pflags) != 0)
915                                 ctx->ctx_pflags2mta |= SMFIP_SKIP;
916                 }
917                 else if (r != SMFIS_CONTINUE)
918                 {
919                         smi_log(SMI_LOG_ERR,
920                                 "%s: st_optionneg[%ld]: xxfi_negotiate returned %d (protocol options=0x%lx, actions=0x%lx)",
921                                 ctx->ctx_smfi->xxfi_name,
922                                 (long) ctx->ctx_id, r, ctx->ctx_mta_pflags,
923                                 ctx->ctx_mta_aflags);
924                         return _SMFIS_ABORT;
925                 }
926                 else
927                 {
928                         ctx->ctx_aflags = m_aflags;
929                         ctx->ctx_pflags = m_pflags;
930                         ctx->ctx_pflags2mta = m_pflags;
931                 }
932
933                 /* check whether some flags need to be "faked" */
934                 i = ctx->ctx_pflags2mta;
935                 if ((ctx->ctx_mta_pflags & i) != i)
936                 {
937                         unsigned int idx;
938                         unsigned long b;
939
940                         /*
941                         **  If some behavior can be faked (set in fake_pflags),
942                         **  but the MTA doesn't support it, then unset
943                         **  that flag in the value that is sent to the MTA.
944                         */
945
946                         for (idx = 0; idx < 32; idx++)
947                         {
948                                 b = 1 << idx;
949                                 if ((ctx->ctx_mta_pflags & b) != b &&
950                                     (fake_pflags & b) == b)
951                                         ctx->ctx_pflags2mta &= ~b;
952                         }
953                 }
954         }
955         else
956         {
957                 /*
958                 **  Set the protocol flags based on the values determined
959                 **  in mi_listener() which checked the defined callbacks.
960                 */
961
962                 ctx->ctx_pflags2mta = ctx->ctx_pflags;
963         }
964
965         /* check whether actions and protocol requirements can be satisfied */
966         i = ctx->ctx_aflags;
967         if ((i & ctx->ctx_mta_aflags) != i)
968         {
969                 smi_log(SMI_LOG_ERR,
970                         "%s: st_optionneg[%ld]: 0x%lx does not fulfill action requirements 0x%x",
971                         ctx->ctx_smfi->xxfi_name,
972                         (long) ctx->ctx_id, ctx->ctx_mta_aflags, i);
973                 return _SMFIS_ABORT;
974         }
975
976         i = ctx->ctx_pflags2mta;
977         if ((ctx->ctx_mta_pflags & i) != i)
978         {
979                 /*
980                 **  Older MTAs do not support some protocol steps.
981                 **  As this protocol is a bit "wierd" (it asks for steps
982                 **  NOT to be taken/sent) we have to check whether we
983                 **  should turn off those "negative" requests.
984                 **  Currently these are only SMFIP_NODATA and SMFIP_NOUNKNOWN.
985                 */
986
987                 if (bitset(SMFIP_NODATA, ctx->ctx_pflags2mta) &&
988                     !bitset(SMFIP_NODATA, ctx->ctx_mta_pflags))
989                         ctx->ctx_pflags2mta &= ~SMFIP_NODATA;
990                 if (bitset(SMFIP_NOUNKNOWN, ctx->ctx_pflags2mta) &&
991                     !bitset(SMFIP_NOUNKNOWN, ctx->ctx_mta_pflags))
992                         ctx->ctx_pflags2mta &= ~SMFIP_NOUNKNOWN;
993                 i = ctx->ctx_pflags2mta;
994         }
995
996         if ((ctx->ctx_mta_pflags & i) != i)
997         {
998                 smi_log(SMI_LOG_ERR,
999                         "%s: st_optionneg[%ld]: 0x%lx does not fulfill protocol requirements 0x%x",
1000                         ctx->ctx_smfi->xxfi_name,
1001                         (long) ctx->ctx_id, ctx->ctx_mta_pflags, i);
1002                 return _SMFIS_ABORT;
1003         }
1004
1005         if (ctx->ctx_dbg > 3)
1006                 sm_dprintf("[%ld] milter_negotiate:"
1007                         " mta_actions=0x%lx, mta_flags=0x%lx"
1008                         " actions=0x%lx, flags=0x%lx\n"
1009                         , (long) ctx->ctx_id
1010                         , ctx->ctx_mta_aflags, ctx->ctx_mta_pflags
1011                         , ctx->ctx_aflags, ctx->ctx_pflags);
1012
1013         return _SMFIS_OPTIONS;
1014 }
1015
1016 /*
1017 **  ST_CONNECTINFO -- receive connection information
1018 **
1019 **      Parameters:
1020 **              g -- generic argument structure
1021 **
1022 **      Returns:
1023 **              continue or filter-specified value
1024 */
1025
1026 static int
1027 st_connectinfo(g)
1028         genarg *g;
1029 {
1030         size_t l;
1031         size_t i;
1032         char *s, family;
1033         unsigned short port = 0;
1034         _SOCK_ADDR sockaddr;
1035         sfsistat (*fi_connect) __P((SMFICTX *, char *, _SOCK_ADDR *));
1036
1037         if (g == NULL)
1038                 return _SMFIS_ABORT;
1039         mi_clr_macros(g->a_ctx, g->a_idx + 1);
1040         if (g->a_ctx->ctx_smfi == NULL ||
1041             (fi_connect = g->a_ctx->ctx_smfi->xxfi_connect) == NULL)
1042                 return SMFIS_CONTINUE;
1043
1044         s = g->a_buf;
1045         i = 0;
1046         l = g->a_len;
1047         while (s[i] != '\0' && i <= l)
1048                 ++i;
1049         if (i + 1 >= l)
1050                 return _SMFIS_ABORT;
1051
1052         /* Move past trailing \0 in host string */
1053         i++;
1054         family = s[i++];
1055         (void) memset(&sockaddr, '\0', sizeof sockaddr);
1056         if (family != SMFIA_UNKNOWN)
1057         {
1058                 if (i + sizeof port >= l)
1059                 {
1060                         smi_log(SMI_LOG_ERR,
1061                                 "%s: connect[%ld]: wrong len %d >= %d",
1062                                 g->a_ctx->ctx_smfi->xxfi_name,
1063                                 (long) g->a_ctx->ctx_id, (int) i, (int) l);
1064                         return _SMFIS_ABORT;
1065                 }
1066                 (void) memcpy((void *) &port, (void *) (s + i),
1067                               sizeof port);
1068                 i += sizeof port;
1069
1070                 /* make sure string is terminated */
1071                 if (s[l - 1] != '\0')
1072                         return _SMFIS_ABORT;
1073 # if NETINET
1074                 if (family == SMFIA_INET)
1075                 {
1076                         if (inet_aton(s + i, (struct in_addr *) &sockaddr.sin.sin_addr)
1077                             != 1)
1078                         {
1079                                 smi_log(SMI_LOG_ERR,
1080                                         "%s: connect[%ld]: inet_aton failed",
1081                                         g->a_ctx->ctx_smfi->xxfi_name,
1082                                         (long) g->a_ctx->ctx_id);
1083                                 return _SMFIS_ABORT;
1084                         }
1085                         sockaddr.sa.sa_family = AF_INET;
1086                         if (port > 0)
1087                                 sockaddr.sin.sin_port = port;
1088                 }
1089                 else
1090 # endif /* NETINET */
1091 # if NETINET6
1092                 if (family == SMFIA_INET6)
1093                 {
1094                         if (mi_inet_pton(AF_INET6, s + i,
1095                                          &sockaddr.sin6.sin6_addr) != 1)
1096                         {
1097                                 smi_log(SMI_LOG_ERR,
1098                                         "%s: connect[%ld]: mi_inet_pton failed",
1099                                         g->a_ctx->ctx_smfi->xxfi_name,
1100                                         (long) g->a_ctx->ctx_id);
1101                                 return _SMFIS_ABORT;
1102                         }
1103                         sockaddr.sa.sa_family = AF_INET6;
1104                         if (port > 0)
1105                                 sockaddr.sin6.sin6_port = port;
1106                 }
1107                 else
1108 # endif /* NETINET6 */
1109 # if NETUNIX
1110                 if (family == SMFIA_UNIX)
1111                 {
1112                         if (sm_strlcpy(sockaddr.sunix.sun_path, s + i,
1113                             sizeof sockaddr.sunix.sun_path) >=
1114                             sizeof sockaddr.sunix.sun_path)
1115                         {
1116                                 smi_log(SMI_LOG_ERR,
1117                                         "%s: connect[%ld]: path too long",
1118                                         g->a_ctx->ctx_smfi->xxfi_name,
1119                                         (long) g->a_ctx->ctx_id);
1120                                 return _SMFIS_ABORT;
1121                         }
1122                         sockaddr.sunix.sun_family = AF_UNIX;
1123                 }
1124                 else
1125 # endif /* NETUNIX */
1126                 {
1127                         smi_log(SMI_LOG_ERR,
1128                                 "%s: connect[%ld]: unknown family %d",
1129                                 g->a_ctx->ctx_smfi->xxfi_name,
1130                                 (long) g->a_ctx->ctx_id, family);
1131                         return _SMFIS_ABORT;
1132                 }
1133         }
1134         return (*fi_connect)(g->a_ctx, g->a_buf,
1135                              family != SMFIA_UNKNOWN ? &sockaddr : NULL);
1136 }
1137
1138 /*
1139 **  ST_EOH -- end of headers
1140 **
1141 **      Parameters:
1142 **              g -- generic argument structure
1143 **
1144 **      Returns:
1145 **              continue or filter-specified value
1146 */
1147
1148 static int
1149 st_eoh(g)
1150         genarg *g;
1151 {
1152         sfsistat (*fi_eoh) __P((SMFICTX *));
1153
1154         if (g == NULL)
1155                 return _SMFIS_ABORT;
1156         if (g->a_ctx->ctx_smfi != NULL &&
1157             (fi_eoh = g->a_ctx->ctx_smfi->xxfi_eoh) != NULL)
1158                 return (*fi_eoh)(g->a_ctx);
1159         return SMFIS_CONTINUE;
1160 }
1161
1162 /*
1163 **  ST_DATA -- DATA command
1164 **
1165 **      Parameters:
1166 **              g -- generic argument structure
1167 **
1168 **      Returns:
1169 **              continue or filter-specified value
1170 */
1171
1172 static int
1173 st_data(g)
1174         genarg *g;
1175 {
1176         sfsistat (*fi_data) __P((SMFICTX *));
1177
1178         if (g == NULL)
1179                 return _SMFIS_ABORT;
1180         if (g->a_ctx->ctx_smfi != NULL &&
1181             g->a_ctx->ctx_smfi->xxfi_version > 3 &&
1182             (fi_data = g->a_ctx->ctx_smfi->xxfi_data) != NULL)
1183                 return (*fi_data)(g->a_ctx);
1184         return SMFIS_CONTINUE;
1185 }
1186
1187 /*
1188 **  ST_HELO -- helo/ehlo command
1189 **
1190 **      Parameters:
1191 **              g -- generic argument structure
1192 **
1193 **      Returns:
1194 **              continue or filter-specified value
1195 */
1196
1197 static int
1198 st_helo(g)
1199         genarg *g;
1200 {
1201         sfsistat (*fi_helo) __P((SMFICTX *, char *));
1202
1203         if (g == NULL)
1204                 return _SMFIS_ABORT;
1205         mi_clr_macros(g->a_ctx, g->a_idx + 1);
1206         if (g->a_ctx->ctx_smfi != NULL &&
1207             (fi_helo = g->a_ctx->ctx_smfi->xxfi_helo) != NULL)
1208         {
1209                 /* paranoia: check for terminating '\0' */
1210                 if (g->a_len == 0 || g->a_buf[g->a_len - 1] != '\0')
1211                         return MI_FAILURE;
1212                 return (*fi_helo)(g->a_ctx, g->a_buf);
1213         }
1214         return SMFIS_CONTINUE;
1215 }
1216
1217 /*
1218 **  ST_HEADER -- header line
1219 **
1220 **      Parameters:
1221 **              g -- generic argument structure
1222 **
1223 **      Returns:
1224 **              continue or filter-specified value
1225 */
1226
1227 static int
1228 st_header(g)
1229         genarg *g;
1230 {
1231         char *hf, *hv;
1232         sfsistat (*fi_header) __P((SMFICTX *, char *, char *));
1233
1234         if (g == NULL)
1235                 return _SMFIS_ABORT;
1236         if (g->a_ctx->ctx_smfi == NULL ||
1237             (fi_header = g->a_ctx->ctx_smfi->xxfi_header) == NULL)
1238                 return SMFIS_CONTINUE;
1239         if (dec_arg2(g->a_buf, g->a_len, &hf, &hv) == MI_SUCCESS)
1240                 return (*fi_header)(g->a_ctx, hf, hv);
1241         else
1242                 return _SMFIS_ABORT;
1243 }
1244
1245 #define ARGV_FCT(lf, rf, idx)                                   \
1246         char **argv;                                            \
1247         sfsistat (*lf) __P((SMFICTX *, char **));               \
1248         int r;                                                  \
1249                                                                 \
1250         if (g == NULL)                                          \
1251                 return _SMFIS_ABORT;                            \
1252         mi_clr_macros(g->a_ctx, g->a_idx + 1);                  \
1253         if (g->a_ctx->ctx_smfi == NULL ||                       \
1254             (lf = g->a_ctx->ctx_smfi->rf) == NULL)              \
1255                 return SMFIS_CONTINUE;                          \
1256         if ((argv = dec_argv(g->a_buf, g->a_len)) == NULL)      \
1257                 return _SMFIS_ABORT;                            \
1258         r = (*lf)(g->a_ctx, argv);                              \
1259         free(argv);                                             \
1260         return r;
1261
1262 /*
1263 **  ST_SENDER -- MAIL FROM command
1264 **
1265 **      Parameters:
1266 **              g -- generic argument structure
1267 **
1268 **      Returns:
1269 **              continue or filter-specified value
1270 */
1271
1272 static int
1273 st_sender(g)
1274         genarg *g;
1275 {
1276         ARGV_FCT(fi_envfrom, xxfi_envfrom, CI_MAIL)
1277 }
1278
1279 /*
1280 **  ST_RCPT -- RCPT TO command
1281 **
1282 **      Parameters:
1283 **              g -- generic argument structure
1284 **
1285 **      Returns:
1286 **              continue or filter-specified value
1287 */
1288
1289 static int
1290 st_rcpt(g)
1291         genarg *g;
1292 {
1293         ARGV_FCT(fi_envrcpt, xxfi_envrcpt, CI_RCPT)
1294 }
1295
1296 /*
1297 **  ST_UNKNOWN -- unrecognized or unimplemented command
1298 **
1299 **      Parameters:
1300 **              g -- generic argument structure
1301 **
1302 **      Returns:
1303 **              continue or filter-specified value
1304 */
1305
1306 static int
1307 st_unknown(g)
1308         genarg *g;
1309 {
1310         sfsistat (*fi_unknown) __P((SMFICTX *, const char *));
1311
1312         if (g == NULL)
1313                 return _SMFIS_ABORT;
1314         if (g->a_ctx->ctx_smfi != NULL &&
1315             g->a_ctx->ctx_smfi->xxfi_version > 2 &&
1316             (fi_unknown = g->a_ctx->ctx_smfi->xxfi_unknown) != NULL)
1317                 return (*fi_unknown)(g->a_ctx, (const char *) g->a_buf);
1318         return SMFIS_CONTINUE;
1319 }
1320
1321 /*
1322 **  ST_MACROS -- deal with macros received from the MTA
1323 **
1324 **      Parameters:
1325 **              g -- generic argument structure
1326 **
1327 **      Returns:
1328 **              continue/keep
1329 **
1330 **      Side effects:
1331 **              set pointer in macro array to current values.
1332 */
1333
1334 static int
1335 st_macros(g)
1336         genarg *g;
1337 {
1338         int i;
1339         char **argv;
1340
1341         if (g == NULL || g->a_len < 1)
1342                 return _SMFIS_FAIL;
1343         if ((argv = dec_argv(g->a_buf + 1, g->a_len - 1)) == NULL)
1344                 return _SMFIS_FAIL;
1345         switch (g->a_buf[0])
1346         {
1347           case SMFIC_CONNECT:
1348                 i = CI_CONN;
1349                 break;
1350           case SMFIC_HELO:
1351                 i = CI_HELO;
1352                 break;
1353           case SMFIC_MAIL:
1354                 i = CI_MAIL;
1355                 break;
1356           case SMFIC_RCPT:
1357                 i = CI_RCPT;
1358                 break;
1359           case SMFIC_DATA:
1360                 i = CI_DATA;
1361                 break;
1362           case SMFIC_BODYEOB:
1363                 i = CI_EOM;
1364                 break;
1365           case SMFIC_EOH:
1366                 i = CI_EOH;
1367                 break;
1368           default:
1369                 free(argv);
1370                 return _SMFIS_FAIL;
1371         }
1372         if (g->a_ctx->ctx_mac_ptr[i] != NULL)
1373                 free(g->a_ctx->ctx_mac_ptr[i]);
1374         if (g->a_ctx->ctx_mac_buf[i] != NULL)
1375                 free(g->a_ctx->ctx_mac_buf[i]);
1376         g->a_ctx->ctx_mac_ptr[i] = argv;
1377         g->a_ctx->ctx_mac_buf[i] = g->a_buf;
1378         return _SMFIS_KEEP;
1379 }
1380
1381 /*
1382 **  ST_QUIT -- quit command
1383 **
1384 **      Parameters:
1385 **              g -- generic argument structure
1386 **
1387 **      Returns:
1388 **              noreply
1389 */
1390
1391 /* ARGSUSED */
1392 static int
1393 st_quit(g)
1394         genarg *g;
1395 {
1396         sfsistat (*fi_close) __P((SMFICTX *));
1397
1398         if (g == NULL)
1399                 return _SMFIS_ABORT;
1400         if (g->a_ctx->ctx_smfi != NULL &&
1401             (fi_close = g->a_ctx->ctx_smfi->xxfi_close) != NULL)
1402                 (void) (*fi_close)(g->a_ctx);
1403         mi_clr_macros(g->a_ctx, 0);
1404         return _SMFIS_NOREPLY;
1405 }
1406
1407 /*
1408 **  ST_BODYCHUNK -- deal with a piece of the mail body
1409 **
1410 **      Parameters:
1411 **              g -- generic argument structure
1412 **
1413 **      Returns:
1414 **              continue or filter-specified value
1415 */
1416
1417 static int
1418 st_bodychunk(g)
1419         genarg *g;
1420 {
1421         sfsistat (*fi_body) __P((SMFICTX *, unsigned char *, size_t));
1422
1423         if (g == NULL)
1424                 return _SMFIS_ABORT;
1425         if (g->a_ctx->ctx_smfi != NULL &&
1426             (fi_body = g->a_ctx->ctx_smfi->xxfi_body) != NULL)
1427                 return (*fi_body)(g->a_ctx, (unsigned char *)g->a_buf,
1428                                   g->a_len);
1429         return SMFIS_CONTINUE;
1430 }
1431
1432 /*
1433 **  ST_BODYEND -- deal with the last piece of the mail body
1434 **
1435 **      Parameters:
1436 **              g -- generic argument structure
1437 **
1438 **      Returns:
1439 **              continue or filter-specified value
1440 **
1441 **      Side effects:
1442 **              sends a reply for the body part (if non-empty).
1443 */
1444
1445 static int
1446 st_bodyend(g)
1447         genarg *g;
1448 {
1449         sfsistat r;
1450         sfsistat (*fi_body) __P((SMFICTX *, unsigned char *, size_t));
1451         sfsistat (*fi_eom) __P((SMFICTX *));
1452
1453         if (g == NULL)
1454                 return _SMFIS_ABORT;
1455         r = SMFIS_CONTINUE;
1456         if (g->a_ctx->ctx_smfi != NULL)
1457         {
1458                 if ((fi_body = g->a_ctx->ctx_smfi->xxfi_body) != NULL &&
1459                     g->a_len > 0)
1460                 {
1461                         socket_t sd;
1462                         struct timeval timeout;
1463
1464                         timeout.tv_sec = g->a_ctx->ctx_timeout;
1465                         timeout.tv_usec = 0;
1466                         sd = g->a_ctx->ctx_sd;
1467                         r = (*fi_body)(g->a_ctx, (unsigned char *)g->a_buf,
1468                                        g->a_len);
1469                         if (r != SMFIS_CONTINUE &&
1470                             sendreply(r, sd, &timeout, g->a_ctx) != MI_SUCCESS)
1471                                 return _SMFIS_ABORT;
1472                 }
1473         }
1474         if (r == SMFIS_CONTINUE &&
1475             (fi_eom = g->a_ctx->ctx_smfi->xxfi_eom) != NULL)
1476                 return (*fi_eom)(g->a_ctx);
1477         return r;
1478 }
1479
1480 /*
1481 **  ST_ABORTFCT -- deal with aborts
1482 **
1483 **      Parameters:
1484 **              g -- generic argument structure
1485 **
1486 **      Returns:
1487 **              abort or filter-specified value
1488 */
1489
1490 static int
1491 st_abortfct(g)
1492         genarg *g;
1493 {
1494         sfsistat (*fi_abort) __P((SMFICTX *));
1495
1496         if (g == NULL)
1497                 return _SMFIS_ABORT;
1498         if (g != NULL && g->a_ctx->ctx_smfi != NULL &&
1499             (fi_abort = g->a_ctx->ctx_smfi->xxfi_abort) != NULL)
1500                 (void) (*fi_abort)(g->a_ctx);
1501         return _SMFIS_NOREPLY;
1502 }
1503
1504 /*
1505 **  TRANS_OK -- is the state transition ok?
1506 **
1507 **      Parameters:
1508 **              old -- old state
1509 **              new -- new state
1510 **
1511 **      Returns:
1512 **              state transition ok
1513 */
1514
1515 static bool
1516 trans_ok(old, new)
1517         int old, new;
1518 {
1519         int s, n;
1520
1521         s = old;
1522         if (s >= SIZE_NEXT_STATES)
1523                 return false;
1524         do
1525         {
1526                 /* is this state transition allowed? */
1527                 if ((MI_MASK(new) & next_states[s]) != 0)
1528                         return true;
1529
1530                 /*
1531                 **  no: try next state;
1532                 **  this works since the relevant states are ordered
1533                 **  strict sequentially
1534                 */
1535
1536                 n = s + 1;
1537                 if (n >= SIZE_NEXT_STATES)
1538                         return false;
1539
1540                 /*
1541                 **  can we actually "skip" this state?
1542                 **  see fix_stm() which sets this bit for those
1543                 **  states which the filter program is not interested in
1544                 */
1545
1546                 if (bitset(NX_SKIP, next_states[n]))
1547                         s = n;
1548                 else
1549                         return false;
1550         } while (s < SIZE_NEXT_STATES);
1551         return false;
1552 }
1553
1554 /*
1555 **  FIX_STM -- add "skip" bits to the state transition table
1556 **
1557 **      Parameters:
1558 **              ctx -- context structure
1559 **
1560 **      Returns:
1561 **              None.
1562 **
1563 **      Side effects:
1564 **              may change state transition table.
1565 */
1566
1567 static void
1568 fix_stm(ctx)
1569         SMFICTX_PTR ctx;
1570 {
1571         unsigned long fl;
1572
1573         if (ctx == NULL || ctx->ctx_smfi == NULL)
1574                 return;
1575         fl = ctx->ctx_pflags;
1576         if (bitset(SMFIP_NOCONNECT, fl))
1577                 next_states[ST_CONN] |= NX_SKIP;
1578         if (bitset(SMFIP_NOHELO, fl))
1579                 next_states[ST_HELO] |= NX_SKIP;
1580         if (bitset(SMFIP_NOMAIL, fl))
1581                 next_states[ST_MAIL] |= NX_SKIP;
1582         if (bitset(SMFIP_NORCPT, fl))
1583                 next_states[ST_RCPT] |= NX_SKIP;
1584         if (bitset(SMFIP_NOHDRS, fl))
1585                 next_states[ST_HDRS] |= NX_SKIP;
1586         if (bitset(SMFIP_NOEOH, fl))
1587                 next_states[ST_EOHS] |= NX_SKIP;
1588         if (bitset(SMFIP_NOBODY, fl))
1589                 next_states[ST_BODY] |= NX_SKIP;
1590         if (bitset(SMFIP_NODATA, fl))
1591                 next_states[ST_DATA] |= NX_SKIP;
1592         if (bitset(SMFIP_NOUNKNOWN, fl))
1593                 next_states[ST_UNKN] |= NX_SKIP;
1594 }
1595
1596 /*
1597 **  DEC_ARGV -- split a buffer into a list of strings, NULL terminated
1598 **
1599 **      Parameters:
1600 **              buf -- buffer with several strings
1601 **              len -- length of buffer
1602 **
1603 **      Returns:
1604 **              array of pointers to the individual strings
1605 */
1606
1607 static char **
1608 dec_argv(buf, len)
1609         char *buf;
1610         size_t len;
1611 {
1612         char **s;
1613         size_t i;
1614         int elem, nelem;
1615
1616         nelem = 0;
1617         for (i = 0; i < len; i++)
1618         {
1619                 if (buf[i] == '\0')
1620                         ++nelem;
1621         }
1622         if (nelem == 0)
1623                 return NULL;
1624
1625         /* last entry is only for the name */
1626         s = (char **)malloc((nelem + 1) * (sizeof *s));
1627         if (s == NULL)
1628                 return NULL;
1629         s[0] = buf;
1630         for (i = 0, elem = 0; i < len && elem < nelem; i++)
1631         {
1632                 if (buf[i] == '\0')
1633                 {
1634                         ++elem;
1635                         if (i + 1 >= len)
1636                                 s[elem] = NULL;
1637                         else
1638                                 s[elem] = &(buf[i + 1]);
1639                 }
1640         }
1641
1642         /* overwrite last entry (already done above, just paranoia) */
1643         s[elem] = NULL;
1644         return s;
1645 }
1646
1647 /*
1648 **  DEC_ARG2 -- split a buffer into two strings
1649 **
1650 **      Parameters:
1651 **              buf -- buffer with two strings
1652 **              len -- length of buffer
1653 **              s1,s2 -- pointer to result strings
1654 **
1655 **      Returns:
1656 **              MI_FAILURE/MI_SUCCESS
1657 */
1658
1659 static int
1660 dec_arg2(buf, len, s1, s2)
1661         char *buf;
1662         size_t len;
1663         char **s1;
1664         char **s2;
1665 {
1666         size_t i;
1667
1668         /* paranoia: check for terminating '\0' */
1669         if (len == 0 || buf[len - 1] != '\0')
1670                 return MI_FAILURE;
1671         *s1 = buf;
1672         for (i = 1; i < len && buf[i] != '\0'; i++)
1673                 continue;
1674         if (i >= len - 1)
1675                 return MI_FAILURE;
1676         *s2 = buf + i + 1;
1677         return MI_SUCCESS;
1678 }
1679
1680 /*
1681 **  SENDOK -- is it ok for the filter to send stuff to the MTA?
1682 **
1683 **      Parameters:
1684 **              ctx -- context structure
1685 **              flag -- flag to check
1686 **
1687 **      Returns:
1688 **              sending allowed (in current state)
1689 */
1690
1691 bool
1692 mi_sendok(ctx, flag)
1693         SMFICTX_PTR ctx;
1694         int flag;
1695 {
1696         if (ctx == NULL || ctx->ctx_smfi == NULL)
1697                 return false;
1698
1699         /* did the milter request this operation? */
1700         if (flag != 0 && !bitset(flag, ctx->ctx_aflags))
1701                 return false;
1702
1703         /* are we in the correct state? It must be "End of Message". */
1704         return ctx->ctx_state == ST_ENDM;
1705 }
1706
1707 #if _FFR_WORKERS_POOL
1708 /*
1709 **  MI_RD_SOCKET_READY - checks if the socket is ready for read(2)
1710 **
1711 **      Parameters:
1712 **              sd -- socket_t
1713 **
1714 **      Returns:
1715 **              true iff socket is ready for read(2)
1716 */
1717
1718 #define MI_RD_CMD_TO  1
1719 #define MI_RD_MAX_ERR 16
1720
1721 static bool
1722 mi_rd_socket_ready (sd)
1723         socket_t sd;
1724 {
1725         int n;
1726         int nerr = 0;
1727 #if SM_CONF_POLL
1728                 struct pollfd pfd;
1729 #else /* SM_CONF_POLL */
1730                 fd_set  rd_set, exc_set;
1731 #endif /* SM_CONF_POLL */
1732
1733         do
1734         {
1735 #if SM_CONF_POLL
1736                 pfd.fd = sd;
1737                 pfd.events = POLLIN;
1738                 pfd.revents = 0;
1739
1740                 n = poll(&pfd, 1, MI_RD_CMD_TO);
1741 #else /* SM_CONF_POLL */
1742                 struct timeval timeout;
1743
1744                 FD_ZERO(&rd_set);
1745                 FD_ZERO(&exc_set);
1746                 FD_SET(sd, &rd_set);
1747                 FD_SET(sd, &exc_set);
1748
1749                 timeout.tv_sec = MI_RD_CMD_TO / 1000;
1750                 timeout.tv_usec = 0;
1751                 n = select(sd + 1, &rd_set, NULL, &exc_set, &timeout);
1752 #endif /* SM_CONF_POLL */
1753
1754                 if (n < 0)
1755                 {
1756                         if (errno == EINTR)
1757                         {
1758                                 nerr++;
1759                                 continue;
1760                         }
1761                         return true;
1762                 }
1763
1764                 if (n == 0)
1765                         return false;
1766                 break;
1767         } while (nerr < MI_RD_MAX_ERR);
1768         if (nerr >= MI_RD_MAX_ERR)
1769                 return false;
1770
1771 #if SM_CONF_POLL
1772         return (pfd.revents != 0);
1773 #else /* SM_CONF_POLL */
1774         return FD_ISSET(sd, &rd_set) || FD_ISSET(sd, &exc_set);
1775 #endif /* SM_CONF_POLL */
1776 }
1777 #endif /* _FFR_WORKERS_POOL */