1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
<protected function build_message($no_bcc = false)
{
$newline = $this->config['newline'];
$charset = $this->config['charset'];
$encoding = $this->config['encoding'];
$headers = '';
$parts = array('Date', 'Return-Path', 'From', 'To', 'Cc', 'Bcc', 'Reply-To', 'Subject', 'Message-ID', 'X-Priority', 'X-Mailer', 'MIME-Version', 'Content-Type');
$no_bcc and array_splice($parts, 5, 1);
$this->config['smime']['enabled'] and array_splice($parts, -2, 2);
foreach ($parts as $part)
{
$headers .= $this->get_header($part);
}
foreach ($this->extra_headers as $header => $value)
{
$headers .= $header.': '.$value.$newline;
}
$headers .= $newline;
$body = '';
if ($this->type === 'plain' or $this->type === 'html')
{
if ($this->config['smime']['enabled'])
{
$body .= 'Content-Type: text/plain; charset="'.$charset.'"'.$newline;
$body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline;
}
$body .= $this->body;
}
else
{
if ($this->config['smime']['enabled'])
{
$body .= $this->get_header('Content-Type').$newline;
}
switch ($this->type)
{
case 'html_alt':
$body .= '--'.$this->boundaries[0].$newline;
$body .= 'Content-Type: text/plain; charset="'.$charset.'"'.$newline;
$body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline;
$body .= $this->alt_body.$newline.$newline;
$body .= '--'.$this->boundaries[0].$newline;
$body .= 'Content-Type: text/html; charset="'.$charset.'"'.$newline;
$body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline;
$body .= $this->body.$newline.$newline;
$body .= '--'.$this->boundaries[0].'--';
break;
case 'plain_attach':
case 'html_attach':
case 'html_inline':
$body .= '--'.$this->boundaries[0].$newline;
$text_type = (stripos($this->type, 'html') !== false) ? 'html' : 'plain';
$body .= 'Content-Type: text/'.$text_type.'; charset="'.$charset.'"'.$newline;
$body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline;
$body .= $this->body.$newline.$newline;
$attach_type = (stripos($this->type, 'attach') !== false) ? 'attachment' : 'inline';
$body .= $this->get_attachment_headers($attach_type, $this->boundaries[0]);
$body .= '--'.$this->boundaries[0].'--';
break;
case 'html_alt_inline':
$body .= '--'.$this->boundaries[0].$newline;
$body .= 'Content-Type: text/plain'.'; charset="'.$charset.'"'.$newline;
$body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline;
$body .= $this->alt_body.$newline.$newline;
$body .= '--'.$this->boundaries[0].$newline;
$body .= 'Content-Type: multipart/related;'.$newline."\tboundary=\"{$this->boundaries[1]}\"".$newline.$newline;
$body .= '--'.$this->boundaries[1].$newline;
$body .= 'Content-Type: text/html; charset="'.$charset.'"'.$newline;
$body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline;
$body .= $this->body.$newline.$newline;
$body .= $this->get_attachment_headers('inline', $this->boundaries[1]);
$body .= '--'.$this->boundaries[1].'--'.$newline.$newline;
$body .= '--'.$this->boundaries[0].'--';
break;
case 'html_alt_attach':
case 'html_inline_attach':
$body .= '--'.$this->boundaries[0].$newline;
$body .= 'Content-Type: multipart/alternative;'.$newline."\t boundary=\"{$this->boundaries[1]}\"".$newline.$newline;
if (stripos($this->type, 'alt') !== false)
{
$body .= '--'.$this->boundaries[1].$newline;
$body .= 'Content-Type: text/plain; charset="'.$charset.'"'.$newline;
$body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline;
$body .= $this->alt_body.$newline.$newline;
}
$body .= '--'.$this->boundaries[1].$newline;
$body .= 'Content-Type: text/html; charset="'.$charset.'"'.$newline;
$body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline;
$body .= $this->body.$newline.$newline;
if (stripos($this->type, 'inline') !== false)
{
$body .= $this->get_attachment_headers('inline', $this->boundaries[1]);
$body .= $this->alt_body.$newline.$newline;
}
$body .= '--'.$this->boundaries[1].'--'.$newline.$newline;
$body .= $this->get_attachment_headers('attachment', $this->boundaries[0]);
$body .= '--'.$this->boundaries[0].'--';
break;
case 'html_alt_inline_attach':
$body .= '--'.$this->boundaries[0].$newline;
$body .= 'Content-Type: multipart/alternative;'.$newline."\t boundary=\"{$this->boundaries[1]}\"".$newline.$newline;
$body .= '--'.$this->boundaries[1].$newline;
$body .= 'Content-Type: text/plain; charset="'.$charset.'"'.$newline;
$body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline;
$body .= $this->alt_body.$newline.$newline;
$body .= '--'.$this->boundaries[1].$newline;
$body .= 'Content-Type: multipart/related;'.$newline."\t boundary=\"{$this->boundaries[2]}\"".$newline.$newline;
$body .= '--'.$this->boundaries[2].$newline;
$body .= 'Content-Type: text/html; charset="'.$charset.'"'.$newline;
$body .= 'Content-Transfer-Encoding: '.$encoding.$newline.$newline;
$body .= $this->body.$newline.$newline;
$body .= $this->get_attachment_headers('inline', $this->boundaries[2]);
$body .= $this->alt_body.$newline.$newline;
$body .= '--'.$this->boundaries[2].'--'.$newline.$newline;
$body .= '--'.$this->boundaries[1].'--'.$newline.$newline;
$body .= $this->get_attachment_headers('attachment', $this->boundaries[0]);
$body .= '--'.$this->boundaries[0].'--';
break;
}
}
if ($this->config['smime']['enabled'])
{
$tmp_dir = $this->config['smime']['tmp_dir'];
$infilename = 'email_'.md5($body.microtime());
$outfilename = $infilename.'_out';
$signcert = 'file://'.$this->config['smime']['signcert'];
$privkey = 'file://'.$this->config['smime']['privkey'];
$headers = substr($headers, 0, -strlen($newline)*2);
if ( ! is_writable($tmp_dir))
{
throw new \FuelException('Cannot write into directory "'.$tmp_dir.'"');
}
if ( ! is_readable($signcert) || ! is_readable($privkey))
{
throw new \FuelException('Cannot read certificate or key.');
}
if ($this->config['smime']['keypass'])
{
$privkey = array($privkey, $this->config['smime']['keypass']);
}
\File::create($tmp_dir, $infilename, $body);
openssl_pkcs7_sign($tmp_dir.$infilename, $tmp_dir.$outfilename, $signcert, $privkey, array($headers));
$body = \File::read($tmp_dir.$outfilename, true);
\File::delete($tmp_dir.$infilename);
\File::delete($tmp_dir.$outfilename);
$headers = '';
$body = strtr($body, array_fill_keys(array("\r\n", "\r", "\n"), $newline));
}
return array(
'header' => $headers,
'body' => $body,
);
}
|