~ubuntu-branches/debian/sid/postfix/sid

« back to all changes in this revision

Viewing changes to src/smtp/smtp_reuse.c

  • Committer: Package Import Robot
  • Author(s): LaMont Jones, LaMont Jones, localization folks
  • Date: 2014-02-11 07:44:30 UTC
  • mfrom: (1.1.41)
  • Revision ID: package-import@ubuntu.com-20140211074430-91tdwgjriazawdz4
Tags: 2.11.0-1
[LaMont Jones]

* New upstream release: 2.11.0

[localization folks]

* l10n: Updated German translations.  Closes: #734893 (Helge Kreutzmann)

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
/*      #include <smtp.h>
8
8
/*      #include <smtp_reuse.h>
9
9
/*
10
 
/*      void    smtp_save_session(state)
11
 
/*      SMTP_STATE *state;
12
 
/*
13
 
/*      SMTP_SESSION *smtp_reuse_domain(state, lookup_mx, domain, port)
14
 
/*      SMTP_STATE *state;
15
 
/*      int     lookup_mx;
16
 
/*      char    *domain;
17
 
/*      unsigned port;
18
 
/*
19
 
/*      SMTP_SESSION *smtp_reuse_addr(state, addr, port)
20
 
/*      SMTP_STATE *state;
21
 
/*      const char *addr;
22
 
/*      unsigned port;
 
10
/*      void    smtp_save_session(state, name_key_flags, endp_key_flags)
 
11
/*      SMTP_STATE *state;
 
12
/*      int     name_key_flags;
 
13
/*      int     endp_key_flags;
 
14
/*
 
15
/*      SMTP_SESSION *smtp_reuse_nexthop(state, name_key_flags)
 
16
/*      SMTP_STATE *state;
 
17
/*      int     name_key_flags;
 
18
/*
 
19
/*      SMTP_SESSION *smtp_reuse_addr(state, endp_key_flags)
 
20
/*      SMTP_STATE *state;
 
21
/*      int     endp_key_flags;
23
22
/* DESCRIPTION
24
23
/*      This module implements the SMTP client specific interface to
25
24
/*      the generic session cache infrastructure.
26
25
/*
27
 
/*      Each cached connection identifier includes the name of the
28
 
/*      mail delivery service. Thus, cached connections are not
29
 
/*      shared between different services.
 
26
/*      A cached connection is closed when the TLS policy requires
 
27
/*      that TLS is enabled.
30
28
/*
31
29
/*      smtp_save_session() stores the current session under the
32
30
/*      next-hop logical destination (if available) and under the
33
31
/*      remote server address.  The SMTP_SESSION object is destroyed.
34
32
/*
35
 
/*      smtp_reuse_domain() looks up a cached session by its logical
 
33
/*      smtp_reuse_nexthop() looks up a cached session by its logical
36
34
/*      destination, and verifies that the session is still alive.
37
 
/*      The restored session information includes the "best MX" bit.
 
35
/*      The restored session information includes the "best MX" bit
 
36
/*      and overrides the iterator dest, host and addr fields.
38
37
/*      The result is null in case of failure.
39
38
/*
40
39
/*      smtp_reuse_addr() looks up a cached session by its server
41
40
/*      address, and verifies that the session is still alive.
42
 
/*      This operation is disabled when the legacy tls_per_site
43
 
/*      or smtp_sasl_password_maps features are enabled.
 
41
/*      The restored session information does not include the "best
 
42
/*      MX" bit, and does not override the iterator dest, host and
 
43
/*      addr fields.
44
44
/*      The result is null in case of failure.
45
45
/*
46
46
/*      Arguments:
47
47
/* .IP state
48
48
/*      SMTP client state, including the current session, the original
49
49
/*      next-hop domain, etc.
50
 
/* .IP lookup_mx
51
 
/*      Whether or not the domain is subject to MX lookup.
52
 
/* .IP domain
53
 
/*      Domain name or bare numerical address.
54
 
/* .IP addr
55
 
/*      The remote server address as printable text.
56
 
/* .IP port
57
 
/*      The remote server port, network byte order.
 
50
/* .IP name_key_flags
 
51
/*      Explicit declaration of context that should be used to look
 
52
/*      up a cached connection by its logical destination.
 
53
/*      See smtp_key(3) for details.
 
54
/* .IP endp_key_flags
 
55
/*      Explicit declaration of context that should be used to look
 
56
/*      up a cached connection by its server address.
 
57
/*      See smtp_key(3) for details.
58
58
/* LICENSE
59
59
/* .ad
60
60
/* .fi
95
95
#include <smtp_reuse.h>
96
96
 
97
97
 /*
98
 
  * We encode the MX lookup/A lookup method into the name under which SMTP
99
 
  * session information is cached. The following macros serve to make the
100
 
  * remainder of the code less obscure.
 
98
  * Key field delimiter, and place holder field value for
 
99
  * unavailable/inapplicable information.
101
100
  */
