mirror of
https://github.com/vdukhovni/postfix
synced 2025-09-02 07:05:27 +00:00
postfix-2.5-20071223
This commit is contained in:
committed by
Viktor Dukhovni
parent
99dd94c9fd
commit
a82a55628d
1
postfix/.indent.pro
vendored
1
postfix/.indent.pro
vendored
@@ -143,6 +143,7 @@
|
|||||||
-TMILTER
|
-TMILTER
|
||||||
-TMILTER8
|
-TMILTER8
|
||||||
-TMILTERS
|
-TMILTERS
|
||||||
|
-TMILTER_MACROS
|
||||||
-TMILTER_MSG_CONTEXT
|
-TMILTER_MSG_CONTEXT
|
||||||
-TMIME_ENCODING
|
-TMIME_ENCODING
|
||||||
-TMIME_INFO
|
-TMIME_INFO
|
||||||
|
@@ -14053,3 +14053,12 @@ Apologies for any names omitted.
|
|||||||
|
|
||||||
Further polishing of the Milter code and logging. File:
|
Further polishing of the Milter code and logging. File:
|
||||||
milter/milter8.c.
|
milter/milter8.c.
|
||||||
|
|
||||||
|
20071123
|
||||||
|
|
||||||
|
Further polishing of the Milter code. With SETSYMLIST, each
|
||||||
|
Milter can update its own macros instead of clobbering
|
||||||
|
the global copy is shared with other Milters. Also an
|
||||||
|
opportunity to clean up some ad-hoc code for sending macro
|
||||||
|
lists from smtp(8) to cleanup(8). Files: milter/milter.c,
|
||||||
|
milter/milter8.c, milter/milter_macros.c.
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
/* specified attribute scan routine. dsb_scan() is meant
|
/* specified attribute scan routine. dsb_scan() is meant
|
||||||
/* to be passed as a call-back to attr_scan(), thusly:
|
/* to be passed as a call-back to attr_scan(), thusly:
|
||||||
/*
|
/*
|
||||||
/* ... ATTR_SCAN_FUNC, dsb_scan, (void *) &dsbuf, ...
|
/* ... ATTR_TYPE_FUNC, dsb_scan, (void *) &dsbuf, ...
|
||||||
/* DIAGNOSTICS
|
/* DIAGNOSTICS
|
||||||
/* Fatal: out of memory.
|
/* Fatal: out of memory.
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
/* the specified attribute print routine. dsn_print() is meant
|
/* the specified attribute print routine. dsn_print() is meant
|
||||||
/* to be passed as a call-back to attr_print(), thusly:
|
/* to be passed as a call-back to attr_print(), thusly:
|
||||||
/*
|
/*
|
||||||
/* ... ATTR_PRINT_FUNC, dsn_print, (void *) dsn, ...
|
/* ... ATTR_TYPE_FUNC, dsn_print, (void *) dsn, ...
|
||||||
/* DIAGNOSTICS
|
/* DIAGNOSTICS
|
||||||
/* Fatal: out of memory.
|
/* Fatal: out of memory.
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
|
@@ -20,7 +20,7 @@
|
|||||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||||
* patchlevel; they change the release date only.
|
* patchlevel; they change the release date only.
|
||||||
*/
|
*/
|
||||||
#define MAIL_RELEASE_DATE "20071222"
|
#define MAIL_RELEASE_DATE "20071223"
|
||||||
#define MAIL_VERSION_NUMBER "2.5"
|
#define MAIL_VERSION_NUMBER "2.5"
|
||||||
|
|
||||||
#ifdef SNAPSHOT
|
#ifdef SNAPSHOT
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
/* msg_stats_print() is meant to be passed as a call-back to
|
/* msg_stats_print() is meant to be passed as a call-back to
|
||||||
/* attr_print(), thusly:
|
/* attr_print(), thusly:
|
||||||
/*
|
/*
|
||||||
/* ... ATTR_PRINT_FUNC, msg_stats_print, (void *) stats, ...
|
/* ... ATTR_TYPE_FUNC, msg_stats_print, (void *) stats, ...
|
||||||
/* DIAGNOSTICS
|
/* DIAGNOSTICS
|
||||||
/* Fatal: out of memory.
|
/* Fatal: out of memory.
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
|
@@ -41,7 +41,7 @@
|
|||||||
/* using the specified attribute scan routine. rcpb_scan()
|
/* using the specified attribute scan routine. rcpb_scan()
|
||||||
/* is meant to be passed as a call-back to attr_scan(), thusly:
|
/* is meant to be passed as a call-back to attr_scan(), thusly:
|
||||||
/*
|
/*
|
||||||
/* ... ATTR_SCAN_FUNC, rcpb_scan, (void *) rcpt_buf, ...
|
/* ... ATTR_TYPE_FUNC, rcpb_scan, (void *) rcpt_buf, ...
|
||||||
/*
|
/*
|
||||||
/* rcpb_create(), rcpb_reset() and rcpb_free() create, wipe
|
/* rcpb_create(), rcpb_reset() and rcpb_free() create, wipe
|
||||||
/* and destroy recipient buffer instances.
|
/* and destroy recipient buffer instances.
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
/* routine. rcpt_print() is meant to be passed as a call-back
|
/* routine. rcpt_print() is meant to be passed as a call-back
|
||||||
/* to attr_print(), thusly:
|
/* to attr_print(), thusly:
|
||||||
/*
|
/*
|
||||||
/* ... ATTR_PRINT_FUNC, rcpt_print, (void *) recipient, ...
|
/* ... ATTR_TYPE_FUNC, rcpt_print, (void *) recipient, ...
|
||||||
/* DIAGNOSTICS
|
/* DIAGNOSTICS
|
||||||
/* Fatal: out of memory.
|
/* Fatal: out of memory.
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
SRCS = milter.c milter8.c
|
SRCS = milter.c milter8.c milter_macros.c
|
||||||
OBJS = milter.o milter8.o
|
OBJS = milter.o milter8.o milter_macros.o
|
||||||
HDRS = milter.h
|
HDRS = milter.h
|
||||||
TESTSRC =
|
TESTSRC =
|
||||||
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
|
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
|
||||||
@@ -117,4 +117,15 @@ milter8.o: ../../include/vstream.h
|
|||||||
milter8.o: ../../include/vstring.h
|
milter8.o: ../../include/vstring.h
|
||||||
milter8.o: milter.h
|
milter8.o: milter.h
|
||||||
milter8.o: milter8.c
|
milter8.o: milter8.c
|
||||||
|
milter_macros.o: ../../include/argv.h
|
||||||
|
milter_macros.o: ../../include/attr.h
|
||||||
|
milter_macros.o: ../../include/iostuff.h
|
||||||
|
milter_macros.o: ../../include/mail_proto.h
|
||||||
|
milter_macros.o: ../../include/mymalloc.h
|
||||||
|
milter_macros.o: ../../include/sys_defs.h
|
||||||
|
milter_macros.o: ../../include/vbuf.h
|
||||||
|
milter_macros.o: ../../include/vstream.h
|
||||||
|
milter_macros.o: ../../include/vstring.h
|
||||||
|
milter_macros.o: milter.h
|
||||||
|
milter_macros.o: milter_macros.c
|
||||||
test-milter.o: test-milter.c
|
test-milter.o: test-milter.c
|
||||||
|
@@ -310,15 +310,27 @@ const char *milter_conn_event(MILTERS *milters,
|
|||||||
{
|
{
|
||||||
const char *resp;
|
const char *resp;
|
||||||
MILTER *m;
|
MILTER *m;
|
||||||
ARGV *macros;
|
ARGV *global_macros = 0;
|
||||||
|
ARGV *any_macros;
|
||||||
|
|
||||||
|
#define MILTER_MACRO_EVAL(global_macros, m, milters, member) \
|
||||||
|
((m->macros && m->macros->member[0]) ? \
|
||||||
|
milter_macro_lookup(milters, m->macros->member) : \
|
||||||
|
global_macros ? global_macros : \
|
||||||
|
(global_macros = \
|
||||||
|
milter_macro_lookup(milters, milters->macros->member)))
|
||||||
|
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("report connect to all milters");
|
msg_info("report connect to all milters");
|
||||||
macros = milter_macro_lookup(milters, milters->conn_macros);
|
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
||||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next)
|
any_macros = MILTER_MACRO_EVAL(global_macros, m, milters, conn_macros);
|
||||||
resp = m->conn_event(m, client_name, client_addr, client_port,
|
resp = m->conn_event(m, client_name, client_addr, client_port,
|
||||||
addr_family, macros);
|
addr_family, any_macros);
|
||||||
argv_free(macros);
|
if (any_macros != global_macros)
|
||||||
|
argv_free(any_macros);
|
||||||
|
}
|
||||||
|
if (global_macros)
|
||||||
|
argv_free(global_macros);
|
||||||
return (resp);
|
return (resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,16 +341,19 @@ const char *milter_helo_event(MILTERS *milters, const char *helo_name,
|
|||||||
{
|
{
|
||||||
const char *resp;
|
const char *resp;
|
||||||
MILTER *m;
|
MILTER *m;
|
||||||
ARGV *macros;
|
ARGV *global_macros = 0;
|
||||||
|
ARGV *any_macros;
|
||||||
|
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("report helo to all milters");
|
msg_info("report helo to all milters");
|
||||||
macros = milters->helo_macros == 0 ? 0 :
|
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
||||||
milter_macro_lookup(milters, milters->helo_macros);
|
any_macros = MILTER_MACRO_EVAL(global_macros, m, milters, helo_macros);
|
||||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next)
|
resp = m->helo_event(m, helo_name, esmtp_flag, any_macros);
|
||||||
resp = m->helo_event(m, helo_name, esmtp_flag, macros);
|
if (any_macros != global_macros)
|
||||||
if (macros)
|
argv_free(any_macros);
|
||||||
argv_free(macros);
|
}
|
||||||
|
if (global_macros)
|
||||||
|
argv_free(global_macros);
|
||||||
return (resp);
|
return (resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,16 +363,19 @@ const char *milter_mail_event(MILTERS *milters, const char **argv)
|
|||||||
{
|
{
|
||||||
const char *resp;
|
const char *resp;
|
||||||
MILTER *m;
|
MILTER *m;
|
||||||
ARGV *macros;
|
ARGV *global_macros = 0;
|
||||||
|
ARGV *any_macros;
|
||||||
|
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("report sender to all milters");
|
msg_info("report sender to all milters");
|
||||||
macros = milters->mail_macros == 0 ? 0 :
|
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
||||||
milter_macro_lookup(milters, milters->mail_macros);
|
any_macros = MILTER_MACRO_EVAL(global_macros, m, milters, mail_macros);
|
||||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next)
|
resp = m->mail_event(m, argv, any_macros);
|
||||||
resp = m->mail_event(m, argv, macros);
|
if (any_macros != global_macros)
|
||||||
if (macros)
|
argv_free(any_macros);
|
||||||
argv_free(macros);
|
}
|
||||||
|
if (global_macros)
|
||||||
|
argv_free(global_macros);
|
||||||
return (resp);
|
return (resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,16 +385,19 @@ const char *milter_rcpt_event(MILTERS *milters, const char **argv)
|
|||||||
{
|
{
|
||||||
const char *resp;
|
const char *resp;
|
||||||
MILTER *m;
|
MILTER *m;
|
||||||
ARGV *macros;
|
ARGV *global_macros = 0;
|
||||||
|
ARGV *any_macros;
|
||||||
|
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("report recipient to all milters");
|
msg_info("report recipient to all milters");
|
||||||
macros = milters->rcpt_macros == 0 ? 0 :
|
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
||||||
milter_macro_lookup(milters, milters->rcpt_macros);
|
any_macros = MILTER_MACRO_EVAL(global_macros, m, milters, rcpt_macros);
|
||||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next)
|
resp = m->rcpt_event(m, argv, any_macros);
|
||||||
resp = m->rcpt_event(m, argv, macros);
|
if (any_macros != global_macros)
|
||||||
if (macros)
|
argv_free(any_macros);
|
||||||
argv_free(macros);
|
}
|
||||||
|
if (global_macros)
|
||||||
|
argv_free(global_macros);
|
||||||
return (resp);
|
return (resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,26 +405,21 @@ const char *milter_rcpt_event(MILTERS *milters, const char **argv)
|
|||||||
|
|
||||||
const char *milter_data_event(MILTERS *milters)
|
const char *milter_data_event(MILTERS *milters)
|
||||||
{
|
{
|
||||||
const char *myname = "milter_data_event";
|
|
||||||
const char *resp;
|
const char *resp;
|
||||||
MILTER *m;
|
MILTER *m;
|
||||||
ARGV *macros = 0;
|
ARGV *global_macros = 0;
|
||||||
|
ARGV *any_macros;
|
||||||
|
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("report data to all milters");
|
msg_info("report data to all milters");
|
||||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
||||||
if (m->data_event) {
|
any_macros = MILTER_MACRO_EVAL(global_macros, m, milters, data_macros);
|
||||||
if (macros == 0 && milters->data_macros)
|
resp = m->data_event(m, any_macros);
|
||||||
macros = milter_macro_lookup(milters, milters->data_macros);
|
if (any_macros != global_macros)
|
||||||
resp = m->data_event(m, macros);
|
argv_free(any_macros);
|
||||||
} else {
|
|
||||||
if (msg_verbose)
|
|
||||||
msg_info("%s: skip milter %s (command unimplemented)",
|
|
||||||
myname, m->name);
|
|
||||||
}
|
}
|
||||||
}
|
if (global_macros)
|
||||||
if (macros)
|
argv_free(global_macros);
|
||||||
argv_free(macros);
|
|
||||||
return (resp);
|
return (resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -411,26 +427,21 @@ const char *milter_data_event(MILTERS *milters)
|
|||||||
|
|
||||||
const char *milter_unknown_event(MILTERS *milters, const char *command)
|
const char *milter_unknown_event(MILTERS *milters, const char *command)
|
||||||
{
|
{
|
||||||
const char *myname = "milter_unknown_event";
|
|
||||||
const char *resp;
|
const char *resp;
|
||||||
MILTER *m;
|
MILTER *m;
|
||||||
ARGV *macros = 0;
|
ARGV *global_macros = 0;
|
||||||
|
ARGV *any_macros;
|
||||||
|
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("report unknown command to all milters");
|
msg_info("report unknown command to all milters");
|
||||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
||||||
if (m->unknown_event) {
|
any_macros = MILTER_MACRO_EVAL(global_macros, m, milters, unk_macros);
|
||||||
if (macros == 0 && milters->unk_macros)
|
resp = m->unknown_event(m, command, any_macros);
|
||||||
macros = milter_macro_lookup(milters, milters->unk_macros);
|
if (any_macros != global_macros)
|
||||||
resp = m->unknown_event(m, command, macros);
|
argv_free(any_macros);
|
||||||
} else {
|
|
||||||
if (msg_verbose)
|
|
||||||
msg_info("%s: skip milter %s (command unimplemented)",
|
|
||||||
myname, m->name);
|
|
||||||
}
|
}
|
||||||
}
|
if (global_macros)
|
||||||
if (macros)
|
argv_free(global_macros);
|
||||||
argv_free(macros);
|
|
||||||
return (resp);
|
return (resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,21 +465,26 @@ const char *milter_message(MILTERS *milters, VSTREAM *fp, off_t data_offset)
|
|||||||
{
|
{
|
||||||
const char *resp;
|
const char *resp;
|
||||||
MILTER *m;
|
MILTER *m;
|
||||||
ARGV *eoh_macros;
|
ARGV *global_eoh_macros = 0;
|
||||||
ARGV *eod_macros;
|
ARGV *global_eod_macros = 0;
|
||||||
|
ARGV *any_eoh_macros;
|
||||||
|
ARGV *any_eod_macros;
|
||||||
|
|
||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("inspect content by all milters");
|
msg_info("inspect content by all milters");
|
||||||
eoh_macros = milters->eoh_macros == 0 ? 0 :
|
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
|
||||||
milter_macro_lookup(milters, milters->eoh_macros);
|
any_eoh_macros = MILTER_MACRO_EVAL(global_eoh_macros, m, milters, eoh_macros);
|
||||||
eod_macros = milters->eod_macros == 0 ? 0 :
|
any_eod_macros = MILTER_MACRO_EVAL(global_eod_macros, m, milters, eod_macros);
|
||||||
milter_macro_lookup(milters, milters->eod_macros);
|
resp = m->message(m, fp, data_offset, any_eoh_macros, any_eod_macros);
|
||||||
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next)
|
if (any_eoh_macros != global_eoh_macros)
|
||||||
resp = m->message(m, fp, data_offset, eoh_macros, eod_macros);
|
argv_free(any_eoh_macros);
|
||||||
if (eoh_macros)
|
if (any_eod_macros != global_eod_macros)
|
||||||
argv_free(eoh_macros);
|
argv_free(any_eod_macros);
|
||||||
if (eod_macros)
|
}
|
||||||
argv_free(eod_macros);
|
if (global_eoh_macros)
|
||||||
|
argv_free(global_eoh_macros);
|
||||||
|
if (global_eod_macros)
|
||||||
|
argv_free(global_eod_macros);
|
||||||
return (resp);
|
return (resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,22 +512,15 @@ void milter_disc_event(MILTERS *milters)
|
|||||||
m->disc_event(m);
|
m->disc_event(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* milter_create - create milter list */
|
/* milter_new - create milter list */
|
||||||
|
|
||||||
MILTERS *milter_create(const char *names,
|
MILTERS *milter_new(const char *names,
|
||||||
int conn_timeout,
|
int conn_timeout,
|
||||||
int cmd_timeout,
|
int cmd_timeout,
|
||||||
int msg_timeout,
|
int msg_timeout,
|
||||||
const char *protocol,
|
const char *protocol,
|
||||||
const char *def_action,
|
const char *def_action,
|
||||||
const char *conn_macros,
|
MILTER_MACROS *macros)
|
||||||
const char *helo_macros,
|
|
||||||
const char *mail_macros,
|
|
||||||
const char *rcpt_macros,
|
|
||||||
const char *data_macros,
|
|
||||||
const char *eoh_macros,
|
|
||||||
const char *eod_macros,
|
|
||||||
const char *unk_macros)
|
|
||||||
{
|
{
|
||||||
MILTERS *milters;
|
MILTERS *milters;
|
||||||
MILTER *head = 0;
|
MILTER *head = 0;
|
||||||
@@ -544,14 +553,7 @@ MILTERS *milter_create(const char *names,
|
|||||||
milters->milter_list = head;
|
milters->milter_list = head;
|
||||||
milters->mac_lookup = 0;
|
milters->mac_lookup = 0;
|
||||||
milters->mac_context = 0;
|
milters->mac_context = 0;
|
||||||
milters->conn_macros = mystrdup(conn_macros);
|
milters->macros = macros;
|
||||||
milters->helo_macros = mystrdup(helo_macros);
|
|
||||||
milters->mail_macros = mystrdup(mail_macros);
|
|
||||||
milters->rcpt_macros = mystrdup(rcpt_macros);
|
|
||||||
milters->data_macros = mystrdup(data_macros);
|
|
||||||
milters->eoh_macros = mystrdup(eoh_macros);
|
|
||||||
milters->eod_macros = mystrdup(eod_macros);
|
|
||||||
milters->unk_macros = mystrdup(unk_macros);
|
|
||||||
milters->add_header = 0;
|
milters->add_header = 0;
|
||||||
milters->upd_header = milters->ins_header = 0;
|
milters->upd_header = milters->ins_header = 0;
|
||||||
milters->del_header = 0;
|
milters->del_header = 0;
|
||||||
@@ -572,39 +574,11 @@ void milter_free(MILTERS *milters)
|
|||||||
msg_info("free all milters");
|
msg_info("free all milters");
|
||||||
for (m = milters->milter_list; m != 0; m = next)
|
for (m = milters->milter_list; m != 0; m = next)
|
||||||
next = m->next, m->free(m);
|
next = m->next, m->free(m);
|
||||||
if (milters->conn_macros)
|
if (milters->macros)
|
||||||
myfree(milters->conn_macros);
|
milter_macros_free(milters->macros);
|
||||||
if (milters->helo_macros)
|
|
||||||
myfree(milters->helo_macros);
|
|
||||||
if (milters->mail_macros)
|
|
||||||
myfree(milters->mail_macros);
|
|
||||||
if (milters->rcpt_macros)
|
|
||||||
myfree(milters->rcpt_macros);
|
|
||||||
if (milters->rcpt_macros)
|
|
||||||
myfree(milters->data_macros);
|
|
||||||
if (milters->eoh_macros)
|
|
||||||
myfree(milters->eoh_macros);
|
|
||||||
if (milters->eod_macros)
|
|
||||||
myfree(milters->eod_macros);
|
|
||||||
if (milters->unk_macros)
|
|
||||||
myfree(milters->unk_macros);
|
|
||||||
myfree((char *) milters);
|
myfree((char *) milters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Temporary protocol to send /receive milter instances. This needs to be
|
|
||||||
* extended with type information when we support both Sendmail8 and
|
|
||||||
* Sendmail X protocols.
|
|
||||||
*/
|
|
||||||
#define MAIL_ATTR_MILT_CONN "conn_macros"
|
|
||||||
#define MAIL_ATTR_MILT_HELO "helo_macros"
|
|
||||||
#define MAIL_ATTR_MILT_MAIL "mail_macros"
|
|
||||||
#define MAIL_ATTR_MILT_RCPT "rcpt_macros"
|
|
||||||
#define MAIL_ATTR_MILT_DATA "data_macros"
|
|
||||||
#define MAIL_ATTR_MILT_EOH "eoh_macros"
|
|
||||||
#define MAIL_ATTR_MILT_EOD "eod_macros"
|
|
||||||
#define MAIL_ATTR_MILT_UNK "unk_macros"
|
|
||||||
|
|
||||||
/* milter_dummy - send empty milter list */
|
/* milter_dummy - send empty milter list */
|
||||||
|
|
||||||
int milter_dummy(MILTERS *milters, VSTREAM *stream)
|
int milter_dummy(MILTERS *milters, VSTREAM *stream)
|
||||||
@@ -640,14 +614,8 @@ int milter_send(MILTERS *milters, VSTREAM *stream)
|
|||||||
* Send the filter macro names.
|
* Send the filter macro names.
|
||||||
*/
|
*/
|
||||||
(void) attr_print(stream, ATTR_FLAG_MORE,
|
(void) attr_print(stream, ATTR_FLAG_MORE,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_CONN, milters->conn_macros,
|
ATTR_TYPE_FUNC, milter_macros_print,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_HELO, milters->helo_macros,
|
(void *) milters->macros,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAIL, milters->mail_macros,
|
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_RCPT, milters->rcpt_macros,
|
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_DATA, milters->data_macros,
|
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_EOH, milters->eoh_macros,
|
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_EOD, milters->eod_macros,
|
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_UNK, milters->unk_macros,
|
|
||||||
ATTR_TYPE_END);
|
ATTR_TYPE_END);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -675,44 +643,12 @@ MILTERS *milter_receive(VSTREAM *stream, int count)
|
|||||||
MILTER *head = 0;
|
MILTER *head = 0;
|
||||||
MILTER *tail = 0;
|
MILTER *tail = 0;
|
||||||
MILTER *milter = 0;
|
MILTER *milter = 0;
|
||||||
VSTRING *conn_macros;
|
MILTER_MACROS *macros = milter_macros_alloc(MILTER_MACROS_ALLOC_ZERO);
|
||||||
VSTRING *helo_macros;
|
|
||||||
VSTRING *mail_macros;
|
|
||||||
VSTRING *rcpt_macros;
|
|
||||||
VSTRING *data_macros;
|
|
||||||
VSTRING *eoh_macros;
|
|
||||||
VSTRING *eod_macros;
|
|
||||||
VSTRING *unk_macros;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Receive filter macros.
|
|
||||||
*/
|
|
||||||
#define FREE_BUFFERS() do { \
|
|
||||||
vstring_free(conn_macros); vstring_free(helo_macros); \
|
|
||||||
vstring_free(mail_macros); vstring_free(rcpt_macros); \
|
|
||||||
vstring_free(data_macros); vstring_free(eoh_macros); \
|
|
||||||
vstring_free(eod_macros); vstring_free(unk_macros); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
conn_macros = vstring_alloc(10);
|
|
||||||
helo_macros = vstring_alloc(10);
|
|
||||||
mail_macros = vstring_alloc(10);
|
|
||||||
rcpt_macros = vstring_alloc(10);
|
|
||||||
data_macros = vstring_alloc(10);
|
|
||||||
eoh_macros = vstring_alloc(10);
|
|
||||||
eod_macros = vstring_alloc(10);
|
|
||||||
unk_macros = vstring_alloc(10);
|
|
||||||
if (attr_scan(stream, ATTR_FLAG_STRICT | ATTR_FLAG_MORE,
|
if (attr_scan(stream, ATTR_FLAG_STRICT | ATTR_FLAG_MORE,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_CONN, conn_macros,
|
ATTR_TYPE_FUNC, milter_macros_scan, (void *) macros,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_HELO, helo_macros,
|
ATTR_TYPE_END) != 1) {
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAIL, mail_macros,
|
milter_macros_free(macros);
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_RCPT, rcpt_macros,
|
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_DATA, data_macros,
|
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_EOH, eoh_macros,
|
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_EOD, eod_macros,
|
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_UNK, unk_macros,
|
|
||||||
ATTR_TYPE_END) != 8) {
|
|
||||||
FREE_BUFFERS();
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
#define NO_MILTERS ((char *) 0)
|
#define NO_MILTERS ((char *) 0)
|
||||||
@@ -720,12 +656,7 @@ MILTERS *milter_receive(VSTREAM *stream, int count)
|
|||||||
#define NO_PROTOCOL ((char *) 0)
|
#define NO_PROTOCOL ((char *) 0)
|
||||||
#define NO_ACTION ((char *) 0)
|
#define NO_ACTION ((char *) 0)
|
||||||
|
|
||||||
milters = milter_create(NO_MILTERS, NO_TIMEOUTS, NO_PROTOCOL, NO_ACTION,
|
milters = milter_new(NO_MILTERS, NO_TIMEOUTS, NO_PROTOCOL, NO_ACTION, macros);
|
||||||
STR(conn_macros), STR(helo_macros),
|
|
||||||
STR(mail_macros), STR(rcpt_macros),
|
|
||||||
STR(data_macros), STR(eoh_macros),
|
|
||||||
STR(eod_macros), STR(unk_macros));
|
|
||||||
FREE_BUFFERS();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Receive the filters.
|
* Receive the filters.
|
||||||
|
@@ -18,6 +18,11 @@
|
|||||||
#include <vstream.h>
|
#include <vstream.h>
|
||||||
#include <argv.h>
|
#include <argv.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Global library.
|
||||||
|
*/
|
||||||
|
#include <attr.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Each Milter handle is an element of a null-terminated linked list. The
|
* Each Milter handle is an element of a null-terminated linked list. The
|
||||||
* functions are virtual so that we can support multiple MTA-side Milter
|
* functions are virtual so that we can support multiple MTA-side Milter
|
||||||
@@ -28,6 +33,7 @@ typedef struct MILTER {
|
|||||||
char *name; /* full name including transport */
|
char *name; /* full name including transport */
|
||||||
struct MILTER *next; /* linkage */
|
struct MILTER *next; /* linkage */
|
||||||
struct MILTERS *parent; /* parent information */
|
struct MILTERS *parent; /* parent information */
|
||||||
|
struct MILTER_MACROS *macros; /* private macros */
|
||||||
const char *(*conn_event) (struct MILTER *, const char *, const char *, const char *, unsigned, ARGV *);
|
const char *(*conn_event) (struct MILTER *, const char *, const char *, const char *, unsigned, ARGV *);
|
||||||
const char *(*helo_event) (struct MILTER *, const char *, int, ARGV *);
|
const char *(*helo_event) (struct MILTER *, const char *, int, ARGV *);
|
||||||
const char *(*mail_event) (struct MILTER *, const char **, ARGV *);
|
const char *(*mail_event) (struct MILTER *, const char **, ARGV *);
|
||||||
@@ -46,6 +52,70 @@ typedef struct MILTER {
|
|||||||
extern MILTER *milter8_create(const char *, int, int, int, const char *, const char *, struct MILTERS *);
|
extern MILTER *milter8_create(const char *, int, int, int, const char *, const char *, struct MILTERS *);
|
||||||
extern MILTER *milter8_receive(VSTREAM *, struct MILTERS *);
|
extern MILTER *milter8_receive(VSTREAM *, struct MILTERS *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As of Sendmail 8.14 each milter can override the default macro list. If a
|
||||||
|
* Milter has its own macro list, a null member means use the global
|
||||||
|
* definition.
|
||||||
|
*/
|
||||||
|
typedef struct MILTER_MACROS {
|
||||||
|
char *conn_macros; /* macros for connect event */
|
||||||
|
char *helo_macros; /* macros for HELO/EHLO command */
|
||||||
|
char *mail_macros; /* macros for MAIL FROM command */
|
||||||
|
char *rcpt_macros; /* macros for RCPT TO command */
|
||||||
|
char *data_macros; /* macros for DATA command */
|
||||||
|
char *eoh_macros; /* macros for end-of-headers */
|
||||||
|
char *eod_macros; /* macros for END-OF-DATA command */
|
||||||
|
char *unk_macros; /* macros for unknown command */
|
||||||
|
} MILTER_MACROS;
|
||||||
|
|
||||||
|
extern MILTER_MACROS *milter_macros_create(const char *, const char *,
|
||||||
|
const char *, const char *,
|
||||||
|
const char *, const char *,
|
||||||
|
const char *, const char *);
|
||||||
|
extern MILTER_MACROS *milter_macros_alloc(int);
|
||||||
|
extern void milter_macros_free(MILTER_MACROS *);
|
||||||
|
extern int milter_macros_print(ATTR_PRINT_MASTER_FN, VSTREAM *, int, void *);
|
||||||
|
extern int milter_macros_scan(ATTR_SCAN_MASTER_FN, VSTREAM *, int, void *);
|
||||||
|
|
||||||
|
#define MILTER_MACROS_ALLOC_ZERO 1 /* null pointer */
|
||||||
|
#define MILTER_MACROS_ALLOC_EMPTY 2 /* mystrdup(""); */
|
||||||
|
|
||||||
|
#define milter_macros_wipe(mp) do { \
|
||||||
|
MILTER_MACROS *__mp = mp; \
|
||||||
|
if (__mp->conn_macros) \
|
||||||
|
myfree(__mp->conn_macros); \
|
||||||
|
if (__mp->helo_macros) \
|
||||||
|
myfree(__mp->helo_macros); \
|
||||||
|
if (__mp->mail_macros) \
|
||||||
|
myfree(__mp->mail_macros); \
|
||||||
|
if (__mp->rcpt_macros) \
|
||||||
|
myfree(__mp->rcpt_macros); \
|
||||||
|
if (__mp->data_macros) \
|
||||||
|
myfree(__mp->data_macros); \
|
||||||
|
if (__mp->eoh_macros) \
|
||||||
|
myfree(__mp->eoh_macros); \
|
||||||
|
if (__mp->eod_macros) \
|
||||||
|
myfree(__mp->eod_macros); \
|
||||||
|
if (__mp->unk_macros) \
|
||||||
|
myfree(__mp->unk_macros); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define milter_macros_zero(mp) milter_macros_init(mp, 0)
|
||||||
|
|
||||||
|
#define milter_macros_init(mp, expr) do { \
|
||||||
|
MILTER_MACROS *__mp = (mp); \
|
||||||
|
char *__expr = (expr); \
|
||||||
|
__mp->conn_macros = __expr; \
|
||||||
|
__mp->helo_macros = __expr; \
|
||||||
|
__mp->mail_macros = __expr; \
|
||||||
|
__mp->rcpt_macros = __expr; \
|
||||||
|
__mp->data_macros = __expr; \
|
||||||
|
__mp->eoh_macros = __expr; \
|
||||||
|
__mp->eod_macros = __expr; \
|
||||||
|
__mp->unk_macros = __expr; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A bunch of Milters.
|
* A bunch of Milters.
|
||||||
*/
|
*/
|
||||||
@@ -60,14 +130,7 @@ typedef struct MILTERS {
|
|||||||
MILTER *milter_list; /* linked list of Milters */
|
MILTER *milter_list; /* linked list of Milters */
|
||||||
MILTER_MAC_LOOKUP_FN mac_lookup;
|
MILTER_MAC_LOOKUP_FN mac_lookup;
|
||||||
void *mac_context; /* macro lookup context */
|
void *mac_context; /* macro lookup context */
|
||||||
char *conn_macros; /* macros for connect event */
|
struct MILTER_MACROS *macros;
|
||||||
char *helo_macros; /* macros for HELO/EHLO command */
|
|
||||||
char *mail_macros; /* macros for MAIL FROM command */
|
|
||||||
char *rcpt_macros; /* macros for RCPT TO command */
|
|
||||||
char *data_macros; /* macros for DATA command */
|
|
||||||
char *eoh_macros; /* macros for end-of-headers */
|
|
||||||
char *eod_macros; /* macros for END-OF-DATA command */
|
|
||||||
char *unk_macros; /* macros for unknown command */
|
|
||||||
void *chg_context; /* context for queue file changes */
|
void *chg_context; /* context for queue file changes */
|
||||||
MILTER_ADD_HEADER_FN add_header;
|
MILTER_ADD_HEADER_FN add_header;
|
||||||
MILTER_EDIT_HEADER_FN upd_header;
|
MILTER_EDIT_HEADER_FN upd_header;
|
||||||
@@ -78,12 +141,17 @@ typedef struct MILTERS {
|
|||||||
MILTER_EDIT_BODY_FN repl_body;
|
MILTER_EDIT_BODY_FN repl_body;
|
||||||
} MILTERS;
|
} MILTERS;
|
||||||
|
|
||||||
extern MILTERS *milter_create(const char *, int, int, int,
|
#define milter_create(milter_names, conn_timeout, cmd_timeout, msg_timeout, \
|
||||||
const char *, const char *,
|
protocol, def_action, conn_macros, helo_macros, \
|
||||||
const char *, const char *,
|
mail_macros, rcpt_macros, data_macros, eoh_macros, \
|
||||||
const char *, const char *,
|
eod_macros, unk_macros) \
|
||||||
const char *, const char *,
|
milter_new(milter_names, conn_timeout, cmd_timeout, msg_timeout, \
|
||||||
const char *, const char *);
|
protocol, def_action, milter_macros_create(conn_macros, \
|
||||||
|
helo_macros, mail_macros, rcpt_macros, data_macros, \
|
||||||
|
eoh_macros, eod_macros, unk_macros))
|
||||||
|
|
||||||
|
extern MILTERS *milter_new(const char *, int, int, int, const char *,
|
||||||
|
const char *, MILTER_MACROS *);
|
||||||
extern void milter_macro_callback(MILTERS *, MILTER_MAC_LOOKUP_FN, void *);
|
extern void milter_macro_callback(MILTERS *, MILTER_MAC_LOOKUP_FN, void *);
|
||||||
extern void milter_edit_callback(MILTERS *milters, MILTER_ADD_HEADER_FN,
|
extern void milter_edit_callback(MILTERS *milters, MILTER_ADD_HEADER_FN,
|
||||||
MILTER_EDIT_HEADER_FN, MILTER_EDIT_HEADER_FN,
|
MILTER_EDIT_HEADER_FN, MILTER_EDIT_HEADER_FN,
|
||||||
|
@@ -322,17 +322,17 @@ static NAME_CODE smfim_table[] = {
|
|||||||
* members, without using a switch statement.
|
* members, without using a switch statement.
|
||||||
*/
|
*/
|
||||||
static size_t milter8_macro_offsets[] = {
|
static size_t milter8_macro_offsets[] = {
|
||||||
offsetof(MILTERS, conn_macros), /* SMFIM_CONNECT */
|
offsetof(MILTER_MACROS, conn_macros), /* SMFIM_CONNECT */
|
||||||
offsetof(MILTERS, helo_macros), /* SMFIM_HELO */
|
offsetof(MILTER_MACROS, helo_macros), /* SMFIM_HELO */
|
||||||
offsetof(MILTERS, mail_macros), /* SMFIM_ENVFROM */
|
offsetof(MILTER_MACROS, mail_macros), /* SMFIM_ENVFROM */
|
||||||
offsetof(MILTERS, rcpt_macros), /* SMFIM_ENVRCPT */
|
offsetof(MILTER_MACROS, rcpt_macros), /* SMFIM_ENVRCPT */
|
||||||
offsetof(MILTERS, data_macros), /* SMFIM_DATA */
|
offsetof(MILTER_MACROS, data_macros), /* SMFIM_DATA */
|
||||||
offsetof(MILTERS, eod_macros), /* Note: SMFIM_EOM < SMFIM_EOH */
|
offsetof(MILTER_MACROS, eod_macros),/* Note: SMFIM_EOM < SMFIM_EOH */
|
||||||
offsetof(MILTERS, eoh_macros), /* Note: SMFIM_EOH > SMFIM_EOM */
|
offsetof(MILTER_MACROS, eoh_macros),/* Note: SMFIM_EOH > SMFIM_EOM */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MILTER8_MACRO_PTR(__milters, __type) \
|
#define MILTER8_MACRO_PTR(__macros, __type) \
|
||||||
((char **) (((char *) (__milters)) + milter8_macro_offsets[(__type)]))
|
((char **) (((char *) (__macros)) + milter8_macro_offsets[(__type)]))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* How much buffer space is available for sending body content.
|
* How much buffer space is available for sending body content.
|
||||||
@@ -1734,6 +1734,8 @@ static void milter8_connect(MILTER8 *milter)
|
|||||||
const char *smfim_name;
|
const char *smfim_name;
|
||||||
char **mac_value_ptr;
|
char **mac_value_ptr;
|
||||||
|
|
||||||
|
milter->m.macros = milter_macros_alloc(MILTER_MACROS_ALLOC_EMPTY);
|
||||||
|
|
||||||
while (data_len > 0
|
while (data_len > 0
|
||||||
&& milter8_read_data(milter, &data_len,
|
&& milter8_read_data(milter, &data_len,
|
||||||
MILTER8_DATA_HLONG, &mac_type,
|
MILTER8_DATA_HLONG, &mac_type,
|
||||||
@@ -1747,7 +1749,7 @@ static void milter8_connect(MILTER8 *milter)
|
|||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("override %s macro list with \"%s\"",
|
msg_info("override %s macro list with \"%s\"",
|
||||||
smfim_name, STR(buf));
|
smfim_name, STR(buf));
|
||||||
mac_value_ptr = MILTER8_MACRO_PTR(milter->m.parent, mac_type);
|
mac_value_ptr = MILTER8_MACRO_PTR(milter->m.macros, mac_type);
|
||||||
if (*mac_value_ptr != 0)
|
if (*mac_value_ptr != 0)
|
||||||
myfree(*mac_value_ptr);
|
myfree(*mac_value_ptr);
|
||||||
*mac_value_ptr = mystrdup(STR(buf));
|
*mac_value_ptr = mystrdup(STR(buf));
|
||||||
@@ -2467,6 +2469,7 @@ static const char *milter8_message(MILTER *m, VSTREAM *qfile,
|
|||||||
#define MAIL_ATTR_MILT_CMD "milter_cmd_timeout"
|
#define MAIL_ATTR_MILT_CMD "milter_cmd_timeout"
|
||||||
#define MAIL_ATTR_MILT_MSG "milter_msg_timeout"
|
#define MAIL_ATTR_MILT_MSG "milter_msg_timeout"
|
||||||
#define MAIL_ATTR_MILT_ACT "milter_action"
|
#define MAIL_ATTR_MILT_ACT "milter_action"
|
||||||
|
#define MAIL_ATTR_MILT_MAC "milter_macro_list"
|
||||||
|
|
||||||
/* milter8_active - report if this milter still wants events */
|
/* milter8_active - report if this milter still wants events */
|
||||||
|
|
||||||
@@ -2489,7 +2492,7 @@ static int milter8_send(MILTER *m, VSTREAM *stream)
|
|||||||
if (msg_verbose)
|
if (msg_verbose)
|
||||||
msg_info("%s: milter %s", myname, milter->m.name);
|
msg_info("%s: milter %s", myname, milter->m.name);
|
||||||
|
|
||||||
if (attr_print(stream, ATTR_FLAG_NONE,
|
if (attr_print(stream, ATTR_FLAG_MORE,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_NAME, milter->m.name,
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_NAME, milter->m.name,
|
||||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_VERS, milter->version,
|
ATTR_TYPE_INT, MAIL_ATTR_MILT_VERS, milter->version,
|
||||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_ACTS, milter->rq_mask,
|
ATTR_TYPE_INT, MAIL_ATTR_MILT_ACTS, milter->rq_mask,
|
||||||
@@ -2500,7 +2503,16 @@ static int milter8_send(MILTER *m, VSTREAM *stream)
|
|||||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_CMD, milter->cmd_timeout,
|
ATTR_TYPE_INT, MAIL_ATTR_MILT_CMD, milter->cmd_timeout,
|
||||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_MSG, milter->msg_timeout,
|
ATTR_TYPE_INT, MAIL_ATTR_MILT_MSG, milter->msg_timeout,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_ACT, milter->def_action,
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_ACT, milter->def_action,
|
||||||
|
ATTR_TYPE_INT, MAIL_ATTR_MILT_MAC, milter->m.macros != 0,
|
||||||
ATTR_TYPE_END) != 0
|
ATTR_TYPE_END) != 0
|
||||||
|
|| (milter->m.macros != 0
|
||||||
|
&& attr_print(stream, ATTR_FLAG_NONE,
|
||||||
|
ATTR_TYPE_FUNC, milter_macros_print,
|
||||||
|
(void *) milter->m.macros,
|
||||||
|
ATTR_TYPE_END) != 0)
|
||||||
|
|| (milter->m.macros == 0
|
||||||
|
&& attr_print(stream, ATTR_FLAG_NONE,
|
||||||
|
ATTR_TYPE_END) != 0)
|
||||||
|| vstream_fflush(stream) != 0) {
|
|| vstream_fflush(stream) != 0) {
|
||||||
return (-1);
|
return (-1);
|
||||||
#ifdef CANT_WRITE_BEFORE_SENDING_FD
|
#ifdef CANT_WRITE_BEFORE_SENDING_FD
|
||||||
@@ -2543,12 +2555,20 @@ MILTER *milter8_receive(VSTREAM *stream, MILTERS *parent)
|
|||||||
int cmd_timeout;
|
int cmd_timeout;
|
||||||
int msg_timeout;
|
int msg_timeout;
|
||||||
int fd;
|
int fd;
|
||||||
|
int has_macros;
|
||||||
|
MILTER_MACROS *macros = 0;
|
||||||
|
|
||||||
|
#define FREE_MACROS_AND_RETURN(x) do { \
|
||||||
|
if (macros) \
|
||||||
|
milter_macros_free(macros); \
|
||||||
|
return (x); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
if (name_buf == 0) {
|
if (name_buf == 0) {
|
||||||
name_buf = vstring_alloc(10);
|
name_buf = vstring_alloc(10);
|
||||||
act_buf = vstring_alloc(10);
|
act_buf = vstring_alloc(10);
|
||||||
}
|
}
|
||||||
if (attr_scan(stream, ATTR_FLAG_STRICT,
|
if (attr_scan(stream, ATTR_FLAG_STRICT | ATTR_FLAG_MORE,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_NAME, name_buf,
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_NAME, name_buf,
|
||||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_VERS, &version,
|
ATTR_TYPE_INT, MAIL_ATTR_MILT_VERS, &version,
|
||||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_ACTS, &rq_mask,
|
ATTR_TYPE_INT, MAIL_ATTR_MILT_ACTS, &rq_mask,
|
||||||
@@ -2559,22 +2579,32 @@ MILTER *milter8_receive(VSTREAM *stream, MILTERS *parent)
|
|||||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_CMD, &cmd_timeout,
|
ATTR_TYPE_INT, MAIL_ATTR_MILT_CMD, &cmd_timeout,
|
||||||
ATTR_TYPE_INT, MAIL_ATTR_MILT_MSG, &msg_timeout,
|
ATTR_TYPE_INT, MAIL_ATTR_MILT_MSG, &msg_timeout,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_MILT_ACT, act_buf,
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_ACT, act_buf,
|
||||||
ATTR_TYPE_END) < 9) {
|
ATTR_TYPE_INT, MAIL_ATTR_MILT_MAC, &has_macros,
|
||||||
return (0);
|
ATTR_TYPE_END) < 10
|
||||||
|
|| (has_macros != 0
|
||||||
|
&& attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
|
ATTR_TYPE_FUNC, milter_macros_scan,
|
||||||
|
(void *) (macros =
|
||||||
|
milter_macros_alloc(MILTER_MACROS_ALLOC_ZERO)),
|
||||||
|
ATTR_TYPE_END) < 1)
|
||||||
|
|| (has_macros == 0
|
||||||
|
&& attr_scan(stream, ATTR_FLAG_STRICT,
|
||||||
|
ATTR_TYPE_END) < 0)) {
|
||||||
|
FREE_MACROS_AND_RETURN(0);
|
||||||
#ifdef CANT_WRITE_BEFORE_SENDING_FD
|
#ifdef CANT_WRITE_BEFORE_SENDING_FD
|
||||||
} else if (attr_print(stream, ATTR_FLAG_NONE,
|
} else if (attr_print(stream, ATTR_FLAG_NONE,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
|
ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
|
||||||
ATTR_TYPE_END) != 0
|
ATTR_TYPE_END) != 0
|
||||||
|| vstream_fflush(stream) != 0) {
|
|| vstream_fflush(stream) != 0) {
|
||||||
return (0);
|
FREE_MACROS_AND_RETURN(0);
|
||||||
#endif
|
#endif
|
||||||
} else if ((fd = LOCAL_RECV_FD(vstream_fileno(stream))) < 0) {
|
} else if ((fd = LOCAL_RECV_FD(vstream_fileno(stream))) < 0) {
|
||||||
return (0);
|
FREE_MACROS_AND_RETURN(0);
|
||||||
#ifdef MUST_READ_AFTER_SENDING_FD
|
#ifdef MUST_READ_AFTER_SENDING_FD
|
||||||
} else if (attr_print(stream, ATTR_FLAG_NONE,
|
} else if (attr_print(stream, ATTR_FLAG_NONE,
|
||||||
ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
|
ATTR_TYPE_STR, MAIL_ATTR_DUMMY, "",
|
||||||
ATTR_TYPE_END) != 0) {
|
ATTR_TYPE_END) != 0) {
|
||||||
return (0);
|
FREE_MACROS_AND_RETURN(0);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#define NO_PROTOCOL ((char *) 0)
|
#define NO_PROTOCOL ((char *) 0)
|
||||||
@@ -2585,6 +2615,7 @@ MILTER *milter8_receive(VSTREAM *stream, MILTERS *parent)
|
|||||||
milter = milter8_alloc(STR(name_buf), conn_timeout, cmd_timeout,
|
milter = milter8_alloc(STR(name_buf), conn_timeout, cmd_timeout,
|
||||||
msg_timeout, NO_PROTOCOL, STR(act_buf), parent);
|
msg_timeout, NO_PROTOCOL, STR(act_buf), parent);
|
||||||
milter->fp = vstream_fdopen(fd, O_RDWR);
|
milter->fp = vstream_fdopen(fd, O_RDWR);
|
||||||
|
milter->m.macros = macros;
|
||||||
vstream_control(milter->fp, VSTREAM_CTL_DOUBLE, VSTREAM_CTL_END);
|
vstream_control(milter->fp, VSTREAM_CTL_DOUBLE, VSTREAM_CTL_END);
|
||||||
/* Avoid poor performance when TCP MSS > VSTREAM_BUFSIZE. */
|
/* Avoid poor performance when TCP MSS > VSTREAM_BUFSIZE. */
|
||||||
vstream_tweak_sock(milter->fp);
|
vstream_tweak_sock(milter->fp);
|
||||||
@@ -2615,6 +2646,8 @@ static void milter8_free(MILTER *m)
|
|||||||
myfree(milter->def_action);
|
myfree(milter->def_action);
|
||||||
if (milter->def_reply)
|
if (milter->def_reply)
|
||||||
myfree(milter->def_reply);
|
myfree(milter->def_reply);
|
||||||
|
if (milter->m.macros)
|
||||||
|
milter_macros_free(milter->m.macros);
|
||||||
myfree((char *) milter);
|
myfree((char *) milter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2635,6 +2668,7 @@ static MILTER8 *milter8_alloc(const char *name, int conn_timeout,
|
|||||||
milter->m.name = mystrdup(name);
|
milter->m.name = mystrdup(name);
|
||||||
milter->m.next = 0;
|
milter->m.next = 0;
|
||||||
milter->m.parent = parent;
|
milter->m.parent = parent;
|
||||||
|
milter->m.macros = 0;
|
||||||
milter->m.conn_event = milter8_conn_event;
|
milter->m.conn_event = milter8_conn_event;
|
||||||
milter->m.helo_event = milter8_helo_event;
|
milter->m.helo_event = milter8_helo_event;
|
||||||
milter->m.mail_event = milter8_mail_event;
|
milter->m.mail_event = milter8_mail_event;
|
||||||
|
247
postfix/src/milter/milter_macros.c
Normal file
247
postfix/src/milter/milter_macros.c
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
/*++
|
||||||
|
/* NAME
|
||||||
|
/* milter_macros
|
||||||
|
/* SUMMARY
|
||||||
|
/* manipulate MILTER_MACROS structures
|
||||||
|
/* SYNOPSIS
|
||||||
|
/* #include <milter.h>
|
||||||
|
/*
|
||||||
|
/* MILTER_MACROS *milter_macros_create(conn_macros, helo_macros,
|
||||||
|
/* mail_macros, rcpt_macros,
|
||||||
|
/* data_macros, eoh_macros,
|
||||||
|
/* eod_macros, unk_macros)
|
||||||
|
/* const char *conn_macros;
|
||||||
|
/* const char *helo_macros;
|
||||||
|
/* const char *mail_macros;
|
||||||
|
/* const char *rcpt_macrps;
|
||||||
|
/* const char *data_macros;
|
||||||
|
/* const char *eoh_macros;
|
||||||
|
/* const char *eod_macros;
|
||||||
|
/* const char *unk_macros;
|
||||||
|
/*
|
||||||
|
/* MILTER_MACROS *milter_macros_alloc(init_mode)
|
||||||
|
/* int init_mode;
|
||||||
|
/*
|
||||||
|
/* void milter_macros_free(mp)
|
||||||
|
/* MILTER_MACROS *mp;
|
||||||
|
/*
|
||||||
|
/* int milter_macros_print(print_fn, stream, flags, ptr)
|
||||||
|
/* ATTR_PRINT_MASTER_FN print_fn;
|
||||||
|
/* VSTREAM *stream;
|
||||||
|
/* int flags;
|
||||||
|
/* void *ptr;
|
||||||
|
/*
|
||||||
|
/* int milter_macros_scan(scan_fn, fp, flags, ptr)
|
||||||
|
/* ATTR_SCAN_MASTER_FN scan_fn;
|
||||||
|
/* VSTREAM *fp;
|
||||||
|
/* int flags;
|
||||||
|
/* void *ptr;
|
||||||
|
/* DESCRIPTION
|
||||||
|
/* Sendmail mail filter (Milter) applications receive sets of
|
||||||
|
/* macro (name=value) pairs with each SMTP or content event.
|
||||||
|
/* In Postfix, the lists of names are stored in MILTER_MACROS
|
||||||
|
/* structures. By default, the same structure is shared by all
|
||||||
|
/* Milter applications; it is initialized with information
|
||||||
|
/* from main.cf. With Sendmail 8.14 a Milter can override one
|
||||||
|
/* or more lists of macro names, and individual filters may
|
||||||
|
/* have their own partial list.
|
||||||
|
/*
|
||||||
|
/* This module maintains the macro name lists as mystrdup()'ed
|
||||||
|
/* values. The user is explicitly allowed to update these
|
||||||
|
/* values directly, as long as they respect the mystrdup()
|
||||||
|
/* interface.
|
||||||
|
/*
|
||||||
|
/* milter_macros_create() creates a MILTER_MACROS structure
|
||||||
|
/* and initializes it with copies of its string arguments.
|
||||||
|
/*
|
||||||
|
/* milter_macros_alloc() creates a MILTER_MACROS structure
|
||||||
|
/* that is initialized according to its init_mode argument.
|
||||||
|
/* .IP MILTER_MACROS_ALLOC_ZERO
|
||||||
|
/* Initialize all members as null pointers. This mode is
|
||||||
|
/* recommended for applications that use milter_macros_scan().
|
||||||
|
/* .IP MILTER_MACROS_ALLOC_EMPTY
|
||||||
|
/* Initialize all members with mystrdup(""). This is not as
|
||||||
|
/* expensive as it appears to be. This mode is recommend for
|
||||||
|
/* applications that update individual MILTER_MACROS members
|
||||||
|
/* directly.
|
||||||
|
/* .PP
|
||||||
|
/* milter_macros_free() destroys a MILTER_MACROS structure and
|
||||||
|
/* frees any strings referenced by it.
|
||||||
|
/*
|
||||||
|
/* milter_macros_print() writes the contents of a MILTER_MACROS
|
||||||
|
/* structure to the named stream using the specified attribute
|
||||||
|
/* print routine. milter_macros_print() is meant to be passed
|
||||||
|
/* as a call-back to attr_print*(), thusly:
|
||||||
|
/*
|
||||||
|
/* ATTR_TYPE_FUNC, milter_macros_print, (void *) macros,
|
||||||
|
/*
|
||||||
|
/* milter_macros_scan() reads a MILTER_MACROS structure from
|
||||||
|
/* the named stream using the specified attribute scan routine.
|
||||||
|
/* milter_macros_scan() is meant to be passed as a call-back
|
||||||
|
/* to attr_scan*(), thusly:
|
||||||
|
/*
|
||||||
|
/* ATTR_TYPE_FUNC, milter_macros_scan, (void *) macros,
|
||||||
|
/* DIAGNOSTICS
|
||||||
|
/* Fatal: out of memory.
|
||||||
|
/* LICENSE
|
||||||
|
/* .ad
|
||||||
|
/* .fi
|
||||||
|
/* The Secure Mailer license must be distributed with this
|
||||||
|
/* software.
|
||||||
|
/* AUTHOR(S)
|
||||||
|
/* Wietse Venema IBM T.J. Watson Research P.O. Box 704 Yorktown
|
||||||
|
/* Heights, NY 10598, USA
|
||||||
|
/*--*/
|
||||||
|
|
||||||
|
/* System library. */
|
||||||
|
|
||||||
|
#include <sys_defs.h>
|
||||||
|
|
||||||
|
/* Utility library. */
|
||||||
|
|
||||||
|
#include <msg.h>
|
||||||
|
#include <attr.h>
|
||||||
|
#include <mymalloc.h>
|
||||||
|
#include <vstring.h>
|
||||||
|
|
||||||
|
/* Global library. */
|
||||||
|
|
||||||
|
#include <mail_proto.h>
|
||||||
|
#include <milter.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ad-hoc protocol to send/receive milter macro name lists.
|
||||||
|
*/
|
||||||
|
#define MAIL_ATTR_MILT_MAC_CONN "conn_macros"
|
||||||
|
#define MAIL_ATTR_MILT_MAC_HELO "helo_macros"
|
||||||
|
#define MAIL_ATTR_MILT_MAC_MAIL "mail_macros"
|
||||||
|
#define MAIL_ATTR_MILT_MAC_RCPT "rcpt_macros"
|
||||||
|
#define MAIL_ATTR_MILT_MAC_DATA "data_macros"
|
||||||
|
#define MAIL_ATTR_MILT_MAC_EOH "eoh_macros"
|
||||||
|
#define MAIL_ATTR_MILT_MAC_EOD "eod_macros"
|
||||||
|
#define MAIL_ATTR_MILT_MAC_UNK "unk_macros"
|
||||||
|
|
||||||
|
/* milter_macros_print - write recipient to stream */
|
||||||
|
|
||||||
|
int milter_macros_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
|
||||||
|
int flags, void *ptr)
|
||||||
|
{
|
||||||
|
MILTER_MACROS *mp = (MILTER_MACROS *) ptr;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The attribute order does not matter, except that it must be the same
|
||||||
|
* as in the milter_macros_scan() function.
|
||||||
|
*/
|
||||||
|
ret = print_fn(fp, flags | ATTR_FLAG_MORE,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_CONN, mp->conn_macros,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_HELO, mp->helo_macros,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_MAIL, mp->mail_macros,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_RCPT, mp->rcpt_macros,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_DATA, mp->data_macros,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_EOH, mp->eoh_macros,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_EOD, mp->eod_macros,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_UNK, mp->unk_macros,
|
||||||
|
ATTR_TYPE_END);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* milter_macros_scan - receive milter macro name list */
|
||||||
|
|
||||||
|
int milter_macros_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
|
||||||
|
int flags, void *ptr)
|
||||||
|
{
|
||||||
|
MILTER_MACROS *mp = (MILTER_MACROS *) ptr;
|
||||||
|
int ret;
|
||||||
|
VSTRING *conn_macros = vstring_alloc(10);
|
||||||
|
VSTRING *helo_macros = vstring_alloc(10);
|
||||||
|
VSTRING *mail_macros = vstring_alloc(10);
|
||||||
|
VSTRING *rcpt_macros = vstring_alloc(10);
|
||||||
|
VSTRING *data_macros = vstring_alloc(10);
|
||||||
|
VSTRING *eoh_macros = vstring_alloc(10);
|
||||||
|
VSTRING *eod_macros = vstring_alloc(10);
|
||||||
|
VSTRING *unk_macros = vstring_alloc(10);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The attribute order does not matter, except that it must be the same
|
||||||
|
* as in the milter_macros_print() function.
|
||||||
|
*/
|
||||||
|
ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_CONN, conn_macros,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_HELO, helo_macros,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_MAIL, mail_macros,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_RCPT, rcpt_macros,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_DATA, data_macros,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_EOH, eoh_macros,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_EOD, eod_macros,
|
||||||
|
ATTR_TYPE_STR, MAIL_ATTR_MILT_MAC_UNK, unk_macros,
|
||||||
|
ATTR_TYPE_END);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't optimize for error.
|
||||||
|
*/
|
||||||
|
mp->conn_macros = vstring_export(conn_macros);
|
||||||
|
mp->helo_macros = vstring_export(helo_macros);
|
||||||
|
mp->mail_macros = vstring_export(mail_macros);
|
||||||
|
mp->rcpt_macros = vstring_export(rcpt_macros);
|
||||||
|
mp->data_macros = vstring_export(data_macros);
|
||||||
|
mp->eoh_macros = vstring_export(eoh_macros);
|
||||||
|
mp->eod_macros = vstring_export(eod_macros);
|
||||||
|
mp->unk_macros = vstring_export(unk_macros);
|
||||||
|
|
||||||
|
return (ret == 8 ? 1 : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* milter_macros_create - create and initialize macros structure */
|
||||||
|
|
||||||
|
MILTER_MACROS *milter_macros_create(const char *conn_macros,
|
||||||
|
const char *helo_macros,
|
||||||
|
const char *mail_macros,
|
||||||
|
const char *rcpt_macros,
|
||||||
|
const char *data_macros,
|
||||||
|
const char *eoh_macros,
|
||||||
|
const char *eod_macros,
|
||||||
|
const char *unk_macros)
|
||||||
|
{
|
||||||
|
MILTER_MACROS *mp;
|
||||||
|
|
||||||
|
mp = (MILTER_MACROS *) mymalloc(sizeof(*mp));
|
||||||
|
mp->conn_macros = mystrdup(conn_macros);
|
||||||
|
mp->helo_macros = mystrdup(helo_macros);
|
||||||
|
mp->mail_macros = mystrdup(mail_macros);
|
||||||
|
mp->rcpt_macros = mystrdup(rcpt_macros);
|
||||||
|
mp->data_macros = mystrdup(data_macros);
|
||||||
|
mp->eoh_macros = mystrdup(eoh_macros);
|
||||||
|
mp->eod_macros = mystrdup(eod_macros);
|
||||||
|
mp->unk_macros = mystrdup(unk_macros);
|
||||||
|
|
||||||
|
return (mp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* milter_macros_alloc - allocate memory for structure with simple initialization */
|
||||||
|
|
||||||
|
MILTER_MACROS *milter_macros_alloc(int mode)
|
||||||
|
{
|
||||||
|
MILTER_MACROS *mp;
|
||||||
|
|
||||||
|
mp = (MILTER_MACROS *) mymalloc(sizeof(*mp));
|
||||||
|
switch (mode) {
|
||||||
|
case MILTER_MACROS_ALLOC_ZERO:
|
||||||
|
milter_macros_init(mp, 0);
|
||||||
|
break;
|
||||||
|
case MILTER_MACROS_ALLOC_EMPTY:
|
||||||
|
milter_macros_init(mp, mystrdup(""));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
msg_panic("milter_macros_alloc: unknown mode %d", mode);
|
||||||
|
}
|
||||||
|
return (mp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* milter_macros_free - destroy memory for MILTER_MACROS structure */
|
||||||
|
|
||||||
|
void milter_macros_free(MILTER_MACROS *mp)
|
||||||
|
{
|
||||||
|
milter_macros_wipe(mp);
|
||||||
|
myfree((char *) mp);
|
||||||
|
}
|
Reference in New Issue
Block a user