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