~ubuntu-branches/ubuntu/trusty/postfix/trusty-updates

« back to all changes in this revision

Viewing changes to src/smtpd/smtpd_peer.c

Tags: upstream-2.3.1
ImportĀ upstreamĀ versionĀ 2.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
/*      Where information is unavailable, the name and/or address
18
18
/*      are set to "unknown".
19
19
/*
 
20
/*      This module uses the local name service via getaddrinfo()
 
21
/*      and getnameinfo(). It does not query the DNS directly.
 
22
/*
20
23
/*      smtpd_peer_init() updates the following fields:
21
24
/* .IP name
22
 
/*      The client hostname. An unknown name is represented by the
23
 
/*      string "unknown".
 
25
/*      The verified client hostname. This name is represented by
 
26
/*      the string "unknown" when 1) the address->name lookup failed,
 
27
/*      2) the name->address mapping fails, or 3) the name->address
 
28
/*      does not produce the client IP address.
 
29
/* .IP reverse_name
 
30
/*      The unverified client hostname as found with address->name
 
31
/*      lookup; it is not verified for consistency with the client
 
32
/*      IP address result from name->address lookup.
 
33
/* .IP forward_name
 
34
/*      The unverified client hostname as found with address->name
 
35
/*      lookup followed by name->address lookup; it is not verified
 
36
/*      for consistency with the result from address->name lookup.
 
37
/*      For example, when the address->name lookup produces as
 
38
/*      hostname an alias, the name->address lookup will produce
 
39
/*      as hostname the expansion of that alias, so that the two
 
40
/*      lookups produce different names.
24
41
/* .IP addr
25
42
/*      Printable representation of the client address.
26
43
/* .IP namaddr
27
44
/*      String of the form: "name[addr]".
28
 
/* .IP peer_code
29
 
/*      The peer_code result field specifies how the client name
 
45
/* .IP rfc_addr
 
46
/*      String of the form "ipv4addr" or "ipv6:ipv6addr" for use
 
47
/*      in Received: message headers.
 
48
/* .IP name_status
 
49
/*      The name_status result field specifies how the name
30
50
/*      information should be interpreted:
31
51
/* .RS
32
52
/* .IP 2
33
 
/*      Both name lookup and name verification succeeded.
34
 
/* .IP 4
35
 
/*      The name lookup or name verification failed with a recoverable
36
 
/*      error (no address->name mapping or no name->address mapping).
37
 
/* .IP 5
38
 
/*      The name lookup or verification failed with an unrecoverable
39
 
/*      error (no address->name mapping, bad hostname syntax, no
40
 
/*      name->address mapping, client address not listed for hostname).
 
53
/*      The address->name lookup and name->address lookup produced
 
54
/*      the client IP address.
 
55
/* .IP 4
 
56
/*      The address->name lookup or name->address lookup failed
 
57
/*      with a recoverable error.
 
58
/* .IP 5
 
59
/*      The address->name lookup or name->address lookup failed
 
60
/*      with an unrecoverable error, or the result did not match
 
61
/*      the client IP address.
 
62
/* .RE
 
63
/* .IP reverse_name_status
 
64
/*      The reverse_name_status result field specifies how the
 
65
/*      reverse_name information should be interpreted:
 
66
/* .RS .IP 2
 
67
/*      The address->name lookup succeeded.
 
68
/* .IP 4
 
69
/*      The address->name lookup failed with a recoverable error.
 
70
/* .IP 5
 
71
/*      The address->name lookup failed with an unrecoverable error.
 
72
/* .RE .IP forward_name_status
 
73
/*      The forward_name_status result field specifies how the
 
74
/*      forward_name information should be interpreted:
 
75
/* .RS .IP 2
 
76
/*      The address->name and name->address lookup succeeded.
 
77
/* .IP 4
 
78
/*      The address->name lookup or name->address failed with a
 
79
/*      recoverable error.
 
80
/* .IP 5
 
81
/*      The address->name lookup or name->address failed with an
 
82
/*      unrecoverable error.
41
83
/* .RE
42
84
/* .PP
43
85
/*      smtpd_peer_reset() releases memory allocated by smtpd_peer_init().
76
118
 
77
119
#include <mail_proto.h>
78
120
#include <valid_mailhost_addr.h>
 
121
#include <mail_params.h>
79
122
 
80
123
/* Application-specific. */
81
124
 
85
128
 
