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