~ubuntu-branches/ubuntu/trusty/nginx/trusty-proposed

« back to all changes in this revision

Viewing changes to src/mail/ngx_mail_handler.c

  • Committer: Package Import Robot
  • Author(s): Kartik Mistry
  • Date: 2013-04-25 12:51:45 UTC
  • mfrom: (1.3.28)
  • mto: (1.3.29) (15.1.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 64.
  • Revision ID: package-import@ubuntu.com-20130425125145-ugl0wor6bq0u5eae
Tags: upstream-1.4.0
ImportĀ upstreamĀ versionĀ 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 
2
2
/*
3
3
 * Copyright (C) Igor Sysoev
 
4
 * Copyright (C) Nginx, Inc.
4
5
 */
5
6
 
6
7
 
21
22
void
22
23
ngx_mail_init_connection(ngx_connection_t *c)
23
24
{
24
 
    in_addr_t             in_addr;
25
 
    socklen_t             len;
26
 
    ngx_uint_t            i;
27
 
    struct sockaddr_in    sin;
28
 
    ngx_mail_log_ctx_t   *ctx;
29
 
    ngx_mail_in_port_t   *imip;
30
 
    ngx_mail_in_addr_t   *imia;
31
 
    ngx_mail_session_t   *s;
 
25
    ngx_uint_t             i;
 
26
    ngx_mail_port_t       *port;
 
27
    struct sockaddr       *sa;
 
28
    struct sockaddr_in    *sin;
 
29
    ngx_mail_log_ctx_t    *ctx;
 
30
    ngx_mail_in_addr_t    *addr;
 
31
    ngx_mail_session_t    *s;
 
32
    ngx_mail_addr_conf_t  *addr_conf;
 
33
#if (NGX_HAVE_INET6)
 
34
    struct sockaddr_in6   *sin6;
 
35
    ngx_mail_in6_addr_t   *addr6;
 
36
#endif
 
37
 
32
38
 
33
39
    /* find the server configuration for the address:port */
34
40
 
35
 
    /* AF_INET only */
36
 
 
37
 
    imip = c->listening->servers;
38
 
    imia = imip->addrs;
39
 
 
40
 
    i = 0;
41
 
 
42
 
    if (imip->naddrs > 1) {
 
41
    port = c->listening->servers;
 
42
 
 
43
    if (port->naddrs > 1) {
43
44
 
44
45
        /*
45
46
         * There are several addresses on this port and one of them
49
50
         * AcceptEx() already gave this address.
50
51
         */
51
52
 
52
 
#if (NGX_WIN32)
53
 
        if (c->local_sockaddr) {
54
 
            in_addr =
55
 
                   ((struct sockaddr_in *) c->local_sockaddr)->sin_addr.s_addr;
56
 
 
57
 
        } else
58
 
#endif
59
 
        {
60
 
            len = sizeof(struct sockaddr_in);
61
 
            if (getsockname(c->fd, (struct sockaddr *) &sin, &len) == -1) {
62
 
                ngx_connection_error(c, ngx_socket_errno,
63
 
                                     "getsockname() failed");
64
 
                ngx_mail_close_connection(c);
65
 
                return;
66
 
            }
67
 
 
68
 
            in_addr = sin.sin_addr.s_addr;
69
 
        }
70
 
 
71
 
        /* the last address is "*" */
72
 
 
73
 
        for ( /* void */ ; i < imip->naddrs - 1; i++) {
74
 
            if (in_addr == imia[i].addr) {
75
 
                break;
76
 
            }
 
53
        if (ngx_connection_local_sockaddr(c, NULL, 0) != NGX_OK) {
 
54
            ngx_mail_close_connection(c);
 
55
            return;
 
56
        }
 
57
 
 
58
        sa = c->local_sockaddr;
 
59
 
 
60
        switch (sa->sa_family) {
 
61
 
 
62
#if (NGX_HAVE_INET6)
 
63
        case AF_INET6:
 
64
            sin6 = (struct sockaddr_in6 *) sa;
 
65
 
 
66
            addr6 = port->addrs;
 
67
 
 
68
            /* the last address is "*" */
 
69
 
 
70
            for (i = 0; i < port->naddrs - 1; i++) {
 
71
                if (ngx_memcmp(&addr6[i].addr6, &sin6->sin6_addr, 16) == 0) {
 
72
                    break;
 
73
                }
 
74
            }
 
75
 
 
76
            addr_conf = &addr6[i].conf;
 
77
 
 
78
            break;
 
79
#endif
 
80
 
 
81
        default: /* AF_INET */
 
82
            sin = (struct sockaddr_in *) sa;
 
83
 
 
84
            addr = port->addrs;
 
85
 
 
86
            /* the last address is "*" */
 
87
 
 
88
            for (i = 0; i < port->naddrs - 1; i++) {
 
89
                if (addr[i].addr == sin->sin_addr.s_addr) {
 
90
                    break;
 
91
                }
 
92
            }
 
93
 
 
94
            addr_conf = &addr[i].conf;
 
95
 
 
96
            break;
 
97
        }
 
98
 
 
99
    } else {
 
100
        switch (c->local_sockaddr->sa_family) {
 
101
 
 
102
#if (NGX_HAVE_INET6)
 
103
        case AF_INET6:
 
104
            addr6 = port->addrs;
 
105
            addr_conf = &addr6[0].conf;
 
106
            break;
 
107
#endif
 
108
 
 
109
        default: /* AF_INET */
 
110
            addr = port->addrs;
 
111
            addr_conf = &addr[0].conf;
 
112
            break;
77
113
        }
78
114
    }
79
115
 
80
 
 
81
116
    s = ngx_pcalloc(c->pool, sizeof(ngx_mail_session_t));
82
117
    if (s == NULL) {
83
118
        ngx_mail_close_connection(c);
84
119
        return;
85
120
    }
86
121
 
87
 
    s->main_conf = imia[i].ctx->main_conf;
88
 
    s->srv_conf = imia[i].ctx->srv_conf;
 
122
    s->main_conf = addr_conf->ctx->main_conf;
 
123
    s->srv_conf = addr_conf->ctx->srv_conf;
89
124
 
90
 
    s->addr_text = &imia[i].addr_text;
 
125
    s->addr_text = &addr_conf->addr_text;
91
126
 
92
127
    c->data = s;
93
128
    s->connection = c;
118
153
    sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
119
154
 
120
155
    if (sslcf->enable) {
121
 
        ngx_mail_ssl_init_connection(&sslcf->ssl, c);
122
 
        return;
123
 
    }
 
156
        c->log->action = "SSL handshaking";
 
157
 
 
158
        ngx_mail_ssl_init_connection(&sslcf->ssl, c);
 
159
        return;
 
160
    }
 
161
 
 
162
    if (addr_conf->ssl) {
 
163
 
 
164
        c->log->action = "SSL handshaking";
 
165
 
 
166
        if (sslcf->ssl.ctx == NULL) {
 
167
            ngx_log_error(NGX_LOG_ERR, c->log, 0,
 
168
                          "no \"ssl_certificate\" is defined "
 
169
                          "in server listening on SSL port");
 
170
            ngx_mail_close_connection(c);
 
171
            return;
 
172
        }
 
173
 
 
174
        ngx_mail_ssl_init_connection(&sslcf->ssl, c);
 
175
        return;
 
176
    }
 
177
 
124
178
    }
125
179
#endif
126
180
 
198
252
            return;
199
253
        }
200
254
 
 
255
        c->read->ready = 0;
 
256
 
201
257
        ngx_mail_init_session(c);
202
258
        return;
203
259
    }
