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