102
 
#define NO_MX_LOOKUP    0
103
 
 
104
 
#define SMTP_SCACHE_LABEL(mx_lookup_flag) \
105
 
        ((mx_lookup_flag) ? "%s:%s:%u" : "%s:[%s]:%u")
 
101
#define SMTP_REUSE_KEY_DELIM_NA "\n*"
106
102
 
107
103
/* smtp_save_session - save session under next-hop name and server address */
108
104
 
109
 
void    smtp_save_session(SMTP_STATE *state)
 
105
void    smtp_save_session(SMTP_STATE *state, int name_key_flags,
 
106
                                  int endp_key_flags)
110
107
{
111
108
    SMTP_SESSION *session = state->session;
112
109
    int     fd;
114
111
    /*
115
112
     * Encode the next-hop logical destination, if available. Reuse storage
116
113
     * that is also used for cache lookup queries.
117
 
     * 
118
 
     * Note: if the label needs to be made more specific (with e.g., SASL login
119
 
     * information), just append the text with vstring_sprintf_append().
120
114
     */
121
115
    if (HAVE_NEXTHOP_STATE(state))
122
 
        vstring_sprintf(state->dest_label,
123
 
                        SMTP_SCACHE_LABEL(state->nexthop_lookup_mx),
124
 
                        state->service, state->nexthop_domain,
125
 
                        ntohs(state->nexthop_port));
 
116
        smtp_key_prefix(state->dest_label, SMTP_REUSE_KEY_DELIM_NA,
 
117
                        state->iterator, name_key_flags);
126
118
 
127
119
    /*
128
120
     * Encode the physical endpoint name. Reuse storage that is also used for
129
121
     * cache lookup queries.
130
 
     * 
131
 
     * Note: if the label needs to be made more specific (with e.g., SASL login
132
 
     * information), just append the text with vstring_sprintf_append().
133
122
     */
134
 
    vstring_sprintf(state->endp_label,
135
 
                    SMTP_SCACHE_LABEL(NO_MX_LOOKUP),
136
 
                    state->service, session->addr, ntohs(session->port));
 
123
    smtp_key_prefix(state->endp_label, SMTP_REUSE_KEY_DELIM_NA,
 
124
                    state->iterator, endp_key_flags);
137
125
 
138
126
    /*
139
127
     * Passivate the SMTP_SESSION object, destroying the object in the
167
155
                                               const char *label)
168
156
{
169
157
    const char *myname = "smtp_reuse_common";
 
158
    SMTP_ITERATOR *iter = state->iterator;
170
159
    SMTP_SESSION *session;
171
160
 
172
161
    /*
 
162
     * Can't happen. Both smtp_reuse_nexthop() and smtp_reuse_addr() decline
 
163
     * the request when the TLS policy is not TLS_LEV_NONE.
 
164
     */
 
165
#ifdef USE_TLS
 
166
    if (state->tls->level > TLS_LEV_NONE)
 
167
        msg_panic("%s: unexpected plain-text cached session to %s",
 
168
                  myname, label);
 
169
#endif
 
170
 
 
171
    /*
173
172
     * Re-activate the SMTP_SESSION object.
174
173
     */
175
 
    session = smtp_session_activate(fd, state->dest_prop, state->endp_prop);
 
174
    session = smtp_session_activate(fd, state->iterator, state->dest_prop,
 
175
                                    state->endp_prop);
176
176
    if (session == 0) {
177
177
        msg_warn("%s: bad cached session attribute for %s", myname, label);
178
178
        (void) close(fd);
180
180
    }
181
181
    state->session = session;
182
182
    session->state = state;
183
 
 
184
 
    /*
185
 
     * XXX Temporary fix.
186
 
     * 
187
 
     * Cached connections are always plaintext. They must never be reused when
188
 
     * TLS encryption is required.
189
 
     * 
190
 
     * As long as we support the legacy smtp_tls_per_site feature, we must
191
 
     * search the connection cache before making TLS policy decisions. This
192
 
     * is because the policy can depend on the server name. For example, a
193
 
     * site could have a global policy that requires encryption, with
194
 
     * per-server exceptions that allow plaintext.
195
 
     * 
196
 
     * With the newer smtp_tls_policy_maps feature, the policy depends on the
197
 
     * next-hop destination only. We can avoid unnecessary connection cache
198
 
     * lookups, because we can compute the TLS policy much earlier.
199
 
     */
200
183
#ifdef USE_TLS
201
 
    if (session->tls_level >= TLS_LEV_ENCRYPT) {
202
 
        if (msg_verbose)
203
 
            msg_info("%s: skipping plain-text cached session to %s",
204
 
                     myname, label);
205
 
        smtp_quit(state);                       /* Close politely */
206
 
        smtp_session_free(session);             /* And avoid leaks */
207
 
        return (state->session = 0);
208
 
    }
 
184
    session->tls = state->tls;                  /* TEMPORARY */
209
185
#endif
210
186
 
211
187
    /*
225
201
    /*
226
202
     * Update the list of used cached addresses.
227
203
     */
228
 
    htable_enter(state->cache_used, session->addr, (char *) 0);
 
204
    htable_enter(state->cache_used, STR(iter->addr), (char *) 0);
229
205
 
230
206
    return (session);
231
207
}
232
208
 
