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

« back to all changes in this revision

Viewing changes to src/mail/ngx_mail_proxy_module.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
 
60
61
      NULL },
61
62
 
62
63
    { ngx_string("proxy_pass_error_message"),
63
 
      NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
 
64
      NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
64
65
      ngx_conf_set_flag_slot,
65
66
      NGX_MAIL_SRV_CONF_OFFSET,
66
67
      offsetof(ngx_mail_proxy_conf_t, pass_error_message),
104
105
};
105
106
 
106
107
 
107
 
static u_char  smtp_ok[] = "235 2.0.0 OK" CRLF;
 
108
static u_char  smtp_auth_ok[] = "235 2.0.0 OK" CRLF;
108
109
 
109
110
 
110
111
void
111
 
ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_peer_addr_t *peer)
 
112
ngx_mail_proxy_init(ngx_mail_session_t *s, ngx_addr_t *peer)
112
113
{
113
114
    int                        keepalive;
114
115
    ngx_int_t                  rc;
201
202
 
202
203
    ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0, "mail proxy block read");
203
204
 
204
 
    if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
 
205
    if (ngx_handle_read_event(rev, 0) != NGX_OK) {
205
206
        c = rev->data;
206
207
        s = c->data;
207
208
 
253
254
        s->connection->log->action = "sending user name to upstream";
254
255
 
255
256
        line.len = sizeof("USER ")  - 1 + s->login.len + 2;
256
 
        line.data = ngx_palloc(c->pool, line.len);
 
257
        line.data = ngx_pnalloc(c->pool, line.len);
257
258
        if (line.data == NULL) {
258
259
            ngx_mail_proxy_internal_server_error(s);
259
260
            return;
272
273
        s->connection->log->action = "sending password to upstream";
273
274
 
274
275
        line.len = sizeof("PASS ")  - 1 + s->passwd.len + 2;
275
 
        line.data = ngx_palloc(c->pool, line.len);
 
276
        line.data = ngx_pnalloc(c->pool, line.len);
276
277
        if (line.data == NULL) {
277
278
            ngx_mail_proxy_internal_server_error(s);
278
279
            return;
304
305
 
305
306
    default:
306
307
#if (NGX_SUPPRESS_WARN)
307
 
        line.len = 0;
308
 
        line.data = NULL;
 
308
        ngx_str_null(&line);
309
309
#endif
310
310
        break;
311
311
    }
369
369
 
370
370
        line.len = s->tag.len + sizeof("LOGIN ") - 1
371
371
                   + 1 + NGX_SIZE_T_LEN + 1 + 2;
372
 
        line.data = ngx_palloc(c->pool, line.len);
 
372
        line.data = ngx_pnalloc(c->pool, line.len);
373
373
        if (line.data == NULL) {
374
374
            ngx_mail_proxy_internal_server_error(s);
375
375
            return;
388
388
        s->connection->log->action = "sending user name to upstream";
389
389
 
390
390
        line.len = s->login.len + 1 + 1 + NGX_SIZE_T_LEN + 1 + 2;
391
 
        line.data = ngx_palloc(c->pool, line.len);
 
391
        line.data = ngx_pnalloc(c->pool, line.len);
392
392
        if (line.data == NULL) {
393
393
            ngx_mail_proxy_internal_server_error(s);
394
394
            return;
408
408
        s->connection->log->action = "sending password to upstream";
409
409
 
410
410
        line.len = s->passwd.len + 2;
411
 
        line.data = ngx_palloc(c->pool, line.len);
 
411
        line.data = ngx_pnalloc(c->pool, line.len);
412
412
        if (line.data == NULL) {
413
413
            ngx_mail_proxy_internal_server_error(s);
414
414
            return;
439
439
 
440
440
    default:
441
441
#if (NGX_SUPPRESS_WARN)
442
 
        line.len = 0;
443
 
        line.data = NULL;
 
442
        ngx_str_null(&line);
444
443
#endif
445
444
        break;
446
445
    }
465
464
    u_char                    *p;
466
465
    ngx_int_t                  rc;
467
466
    ngx_str_t                  line;
 
467
    ngx_buf_t                 *b;
468
468
    ngx_connection_t          *c;
469
469
    ngx_mail_session_t        *s;
470
470
    ngx_mail_proxy_conf_t     *pcf;
505
505
        cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module);
506
506
 
507
507
        line.len = sizeof("HELO ")  - 1 + cscf->server_name.len + 2;
508
 
        line.data = ngx_palloc(c->pool, line.len);
 
508
        line.data = ngx_pnalloc(c->pool, line.len);
509
509
        if (line.data == NULL) {
510
510
            ngx_mail_proxy_internal_server_error(s);
511
511
            return;
520
520
        p = ngx_cpymem(p, cscf->server_name.data, cscf->server_name.len);
521
521
        *p++ = CR; *p = LF;
522
522
 
523
 
        s->mail_state = pcf->xclient ? ngx_smtp_helo: ngx_smtp_noxclient;
 
523
        if (pcf->xclient) {
 
524
            s->mail_state = ngx_smtp_helo_xclient;
 
525
 
 
526
        } else if (s->auth_method == NGX_MAIL_AUTH_NONE) {
 
527
            s->mail_state = ngx_smtp_helo_from;
 
528
 
 
529
        } else {
 
530
            s->mail_state = ngx_smtp_helo;
 
531
        }
524
532
 
525
533
        break;
526
534
 
527
 
    case ngx_smtp_helo:
 
535
    case ngx_smtp_helo_xclient:
528
536
        ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
529
537
                       "mail proxy send xclient");
530
538
 
531
539
        s->connection->log->action = "sending XCLIENT to upstream";
532
540
 
533
 
        line.len = sizeof("XCLIENT PROTO=SMTP HELO= ADDR= LOGIN= NAME="
 
541
        line.len = sizeof("XCLIENT ADDR= LOGIN= NAME="
534
542
                          CRLF) - 1
535
 
                   + s->esmtp + s->smtp_helo.len
536
543
                   + s->connection->addr_text.len + s->login.len + s->host.len;
537
544
 
538
 
        line.data = ngx_palloc(c->pool, line.len);
 
545
        line.data = ngx_pnalloc(c->pool, line.len);
539
546
        if (line.data == NULL) {
540
547
            ngx_mail_proxy_internal_server_error(s);
541
548
            return;
542
549
        }
543
550
 
 
551
        line.len = ngx_sprintf(line.data,
 
552
                       "XCLIENT ADDR=%V%s%V NAME=%V" CRLF,
 
553
                       &s->connection->addr_text,
 
554
                       (s->login.len ? " LOGIN=" : ""), &s->login, &s->host)
 
555
                   - line.data;
 
556
 
544
557
        if (s->smtp_helo.len) {
545
 
            line.len = ngx_sprintf(line.data,
546
 
                           "XCLIENT PROTO=%sSMTP HELO=%V ADDR=%V LOGIN=%V "
547
 
                           "NAME=%V" CRLF,
548
 
                           (s->esmtp ? "E" : ""), &s->smtp_helo,
549
 
                           &s->connection->addr_text, &s->login, &s->host)
550
 
                       - line.data;
 
558
            s->mail_state = ngx_smtp_xclient_helo;
 
559
 
 
560
        } else if (s->auth_method == NGX_MAIL_AUTH_NONE) {
 
561
            s->mail_state = ngx_smtp_xclient_from;
 
562
 
551
563
        } else {
552
 
            line.len = ngx_sprintf(line.data,
553
 
                           "XCLIENT PROTO=SMTP ADDR=%V LOGIN=%V NAME=%V" CRLF,
554
 
                           &s->connection->addr_text, &s->login, &s->host)
555
 
                       - line.data;
556
 
        }
557
 
 
558
 
        s->mail_state = ngx_smtp_xclient;
559
 
        break;
560
 
 
561
 
    case ngx_smtp_noxclient:
 
564
            s->mail_state = ngx_smtp_xclient;
 
565
        }
 
566
 
 
567
        break;
 
568
 
 
569
    case ngx_smtp_xclient_helo:
 
570
        ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
 
571
                       "mail proxy send client ehlo");
 
572
 
 
573
        s->connection->log->action = "sending client HELO/EHLO to upstream";
 
574
 
 
575
        line.len = sizeof("HELO " CRLF) - 1 + s->smtp_helo.len;
 
576
 
 
577
        line.data = ngx_pnalloc(c->pool, line.len);
 
578
        if (line.data == NULL) {
 
579
            ngx_mail_proxy_internal_server_error(s);
 
580
            return;
 
581
        }
 
582
 
 
583
        line.len = ngx_sprintf(line.data,
 
584
                       ((s->esmtp) ? "EHLO %V" CRLF : "HELO %V" CRLF),
 
585
                       &s->smtp_helo)
 
586
                   - line.data;
 
587
 
 
588
        s->mail_state = (s->auth_method == NGX_MAIL_AUTH_NONE) ?
 
589
                            ngx_smtp_helo_from : ngx_smtp_helo;
 
590
 
 
591
        break;
 
592
 
 
593
    case ngx_smtp_helo_from:
 
594
    case ngx_smtp_xclient_from:
 
595
        ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
 
596
                       "mail proxy send mail from");
 
597
 
 
598
        s->connection->log->action = "sending MAIL FROM to upstream";
 
599
 
 
600
        line.len = s->smtp_from.len + sizeof(CRLF) - 1;
 
601
        line.data = ngx_pnalloc(c->pool, line.len);
 
602
        if (line.data == NULL) {
 
603
            ngx_mail_proxy_internal_server_error(s);
 
604
            return;
 
605
        }
 
606
 
 
607
        p = ngx_cpymem(line.data, s->smtp_from.data, s->smtp_from.len);
 
608
        *p++ = CR; *p = LF;
 
609
 
 
610
        s->mail_state = ngx_smtp_from;
 
611
 
 
612
        break;
 
613
 
 
614
    case ngx_smtp_from:
 
615
        ngx_log_debug0(NGX_LOG_DEBUG_MAIL, rev->log, 0,
 
616
                       "mail proxy send rcpt to");
 
617
 
 
618
        s->connection->log->action = "sending RCPT TO to upstream";
 
619
 
 
620
        line.len = s->smtp_to.len + sizeof(CRLF) - 1;
 
621
        line.data = ngx_pnalloc(c->pool, line.len);
 
622
        if (line.data == NULL) {
 
623
            ngx_mail_proxy_internal_server_error(s);
 
624
            return;
 
625
        }
 
626
 
 
627
        p = ngx_cpymem(line.data, s->smtp_to.data, s->smtp_to.len);
 
628
        *p++ = CR; *p = LF;
 
629
 
 
630
        s->mail_state = ngx_smtp_to;
 
631
 
 
632
        break;
 
633
 
 
634
    case ngx_smtp_helo:
562
635
    case ngx_smtp_xclient:
563
 
 
564
 
        ngx_memcpy(s->proxy->buffer->start, smtp_ok, sizeof(smtp_ok) - 1);
565
 
 
566
 
        s->proxy->buffer->pos = s->proxy->buffer->start;
567
 
        s->proxy->buffer->last = s->proxy->buffer->start + sizeof(smtp_ok) - 1;
 
636
    case ngx_smtp_to:
 
637
 
 
638
        b = s->proxy->buffer;
 
639
 
 
640
        if (s->auth_method == NGX_MAIL_AUTH_NONE) {
 
641
            b->pos = b->start;
 
642
 
 
643
        } else {
 
644
            ngx_memcpy(b->start, smtp_auth_ok, sizeof(smtp_auth_ok) - 1);
 
645
            b->last = b->start + sizeof(smtp_auth_ok) - 1;
 
646
        }
568
647
 
569
648
        s->connection->read->handler = ngx_mail_proxy_handler;
570
649
        s->connection->write->handler = ngx_mail_proxy_handler;
584
663
 
585
664
    default:
586
665
#if (NGX_SUPPRESS_WARN)
587
 
        line.len = 0;
588
 
        line.data = NULL;
 
666
        ngx_str_null(&line);
589
667
#endif
590
668
        break;
591
669
    }