86
129
void    smtpd_peer_init(SMTPD_STATE *state)
87
130
{
88
 
    char   *myname = "smtpd_peer_init";
89
 
    SOCKADDR_SIZE sa_len;
 
131
    const char *myname = "smtpd_peer_init";
 
132
    SOCKADDR_SIZE sa_length;
90
133
    struct sockaddr *sa;
91
134
    INET_PROTO_INFO *proto_info = inet_proto_info();
92
135
 
93
136
    sa = (struct sockaddr *) & (state->sockaddr);
94
 
    sa_len = sizeof(state->sockaddr);
 
137
    sa_length = sizeof(state->sockaddr);
95
138
 
96
139
    /*
97
140
     * Look up the peer address information.
 
141
     * 
 
142
     * XXX If we make local endpoint (getsockname) information available to
 
143
     * Milter applications as {if_name} and {if_addr}, then we also must be
 
144
     * able to provide this via the XCLIENT command for Milter testing.
 
145
     * 
 
146
     * XXX If support were to be added for Milter applications in down-stream
 
147
     * MTAs, then consistency demands that we propagate a lot of Sendmail
 
148
     * macro information via the XFORWARD command. Otherwise we could end up
 
149
     * with a very confusing situation.
98
150
     */
99
 
    if (getpeername(vstream_fileno(state->client), sa, &sa_len) >= 0) {
 
151
    if (getpeername(vstream_fileno(state->client), sa, &sa_length) >= 0) {
100
152
        errno = 0;
101
153
    }
102
154
 
105
157
     */
106
158
    if (errno == ECONNRESET || errno == ECONNABORTED) {
107
159
        state->name = mystrdup(CLIENT_NAME_UNKNOWN);
 
160
        state->reverse_name = mystrdup(CLIENT_NAME_UNKNOWN);
108
161
        state->addr = mystrdup(CLIENT_ADDR_UNKNOWN);
109
162
        state->rfc_addr = mystrdup(CLIENT_ADDR_UNKNOWN);
110
 
        state->peer_code = SMTPD_PEER_CODE_PERM;
 
163
        state->addr_family = AF_UNSPEC;
 
164
        state->name_status = SMTPD_PEER_CODE_PERM;
 
165
        state->reverse_name_status = SMTPD_PEER_CODE_PERM;
111
166
    }
112
167
 
113
168
    /*
121
176
        char   *colonp;
122
177
 
123
178
        /*
 
179
         * Sorry, but there are some things that we just cannot do while
 
180
         * connected to the network.
 
181
         */
 
182
        if (geteuid() != var_owner_uid || getuid() != var_owner_uid) {
 
183
            msg_error("incorrect SMTP server privileges: uid=%lu euid=%lu",
 
184
                      (unsigned long) getuid(), (unsigned long) geteuid());
 
185
            msg_fatal("the Postfix SMTP server must run with $%s privileges",
 
186
                      VAR_MAIL_OWNER);
 
187
        }
 
188
 
 
189
        /*
124
190
         * Convert the client address to printable form.
125
191
         */
126
 
        if ((aierr = sockaddr_to_hostaddr(sa, sa_len, &client_addr,
 
192
        if ((aierr = sockaddr_to_hostaddr(sa, sa_length, &client_addr,
127
193
                                          (MAI_SERVPORT_STR *) 0, 0)) != 0)
128
194
            msg_fatal("%s: cannot convert client address to string: %s",
129
195
                      myname, MAI_STRERROR(aierr));
147
213
 
148
214
                state->addr = mystrdup(colonp + 1);
149
215
                state->rfc_addr = mystrdup(colonp + 1);
 
216
                state->addr_family = AF_INET;
150
217
                aierr = hostaddr_to_sockaddr(state->addr, (char *) 0, 0, &res0);
151
218
                if (aierr)
152
219
                    msg_fatal("%s: cannot convert %s from string to binary: %s",
153
220
                              myname, state->addr, MAI_STRERROR(aierr));
154
 
                sa_len = res0->ai_addrlen;
155
 
                memcpy((char *) sa, res0->ai_addr, sa_len);
 
221
                sa_length = res0->ai_addrlen;
 
222
                if (sa_length > sizeof(state->sockaddr))
 
223
                    sa_length = sizeof(state->sockaddr);
 
224
                memcpy((char *) sa, res0->ai_addr, sa_length);
156
225
                freeaddrinfo(res0);             /* 200412 */
157
226
            }
158
227
 
168
237
                state->addr = mystrdup(client_addr.buf);
169
238
                state->rfc_addr =
170
239
                    concatenate(IPV6_COL, client_addr.buf, (char *) 0);
 
240
                state->addr_family = sa->sa_family;
171
241
            }
172
242
        }
173
243
 
179
249
        {
180
250
            state->addr = mystrdup(client_addr.buf);
181
251
            state->rfc_addr = mystrdup(client_addr.buf);
 
252
            state->addr_family = sa->sa_family;
182
253
        }
183
254
 
184
255
        /*
196
267
#define REJECT_PEER_NAME(state, code) { \
197
268
        myfree(state->name); \
198
269
        state->name = mystrdup(CLIENT_NAME_UNKNOWN); \
199
 
        state->peer_code = code; \
 
270
        state->name_status = code; \
200
271
    }
201
272
 
202
 
        if ((aierr = sockaddr_to_hostname(sa, sa_len, &client_name,
203
 
                                          (MAI_SERVNAME_STR *) 0, 0)) != 0) {
204
 
            state->name = mystrdup(CLIENT_NAME_UNKNOWN);
205
 
            state->peer_code = (TEMP_AI_ERROR(aierr) ?
206
 
                                SMTPD_PEER_CODE_TEMP : SMTPD_PEER_CODE_PERM);
 
273
        if (var_smtpd_peername_lookup == 0) {
 
274
            state->name = mystrdup(CLIENT_NAME_UNKNOWN);
 
275
            state->reverse_name = mystrdup(CLIENT_NAME_UNKNOWN);
 
276
            state->name_status = SMTPD_PEER_CODE_PERM;
 
277
            state->reverse_name_status = SMTPD_PEER_CODE_PERM;
 
278
        } else if ((aierr = sockaddr_to_hostname(sa, sa_length, &client_name,
 
279
                                         (MAI_SERVNAME_STR *) 0, 0)) != 0) {
 
280
            state->name = mystrdup(CLIENT_NAME_UNKNOWN);
 
281
            state->reverse_name = mystrdup(CLIENT_NAME_UNKNOWN);
 
282
            state->name_status = (TEMP_AI_ERROR(aierr) ?
 
283
                               SMTPD_PEER_CODE_TEMP : SMTPD_PEER_CODE_PERM);
 
284
            state->reverse_name_status = (TEMP_AI_ERROR(aierr) ?
 
285
                               SMTPD_PEER_CODE_TEMP : SMTPD_PEER_CODE_PERM);
207
286
        } else {
208
287
            struct addrinfo *res0;
209
288
            struct addrinfo *res;
210
289
 
211
290
            state->name = mystrdup(client_name.buf);
212
 
            state->peer_code = SMTPD_PEER_CODE_OK;
 
291
            state->reverse_name = mystrdup(client_name.buf);
 
292
            state->name_status = SMTPD_PEER_CODE_OK;
 
293
            state->reverse_name_status = SMTPD_PEER_CODE_OK;
213
294
 
214
295
            /*
215
296
             * Reject the hostname if it does not list the peer address.
 
297
             * Without further validation or qualification, such information
 
298
             * must not be allowed to enter the audit trail, as people would
 
299
             * draw false conclusions.
216
300
             */
217
301
            aierr = hostname_to_sockaddr(state->name, (char *) 0, 0, &res0);
218
302
            if (aierr) {
219
303
                msg_warn("%s: hostname %s verification failed: %s",
220
304
                         state->addr, state->name, MAI_STRERROR(aierr));
221
305
                REJECT_PEER_NAME(state, (TEMP_AI_ERROR(aierr) ?
222
 
                              SMTPD_PEER_CODE_TEMP : SMTPD_PEER_CODE_PERM));
 
306
                            SMTPD_PEER_CODE_TEMP : SMTPD_PEER_CODE_FORGED));
223
307
            } else {
224
308
                for (res = res0; /* void */ ; res = res->ai_next) {
225
309
                    if (res == 0) {
226
310
                        msg_warn("%s: address not listed for hostname %s",
227
311
                                 state->addr, state->name);
228
 
                        REJECT_PEER_NAME(state, SMTPD_PEER_CODE_PERM);
 
312
                        REJECT_PEER_NAME(state, SMTPD_PEER_CODE_FORGED);
229
313
                        break;
230
314
                    }
231
315
                    if (strchr((char *) proto_info->sa_family_list, res->ai_family) == 0) {
247
331
     */
248
332
    else {
249
333
        state->name = mystrdup("localhost");
 
334
        state->reverse_name = mystrdup("localhost");
250
335
        state->addr = mystrdup("127.0.0.1");    /* XXX bogus. */
251
336
        state->rfc_addr = mystrdup("127.0.0.1");/* XXX bogus. */
252
 
        state->peer_code = SMTPD_PEER_CODE_OK;
 
337
        state->addr_family = AF_UNSPEC;
 
338
        state->name_status = SMTPD_PEER_CODE_OK;
 
339
        state->reverse_name_status = SMTPD_PEER_CODE_OK;
253
340
    }
254
341
 
255
342
    /*
264
351
void    smtpd_peer_reset(SMTPD_STATE *state)
265
352
{
266
353
    myfree(state->name);
 
354
    myfree(state->reverse_name);
267
355
    myfree(state->addr);
268
356
    myfree(state->namaddr);
269
357
    myfree(state->rfc_addr);