233
 
/* smtp_reuse_domain - reuse session cached under domain name */
 
209
/* smtp_reuse_nexthop - reuse session cached under nexthop name */
234
210
 
235
 
SMTP_SESSION *smtp_reuse_domain(SMTP_STATE *state, int lookup_mx,
236
 
                                        const char *domain, unsigned port)
 
211
SMTP_SESSION *smtp_reuse_nexthop(SMTP_STATE *state, int name_key_flags)
237
212
{
238
213
    SMTP_SESSION *session;
239
214
    int     fd;
240
215
 
241
216
    /*
 
217
     * Don't look up an existing plaintext connection when a new connection
 
218
     * would (try to) use TLS.
 
219
     */
 
220
#ifdef USE_TLS
 
221
    if (state->tls->level > TLS_LEV_NONE)
 
222
        return (0);
 
223
#endif
 
224
 
 
225
    /*
242
226
     * Look up the session by its logical name.
243
 
     * 
244
 
     * Note: if the label needs to be made more specific (with e.g., SASL login
245
 
     * information), just append the text with vstring_sprintf_append().
246
227
     */
247
 
    vstring_sprintf(state->dest_label, SMTP_SCACHE_LABEL(lookup_mx),
248
 
                    state->service, domain, ntohs(port));
 
228
    smtp_key_prefix(state->dest_label, SMTP_REUSE_KEY_DELIM_NA,
 
229
                    state->iterator, name_key_flags);
249
230
    if ((fd = scache_find_dest(smtp_scache, STR(state->dest_label),
250
231
                               state->dest_prop, state->endp_prop)) < 0)
251
232
        return (0);
260
241
 
261
242
/* smtp_reuse_addr - reuse session cached under numerical address */
262
243
 
263
 
SMTP_SESSION *smtp_reuse_addr(SMTP_STATE *state, const char *addr,
264
 
                                      unsigned port)
 
244
SMTP_SESSION *smtp_reuse_addr(SMTP_STATE *state, int endp_key_flags)
265
245
{
266
246
    SMTP_SESSION *session;
267
247
    int     fd;
268
248
 
269
249
    /*
270
 
     * XXX Disable connection cache lookup by server IP address when the
271
 
     * tls_per_site policy or smtp_sasl_password_maps features are enabled.
272
 
     * This connection may have been created under a different hostname that
273
 
     * resolves to the same IP address. We don't want to use the wrong SASL
274
 
     * credentials or the wrong TLS policy.
 
250
     * Don't look up an existing plaintext connection when a new connection
 
251
     * would (try to) use TLS.
275
252
     */
276
 
    if ((var_smtp_tls_per_site && *var_smtp_tls_per_site)
277
 
        || (var_smtp_tls_policy && *var_smtp_tls_policy))
 
253
#ifdef USE_TLS
 
254
    if (state->tls->level > TLS_LEV_NONE)
278
255
        return (0);
 
256
#endif
279
257
 
280
258
    /*
281
259
     * Look up the session by its IP address. This means that we have no
282
260
     * destination-to-address binding properties.
283
 
     * 
284
 
     * Note: if the label needs to be made more specific (with e.g., SASL login
285
 
     * information), just append the text with vstring_sprintf_append().
286
261
     */
287
 
    vstring_sprintf(state->endp_label, SMTP_SCACHE_LABEL(NO_MX_LOOKUP),
288
 
                    state->service, addr, ntohs(port));
 
262
    smtp_key_prefix(state->endp_label, SMTP_REUSE_KEY_DELIM_NA,
 
263
                    state->iterator, endp_key_flags);
289
264
    if ((fd = scache_find_endp(smtp_scache, STR(state->endp_label),
290
265
                               state->endp_prop)) < 0)
291
266
        return (0);
298
273
     */
299
274
    session = smtp_reuse_common(state, fd, STR(state->endp_label));
300
275
 
301
 
    /*
302
 
     * XXX What if hostnames don't match (addr->name versus session->name),
303
 
     * or if the SASL login name for this host does not match the SASL login
304
 
     * name that was used when opening this session? If something depends
305
 
     * critically on such information being identical, then that information
306
 
     * should be included in the logical and physical labels under which a
307
 
     * session is cached.
308
 
     */
309
276
    return (session);
310
277
}