summaryrefslogtreecommitdiffstats
path: root/src/postscreen/postscreen_expand.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/postscreen/postscreen_expand.c')
-rw-r--r--src/postscreen/postscreen_expand.c141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/postscreen/postscreen_expand.c b/src/postscreen/postscreen_expand.c
new file mode 100644
index 0000000..ecda543
--- /dev/null
+++ b/src/postscreen/postscreen_expand.c
@@ -0,0 +1,141 @@
+/*++
+/* NAME
+/* postscreen_expand 3
+/* SUMMARY
+/* SMTP server macro expansion
+/* SYNOPSIS
+/* #include <postscreen.h>
+/*
+/* void psc_expand_init()
+/*
+/* VSTRING *psc_expand_filter;
+/*
+/* const char *psc_expand_lookup(name, unused_mode, context)
+/* const char *name;
+/* int unused_mode;
+/* char *context;
+/* DESCRIPTION
+/* This module expands session-related macros.
+/*
+/* psc_expand_init() performs one-time initialization
+/* of the psc_expand_filter buffer.
+/*
+/* The psc_expand_filter buffer contains the characters
+/* that are allowed in macro expansion, as specified with the
+/* psc_expand_filter configuration parameter.
+/*
+/* psc_expand_lookup() returns the value of the named
+/* macro or a null pointer.
+/*
+/* Arguments:
+/* .IP name
+/* Macro name.
+/* .IP context
+/* Call-back context (a PSC_STATE pointer).
+/* DIAGNOSTICS
+/* Panic: interface violations. Fatal errors: out of memory.
+/* internal protocol errors. postscreen_expand() returns the
+/* binary OR of MAC_PARSE_ERROR (syntax error) and MAC_PARSE_UNDEF
+/* (undefined macro name).
+/* 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>
+#include <time.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <vstring.h>
+#include <stringops.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+#include <mail_proto.h>
+
+/* Application-specific. */
+
+#include <postscreen.h>
+
+ /*
+ * Pre-parsed expansion filter.
+ */
+VSTRING *psc_expand_filter;
+
+/* psc_expand_init - initialize once during process lifetime */
+
+void psc_expand_init(void)
+{
+
+ /*
+ * Expand the expansion filter :-)
+ */
+ psc_expand_filter = vstring_alloc(10);
+ unescape(psc_expand_filter, var_psc_exp_filter);
+}
+
+/* psc_expand_lookup - generic SMTP attribute $name expansion */
+
+const char *psc_expand_lookup(const char *name, int unused_mode,
+ void *context)
+{
+ PSC_STATE *state = (PSC_STATE *) context;
+ time_t now;
+ struct tm *lt;
+
+ if (state->expand_buf == 0)
+ state->expand_buf = vstring_alloc(10);
+
+ if (msg_verbose > 1)
+ msg_info("psc_expand_lookup: ${%s}", name);
+
+#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)
+#define STREQN(x,y,n) (*(x) == *(y) && strncmp((x), (y), (n)) == 0)
+#define CONST_LEN(x) (sizeof(x) - 1)
+
+ /*
+ * Don't query main.cf parameters, as the result of expansion could
+ * reveal system-internal information in server replies.
+ *
+ * XXX: This said, multiple servers may be behind a single client-visible
+ * name or IP address, and each may generate its own logs. Therefore, it
+ * may be useful to expose the replying MTA id (myhostname) in the
+ * contact footer, to identify the right logs. So while we don't expose
+ * the raw configuration dictionary, we do expose "$myhostname" as
+ * expanded in var_myhostname.
+ *
+ * Return NULL only for non-existent names.
+ */
+ if (STREQ(name, MAIL_ATTR_SERVER_NAME)) {
+ return (var_myhostname);
+ } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_ADDR)) {
+ return (state->smtp_client_addr);
+ } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_PORT)) {
+ return (state->smtp_client_port);
+ } if (STREQ(name, MAIL_ATTR_LOCALTIME)) {
+ if (time(&now) == (time_t) -1)
+ msg_fatal("time lookup failed: %m");
+ lt = localtime(&now);
+ VSTRING_RESET(state->expand_buf);
+ do {
+ VSTRING_SPACE(state->expand_buf, 100);
+ } while (strftime(STR(state->expand_buf),
+ vstring_avail(state->expand_buf),
+ "%b %d %H:%M:%S", lt) == 0);
+ return (STR(state->expand_buf));
+ } else {
+ msg_warn("unknown macro name \"%s\" in expansion request", name);
+ return (0);
+ }
+}