1*68e5c67bSchristos /* $NetBSD: postscreen_expand.c,v 1.2 2017/02/14 01:16:47 christos Exp $ */
2e8314800Stron
3e8314800Stron /*++
4e8314800Stron /* NAME
5e8314800Stron /* postscreen_expand 3
6e8314800Stron /* SUMMARY
7e8314800Stron /* SMTP server macro expansion
8e8314800Stron /* SYNOPSIS
9e8314800Stron /* #include <postscreen.h>
10e8314800Stron /*
11e8314800Stron /* void psc_expand_init()
12e8314800Stron /*
13e8314800Stron /* VSTRING *psc_expand_filter;
14e8314800Stron /*
15e8314800Stron /* const char *psc_expand_lookup(name, unused_mode, context)
16e8314800Stron /* const char *name;
17e8314800Stron /* int unused_mode;
18e8314800Stron /* char *context;
19e8314800Stron /* DESCRIPTION
20e8314800Stron /* This module expands session-related macros.
21e8314800Stron /*
22e8314800Stron /* psc_expand_init() performs one-time initialization
23e8314800Stron /* of the psc_expand_filter buffer.
24e8314800Stron /*
25e8314800Stron /* The psc_expand_filter buffer contains the characters
26e8314800Stron /* that are allowed in macro expansion, as specified with the
27e8314800Stron /* psc_expand_filter configuration parameter.
28e8314800Stron /*
29e8314800Stron /* psc_expand_lookup() returns the value of the named
30e8314800Stron /* macro or a null pointer.
31e8314800Stron /*
32e8314800Stron /* Arguments:
33e8314800Stron /* .IP name
34e8314800Stron /* Macro name.
35e8314800Stron /* .IP context
36e8314800Stron /* Call-back context (a PSC_STATE pointer).
37e8314800Stron /* DIAGNOSTICS
38e8314800Stron /* Panic: interface violations. Fatal errors: out of memory.
39e8314800Stron /* internal protocol errors. postscreen_expand() returns the
40e8314800Stron /* binary OR of MAC_PARSE_ERROR (syntax error) and MAC_PARSE_UNDEF
41e8314800Stron /* (undefined macro name).
42e8314800Stron /* LICENSE
43e8314800Stron /* .ad
44e8314800Stron /* .fi
45e8314800Stron /* The Secure Mailer license must be distributed with this software.
46e8314800Stron /* AUTHOR(S)
47e8314800Stron /* Wietse Venema
48e8314800Stron /* IBM T.J. Watson Research
49e8314800Stron /* P.O. Box 704
50e8314800Stron /* Yorktown Heights, NY 10598, USA
51e8314800Stron /*--*/
52e8314800Stron
53e8314800Stron /* System library. */
54e8314800Stron
55e8314800Stron #include <sys_defs.h>
56e8314800Stron #include <time.h>
57e8314800Stron
58e8314800Stron /* Utility library. */
59e8314800Stron
60e8314800Stron #include <msg.h>
61e8314800Stron #include <vstring.h>
62e8314800Stron #include <stringops.h>
63e8314800Stron
64e8314800Stron /* Global library. */
65e8314800Stron
66e8314800Stron #include <mail_params.h>
67e8314800Stron #include <mail_proto.h>
68e8314800Stron
69e8314800Stron /* Application-specific. */
70e8314800Stron
71e8314800Stron #include <postscreen.h>
72e8314800Stron
73e8314800Stron /*
74e8314800Stron * Pre-parsed expansion filter.
75e8314800Stron */
76e8314800Stron VSTRING *psc_expand_filter;
77e8314800Stron
78e8314800Stron /* psc_expand_init - initialize once during process lifetime */
79e8314800Stron
psc_expand_init(void)80e8314800Stron void psc_expand_init(void)
81e8314800Stron {
82e8314800Stron
83e8314800Stron /*
84e8314800Stron * Expand the expansion filter :-)
85e8314800Stron */
86e8314800Stron psc_expand_filter = vstring_alloc(10);
87e8314800Stron unescape(psc_expand_filter, var_psc_exp_filter);
88e8314800Stron }
89e8314800Stron
90e8314800Stron /* psc_expand_lookup - generic SMTP attribute $name expansion */
91e8314800Stron
psc_expand_lookup(const char * name,int unused_mode,void * context)92e8314800Stron const char *psc_expand_lookup(const char *name, int unused_mode,
93837e7c1aSchristos void *context)
94e8314800Stron {
95e8314800Stron PSC_STATE *state = (PSC_STATE *) context;
96e8314800Stron time_t now;
97e8314800Stron struct tm *lt;
98e8314800Stron
99e8314800Stron if (state->expand_buf == 0)
100e8314800Stron state->expand_buf = vstring_alloc(10);
101e8314800Stron
102e8314800Stron if (msg_verbose > 1)
103e8314800Stron msg_info("psc_expand_lookup: ${%s}", name);
104e8314800Stron
105e8314800Stron #define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)
106e8314800Stron #define STREQN(x,y,n) (*(x) == *(y) && strncmp((x), (y), (n)) == 0)
107e8314800Stron #define CONST_LEN(x) (sizeof(x) - 1)
108e8314800Stron
109e8314800Stron /*
110e8314800Stron * Don't query main.cf parameters, as the result of expansion could
111e8314800Stron * reveal system-internal information in server replies.
112e8314800Stron *
113e8314800Stron * XXX: This said, multiple servers may be behind a single client-visible
114e8314800Stron * name or IP address, and each may generate its own logs. Therefore, it
115e8314800Stron * may be useful to expose the replying MTA id (myhostname) in the
116e8314800Stron * contact footer, to identify the right logs. So while we don't expose
117e8314800Stron * the raw configuration dictionary, we do expose "$myhostname" as
118e8314800Stron * expanded in var_myhostname.
119e8314800Stron *
120e8314800Stron * Return NULL only for non-existent names.
121e8314800Stron */
122e8314800Stron if (STREQ(name, MAIL_ATTR_SERVER_NAME)) {
123e8314800Stron return (var_myhostname);
124e8314800Stron } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_ADDR)) {
125e8314800Stron return (state->smtp_client_addr);
126e8314800Stron } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_PORT)) {
127e8314800Stron return (state->smtp_client_port);
128e8314800Stron } if (STREQ(name, MAIL_ATTR_LOCALTIME)) {
129e8314800Stron if (time(&now) == (time_t) -1)
130e8314800Stron msg_fatal("time lookup failed: %m");
131e8314800Stron lt = localtime(&now);
132e8314800Stron VSTRING_RESET(state->expand_buf);
133e8314800Stron do {
134e8314800Stron VSTRING_SPACE(state->expand_buf, 100);
135e8314800Stron } while (strftime(STR(state->expand_buf),
136e8314800Stron vstring_avail(state->expand_buf),
137e8314800Stron "%b %d %H:%M:%S", lt) == 0);
138e8314800Stron return (STR(state->expand_buf));
139e8314800Stron } else {
140e8314800Stron msg_warn("unknown macro name \"%s\" in expansion request", name);
141e8314800Stron return (0);
142e8314800Stron }
143e8314800Stron }
144