~ubuntu-dev/ubuntu/lucid/dovecot/lucid-201002110912

« back to all changes in this revision

Viewing changes to src/deliver/mail-send.c

  • Committer: Chuck Short
  • Date: 2010-01-21 20:21:25 UTC
  • mfrom: (4.1.11 squeeze)
  • Revision ID: zulcss@ubuntu.com-20100121202125-pme73o491kfwj5nc
* Merge from debian testing, remaining changes:
  + Add new binary pkg dovecot-postfix that integrates postfix and dovecot
    automatically: (LP: #164837)
  + debian/control:
    - add new binary with short description
    - set Architecture all for dovecot-postfix (LP: #329878)
  + debian/dovecot-postfix.postinst:
    - create initial certificate symlinks to snakeoil.
    - set up postfix with postconf to:
      - use Maildir/ as the default mailbox.
      - use dovecot as the sasl authentication server.
      - use dovecot LDA (deliver).
      - use tls for smtp{d} services.
    - fix certificates paths in postfix' main.cf
    - add reject_unauth_destination to postfix' recipient restrictions
    - add reject_unknown_sender_domain to postfix' sender restriction
    - rename configuration name on remove, delete on purge
    - restart dovecot after linking certificates
    - handle use case when postfix is unconfigurated
  + debian/dovecot-postfix.dirs: create backup directory for postfix's config
    configuration
  + restart postfix and dovecot.
  + debian/dovecot-postfix.postrm:
    - remove all dovecot related configuration from postfix.
    - restart postfix and dovecot.
  + debian/dovecot-common.init:
    - check if /etc/dovecot/dovecot-postfix.conf exists and use it
      as the configuration file if so.
  + debian/patches/warning-ubuntu-postfix.dpatch
    - add warning about dovecot-postfix.conf in dovecot default
      configuration file
  + debian/patches/dovecot-postfix.conf.diff:
    - Ubuntu server custom changes to the default dovecot configuration for
      better interfation with postfix.
    - enable sieve plugin.
    - Ubuntu server custom changes to the default dovecot configuration for
      better integration with postfix:
      - enable imap, pop3, imaps, pop3s and managesieve by default.
      - enable dovecot LDA (deliver).
      - enable SASL auth socket in postfix private directory
   + debian/rules:
     - copy, patch and install dovecot-postfix.conf in /etc/dovecot/.
     - build architecure independent packages too
   + Use Snakeoil SSL certificates by default.
     - debian/control: Depend on ssl-cert.
     - debian/patches/ssl-cert-snakeoil.dpatch: Change default SSL cert
       paths to snakeoil.
     - debian/dovecot-common.postinst: Relax grep for SSL_* a bit.
   + Add autopkgtest to debian/tests/*.
   + Fast TearDown: Update the lsb init header to not stop in level 6.
   + Add ufw integration:
     - Created debian/dovecot-common.ufw.profile.
     - debian/rules: install profile.
     - debian/control: suggest ufw.
   + debian/{control,rules}: enable PIE hardening.
   + dovecot-imapd, dovecot-pop3: Replaces dovecot-common (<< 1:1.1). (LP: #254721)
   + debian/control: Update Vcs-* headers.
   + Add SMTP-AUTH support for Outlook (login auth mechanism)
* New upstream release.
* debian/patches/gold-fix.patch: Removed. Fixed upstream.
* Moved libexec to lib corrections in dovecot-managesieve.patch and
  dovecot-managesieve-dist.patch to dovecot-example.patch
* debian/patches/dovecot-mboxlocking.patch: Regenerated to avoid FTBFS
  when quilt isn't installed.
* debian/patches/quota-mountpoint.patch: Removed. Not needed anymore.
* debian/patches/dovecot-quota.patch: Removed. Quotas aren't properly
  enabled unless mail_plugins = quota imap_quota.
* debian/patches/gold-fix.patch: Fixed configure script to build even
  with binutils-gold or --no-add-needed linker flag (Closes: #554306)
* debian/dovecot-common.init: fixed LSB headers. Thanks to Pascal Volk.
  (Closes: #558040)
* debian/changelog: added CVE references to previous changelog entry.
* debian/rules: checked up the build system. It's not fragile anymore.
  (Closes: 493803)
* debian/dovecot-common.postinst: Now invoking dpkg-reconfigure
  on dovecot-common is enough to generate new certificates
  if the previous ones were removed. (Closes: #545582)
* debian/rules: No longer install convert-tool in /usr/bin.
  It isn't an user utility and it should stay in /usr/lib/dovecot
  like all other similar tool.
* New upstream release. (Closes: #557601)
* [SECURITY] Fixes local information disclosure and denial of service.
  (see: http://www.dovecot.org/list/dovecot-news/2009-November/000143.html
  and CVE-2009-3897)
* Added myself to uploaders.
* Switched to the new source format "3.0 (quilt)":
  - removed dpatch from build-depends
  - removed debian/README.source because now we use only standard
    dpkg features
  - regenerated all patches
* Prepared to switch to multi-origin source:
  - recreated dovecot-libsieve.patch and dovecot-managesieve-dist.patch
    starting from the upstream tarball
  - removed all autotools related build-depends and build-conflict
  - renamed dovecot-libsieve and dovecot-managesieve directories
    to libsieve and managesieve.
* debian/rules: Moved the configuration of libsieve and managesieve from
  the build phase to the configuration phase
* Added dovecot-dbg package  with debugging symbols.  Thanks Stephan Bosch.
  (Closes: #554710)
* Fixed some stray libexec'isms in the default configuration.
* New upstream release.
* debian/dovecot-common.init:
  - use $CONF when starting the daemon. (Closes: #549944)
  - always output start/stop messages. (Closes: #523810)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2005-2009 Dovecot authors, see the included COPYING file */
2
 
 
3
 
#include "lib.h"
4
 
#include "ioloop.h"
5
 
#include "hostpid.h"
6
 
#include "istream.h"
7
 
#include "str.h"
8
 
#include "str-sanitize.h"
9
 
#include "var-expand.h"
10
 
#include "message-date.h"
11
 
#include "message-size.h"
12
 
#include "duplicate.h"
13
 
#include "istream-header-filter.h"
14
 
#include "smtp-client.h"
15
 
#include "deliver.h"
16
 
#include "mail-send.h"
17
 
 
18
 
#include <stdlib.h>
19
 
#include <sys/wait.h>
20
 
 
21
 
int global_outgoing_count = 0;
22
 
 
23
 
static const struct var_expand_table *
24
 
get_var_expand_table(struct mail *mail, const char *reason,
25
 
                     const char *recipient)
26
 
{
27
 
        static struct var_expand_table static_tab[] = {
28
 
                { 'n', NULL, "crlf" },
29
 
                { 'r', NULL, "reason" },
30
 
                { 's', NULL, "subject" },
31
 
                { 't', NULL, "to" },
32
 
                { '\0', NULL, NULL }
33
 
        };
34
 
        struct var_expand_table *tab;
35
 
        const char *subject;
36
 
 
37
 
        tab = t_malloc(sizeof(static_tab));
38
 
        memcpy(tab, static_tab, sizeof(static_tab));
39
 
 
40
 
        tab[0].value = "\r\n";
41
 
        tab[1].value = reason;
42
 
        if (mail_get_first_header(mail, "Subject", &subject) <= 0)
43
 
                subject = "";
44
 
        tab[2].value = str_sanitize(subject, 80);
45
 
        tab[3].value = recipient;
46
 
 
47
 
        return tab;
48
 
}
49
 
 
50
 
int mail_send_rejection(struct mail *mail, const char *recipient,
51
 
                        const char *reason)
52
 
{
53
 
    struct istream *input;
54
 
    struct smtp_client *smtp_client;
55
 
    FILE *f;
56
 
    struct message_size hdr_size;
57
 
    const char *return_addr, *hdr;
58
 
    const unsigned char *data;
59
 
    const char *value, *msgid, *orig_msgid, *boundary;
60
 
    string_t *str;
61
 
    size_t size;
62
 
    int ret;
63
 
 
64
 
    if (mail_get_first_header(mail, "Auto-Submitted", &value) > 0 &&
65
 
        strcasecmp(value, "no") != 0) {
66
 
            i_info("msgid=%s: Auto-submitted message discarded: %s",
67
 
                   orig_msgid == NULL ? "" : str_sanitize(orig_msgid, 80),
68
 
                   str_sanitize(reason, 512));
69
 
            return 0;
70
 
    }
71
 
 
72
 
    if (mail_get_first_header(mail, "Message-ID", &orig_msgid) < 0)
73
 
            orig_msgid = NULL;
74
 
    return_addr = deliver_get_return_address(mail);
75
 
    if (return_addr == NULL) {
76
 
            i_info("msgid=%s: Return-Path missing, rejection reason: %s",
77
 
                   orig_msgid == NULL ? "" : str_sanitize(orig_msgid, 80),
78
 
                   str_sanitize(reason, 512));
79
 
            return 0;
80
 
    }
81
 
 
82
 
    if (getenv("DEBUG") != NULL) {
83
 
            i_info("Sending a rejection to %s: %s", recipient,
84
 
                   str_sanitize(reason, 512));
85
 
    }
86
 
 
87
 
    smtp_client = smtp_client_open(return_addr, NULL, &f);
88
 
 
89
 
    msgid = deliver_get_new_message_id();
90
 
    boundary = t_strdup_printf("%s/%s", my_pid, deliver_set->hostname);
91
 
 
92
 
    fprintf(f, "Message-ID: %s\r\n", msgid);
93
 
    fprintf(f, "Date: %s\r\n", message_date_create(ioloop_time));
94
 
    fprintf(f, "From: Mail Delivery Subsystem <%s>\r\n",
95
 
            deliver_set->postmaster_address);
96
 
    fprintf(f, "To: <%s>\r\n", return_addr);
97
 
    fprintf(f, "MIME-Version: 1.0\r\n");
98
 
    fprintf(f, "Content-Type: "
99
 
            "multipart/report; report-type=disposition-notification;\r\n"
100
 
            "\tboundary=\"%s\"\r\n", boundary);
101
 
 
102
 
    str = t_str_new(256);
103
 
    var_expand(str, deliver_set->rejection_subject,
104
 
               get_var_expand_table(mail, reason, recipient));
105
 
    fprintf(f, "Subject: %s\r\n", str_c(str));
106
 
 
107
 
    fprintf(f, "Auto-Submitted: auto-replied (rejected)\r\n");
108
 
    fprintf(f, "Precedence: bulk\r\n");
109
 
    fprintf(f, "\r\nThis is a MIME-encapsulated message\r\n\r\n");
110
 
 
111
 
    /* human readable status report */
112
 
    fprintf(f, "--%s\r\n", boundary);
113
 
    fprintf(f, "Content-Type: text/plain; charset=utf-8\r\n");
114
 
    fprintf(f, "Content-Disposition: inline\r\n");
115
 
    fprintf(f, "Content-Transfer-Encoding: 8bit\r\n\r\n");
116
 
 
117
 
    str_truncate(str, 0);
118
 
    var_expand(str, deliver_set->rejection_reason,
119
 
               get_var_expand_table(mail, reason, recipient));
120
 
    fprintf(f, "%s\r\n", str_c(str));
121
 
 
122
 
    /* MDN status report */
123
 
    fprintf(f, "--%s\r\n"
124
 
            "Content-Type: message/disposition-notification\r\n\r\n",
125
 
            boundary);
126
 
    fprintf(f, "Reporting-UA: %s; Dovecot Mail Delivery Agent\r\n",
127
 
            deliver_set->hostname);
128
 
    if (mail_get_first_header(mail, "Original-Recipient", &hdr) > 0)
129
 
            fprintf(f, "Original-Recipient: rfc822; %s\r\n", hdr);
130
 
    fprintf(f, "Final-Recipient: rfc822; %s\r\n", recipient);
131
 
 
132
 
    if (orig_msgid != NULL)
133
 
        fprintf(f, "Original-Message-ID: %s\r\n", orig_msgid);
134
 
    fprintf(f, "Disposition: "
135
 
            "automatic-action/MDN-sent-automatically; deleted\r\n");
136
 
    fprintf(f, "\r\n");
137
 
 
138
 
    /* original message's headers */
139
 
    fprintf(f, "--%s\r\nContent-Type: message/rfc822\r\n\r\n", boundary);
140
 
 
141
 
    if (mail_get_stream(mail, &hdr_size, NULL, &input) == 0) {
142
 
            /* Note: If you add more headers, they need to be sorted.
143
 
               We'll drop Content-Type because we're not including the message
144
 
               body, and having a multipart Content-Type may confuse some
145
 
               MIME parsers when they don't see the message boundaries. */
146
 
            static const char *const exclude_headers[] = {
147
 
                    "Content-Type"
148
 
            };
149
 
 
150
 
            input = i_stream_create_header_filter(input,
151
 
                        HEADER_FILTER_EXCLUDE | HEADER_FILTER_NO_CR |
152
 
                        HEADER_FILTER_HIDE_BODY, exclude_headers,
153
 
                        N_ELEMENTS(exclude_headers),
154
 
                        null_header_filter_callback, NULL);
155
 
 
156
 
            while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) {
157
 
                    if (fwrite(data, size, 1, f) == 0)
158
 
                            break;
159
 
                    i_stream_skip(input, size);
160
 
            }
161
 
            i_stream_unref(&input);
162
 
 
163
 
            i_assert(ret != 0);
164
 
    }
165
 
 
166
 
    fprintf(f, "\r\n\r\n--%s--\r\n", boundary);
167
 
    return smtp_client_close(smtp_client);
168
 
}
169
 
 
170
 
int mail_send_forward(struct mail *mail, const char *forwardto)
171
 
{
172
 
    static const char *hide_headers[] = {
173
 
        "Return-Path"
174
 
    };
175
 
    struct istream *input;
176
 
    struct smtp_client *smtp_client;
177
 
    FILE *f;
178
 
    const unsigned char *data;
179
 
    const char *return_path;
180
 
    size_t size;
181
 
    int ret;
182
 
 
183
 
    if (mail_get_stream(mail, NULL, NULL, &input) < 0)
184
 
            return -1;
185
 
 
186
 
    return_path = deliver_get_return_address(mail);
187
 
    if (getenv("DEBUG") != NULL) {
188
 
            i_info("Sending a forward to <%s> with return path <%s>",
189
 
                   forwardto, return_path);
190
 
    }
191
 
 
192
 
    smtp_client = smtp_client_open(forwardto, return_path, &f);
193
 
 
194
 
    input = i_stream_create_header_filter(input, HEADER_FILTER_EXCLUDE |
195
 
                                          HEADER_FILTER_NO_CR, hide_headers,
196
 
                                          N_ELEMENTS(hide_headers),
197
 
                                          null_header_filter_callback, NULL);
198
 
 
199
 
    while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) {
200
 
            if (fwrite(data, size, 1, f) == 0)
201
 
                    break;
202
 
            i_stream_skip(input, size);
203
 
    }
204
 
    i_stream_unref(&input);
205
 
 
206
 
    return smtp_client_close(smtp_client);
207
 
}
208