236
292
ngx_mail_salt(ngx_mail_session_t *s, ngx_connection_t *c,
237
293
    ngx_mail_core_srv_conf_t *cscf)
238
294
{
239
 
    s->salt.data = ngx_palloc(c->pool,
240
 
                              sizeof(" <18446744073709551616.@>" CRLF) - 1
241
 
                              + NGX_TIME_T_LEN
242
 
                              + cscf->server_name.len);
 
295
    s->salt.data = ngx_pnalloc(c->pool,
 
296
                               sizeof(" <18446744073709551616.@>" CRLF) - 1
 
297
                               + NGX_TIME_T_LEN
 
298
                               + cscf->server_name.len);
243
299
    if (s->salt.data == NULL) {
244
300
        return NGX_ERROR;
245
301
    }
288
344
                   "mail auth plain: \"%V\"", &arg[n]);
289
345
#endif
290
346
 
291
 
    plain.data = ngx_palloc(c->pool, ngx_base64_decoded_length(arg[n].len));
292
 
    if (plain.data == NULL){
 
347
    plain.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len));
 
348
    if (plain.data == NULL) {
293
349
        return NGX_ERROR;
294
350
    }
295
351
 
335
391
 
336
392
 
337
393
ngx_int_t
338
 
ngx_mail_auth_login_username(ngx_mail_session_t *s, ngx_connection_t *c)
 
