xref: /freebsd/contrib/sendmail/libmilter/main.c (revision e2c0e292e8a7ca00ba99bcfccc9e637f45c3e8b1)
106f25ae9SGregory Neil Shapiro /*
25dd76dd0SGregory Neil Shapiro  *  Copyright (c) 1999-2003, 2006, 2007 Proofpoint, Inc. and its suppliers.
306f25ae9SGregory Neil Shapiro  *	All rights reserved.
406f25ae9SGregory Neil Shapiro  *
506f25ae9SGregory Neil Shapiro  * By using this file, you agree to the terms and conditions set
606f25ae9SGregory Neil Shapiro  * forth in the LICENSE file which can be found at the top level of
706f25ae9SGregory Neil Shapiro  * the sendmail distribution.
806f25ae9SGregory Neil Shapiro  *
906f25ae9SGregory Neil Shapiro  */
1006f25ae9SGregory Neil Shapiro 
1140266059SGregory Neil Shapiro #include <sm/gen.h>
124313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: main.c,v 8.85 2013-11-22 20:51:36 ca Exp $")
1306f25ae9SGregory Neil Shapiro 
1406f25ae9SGregory Neil Shapiro #define _DEFINE	1
1506f25ae9SGregory Neil Shapiro #include "libmilter.h"
1606f25ae9SGregory Neil Shapiro #include <fcntl.h>
1706f25ae9SGregory Neil Shapiro #include <sys/stat.h>
1806f25ae9SGregory Neil Shapiro 
1906f25ae9SGregory Neil Shapiro 
2006f25ae9SGregory Neil Shapiro static smfiDesc_ptr smfi = NULL;
2106f25ae9SGregory Neil Shapiro 
2206f25ae9SGregory Neil Shapiro /*
2306f25ae9SGregory Neil Shapiro **  SMFI_REGISTER -- register a filter description
2406f25ae9SGregory Neil Shapiro **
2506f25ae9SGregory Neil Shapiro **	Parameters:
2606f25ae9SGregory Neil Shapiro **		smfilter -- description of filter to register
2706f25ae9SGregory Neil Shapiro **
2806f25ae9SGregory Neil Shapiro **	Returns:
2906f25ae9SGregory Neil Shapiro **		MI_SUCCESS/MI_FAILURE
3006f25ae9SGregory Neil Shapiro */
3106f25ae9SGregory Neil Shapiro 
3206f25ae9SGregory Neil Shapiro int
smfi_register(smfilter)3306f25ae9SGregory Neil Shapiro smfi_register(smfilter)
3406f25ae9SGregory Neil Shapiro 	smfiDesc_str smfilter;
3506f25ae9SGregory Neil Shapiro {
3606f25ae9SGregory Neil Shapiro 	size_t len;
3706f25ae9SGregory Neil Shapiro 
3806f25ae9SGregory Neil Shapiro 	if (smfi == NULL)
3906f25ae9SGregory Neil Shapiro 	{
4006f25ae9SGregory Neil Shapiro 		smfi = (smfiDesc_ptr) malloc(sizeof *smfi);
4106f25ae9SGregory Neil Shapiro 		if (smfi == NULL)
4206f25ae9SGregory Neil Shapiro 			return MI_FAILURE;
4306f25ae9SGregory Neil Shapiro 	}
4406f25ae9SGregory Neil Shapiro 	(void) memcpy(smfi, &smfilter, sizeof *smfi);
4506f25ae9SGregory Neil Shapiro 	if (smfilter.xxfi_name == NULL)
4606f25ae9SGregory Neil Shapiro 		smfilter.xxfi_name = "Unknown";
4706f25ae9SGregory Neil Shapiro 
4806f25ae9SGregory Neil Shapiro 	len = strlen(smfilter.xxfi_name) + 1;
4906f25ae9SGregory Neil Shapiro 	smfi->xxfi_name = (char *) malloc(len);
5006f25ae9SGregory Neil Shapiro 	if (smfi->xxfi_name == NULL)
5106f25ae9SGregory Neil Shapiro 		return MI_FAILURE;
5240266059SGregory Neil Shapiro 	(void) sm_strlcpy(smfi->xxfi_name, smfilter.xxfi_name, len);
5306f25ae9SGregory Neil Shapiro 
5406f25ae9SGregory Neil Shapiro 	/* compare milter version with hard coded version */
55dbe6d91eSGregory Neil Shapiro 	if ((SM_LM_VRS_MAJOR(smfi->xxfi_version) != SM_LM_VRS_MAJOR(SMFI_VERSION) ||
56dbe6d91eSGregory Neil Shapiro 	     SM_LM_VRS_MINOR(smfi->xxfi_version) != SM_LM_VRS_MINOR(SMFI_VERSION)) &&
576d13d6cbSGregory Neil Shapiro 	    smfi->xxfi_version != 2 &&
586d13d6cbSGregory Neil Shapiro 	    smfi->xxfi_version != 3 &&
596d13d6cbSGregory Neil Shapiro 	    smfi->xxfi_version != 4)
6006f25ae9SGregory Neil Shapiro 	{
6106f25ae9SGregory Neil Shapiro 		/* hard failure for now! */
6206f25ae9SGregory Neil Shapiro 		smi_log(SMI_LOG_ERR,
6306f25ae9SGregory Neil Shapiro 			"%s: smfi_register: version mismatch application: %d != milter: %d",
6406f25ae9SGregory Neil Shapiro 			smfi->xxfi_name, smfi->xxfi_version,
6506f25ae9SGregory Neil Shapiro 			(int) SMFI_VERSION);
6640266059SGregory Neil Shapiro 
6740266059SGregory Neil Shapiro 		/* XXX how about smfi? */
6840266059SGregory Neil Shapiro 		free(smfi->xxfi_name);
6906f25ae9SGregory Neil Shapiro 		return MI_FAILURE;
7006f25ae9SGregory Neil Shapiro 	}
7106f25ae9SGregory Neil Shapiro 
7206f25ae9SGregory Neil Shapiro 	return MI_SUCCESS;
7306f25ae9SGregory Neil Shapiro }
7406f25ae9SGregory Neil Shapiro 
7540266059SGregory Neil Shapiro /*
7642e5d165SGregory Neil Shapiro **  SMFI_STOP -- stop milter
7742e5d165SGregory Neil Shapiro **
7842e5d165SGregory Neil Shapiro **	Parameters:
7942e5d165SGregory Neil Shapiro **		none.
8042e5d165SGregory Neil Shapiro **
8142e5d165SGregory Neil Shapiro **	Returns:
8242e5d165SGregory Neil Shapiro **		success.
8342e5d165SGregory Neil Shapiro */
8442e5d165SGregory Neil Shapiro 
8542e5d165SGregory Neil Shapiro int
smfi_stop()8642e5d165SGregory Neil Shapiro smfi_stop()
8742e5d165SGregory Neil Shapiro {
8842e5d165SGregory Neil Shapiro 	mi_stop_milters(MILTER_STOP);
8942e5d165SGregory Neil Shapiro 	return MI_SUCCESS;
9042e5d165SGregory Neil Shapiro }
9142e5d165SGregory Neil Shapiro 
9240266059SGregory Neil Shapiro /*
93323f6dcbSGregory Neil Shapiro **  Default values for some variables.
9440266059SGregory Neil Shapiro **	Most of these can be changed with the functions below.
9540266059SGregory Neil Shapiro */
9640266059SGregory Neil Shapiro 
9706f25ae9SGregory Neil Shapiro static int dbg = 0;
9806f25ae9SGregory Neil Shapiro static char *conn = NULL;
9906f25ae9SGregory Neil Shapiro static int timeout = MI_TIMEOUT;
10042e5d165SGregory Neil Shapiro static int backlog = MI_SOMAXCONN;
10106f25ae9SGregory Neil Shapiro 
10294c01205SGregory Neil Shapiro /*
10394c01205SGregory Neil Shapiro **  SMFI_OPENSOCKET -- try the socket setup to make sure we'll be
10494c01205SGregory Neil Shapiro **		       able to start up
10594c01205SGregory Neil Shapiro **
10694c01205SGregory Neil Shapiro **	Parameters:
107323f6dcbSGregory Neil Shapiro **		rmsocket -- if true, instructs libmilter to attempt
108323f6dcbSGregory Neil Shapiro **			to remove the socket before creating it;
109323f6dcbSGregory Neil Shapiro **			only applies for "local:" or "unix:" sockets
11094c01205SGregory Neil Shapiro **
11194c01205SGregory Neil Shapiro **	Return:
11294c01205SGregory Neil Shapiro **		MI_SUCCESS/MI_FAILURE
11394c01205SGregory Neil Shapiro */
11494c01205SGregory Neil Shapiro 
11594c01205SGregory Neil Shapiro int
smfi_opensocket(rmsocket)116323f6dcbSGregory Neil Shapiro smfi_opensocket(rmsocket)
117323f6dcbSGregory Neil Shapiro 	bool rmsocket;
11894c01205SGregory Neil Shapiro {
11994c01205SGregory Neil Shapiro 	if (smfi == NULL || conn == NULL)
12094c01205SGregory Neil Shapiro 		return MI_FAILURE;
12194c01205SGregory Neil Shapiro 
122323f6dcbSGregory Neil Shapiro 	return mi_opensocket(conn, backlog, dbg, rmsocket, smfi);
12394c01205SGregory Neil Shapiro }
12494c01205SGregory Neil Shapiro 
12540266059SGregory Neil Shapiro /*
12640266059SGregory Neil Shapiro **  SMFI_SETDBG -- set debug level.
12740266059SGregory Neil Shapiro **
12840266059SGregory Neil Shapiro **	Parameters:
12940266059SGregory Neil Shapiro **		odbg -- new debug level.
13040266059SGregory Neil Shapiro **
13140266059SGregory Neil Shapiro **	Returns:
13240266059SGregory Neil Shapiro **		MI_SUCCESS
13340266059SGregory Neil Shapiro */
13440266059SGregory Neil Shapiro 
13506f25ae9SGregory Neil Shapiro int
smfi_setdbg(odbg)13606f25ae9SGregory Neil Shapiro smfi_setdbg(odbg)
13706f25ae9SGregory Neil Shapiro 	int odbg;
13806f25ae9SGregory Neil Shapiro {
13906f25ae9SGregory Neil Shapiro 	dbg = odbg;
14006f25ae9SGregory Neil Shapiro 	return MI_SUCCESS;
14106f25ae9SGregory Neil Shapiro }
14206f25ae9SGregory Neil Shapiro 
14340266059SGregory Neil Shapiro /*
14440266059SGregory Neil Shapiro **  SMFI_SETTIMEOUT -- set timeout (for read/write).
14540266059SGregory Neil Shapiro **
14640266059SGregory Neil Shapiro **	Parameters:
14740266059SGregory Neil Shapiro **		otimeout -- new timeout.
14840266059SGregory Neil Shapiro **
14940266059SGregory Neil Shapiro **	Returns:
15040266059SGregory Neil Shapiro **		MI_SUCCESS
15140266059SGregory Neil Shapiro */
15240266059SGregory Neil Shapiro 
15306f25ae9SGregory Neil Shapiro int
smfi_settimeout(otimeout)15406f25ae9SGregory Neil Shapiro smfi_settimeout(otimeout)
15506f25ae9SGregory Neil Shapiro 	int otimeout;
15606f25ae9SGregory Neil Shapiro {
15706f25ae9SGregory Neil Shapiro 	timeout = otimeout;
15806f25ae9SGregory Neil Shapiro 	return MI_SUCCESS;
15906f25ae9SGregory Neil Shapiro }
16006f25ae9SGregory Neil Shapiro 
16140266059SGregory Neil Shapiro /*
16240266059SGregory Neil Shapiro **  SMFI_SETCONN -- set connection information (socket description)
16340266059SGregory Neil Shapiro **
16440266059SGregory Neil Shapiro **	Parameters:
16540266059SGregory Neil Shapiro **		oconn -- new connection information.
16640266059SGregory Neil Shapiro **
16740266059SGregory Neil Shapiro **	Returns:
16840266059SGregory Neil Shapiro **		MI_SUCCESS/MI_FAILURE
16940266059SGregory Neil Shapiro */
17040266059SGregory Neil Shapiro 
17106f25ae9SGregory Neil Shapiro int
smfi_setconn(oconn)17206f25ae9SGregory Neil Shapiro smfi_setconn(oconn)
17306f25ae9SGregory Neil Shapiro 	char *oconn;
17406f25ae9SGregory Neil Shapiro {
17506f25ae9SGregory Neil Shapiro 	size_t l;
17606f25ae9SGregory Neil Shapiro 
17706f25ae9SGregory Neil Shapiro 	if (oconn == NULL || *oconn == '\0')
17806f25ae9SGregory Neil Shapiro 		return MI_FAILURE;
17906f25ae9SGregory Neil Shapiro 	l = strlen(oconn) + 1;
18006f25ae9SGregory Neil Shapiro 	if ((conn = (char *) malloc(l)) == NULL)
18106f25ae9SGregory Neil Shapiro 		return MI_FAILURE;
18240266059SGregory Neil Shapiro 	if (sm_strlcpy(conn, oconn, l) >= l)
18306f25ae9SGregory Neil Shapiro 		return MI_FAILURE;
18406f25ae9SGregory Neil Shapiro 	return MI_SUCCESS;
18506f25ae9SGregory Neil Shapiro }
18606f25ae9SGregory Neil Shapiro 
18740266059SGregory Neil Shapiro /*
18840266059SGregory Neil Shapiro **  SMFI_SETBACKLOG -- set backlog
18940266059SGregory Neil Shapiro **
19040266059SGregory Neil Shapiro **	Parameters:
191605302a5SGregory Neil Shapiro **		obacklog -- new backlog.
19240266059SGregory Neil Shapiro **
19340266059SGregory Neil Shapiro **	Returns:
19440266059SGregory Neil Shapiro **		MI_SUCCESS/MI_FAILURE
19540266059SGregory Neil Shapiro */
19640266059SGregory Neil Shapiro 
19706f25ae9SGregory Neil Shapiro int
smfi_setbacklog(obacklog)19842e5d165SGregory Neil Shapiro smfi_setbacklog(obacklog)
19942e5d165SGregory Neil Shapiro 	int obacklog;
20042e5d165SGregory Neil Shapiro {
20142e5d165SGregory Neil Shapiro 	if (obacklog <= 0)
20242e5d165SGregory Neil Shapiro 		return MI_FAILURE;
20342e5d165SGregory Neil Shapiro 	backlog = obacklog;
20442e5d165SGregory Neil Shapiro 	return MI_SUCCESS;
20542e5d165SGregory Neil Shapiro }
20642e5d165SGregory Neil Shapiro 
2078774250cSGregory Neil Shapiro 
20840266059SGregory Neil Shapiro /*
209*5b0945b5SGregory Neil Shapiro **  SMFI_MAIN -- setup milter connection and start listener.
21040266059SGregory Neil Shapiro **
21140266059SGregory Neil Shapiro **	Parameters:
21240266059SGregory Neil Shapiro **		none.
21340266059SGregory Neil Shapiro **
21440266059SGregory Neil Shapiro **	Returns:
21540266059SGregory Neil Shapiro **		MI_SUCCESS/MI_FAILURE
21640266059SGregory Neil Shapiro */
21740266059SGregory Neil Shapiro 
21842e5d165SGregory Neil Shapiro int
smfi_main()21906f25ae9SGregory Neil Shapiro smfi_main()
22006f25ae9SGregory Neil Shapiro {
22140266059SGregory Neil Shapiro 	int r;
2228774250cSGregory Neil Shapiro 
22340266059SGregory Neil Shapiro 	(void) signal(SIGPIPE, SIG_IGN);
22406f25ae9SGregory Neil Shapiro 	if (conn == NULL)
22506f25ae9SGregory Neil Shapiro 	{
22606f25ae9SGregory Neil Shapiro 		smi_log(SMI_LOG_FATAL, "%s: missing connection information",
22706f25ae9SGregory Neil Shapiro 			smfi->xxfi_name);
22806f25ae9SGregory Neil Shapiro 		return MI_FAILURE;
22906f25ae9SGregory Neil Shapiro 	}
23006f25ae9SGregory Neil Shapiro 
23106f25ae9SGregory Neil Shapiro 	(void) atexit(mi_clean_signals);
23206f25ae9SGregory Neil Shapiro 	if (mi_control_startup(smfi->xxfi_name) != MI_SUCCESS)
23306f25ae9SGregory Neil Shapiro 	{
23406f25ae9SGregory Neil Shapiro 		smi_log(SMI_LOG_FATAL,
23506f25ae9SGregory Neil Shapiro 			"%s: Couldn't start signal thread",
23606f25ae9SGregory Neil Shapiro 			smfi->xxfi_name);
23706f25ae9SGregory Neil Shapiro 		return MI_FAILURE;
23806f25ae9SGregory Neil Shapiro 	}
239d0cef73dSGregory Neil Shapiro 	r = MI_MONITOR_INIT();
2408774250cSGregory Neil Shapiro 
24106f25ae9SGregory Neil Shapiro 	/* Startup the listener */
24242e5d165SGregory Neil Shapiro 	if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS)
24340266059SGregory Neil Shapiro 		r = MI_FAILURE;
244e92d3f3fSGregory Neil Shapiro 
24540266059SGregory Neil Shapiro 	return r;
24606f25ae9SGregory Neil Shapiro }
24713bd1963SGregory Neil Shapiro 
248