5
/* cache/table lookup key management
9
/* char *smtp_key_prefix(buffer, delim_na, iterator, context_flags)
11
/* const char *delim_na;
12
/* SMTP_ITERATOR *iterator;
15
/* The Postfix SMTP server accesses caches and lookup tables,
16
/* using lookup keys that contain information from various
17
/* contexts: per-server configuration, per-request envelope,
18
/* and results from DNS queries.
20
/* These lookup keys sometimes share the same context information.
21
/* The primary purpose of this API is to ensure that this
22
/* shared context is used consistently, and that its use is
23
/* made explicit (both are needed to verify that there is no
24
/* false cache sharing).
26
/* smtp_key_prefix() constructs a lookup key prefix from context
27
/* that may be shared with other lookup keys. The user is free
28
/* to append additional application-specific context. The result
29
/* value is a pointer to the result text.
33
/* Storage for the result.
35
/* The field delimiter character, and the optional place holder
36
/* character for a) information that is unavailable, b)
37
/* information that is inapplicable, or c) that would result
38
/* in an empty field. Key fields that contain "delim_na"
39
/* characters will be base64-encoded.
40
/* Do not specify "delim_na" characters that are part of the
41
/* base64 character set.
43
/* Information that will be selected by the specified flags.
45
/* Bit-wise OR of one or more of the following.
47
/* .IP SMTP_KEY_FLAG_SERVICE
48
/* The global service name. This is a proxy for
49
/* destination-independent and request-independent context.
50
/* .IP SMTP_KEY_FLAG_SENDER
51
/* The envelope sender address. This is a proxy for sender-dependent
52
/* context, such as per-sender SASL authentication.
53
/* .IP SMTP_KEY_FLAG_REQ_NEXTHOP
54
/* The request nexthop destination. This is a proxy for
55
/* destination-dependent, but host-independent context.
56
/* .IP SMTP_KEY_FLAG_NEXTHOP
57
/* The current iterator's nexthop destination (request nexthop
58
/* or fallback nexthop, including optional [] and :port). This
59
/* is the form that users specify in a SASL or TLS lookup
61
/* .IP SMTP_KEY_FLAG_HOSTNAME
62
/* The current iterator's remote hostname.
63
/* .IP SMTP_KEY_FLAG_ADDR
64
/* The current iterator's remote address.
65
/* .IP SMTP_KEY_FLAG_PORT
66
/* The current iterator's remote port.
69
/* Panic: undefined flag or zero flags. Fatal: out of memory.
73
/* The Secure Mailer license must be distributed with this software.
76
/* IBM T.J. Watson Research
78
/* Yorktown Heights, NY 10598, USA
85
#include <netinet/in.h> /* ntohs() for Solaris or BSD */
86
#include <arpa/inet.h> /* ntohs() for Linux or BSD */
94
#include <base64_code.h>
99
#include <mail_params.h>
102
* Application-specific.
107
* We use a configurable field terminator and optional place holder for data
108
* that is unavailable or inapplicable. We base64-encode content that
109
* contains these characters, and content that needs obfuscation.
112
/* smtp_key_append_na - append place-holder key field */
114
static void smtp_key_append_na(VSTRING *buffer, const char *delim_na)
116
if (delim_na[1] != 0)
117
VSTRING_ADDCH(buffer, delim_na[1]);
118
VSTRING_ADDCH(buffer, delim_na[0]);
121
/* smtp_key_append_str - append string-valued key field */
123
static void smtp_key_append_str(VSTRING *buffer, const char *str,
124
const char *delim_na)
126
if (str == 0 || str[0] == 0) {
127
smtp_key_append_na(buffer, delim_na);
128
} else if (str[strcspn(str, delim_na)] != 0) {
129
base64_encode_opt(buffer, str, strlen(str), BASE64_FLAG_APPEND);
130
VSTRING_ADDCH(buffer, delim_na[0]);
132
vstring_sprintf_append(buffer, "%s%c", str, delim_na[0]);
136
/* smtp_key_append_uint - append unsigned-valued key field */
138
static void smtp_key_append_uint(VSTRING *buffer, unsigned num,
139
const char *delim_na)
141
vstring_sprintf_append(buffer, "%u%c", num, delim_na[0]);
144
/* smtp_key_prefix - format common elements in lookup key */
146
char *smtp_key_prefix(VSTRING *buffer, const char *delim_na,
147
SMTP_ITERATOR *iter, int flags)
149
const char myname[] = "smtp_key_prefix";
150
SMTP_STATE *state = iter->parent; /* private member */
156
msg_panic("%s: no parent state", myname);
157
if (flags & ~SMTP_KEY_MASK_ALL)
158
msg_panic("%s: unknown key flags 0x%x",
159
myname, flags & ~SMTP_KEY_MASK_ALL);
161
msg_panic("%s: zero flags", myname);
166
VSTRING_RESET(buffer);
169
* Per-service and per-request context.
171
if (flags & SMTP_KEY_FLAG_SERVICE)
172
smtp_key_append_str(buffer, state->service, delim_na);
173
if (flags & SMTP_KEY_FLAG_SENDER)
174
smtp_key_append_str(buffer, state->request->sender, delim_na);
177
* Per-destination context, non-canonicalized form.
179
if (flags & SMTP_KEY_FLAG_REQ_NEXTHOP)
180
smtp_key_append_str(buffer, STR(iter->request_nexthop), delim_na);
181
if (flags & SMTP_KEY_FLAG_NEXTHOP)
182
smtp_key_append_str(buffer, STR(iter->dest), delim_na);
185
* Per-host context, canonicalized form.
187
if (flags & SMTP_KEY_FLAG_HOSTNAME)
188
smtp_key_append_str(buffer, STR(iter->host), delim_na);
189
if (flags & SMTP_KEY_FLAG_ADDR)
190
smtp_key_append_str(buffer, STR(iter->addr), delim_na);
191
if (flags & SMTP_KEY_FLAG_PORT)
192
smtp_key_append_uint(buffer, ntohs(iter->port), delim_na);
194
/* Similarly, provide unique TLS fingerprint when applicable. */
196
VSTRING_TERMINATE(buffer);