394
ngx_mail_auth_login_username(ngx_mail_session_t *s, ngx_connection_t *c,
 
395
    ngx_uint_t n)
339
396
{
340
397
    ngx_str_t  *arg;
341
398
 
342
399
    arg = s->args.elts;
343
400
 
344
401
    ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
345
 
                   "mail auth login username: \"%V\"", &arg[0]);
 
402
                   "mail auth login username: \"%V\"", &arg[n]);
346
403
 
347
 
    s->login.data = ngx_palloc(c->pool, ngx_base64_decoded_length(arg[0].len));
348
 
    if (s->login.data == NULL){
 
404
    s->login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len));
 
405
    if (s->login.data == NULL) {
349
406
        return NGX_ERROR;
350
407
    }
351
408
 
352
 
    if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) {
 
409
    if (ngx_decode_base64(&s->login, &arg[n]) != NGX_OK) {
353
410
        ngx_log_error(NGX_LOG_INFO, c->log, 0,
354
411
            "client sent invalid base64 encoding in AUTH LOGIN command");
355
412
        return NGX_MAIL_PARSE_INVALID_COMMAND;
374
431
                   "mail auth login password: \"%V\"", &arg[0]);
375
432
#endif
376
433
 
377
 
    s->passwd.data = ngx_palloc(c->pool, ngx_base64_decoded_length(arg[0].len));
378
 
    if (s->passwd.data == NULL){
 
434
    s->passwd.data = ngx_pnalloc(c->pool,
 
435
                                 ngx_base64_decoded_length(arg[0].len));
 
436
    if (s->passwd.data == NULL) {
379
437
        return NGX_ERROR;
380
438
    }
381
439
 
402
460
    ngx_str_t    salt;
403
461
    ngx_uint_t   n;
404
462
 
405
 
    p = ngx_palloc(c->pool, len + ngx_base64_encoded_length(s->salt.len) + 2);
 
463
    p = ngx_pnalloc(c->pool, len + ngx_base64_encoded_length(s->salt.len) + 2);
406
464
    if (p == NULL) {
407
465
        return NGX_ERROR;
408
466
    }
434
492
    ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
435
493
                   "mail auth cram-md5: \"%V\"", &arg[0]);
436
494
 
437
 
    s->login.data = ngx_palloc(c->pool, ngx_base64_decoded_length(arg[0].len));
438
 
    if (s->login.data == NULL){
 
495
    s->login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[0].len));
 
496
    if (s->login.data == NULL) {
439
497
        return NGX_ERROR;
440
498
    }
441
499
 
491
549
    }
492
550
 
493
551
    if (s->out.len == 0) {
494
 
        if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
 
552
        if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
495
553
            ngx_mail_close_connection(c);
496
554
        }
497
555
 
530
588
 
531
589
    ngx_add_timer(c->write, cscf->timeout);
532
590
 
533
 
    if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
 
591
    if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
534
592
        ngx_mail_close_connection(c);
535
593
        return;
536
594
    }
557
615
    }
558
616
 
559
617
    if (n == NGX_AGAIN) {
560
 
        if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
 
618
        if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
561
619
            ngx_mail_session_internal_server_error(s);
562
620
            return NGX_ERROR;
563
621
        }
651
709
#endif
652
710
 
653
711
#if (NGX_STAT_STUB)
654
 
    ngx_atomic_fetch_add(ngx_stat_active, -1);
 
712
    (void) ngx_atomic_fetch_add(ngx_stat_active, -1);
655
713
#endif
656
714
 
657
715
    c->destroyed = 1;