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