612
690
 
613
691
    ngx_log_debug0(NGX_LOG_DEBUG_MAIL, wev->log, 0, "mail proxy dummy handler");
614
692
 
615
 
    if (ngx_handle_write_event(wev, 0) == NGX_ERROR) {
 
693
    if (ngx_handle_write_event(wev, 0) != NGX_OK) {
616
694
        c = wev->data;
617
695
        s = c->data;
618
696
 
646
724
 
647
725
    b->last += n;
648
726
 
649
 
    if (b->last - b->pos < 5) {
 
727
    if (b->last - b->pos < 4) {
650
728
        return NGX_AGAIN;
651
729
    }
652
730
 
703
781
    default: /* NGX_MAIL_SMTP_PROTOCOL */
704
782
        switch (state) {
705
783
 
 
784
        case ngx_smtp_start:
 
785
            if (p[0] == '2' && p[1] == '2' && p[2] == '0') {
 
786
                return NGX_OK;
 
787
            }
 
788
            break;
 
789
 
706
790
        case ngx_smtp_helo:
707
 
        case ngx_smtp_noxclient:
 
791
        case ngx_smtp_helo_xclient:
 
792
        case ngx_smtp_helo_from:
 
793
        case ngx_smtp_from:
708
794
            if (p[0] == '2' && p[1] == '5' && p[2] == '0') {
709
795
                return NGX_OK;
710
796
            }
711
797
            break;
712
798
 
713
 
        case ngx_smtp_start:
714
799
        case ngx_smtp_xclient:
715
 
            if (p[0] == '2' && p[1] == '2' && p[2] == '0') {
 
800
        case ngx_smtp_xclient_from:
 
801
        case ngx_smtp_xclient_helo:
 
802
            if (p[0] == '2' && (p[1] == '2' || p[1] == '5') && p[2] == '0') {
716
803
                return NGX_OK;
717
804
            }
718
805
            break;
 
806
 
 
807
        case ngx_smtp_to:
 
808
            return NGX_OK;
719
809
        }
720
810
 
721
811
        break;
884
974
        return;
885
975
    }
886
976
 
887
 
    if (ngx_handle_write_event(dst->write, 0) == NGX_ERROR) {
888
 
        ngx_mail_proxy_close_session(s);
889
 
        return;
890
 
    }
891
 
 
892
 
    if (ngx_handle_read_event(dst->read, 0) == NGX_ERROR) {
893
 
        ngx_mail_proxy_close_session(s);
894
 
        return;
895
 
    }
896
 
 
897
 
    if (ngx_handle_write_event(src->write, 0) == NGX_ERROR) {
898
 
        ngx_mail_proxy_close_session(s);
899
 
        return;
900
 
    }
901
 
 
902
 
    if (ngx_handle_read_event(src->read, 0) == NGX_ERROR) {
 
977
    if (ngx_handle_write_event(dst->write, 0) != NGX_OK) {
 
978
        ngx_mail_proxy_close_session(s);
 
979
        return;
 
980
    }
 
981
 
 
982
    if (ngx_handle_read_event(dst->read, 0) != NGX_OK) {
 
983
        ngx_mail_proxy_close_session(s);
 
984
        return;
 
985
    }
 
986
 
 
987
    if (ngx_handle_write_event(src->write, 0) != NGX_OK) {
 
988
        ngx_mail_proxy_close_session(s);
 
989
        return;
 
990
    }
 
991
 
 
992
    if (ngx_handle_read_event(src->read, 0) != NGX_OK) {
903
993
        ngx_mail_proxy_close_session(s);
904
994
        return;
905
995
    }
969
1059
 
970
1060
    pcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_proxy_conf_t));
971
1061
    if (pcf == NULL) {
972
 
        return NGX_CONF_ERROR;
 
1062
        return NULL;
973
1063
    }
974
1064
 
975
1065
    pcf->enable = NGX_CONF_UNSET;