1N/A * Copyright (c) 1999-2004, 2006-2008 Sendmail, Inc. and its suppliers. 1N/A * All rights reserved. 1N/A * By using this file, you agree to the terms and conditions set 1N/A * forth in the LICENSE file which can be found at the top level of 1N/A * the sendmail distribution. 1N/A#
endif /* NETINET || NETINET6 */ 1N/A/* generic argument for functions in the command table */ 1N/A/* structure for commands received from MTA */ 1N/A/* possible values for cm_argt */ 1N/A#
define CM_ARGV 8 /* \0 separated list of args, NULL-terminated */ 1N/A#
define CM_ARGN 9 /* \0 separated list of args (strings) */ 1N/A/* possible values for cm_todo */ 1N/A#
define CT_CONT 0x0000 /* continue reading commands */ 1N/A#
define CT_IGNO 0x0001 /* continue even when error */ 1N/A/* not needed right now, done via return code instead */ 1N/A#
define CT_KEEP 0x0004 /* keep buffer (contains symbols) */ 1N/A#
define CT_END 0x0008 /* last command of session, stop replying */ 1N/A/* index in macro array: macros only for these commands */ 1N/A/* function prototypes */ 1N/A#
endif /* _FFR_WORKERS_POOL */ 1N/A#
define ST_Q_NC 14 /* quit, new connection follows */ 1N/A#
define ST_SKIP 16 /* not a state but required for the state table */ 1N/A/* in a mail transaction? must be before eom according to spec. */ 1N/A** set of next states 1N/A** each state (ST_*) corresponds to bit in an int value (1 << state) 1N/A** each state has a set of allowed transitions ('or' of bits of states) 1N/A** so a state transition is valid if the mask of the next state 1N/A** is set in the NX_* value 1N/A** this function is coded in trans_ok(), see below. 1N/A#
define MI_MASK(x) (
0x0001 << (x))
/* generate a bit "mask" for a state */ 1N/A/* commands received by milter */ 1N/A** Additional (internal) reply codes; 1N/A** MI_ENGINE -- receive commands and process them 1N/A** ctx -- context structure 1N/A#
else /* _FFR_WORKERS_POOL */ 1N/A#
endif /* _FFR_WORKERS_POOL */ 1N/A /* call abort only if in a mail transaction */ 1N/A ** Notice: buf is allocated by mi_rd_cmd() and it will 1N/A ** usually be free()d after it has been used in f(). 1N/A ** However, if the function returns _SMFIS_KEEP then buf 1N/A ** contains macros and will not be free()d. 1N/A ** Hence r must be set to _SMFIS_NONE if a new buf is 1N/A ** allocated to avoid problem with housekeeping, esp. 1N/A ** if the code "break"s out of the loop. 1N/A /* Is the socket ready to be read ??? */ 1N/A#
endif /* _FFR_WORKERS_POOL */ 1N/A ** eof is currently treated as failure -> 1N/A ** abort() instead of close(), otherwise use: 1N/A ** if (cmd != SMFIC_EOF) 1N/A /* unknown command */ 1N/A /* is new state ok? */ 1N/A /* call abort only if in a mail transaction */ 1N/A ** try to reach the new state from HELO 1N/A ** if it can't be reached, ignore the command. 1N/A /* call function to deal with command */ 1N/A /* accept mail, no further actions taken */ 1N/A ** further actions depend on current state 1N/A ** if the IGNO bit is set: "ignore" the error, 1N/A ** i.e., stay in the current state 1N/A /* call abort only if in a mail transaction */ 1N/A /* has close been called? */ 1N/A#
endif /* _FFR_WORKERS_POOL */ 1N/A#
endif /* _FFR_WORKERS_POOL */ 1N/A** GET_NR_BIT -- get "no reply" bit matching state 1N/A** state -- current protocol stage 1N/A** 0: no matching bit 1N/A** >0: the matching "no reply" bit 1N/A** SENDREPLY -- send a reply to the MTA 1N/A** sd -- socket descriptor 1N/A** timeout_ptr -- (ptr to) timeout to use for sending 1N/A** ctx -- context structure 1N/A /* milter said it wouldn't reply, but it lied... */ 1N/A "%s: milter claimed not to reply in state %d but did anyway %d\n",
1N/A ** Force specified behavior, otherwise libmilter 1N/A ** and MTA will fail to communicate properly. 1N/A ** milter doesn't want to send a reply, 1N/A ** but the MTA doesn't have that feature: fake it. 1N/A default:
/* don't send a reply */ 1N/A** CLR_MACROS -- clear set of macros starting from a given index 1N/A** ctx -- context structure 1N/A** m -- index from which to clear all macros 1N/A** MI_CLR_SYMLIST -- clear list of macros 1N/A** ctx -- context structure 1N/A** MI_CLR_CTX -- clear context 1N/A** ctx -- context structure 1N/A "%s: private data not NULL",
1N/A** ST_OPTIONNEG -- negotiate options 1N/A** g -- generic argument structure 1N/A#
endif /* _FFR_MILTER_CHECK */ 1N/A unsigned long,
unsigned long,
1N/A unsigned long,
unsigned long,
1N/A unsigned long *,
unsigned long *,
1N/A unsigned long *,
unsigned long *));
1N/A /* check for minimum length */ 1N/A "%s: st_optionneg[%ld]: len too short %d < %d",
1N/A /* protocol version */ 1N/A /* check for minimum version */ 1N/A "%s: st_optionneg[%ld]: protocol version too old %d < %d",
1N/A /* no flags? set to default value for V1 actions */ 1N/A /* no flags? set to default value for V1 protocol */ 1N/A ** Allow changing the size only if milter is compiled 1N/A ** against a version that supports this. 1N/A ** If a milter is dynamically linked against a newer 1N/A ** libmilter version, we don't want to "surprise" 1N/A ** it with a larger buffer as it may rely on it 1N/A ** even though it is not documented as a limit. 1N/A /* don't log this for now... */ 1N/A "%s: st_optionneg[%ld]: milter version=%X, trying flags=%X",
1N/A#
endif /* _FFR_MDS_NEGOTIATE */ 1N/A ** MTA protocol flags. 1N/A ** We pass the internal flags to the milter as "read only", 1N/A ** i.e., a milter can read them so it knows which size 1N/A ** will be used, but any changes by a milter will be ignored 1N/A ** (see below, search for SMFI_INTERNAL). 1N/A ** Copy flags from milter struct into libmilter context; 1N/A ** this variable will be used later on to check whether 1N/A ** the MTA "actions" can fulfill the milter requirements, 1N/A ** but it may be overwritten by the negotiate callback. 1N/A ** let milter decide whether the features offered by the 1N/A ** MTA are "good enough". 1N/A ** - libmilter can "fake" some features (e.g., SMFIP_NR_HDR) 1N/A ** - m_f2, m_f3 are for future extensions 1N/A#
endif /* _FFR_MILTER_CHECK */ 1N/A ** Types of protocol flags (pflags): 1N/A ** 1. do NOT send protocol step X 1N/A ** send unknown RCPTs) 1N/A ** 3. MTA can deal with "no reply" for various protocol steps 1N/A ** Note: this mean that it isn't possible to simply set all 1N/A ** flags to get "everything": 1N/A ** setting a flag of type 1 turns off a step 1N/A ** (it should be the other way around: 1N/A ** a flag means a protocol step can be sent) 1N/A ** setting a flag of type 3 requires that milter 1N/A ** never sends a reply for the corresponding step. 1N/A ** Summary: the "negation" of protocol flags is causing 1N/A ** problems, but at least for type 3 there is no simple 1N/A ** What should "all options" mean? 1N/A ** send all protocol steps _except_ those for which there is 1N/A ** no callback (currently registered in ctx_pflags) 1N/A ** expect SKIP as return code? Yes 1N/A ** send unknown RCPTs? No, 1N/A ** must be explicitly requested? 1N/A ** "no reply" for some protocol steps? No, 1N/A ** must be explicitly requested. 1N/A "%s: st_optionneg[%ld]: xxfi_negotiate returned %d (protocol options=0x%lx, actions=0x%lx)",
1N/A /* check whether some flags need to be "faked" */ 1N/A ** If some behavior can be faked (set in fake_pflags), 1N/A ** but the MTA doesn't support it, then unset 1N/A ** that flag in the value that is sent to the MTA. 1N/A ** Set the protocol flags based on the values determined 1N/A ** in mi_listener() which checked the defined callbacks. 1N/A /* check whether actions and protocol requirements can be satisfied */ 1N/A "%s: st_optionneg[%ld]: 0x%lx does not fulfill action requirements 0x%x",
1N/A ** Older MTAs do not support some protocol steps. 1N/A ** As this protocol is a bit "wierd" (it asks for steps 1N/A ** should turn off those "negative" requests. 1N/A ** Currently these are only SMFIP_NODATA and SMFIP_NOUNKNOWN. 1N/A "%s: st_optionneg[%ld]: 0x%lx does not fulfill protocol requirements 0x%x",
1N/A " mta_actions=0x%lx, mta_flags=0x%lx" 1N/A " actions=0x%lx, flags=0x%lx\n" 1N/A " testmode=%d, pflags2mta=%X, internal_pflags=%X\n" 1N/A /* in test mode: take flags without further modifications */ 1N/A /* Warning: check statement below! */ 1N/A#
endif /* _FFR_MILTER_CHECK */ 1N/A ** Remove the internal flags that might have been set by a milter 1N/A ** and set only those determined above. 1N/A** ST_CONNECTINFO -- receive connection information 1N/A** g -- generic argument structure 1N/A** continue or filter-specified value 1N/A while (s[i] !=
'\0' && i <= l)
1N/A /* Move past trailing \0 in host string */ 1N/A "%s: connect[%ld]: wrong len %d >= %d",
1N/A /* make sure string is terminated */ 1N/A if (s[l -
1] !=
'\0')
1N/A "%s: connect[%ld]: inet_aton failed",
1N/A#
endif /* NETINET */ 1N/A "%s: connect[%ld]: mi_inet_pton failed",
1N/A#
endif /* NETINET6 */ 1N/A "%s: connect[%ld]: path too long",
1N/A#
endif /* NETUNIX */ 1N/A "%s: connect[%ld]: unknown family %d",
1N/A** ST_EOH -- end of headers 1N/A** g -- generic argument structure 1N/A** continue or filter-specified value 1N/A** ST_DATA -- DATA command 1N/A** g -- generic argument structure 1N/A** continue or filter-specified value 1N/A** g -- generic argument structure 1N/A** continue or filter-specified value 1N/A /* paranoia: check for terminating '\0' */ 1N/A** ST_HEADER -- header line 1N/A** g -- generic argument structure 1N/A** continue or filter-specified value 1N/A** ST_SENDER -- MAIL FROM command 1N/A** g -- generic argument structure 1N/A** continue or filter-specified value 1N/A** ST_RCPT -- RCPT TO command 1N/A** g -- generic argument structure 1N/A** continue or filter-specified value 1N/A** ST_UNKNOWN -- unrecognized or unimplemented command 1N/A** g -- generic argument structure 1N/A** continue or filter-specified value 1N/A** ST_MACROS -- deal with macros received from the MTA 1N/A** g -- generic argument structure 1N/A** set pointer in macro array to current values. 1N/A** ST_QUIT -- quit command 1N/A** g -- generic argument structure 1N/A** ST_BODYCHUNK -- deal with a piece of the mail body 1N/A** g -- generic argument structure 1N/A** continue or filter-specified value 1N/A** ST_BODYEND -- deal with the last piece of the mail body 1N/A** g -- generic argument structure 1N/A** continue or filter-specified value 1N/A** sends a reply for the body part (if non-empty). 1N/A** ST_ABORTFCT -- deal with aborts 1N/A** g -- generic argument structure 1N/A** abort or filter-specified value 1N/A** TRANS_OK -- is the state transition ok? 1N/A** state transition ok 1N/A /* is this state transition allowed? */ 1N/A ** no: try next state; 1N/A ** this works since the relevant states are ordered 1N/A ** strict sequentially 1N/A ** can we actually "skip" this state? 1N/A ** see fix_stm() which sets this bit for those 1N/A ** states which the filter program is not interested in 1N/A** FIX_STM -- add "skip" bits to the state transition table 1N/A** ctx -- context structure 1N/A** may change state transition table. 1N/A** DEC_ARGV -- split a buffer into a list of strings, NULL terminated 1N/A** buf -- buffer with several strings 1N/A** len -- length of buffer 1N/A** array of pointers to the individual strings 1N/A /* last entry is only for the name */ 1N/A /* overwrite last entry (already done above, just paranoia) */ 1N/A** DEC_ARG2 -- split a buffer into two strings 1N/A** buf -- buffer with two strings 1N/A** len -- length of buffer 1N/A** s1,s2 -- pointer to result strings 1N/A /* paranoia: check for terminating '\0' */ 1N/A** SENDOK -- is it ok for the filter to send stuff to the MTA? 1N/A** ctx -- context structure 1N/A** flag -- flag to check 1N/A** sending allowed (in current state) 1N/A /* did the milter request this operation? */ 1N/A /* are we in the correct state? It must be "End of Message". */ 1N/A** MI_RD_SOCKET_READY - checks if the socket is ready for read(2) 1N/A** true iff socket is ready for read(2) 1N/A#
else /* SM_CONF_POLL */ 1N/A#
endif /* SM_CONF_POLL */ 1N/A#
else /* SM_CONF_POLL */ 1N/A#
endif /* SM_CONF_POLL */ 1N/A#
else /* SM_CONF_POLL */ 1N/A#
endif /* SM_CONF_POLL */ 1N/A#
endif /* _FFR_WORKERS_POOL */