1 /* 2 * Copyright (c) 1999-2003 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.109.2.8 2003/12/01 23:57:45 msk 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 /* start 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 #if _FFR_MILTER_MACROS_EOM 68 # define CI_EOM 4 69 # if CI_EOM >= MAX_MACROS_ENTRIES 70 ERROR: do not compile with CI_EOM >= MAX_MACROS_ENTRIES 71 # endif 72 #else /* _FFR_MILTER_MACROS_EOM */ 73 # if CI_RCPT >= MAX_MACROS_ENTRIES 74 ERROR: do not compile with CI_RCPT >= MAX_MACROS_ENTRIES 75 # endif 76 #endif /* _FFR_MILTER_MACROS_EOM */ 77 78 /* function prototypes */ 79 static int st_abortfct __P((genarg *)); 80 static int st_macros __P((genarg *)); 81 static int st_optionneg __P((genarg *)); 82 static int st_bodychunk __P((genarg *)); 83 static int st_connectinfo __P((genarg *)); 84 static int st_bodyend __P((genarg *)); 85 static int st_helo __P((genarg *)); 86 static int st_header __P((genarg *)); 87 static int st_sender __P((genarg *)); 88 static int st_rcpt __P((genarg *)); 89 static int st_eoh __P((genarg *)); 90 static int st_quit __P((genarg *)); 91 static int sendreply __P((sfsistat, socket_t, struct timeval *, SMFICTX_PTR)); 92 static void fix_stm __P((SMFICTX_PTR)); 93 static bool trans_ok __P((int, int)); 94 static char **dec_argv __P((char *, size_t)); 95 static int dec_arg2 __P((char *, size_t, char **, char **)); 96 97 /* states */ 98 #define ST_NONE (-1) 99 #define ST_INIT 0 /* initial state */ 100 #define ST_OPTS 1 /* option negotiation */ 101 #define ST_CONN 2 /* connection info */ 102 #define ST_HELO 3 /* helo */ 103 #define ST_MAIL 4 /* mail from */ 104 #define ST_RCPT 5 /* rcpt to */ 105 #define ST_HDRS 6 /* headers */ 106 #define ST_EOHS 7 /* end of headers */ 107 #define ST_BODY 8 /* body */ 108 #define ST_ENDM 9 /* end of message */ 109 #define ST_QUIT 10 /* quit */ 110 #define ST_ABRT 11 /* abort */ 111 #define ST_LAST ST_ABRT 112 #define ST_SKIP 15 /* not a state but required for the state table */ 113 114 /* in a mail transaction? must be before eom according to spec. */ 115 #define ST_IN_MAIL(st) ((st) >= ST_MAIL && (st) < ST_ENDM) 116 117 /* 118 ** set of next states 119 ** each state (ST_*) corresponds to bit in an int value (1 << state) 120 ** each state has a set of allowed transitions ('or' of bits of states) 121 ** so a state transition is valid if the mask of the next state 122 ** is set in the NX_* value 123 ** this function is coded in trans_ok(), see below. 124 */ 125 126 #define MI_MASK(x) (0x0001 << (x)) /* generate a bit "mask" for a state */ 127 #define NX_INIT (MI_MASK(ST_OPTS)) 128 #define NX_OPTS (MI_MASK(ST_CONN)) 129 #define NX_CONN (MI_MASK(ST_HELO) | MI_MASK(ST_MAIL)) 130 #define NX_HELO (MI_MASK(ST_HELO) | MI_MASK(ST_MAIL)) 131 #define NX_MAIL (MI_MASK(ST_RCPT) | MI_MASK(ST_ABRT)) 132 #define NX_RCPT (MI_MASK(ST_HDRS) | MI_MASK(ST_EOHS) | \ 133 MI_MASK(ST_BODY) | MI_MASK(ST_ENDM) | \ 134 MI_MASK(ST_RCPT) | MI_MASK(ST_ABRT)) 135 #define NX_HDRS (MI_MASK(ST_EOHS) | MI_MASK(ST_HDRS) | MI_MASK(ST_ABRT)) 136 #define NX_EOHS (MI_MASK(ST_BODY) | MI_MASK(ST_ENDM) | MI_MASK(ST_ABRT)) 137 #define NX_BODY (MI_MASK(ST_ENDM) | MI_MASK(ST_BODY) | MI_MASK(ST_ABRT)) 138 #define NX_ENDM (MI_MASK(ST_QUIT) | MI_MASK(ST_MAIL)) 139 #define NX_QUIT 0 140 #define NX_ABRT 0 141 #define NX_SKIP MI_MASK(ST_SKIP) 142 143 static int next_states[] = 144 { 145 NX_INIT, 146 NX_OPTS, 147 NX_CONN, 148 NX_HELO, 149 NX_MAIL, 150 NX_RCPT, 151 NX_HDRS, 152 NX_EOHS, 153 NX_BODY, 154 NX_ENDM, 155 NX_QUIT, 156 NX_ABRT 157 }; 158 159 /* commands received by milter */ 160 static cmdfct cmds[] = 161 { 162 {SMFIC_ABORT, CM_ARG0, ST_ABRT, CT_CONT, CI_NONE, st_abortfct }, 163 {SMFIC_MACRO, CM_ARGV, ST_NONE, CT_KEEP, CI_NONE, st_macros }, 164 {SMFIC_BODY, CM_ARG1, ST_BODY, CT_CONT, CI_NONE, st_bodychunk }, 165 {SMFIC_CONNECT, CM_ARG2, ST_CONN, CT_CONT, CI_CONN, st_connectinfo }, 166 #if _FFR_MILTER_MACROS_EOM 167 {SMFIC_BODYEOB, CM_ARG1, ST_ENDM, CT_CONT, CI_EOM, st_bodyend }, 168 #else /* _FFR_MILTER_MACROS_EOM */ 169 {SMFIC_BODYEOB, CM_ARG1, ST_ENDM, CT_CONT, CI_NONE, st_bodyend }, 170 #endif /* _FFR_MILTER_MACROS_EOM */ 171 {SMFIC_HELO, CM_ARG1, ST_HELO, CT_CONT, CI_HELO, st_helo }, 172 {SMFIC_HEADER, CM_ARG2, ST_HDRS, CT_CONT, CI_NONE, st_header }, 173 {SMFIC_MAIL, CM_ARGV, ST_MAIL, CT_CONT, CI_MAIL, st_sender }, 174 {SMFIC_OPTNEG, CM_ARGO, ST_OPTS, CT_CONT, CI_NONE, st_optionneg }, 175 {SMFIC_EOH, CM_ARG0, ST_EOHS, CT_CONT, CI_NONE, st_eoh }, 176 {SMFIC_QUIT, CM_ARG0, ST_QUIT, CT_END, CI_NONE, st_quit }, 177 {SMFIC_RCPT, CM_ARGV, ST_RCPT, CT_IGNO, CI_RCPT, st_rcpt } 178 }; 179 180 /* additional (internal) reply codes */ 181 #define _SMFIS_KEEP 20 182 #define _SMFIS_ABORT 21 183 #define _SMFIS_OPTIONS 22 184 #define _SMFIS_NOREPLY 23 185 #define _SMFIS_FAIL (-1) 186 #define _SMFIS_NONE (-2) 187 188 /* 189 ** MI_ENGINE -- receive commands and process them 190 ** 191 ** Parameters: 192 ** ctx -- context structure 193 ** 194 ** Returns: 195 ** MI_FAILURE/MI_SUCCESS 196 */ 197 int 198 mi_engine(ctx) 199 SMFICTX_PTR ctx; 200 { 201 size_t len; 202 int i; 203 socket_t sd; 204 int ret = MI_SUCCESS; 205 int ncmds = sizeof(cmds) / sizeof(cmdfct); 206 int curstate = ST_INIT; 207 int newstate; 208 bool call_abort; 209 sfsistat r; 210 char cmd; 211 char *buf = NULL; 212 genarg arg; 213 struct timeval timeout; 214 int (*f) __P((genarg *)); 215 sfsistat (*fi_abort) __P((SMFICTX *)); 216 sfsistat (*fi_close) __P((SMFICTX *)); 217 218 arg.a_ctx = ctx; 219 sd = ctx->ctx_sd; 220 fi_abort = ctx->ctx_smfi->xxfi_abort; 221 mi_clr_macros(ctx, 0); 222 fix_stm(ctx); 223 r = _SMFIS_NONE; 224 do 225 { 226 /* call abort only if in a mail transaction */ 227 call_abort = ST_IN_MAIL(curstate); 228 timeout.tv_sec = ctx->ctx_timeout; 229 timeout.tv_usec = 0; 230 if (mi_stop() == MILTER_ABRT) 231 { 232 if (ctx->ctx_dbg > 3) 233 sm_dprintf("[%d] milter_abort\n", 234 (int) ctx->ctx_id); 235 ret = MI_FAILURE; 236 break; 237 } 238 239 /* 240 ** Notice: buf is allocated by mi_rd_cmd() and it will 241 ** usually be free()d after it has been used in f(). 242 ** However, if the function returns _SMFIS_KEEP then buf 243 ** contains macros and will not be free()d. 244 ** Hence r must be set to _SMFIS_NONE if a new buf is 245 ** allocated to avoid problem with housekeeping, esp. 246 ** if the code "break"s out of the loop. 247 */ 248 249 r = _SMFIS_NONE; 250 if ((buf = mi_rd_cmd(sd, &timeout, &cmd, &len, 251 ctx->ctx_smfi->xxfi_name)) == NULL && 252 cmd < SMFIC_VALIDCMD) 253 { 254 if (ctx->ctx_dbg > 5) 255 sm_dprintf("[%d] mi_engine: mi_rd_cmd error (%x)\n", 256 (int) ctx->ctx_id, (int) cmd); 257 258 /* 259 ** eof is currently treated as failure -> 260 ** abort() instead of close(), otherwise use: 261 ** if (cmd != SMFIC_EOF) 262 */ 263 264 ret = MI_FAILURE; 265 break; 266 } 267 if (ctx->ctx_dbg > 4) 268 sm_dprintf("[%d] got cmd '%c' len %d\n", 269 (int) ctx->ctx_id, cmd, (int) len); 270 for (i = 0; i < ncmds; i++) 271 { 272 if (cmd == cmds[i].cm_cmd) 273 break; 274 } 275 if (i >= ncmds) 276 { 277 /* unknown command */ 278 if (ctx->ctx_dbg > 1) 279 sm_dprintf("[%d] cmd '%c' unknown\n", 280 (int) ctx->ctx_id, cmd); 281 ret = MI_FAILURE; 282 break; 283 } 284 if ((f = cmds[i].cm_fct) == NULL) 285 { 286 /* stop for now */ 287 if (ctx->ctx_dbg > 1) 288 sm_dprintf("[%d] cmd '%c' not impl\n", 289 (int) ctx->ctx_id, cmd); 290 ret = MI_FAILURE; 291 break; 292 } 293 294 /* is new state ok? */ 295 newstate = cmds[i].cm_next; 296 if (ctx->ctx_dbg > 5) 297 sm_dprintf("[%d] cur %x new %x nextmask %x\n", 298 (int) ctx->ctx_id, 299 curstate, newstate, next_states[curstate]); 300 301 if (newstate != ST_NONE && !trans_ok(curstate, newstate)) 302 { 303 if (ctx->ctx_dbg > 1) 304 sm_dprintf("[%d] abort: cur %d (%x) new %d (%x) next %x\n", 305 (int) ctx->ctx_id, 306 curstate, MI_MASK(curstate), 307 newstate, MI_MASK(newstate), 308 next_states[curstate]); 309 310 /* call abort only if in a mail transaction */ 311 if (fi_abort != NULL && call_abort) 312 (void) (*fi_abort)(ctx); 313 314 /* 315 ** try to reach the new state from HELO 316 ** if it can't be reached, ignore the command. 317 */ 318 319 curstate = ST_HELO; 320 if (!trans_ok(curstate, newstate)) 321 { 322 if (buf != NULL) 323 { 324 free(buf); 325 buf = NULL; 326 } 327 continue; 328 } 329 } 330 arg.a_len = len; 331 arg.a_buf = buf; 332 if (newstate != ST_NONE) 333 { 334 curstate = newstate; 335 ctx->ctx_state = curstate; 336 } 337 arg.a_idx = cmds[i].cm_macros; 338 339 /* call function to deal with command */ 340 r = (*f)(&arg); 341 if (r != _SMFIS_KEEP && buf != NULL) 342 { 343 free(buf); 344 buf = NULL; 345 } 346 if (sendreply(r, sd, &timeout, ctx) != MI_SUCCESS) 347 { 348 ret = MI_FAILURE; 349 break; 350 } 351 352 call_abort = ST_IN_MAIL(curstate); 353 if (r == SMFIS_ACCEPT) 354 { 355 /* accept mail, no further actions taken */ 356 curstate = ST_HELO; 357 } 358 else if (r == SMFIS_REJECT || r == SMFIS_DISCARD || 359 r == SMFIS_TEMPFAIL) 360 { 361 /* 362 ** further actions depend on current state 363 ** if the IGNO bit is set: "ignore" the error, 364 ** i.e., stay in the current state 365 */ 366 if (!bitset(CT_IGNO, cmds[i].cm_todo)) 367 curstate = ST_HELO; 368 } 369 else if (r == _SMFIS_ABORT) 370 { 371 if (ctx->ctx_dbg > 5) 372 sm_dprintf("[%d] function returned abort\n", 373 (int) ctx->ctx_id); 374 ret = MI_FAILURE; 375 break; 376 } 377 } while (!bitset(CT_END, cmds[i].cm_todo)); 378 379 if (ret != MI_SUCCESS) 380 { 381 /* call abort only if in a mail transaction */ 382 if (fi_abort != NULL && call_abort) 383 (void) (*fi_abort)(ctx); 384 } 385 386 /* close must always be called */ 387 if ((fi_close = ctx->ctx_smfi->xxfi_close) != NULL) 388 (void) (*fi_close)(ctx); 389 if (r != _SMFIS_KEEP && buf != NULL) 390 free(buf); 391 mi_clr_macros(ctx, 0); 392 return ret; 393 } 394 /* 395 ** SENDREPLY -- send a reply to the MTA 396 ** 397 ** Parameters: 398 ** r -- reply code 399 ** sd -- socket descriptor 400 ** timeout_ptr -- (ptr to) timeout to use for sending 401 ** ctx -- context structure 402 ** 403 ** Returns: 404 ** MI_SUCCESS/MI_FAILURE 405 */ 406 407 static int 408 sendreply(r, sd, timeout_ptr, ctx) 409 sfsistat r; 410 socket_t sd; 411 struct timeval *timeout_ptr; 412 SMFICTX_PTR ctx; 413 { 414 int ret = MI_SUCCESS; 415 416 switch (r) 417 { 418 case SMFIS_CONTINUE: 419 ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_CONTINUE, NULL, 0); 420 break; 421 case SMFIS_TEMPFAIL: 422 case SMFIS_REJECT: 423 if (ctx->ctx_reply != NULL && 424 ((r == SMFIS_TEMPFAIL && *ctx->ctx_reply == '4') || 425 (r == SMFIS_REJECT && *ctx->ctx_reply == '5'))) 426 { 427 ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_REPLYCODE, 428 ctx->ctx_reply, 429 strlen(ctx->ctx_reply) + 1); 430 free(ctx->ctx_reply); 431 ctx->ctx_reply = NULL; 432 } 433 else 434 { 435 ret = mi_wr_cmd(sd, timeout_ptr, r == SMFIS_REJECT ? 436 SMFIR_REJECT : SMFIR_TEMPFAIL, NULL, 0); 437 } 438 break; 439 case SMFIS_DISCARD: 440 ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_DISCARD, NULL, 0); 441 break; 442 case SMFIS_ACCEPT: 443 ret = mi_wr_cmd(sd, timeout_ptr, SMFIR_ACCEPT, NULL, 0); 444 break; 445 case _SMFIS_OPTIONS: 446 { 447 char buf[MILTER_OPTLEN]; 448 mi_int32 v; 449 450 v = htonl(ctx->ctx_smfi->xxfi_version); 451 (void) memcpy(&(buf[0]), (void *) &v, MILTER_LEN_BYTES); 452 v = htonl(ctx->ctx_smfi->xxfi_flags); 453 (void) memcpy(&(buf[MILTER_LEN_BYTES]), (void *) &v, 454 MILTER_LEN_BYTES); 455 v = htonl(ctx->ctx_pflags); 456 (void) memcpy(&(buf[MILTER_LEN_BYTES * 2]), (void *) &v, 457 MILTER_LEN_BYTES); 458 ret = mi_wr_cmd(sd, timeout_ptr, SMFIC_OPTNEG, buf, 459 MILTER_OPTLEN); 460 } 461 break; 462 default: /* don't send a reply */ 463 break; 464 } 465 return ret; 466 } 467 468 /* 469 ** CLR_MACROS -- clear set of macros starting from a given index 470 ** 471 ** Parameters: 472 ** ctx -- context structure 473 ** m -- index from which to clear all macros 474 ** 475 ** Returns: 476 ** None. 477 */ 478 void 479 mi_clr_macros(ctx, m) 480 SMFICTX_PTR ctx; 481 int m; 482 { 483 int i; 484 485 for (i = m; i < MAX_MACROS_ENTRIES; i++) 486 { 487 if (ctx->ctx_mac_ptr[i] != NULL) 488 { 489 free(ctx->ctx_mac_ptr[i]); 490 ctx->ctx_mac_ptr[i] = NULL; 491 } 492 if (ctx->ctx_mac_buf[i] != NULL) 493 { 494 free(ctx->ctx_mac_buf[i]); 495 ctx->ctx_mac_buf[i] = NULL; 496 } 497 } 498 } 499 /* 500 ** ST_OPTIONNEG -- negotiate options 501 ** 502 ** Parameters: 503 ** g -- generic argument structure 504 ** 505 ** Returns: 506 ** abort/send options/continue 507 */ 508 509 static int 510 st_optionneg(g) 511 genarg *g; 512 { 513 mi_int32 i, v; 514 515 if (g == NULL || g->a_ctx->ctx_smfi == NULL) 516 return SMFIS_CONTINUE; 517 mi_clr_macros(g->a_ctx, g->a_idx + 1); 518 519 /* check for minimum length */ 520 if (g->a_len < MILTER_OPTLEN) 521 { 522 smi_log(SMI_LOG_ERR, 523 "%s: st_optionneg[%d]: len too short %d < %d", 524 g->a_ctx->ctx_smfi->xxfi_name, 525 (int) g->a_ctx->ctx_id, (int) g->a_len, 526 MILTER_OPTLEN); 527 return _SMFIS_ABORT; 528 } 529 530 (void) memcpy((void *) &i, (void *) &(g->a_buf[0]), 531 MILTER_LEN_BYTES); 532 v = ntohl(i); 533 if (v < g->a_ctx->ctx_smfi->xxfi_version) 534 { 535 /* hard failure for now! */ 536 smi_log(SMI_LOG_ERR, 537 "%s: st_optionneg[%d]: version mismatch MTA: %d < milter: %d", 538 g->a_ctx->ctx_smfi->xxfi_name, 539 (int) g->a_ctx->ctx_id, (int) v, 540 g->a_ctx->ctx_smfi->xxfi_version); 541 return _SMFIS_ABORT; 542 } 543 544 (void) memcpy((void *) &i, (void *) &(g->a_buf[MILTER_LEN_BYTES]), 545 MILTER_LEN_BYTES); 546 v = ntohl(i); 547 548 /* no flags? set to default value for V1 actions */ 549 if (v == 0) 550 v = SMFI_V1_ACTS; 551 i = g->a_ctx->ctx_smfi->xxfi_flags; 552 if ((v & i) != i) 553 { 554 smi_log(SMI_LOG_ERR, 555 "%s: st_optionneg[%d]: 0x%x does not fulfill action requirements 0x%x", 556 g->a_ctx->ctx_smfi->xxfi_name, 557 (int) g->a_ctx->ctx_id, v, i); 558 return _SMFIS_ABORT; 559 } 560 561 (void) memcpy((void *) &i, (void *) &(g->a_buf[MILTER_LEN_BYTES * 2]), 562 MILTER_LEN_BYTES); 563 v = ntohl(i); 564 565 /* no flags? set to default value for V1 protocol */ 566 if (v == 0) 567 v = SMFI_V1_PROT; 568 i = g->a_ctx->ctx_pflags; 569 if ((v & i) != i) 570 { 571 smi_log(SMI_LOG_ERR, 572 "%s: st_optionneg[%d]: 0x%x does not fulfill protocol requirements 0x%x", 573 g->a_ctx->ctx_smfi->xxfi_name, 574 (int) g->a_ctx->ctx_id, v, i); 575 return _SMFIS_ABORT; 576 } 577 578 return _SMFIS_OPTIONS; 579 } 580 /* 581 ** ST_CONNECTINFO -- receive connection information 582 ** 583 ** Parameters: 584 ** g -- generic argument structure 585 ** 586 ** Returns: 587 ** continue or filter-specified value 588 */ 589 590 static int 591 st_connectinfo(g) 592 genarg *g; 593 { 594 size_t l; 595 size_t i; 596 char *s, family; 597 unsigned short port = 0; 598 _SOCK_ADDR sockaddr; 599 sfsistat (*fi_connect) __P((SMFICTX *, char *, _SOCK_ADDR *)); 600 601 if (g == NULL) 602 return _SMFIS_ABORT; 603 mi_clr_macros(g->a_ctx, g->a_idx + 1); 604 if (g->a_ctx->ctx_smfi == NULL || 605 (fi_connect = g->a_ctx->ctx_smfi->xxfi_connect) == NULL) 606 return SMFIS_CONTINUE; 607 608 s = g->a_buf; 609 i = 0; 610 l = g->a_len; 611 while (s[i] != '\0' && i <= l) 612 ++i; 613 if (i + 1 >= l) 614 return _SMFIS_ABORT; 615 616 /* Move past trailing \0 in host string */ 617 i++; 618 family = s[i++]; 619 (void) memset(&sockaddr, '\0', sizeof sockaddr); 620 if (family != SMFIA_UNKNOWN) 621 { 622 if (i + sizeof port >= l) 623 { 624 smi_log(SMI_LOG_ERR, 625 "%s: connect[%d]: wrong len %d >= %d", 626 g->a_ctx->ctx_smfi->xxfi_name, 627 (int) g->a_ctx->ctx_id, (int) i, (int) l); 628 return _SMFIS_ABORT; 629 } 630 (void) memcpy((void *) &port, (void *) (s + i), 631 sizeof port); 632 i += sizeof port; 633 634 /* make sure string is terminated */ 635 if (s[l - 1] != '\0') 636 return _SMFIS_ABORT; 637 # if NETINET 638 if (family == SMFIA_INET) 639 { 640 if (inet_aton(s + i, (struct in_addr *) &sockaddr.sin.sin_addr) 641 != 1) 642 { 643 smi_log(SMI_LOG_ERR, 644 "%s: connect[%d]: inet_aton failed", 645 g->a_ctx->ctx_smfi->xxfi_name, 646 (int) g->a_ctx->ctx_id); 647 return _SMFIS_ABORT; 648 } 649 sockaddr.sa.sa_family = AF_INET; 650 if (port > 0) 651 sockaddr.sin.sin_port = port; 652 } 653 else 654 # endif /* NETINET */ 655 # if NETINET6 656 if (family == SMFIA_INET6) 657 { 658 if (mi_inet_pton(AF_INET6, s + i, 659 &sockaddr.sin6.sin6_addr) != 1) 660 { 661 smi_log(SMI_LOG_ERR, 662 "%s: connect[%d]: mi_inet_pton failed", 663 g->a_ctx->ctx_smfi->xxfi_name, 664 (int) g->a_ctx->ctx_id); 665 return _SMFIS_ABORT; 666 } 667 sockaddr.sa.sa_family = AF_INET6; 668 if (port > 0) 669 sockaddr.sin6.sin6_port = port; 670 } 671 else 672 # endif /* NETINET6 */ 673 # if NETUNIX 674 if (family == SMFIA_UNIX) 675 { 676 if (sm_strlcpy(sockaddr.sunix.sun_path, s + i, 677 sizeof sockaddr.sunix.sun_path) >= 678 sizeof sockaddr.sunix.sun_path) 679 { 680 smi_log(SMI_LOG_ERR, 681 "%s: connect[%d]: path too long", 682 g->a_ctx->ctx_smfi->xxfi_name, 683 (int) g->a_ctx->ctx_id); 684 return _SMFIS_ABORT; 685 } 686 sockaddr.sunix.sun_family = AF_UNIX; 687 } 688 else 689 # endif /* NETUNIX */ 690 { 691 smi_log(SMI_LOG_ERR, 692 "%s: connect[%d]: unknown family %d", 693 g->a_ctx->ctx_smfi->xxfi_name, 694 (int) g->a_ctx->ctx_id, family); 695 return _SMFIS_ABORT; 696 } 697 } 698 return (*fi_connect)(g->a_ctx, g->a_buf, 699 family != SMFIA_UNKNOWN ? &sockaddr : NULL); 700 } 701 /* 702 ** ST_EOH -- end of headers 703 ** 704 ** Parameters: 705 ** g -- generic argument structure 706 ** 707 ** Returns: 708 ** continue or filter-specified value 709 */ 710 711 static int 712 st_eoh(g) 713 genarg *g; 714 { 715 sfsistat (*fi_eoh) __P((SMFICTX *)); 716 717 if (g == NULL) 718 return _SMFIS_ABORT; 719 if (g->a_ctx->ctx_smfi != NULL && 720 (fi_eoh = g->a_ctx->ctx_smfi->xxfi_eoh) != NULL) 721 return (*fi_eoh)(g->a_ctx); 722 return SMFIS_CONTINUE; 723 } 724 /* 725 ** ST_HELO -- helo/ehlo command 726 ** 727 ** Parameters: 728 ** g -- generic argument structure 729 ** 730 ** Returns: 731 ** continue or filter-specified value 732 */ 733 static int 734 st_helo(g) 735 genarg *g; 736 { 737 sfsistat (*fi_helo) __P((SMFICTX *, char *)); 738 739 if (g == NULL) 740 return _SMFIS_ABORT; 741 mi_clr_macros(g->a_ctx, g->a_idx + 1); 742 if (g->a_ctx->ctx_smfi != NULL && 743 (fi_helo = g->a_ctx->ctx_smfi->xxfi_helo) != NULL) 744 { 745 /* paranoia: check for terminating '\0' */ 746 if (g->a_len == 0 || g->a_buf[g->a_len - 1] != '\0') 747 return MI_FAILURE; 748 return (*fi_helo)(g->a_ctx, g->a_buf); 749 } 750 return SMFIS_CONTINUE; 751 } 752 /* 753 ** ST_HEADER -- header line 754 ** 755 ** Parameters: 756 ** g -- generic argument structure 757 ** 758 ** Returns: 759 ** continue or filter-specified value 760 */ 761 762 static int 763 st_header(g) 764 genarg *g; 765 { 766 char *hf, *hv; 767 sfsistat (*fi_header) __P((SMFICTX *, char *, char *)); 768 769 if (g == NULL) 770 return _SMFIS_ABORT; 771 if (g->a_ctx->ctx_smfi == NULL || 772 (fi_header = g->a_ctx->ctx_smfi->xxfi_header) == NULL) 773 return SMFIS_CONTINUE; 774 if (dec_arg2(g->a_buf, g->a_len, &hf, &hv) == MI_SUCCESS) 775 return (*fi_header)(g->a_ctx, hf, hv); 776 else 777 return _SMFIS_ABORT; 778 } 779 780 #define ARGV_FCT(lf, rf, idx) \ 781 char **argv; \ 782 sfsistat (*lf) __P((SMFICTX *, char **)); \ 783 int r; \ 784 \ 785 if (g == NULL) \ 786 return _SMFIS_ABORT; \ 787 mi_clr_macros(g->a_ctx, g->a_idx + 1); \ 788 if (g->a_ctx->ctx_smfi == NULL || \ 789 (lf = g->a_ctx->ctx_smfi->rf) == NULL) \ 790 return SMFIS_CONTINUE; \ 791 if ((argv = dec_argv(g->a_buf, g->a_len)) == NULL) \ 792 return _SMFIS_ABORT; \ 793 r = (*lf)(g->a_ctx, argv); \ 794 free(argv); \ 795 return r; 796 797 /* 798 ** ST_SENDER -- MAIL FROM command 799 ** 800 ** Parameters: 801 ** g -- generic argument structure 802 ** 803 ** Returns: 804 ** continue or filter-specified value 805 */ 806 807 static int 808 st_sender(g) 809 genarg *g; 810 { 811 ARGV_FCT(fi_envfrom, xxfi_envfrom, CI_MAIL) 812 } 813 /* 814 ** ST_RCPT -- RCPT TO command 815 ** 816 ** Parameters: 817 ** g -- generic argument structure 818 ** 819 ** Returns: 820 ** continue or filter-specified value 821 */ 822 823 static int 824 st_rcpt(g) 825 genarg *g; 826 { 827 ARGV_FCT(fi_envrcpt, xxfi_envrcpt, CI_RCPT) 828 } 829 /* 830 ** ST_MACROS -- deal with macros received from the MTA 831 ** 832 ** Parameters: 833 ** g -- generic argument structure 834 ** 835 ** Returns: 836 ** continue/keep 837 ** 838 ** Side effects: 839 ** set pointer in macro array to current values. 840 */ 841 842 static int 843 st_macros(g) 844 genarg *g; 845 { 846 int i; 847 char **argv; 848 849 if (g == NULL || g->a_len < 1) 850 return _SMFIS_FAIL; 851 if ((argv = dec_argv(g->a_buf + 1, g->a_len - 1)) == NULL) 852 return _SMFIS_FAIL; 853 switch (g->a_buf[0]) 854 { 855 case SMFIC_CONNECT: 856 i = CI_CONN; 857 break; 858 case SMFIC_HELO: 859 i = CI_HELO; 860 break; 861 case SMFIC_MAIL: 862 i = CI_MAIL; 863 break; 864 case SMFIC_RCPT: 865 i = CI_RCPT; 866 break; 867 #if _FFR_MILTER_MACROS_EOM 868 case SMFIC_BODYEOB: 869 i = CI_EOM; 870 break; 871 #endif /* _FFR_MILTER_MACROS_EOM */ 872 default: 873 free(argv); 874 return _SMFIS_FAIL; 875 } 876 if (g->a_ctx->ctx_mac_ptr[i] != NULL) 877 free(g->a_ctx->ctx_mac_ptr[i]); 878 if (g->a_ctx->ctx_mac_buf[i] != NULL) 879 free(g->a_ctx->ctx_mac_buf[i]); 880 g->a_ctx->ctx_mac_ptr[i] = argv; 881 g->a_ctx->ctx_mac_buf[i] = g->a_buf; 882 return _SMFIS_KEEP; 883 } 884 /* 885 ** ST_QUIT -- quit command 886 ** 887 ** Parameters: 888 ** g -- generic argument structure 889 ** 890 ** Returns: 891 ** noreply 892 */ 893 894 /* ARGSUSED */ 895 static int 896 st_quit(g) 897 genarg *g; 898 { 899 return _SMFIS_NOREPLY; 900 } 901 /* 902 ** ST_BODYCHUNK -- deal with a piece of the mail body 903 ** 904 ** Parameters: 905 ** g -- generic argument structure 906 ** 907 ** Returns: 908 ** continue or filter-specified value 909 */ 910 911 static int 912 st_bodychunk(g) 913 genarg *g; 914 { 915 sfsistat (*fi_body) __P((SMFICTX *, unsigned char *, size_t)); 916 917 if (g == NULL) 918 return _SMFIS_ABORT; 919 if (g->a_ctx->ctx_smfi != NULL && 920 (fi_body = g->a_ctx->ctx_smfi->xxfi_body) != NULL) 921 return (*fi_body)(g->a_ctx, (unsigned char *)g->a_buf, 922 g->a_len); 923 return SMFIS_CONTINUE; 924 } 925 /* 926 ** ST_BODYEND -- deal with the last piece of the mail body 927 ** 928 ** Parameters: 929 ** g -- generic argument structure 930 ** 931 ** Returns: 932 ** continue or filter-specified value 933 ** 934 ** Side effects: 935 ** sends a reply for the body part (if non-empty). 936 */ 937 938 static int 939 st_bodyend(g) 940 genarg *g; 941 { 942 sfsistat r; 943 sfsistat (*fi_body) __P((SMFICTX *, unsigned char *, size_t)); 944 sfsistat (*fi_eom) __P((SMFICTX *)); 945 946 if (g == NULL) 947 return _SMFIS_ABORT; 948 r = SMFIS_CONTINUE; 949 if (g->a_ctx->ctx_smfi != NULL) 950 { 951 if ((fi_body = g->a_ctx->ctx_smfi->xxfi_body) != NULL && 952 g->a_len > 0) 953 { 954 socket_t sd; 955 struct timeval timeout; 956 957 timeout.tv_sec = g->a_ctx->ctx_timeout; 958 timeout.tv_usec = 0; 959 sd = g->a_ctx->ctx_sd; 960 r = (*fi_body)(g->a_ctx, (unsigned char *)g->a_buf, 961 g->a_len); 962 if (r != SMFIS_CONTINUE && 963 sendreply(r, sd, &timeout, g->a_ctx) != MI_SUCCESS) 964 return _SMFIS_ABORT; 965 } 966 } 967 if (r == SMFIS_CONTINUE && 968 (fi_eom = g->a_ctx->ctx_smfi->xxfi_eom) != NULL) 969 return (*fi_eom)(g->a_ctx); 970 return r; 971 } 972 /* 973 ** ST_ABORTFCT -- deal with aborts 974 ** 975 ** Parameters: 976 ** g -- generic argument structure 977 ** 978 ** Returns: 979 ** abort or filter-specified value 980 */ 981 982 static int 983 st_abortfct(g) 984 genarg *g; 985 { 986 sfsistat (*fi_abort) __P((SMFICTX *)); 987 988 if (g == NULL) 989 return _SMFIS_ABORT; 990 if (g != NULL && g->a_ctx->ctx_smfi != NULL && 991 (fi_abort = g->a_ctx->ctx_smfi->xxfi_abort) != NULL) 992 (void) (*fi_abort)(g->a_ctx); 993 return _SMFIS_NOREPLY; 994 } 995 /* 996 ** TRANS_OK -- is the state transition ok? 997 ** 998 ** Parameters: 999 ** old -- old state 1000 ** new -- new state 1001 ** 1002 ** Returns: 1003 ** state transition ok 1004 */ 1005 1006 static bool 1007 trans_ok(old, new) 1008 int old, new; 1009 { 1010 int s, n; 1011 1012 s = old; 1013 do 1014 { 1015 /* is this state transition allowed? */ 1016 if ((MI_MASK(new) & next_states[s]) != 0) 1017 return true; 1018 1019 /* 1020 ** no: try next state; 1021 ** this works since the relevant states are ordered 1022 ** strict sequentially 1023 */ 1024 1025 n = s + 1; 1026 1027 /* 1028 ** can we actually "skip" this state? 1029 ** see fix_stm() which sets this bit for those 1030 ** states which the filter program is not interested in 1031 */ 1032 1033 if (bitset(NX_SKIP, next_states[n])) 1034 s = n; 1035 else 1036 return false; 1037 } while (s <= ST_LAST); 1038 return false; 1039 } 1040 /* 1041 ** FIX_STM -- add "skip" bits to the state transition table 1042 ** 1043 ** Parameters: 1044 ** ctx -- context structure 1045 ** 1046 ** Returns: 1047 ** None. 1048 ** 1049 ** Side effects: 1050 ** may change state transition table. 1051 */ 1052 1053 static void 1054 fix_stm(ctx) 1055 SMFICTX_PTR ctx; 1056 { 1057 unsigned long fl; 1058 1059 if (ctx == NULL || ctx->ctx_smfi == NULL) 1060 return; 1061 fl = ctx->ctx_pflags; 1062 if (bitset(SMFIP_NOCONNECT, fl)) 1063 next_states[ST_CONN] |= NX_SKIP; 1064 if (bitset(SMFIP_NOHELO, fl)) 1065 next_states[ST_HELO] |= NX_SKIP; 1066 if (bitset(SMFIP_NOMAIL, fl)) 1067 next_states[ST_MAIL] |= NX_SKIP; 1068 if (bitset(SMFIP_NORCPT, fl)) 1069 next_states[ST_RCPT] |= NX_SKIP; 1070 if (bitset(SMFIP_NOHDRS, fl)) 1071 next_states[ST_HDRS] |= NX_SKIP; 1072 if (bitset(SMFIP_NOEOH, fl)) 1073 next_states[ST_EOHS] |= NX_SKIP; 1074 if (bitset(SMFIP_NOBODY, fl)) 1075 next_states[ST_BODY] |= NX_SKIP; 1076 } 1077 /* 1078 ** DEC_ARGV -- split a buffer into a list of strings, NULL terminated 1079 ** 1080 ** Parameters: 1081 ** buf -- buffer with several strings 1082 ** len -- length of buffer 1083 ** 1084 ** Returns: 1085 ** array of pointers to the individual strings 1086 */ 1087 1088 static char ** 1089 dec_argv(buf, len) 1090 char *buf; 1091 size_t len; 1092 { 1093 char **s; 1094 size_t i; 1095 int elem, nelem; 1096 1097 nelem = 0; 1098 for (i = 0; i < len; i++) 1099 { 1100 if (buf[i] == '\0') 1101 ++nelem; 1102 } 1103 if (nelem == 0) 1104 return NULL; 1105 1106 /* last entry is only for the name */ 1107 s = (char **)malloc((nelem + 1) * (sizeof *s)); 1108 if (s == NULL) 1109 return NULL; 1110 s[0] = buf; 1111 for (i = 0, elem = 0; i < len && elem < nelem; i++) 1112 { 1113 if (buf[i] == '\0') 1114 { 1115 ++elem; 1116 if (i + 1 >= len) 1117 s[elem] = NULL; 1118 else 1119 s[elem] = &(buf[i + 1]); 1120 } 1121 } 1122 1123 /* overwrite last entry (already done above, just paranoia) */ 1124 s[elem] = NULL; 1125 return s; 1126 } 1127 /* 1128 ** DEC_ARG2 -- split a buffer into two strings 1129 ** 1130 ** Parameters: 1131 ** buf -- buffer with two strings 1132 ** len -- length of buffer 1133 ** s1,s2 -- pointer to result strings 1134 ** 1135 ** Returns: 1136 ** MI_FAILURE/MI_SUCCESS 1137 */ 1138 1139 static int 1140 dec_arg2(buf, len, s1, s2) 1141 char *buf; 1142 size_t len; 1143 char **s1; 1144 char **s2; 1145 { 1146 size_t i; 1147 1148 /* paranoia: check for terminating '\0' */ 1149 if (len == 0 || buf[len - 1] != '\0') 1150 return MI_FAILURE; 1151 *s1 = buf; 1152 for (i = 1; i < len && buf[i] != '\0'; i++) 1153 continue; 1154 if (i >= len - 1) 1155 return MI_FAILURE; 1156 *s2 = buf + i + 1; 1157 return MI_SUCCESS; 1158 } 1159 /* 1160 ** SENDOK -- is it ok for the filter to send stuff to the MTA? 1161 ** 1162 ** Parameters: 1163 ** ctx -- context structure 1164 ** flag -- flag to check 1165 ** 1166 ** Returns: 1167 ** sending allowed (in current state) 1168 */ 1169 1170 bool 1171 mi_sendok(ctx, flag) 1172 SMFICTX_PTR ctx; 1173 int flag; 1174 { 1175 if (ctx == NULL || ctx->ctx_smfi == NULL) 1176 return false; 1177 1178 /* did the milter request this operation? */ 1179 if (flag != 0 && !bitset(flag, ctx->ctx_smfi->xxfi_flags)) 1180 return false; 1181 1182 /* are we in the correct state? It must be "End of Message". */ 1183 return ctx->ctx_state == ST_ENDM; 1184 } 1185