aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/smtp.php
blob: 39a95ba3494fb21606f84f82acb9283b65df4b36 (plain)
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
<?php
/***************************************************************************
                                smtp.php
						  -------------------
    begin                : Wed May 09 2001
    copyright            : (C) 2001 The phpBB Group
    email                : support@phpbb.com

    $Id$

 ***************************************************************************/

/***************************************************************************
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 ***************************************************************************/

/****************************************************************************
*	This script should be included if the admin has configured the board for
*	smtp mail instead of standard sendmail.  It includes a function smtpmail
* 	which is identical to the standard built in mail function in usage.
****************************************************************************/

/****************************************************************************
*	Function: 		server_parse
*	Description:	This funtion processes the smtp server's response codes
*	Usage: 			This function is only used interanally by the smtpmail
*						function.  It takes two arguments the first a socket pointer
*						to the opened socket to the server and the second the
*						response code you are looking for.
****************************************************************************/
define('SMTP_INCLUDED', 1);
function server_parse($socket, $response)
{
	if(!($server_response = fgets($socket, 256)))
	{
		message_die(GENERAL_ERROR, "Couldn't get mail server response codes", "", __LINE__, __FILE__);
	}
	if(!(substr($server_response, 0, 3) == $response))
	{
		message_die(GENERAL_ERROR, "Ran into problems sending Mail. Response: $server_response", "", __LINE__, __FILE__);
	}
}

/****************************************************************************
*	Function: 		smtpmail
*	Description: 	This is a functional replacement for php's builtin mail
*						function, that uses smtp.
*	Usage:			The usage for this function is identical to that of php's
*						built in mail function.
****************************************************************************/
function smtpmail($mail_to, $subject, $message, $headers = "")
{
	// For now I'm using an array based $smtp_vars to hold the smtp server
	// info, but it should probably change to $board_config...
	// then the relevant info would be $board_config['smtp_host'] and
	// $board_config['smtp_port'].
	global $board_config;

	//
	// Fix any bare linefeeds in the message to make it RFC821 Compliant.
	//
	$message = preg_replace("/(?<!\r)\n/si", "\r\n", $message);

	if ($headers != "")
	{
		if(is_array($headers))
		{
			if(sizeof($headers) > 1)
			{
				$headers = join("\r\n", $headers);
			}
			else
			{
				$headers = $headers[0];
			}
		}
		$headers = chop($headers);

		//
		// Make sure there are no bare linefeeds in the headers
		//
		$headers = preg_replace("/(?<!\r)\n/si", "\r\n", $headers);
		//
		// Ok this is rather confusing all things considered,
		// but we have to grab bcc and cc headers and treat them differently
		// Something we really didn't take into consideration originally
		//
		$header_array = explode("\r\n", $headers);
		@reset($header_array);
		$headers = "";
		while( list(, $header) = each($header_array) )
		{
			if( preg_match("/^cc:/si", $header) )
			{
				$cc = preg_replace("/^cc:(.*)/si", "\\1", $header);
			}
			else if( preg_match("/^bcc:/si", $header ))
			{
				$bcc = preg_replace("/^bcc:(.*)/si", "\\1", $header);
				$header = "";
			}
			$headers .= $header . "\r\n";
		}
		$headers = chop($headers);
		$cc = explode(",", $cc);
		$bcc = explode(",", $bcc);
	}
	if(trim($mail_to) == "")
	{
		message_die(GENERAL_ERROR, "No email address specified", "", __LINE__, __FILE__);
	}
	if(trim($subject) == "")
	{
		message_die(GENERAL_ERROR, "No email Subject specified", "", __LINE__, __FILE__);
	}
	if(trim($message) == "")
	{
		message_die(GENERAL_ERROR, "Email message was blank", "", __LINE__, __FILE__);
	}
	$mail_to_array = explode(",", $mail_to);

	//
	// Ok we have error checked as much as we can to this point let's get on
	// it already.
	//
	if( !$socket = fsockopen($board_config['smtp_host'], 25, $errno, $errstr, 20) )
	{
		message_die(GENERAL_ERROR, "Could not connect to smtp host : $errno : $errstr", "", __LINE__, __FILE__);
	}
	server_parse($socket, "220");

	// Send the RFC821 specified HELO.
	fputs($socket, "HELO " . $board_config['smtp_host'] . "\r\n");

	// From this point onward most server response codes should be 250
	server_parse($socket, "250");

	// Specify who the mail is from....
	fputs($socket, "MAIL FROM: " . $board_config['board_email'] . "\r\n");
	server_parse($socket, "250");

	// Specify each user to send to and build to header.
	$to_header = "To: ";
	@reset( $mail_to_array );
	while( list( , $mail_to_address ) = each( $mail_to_array ))
	{
		//
		// Add an additional bit of error checking to the To field.
		//
		$mail_to_address = trim($mail_to_address);
		if ( preg_match('/.+\@.+/', $mail_to_address) )
		{
			fputs( $socket, "RCPT TO: $mail_to_address\r\n" );
			server_parse( $socket, "250" );
		}
		$to_header .= "<$mail_to_address>, ";
	}
	// Ok now do the CC and BCC fields...
	@reset( $bcc );
	while( list( , $bcc_address ) = each( $bcc ))
	{
		//
		// Add an additional bit of error checking to bcc header...
		//
		$bcc_address = trim( $bcc_address );
		if ( preg_match('/.+\@.+/', $bcc_address) )
		{
			fputs( $socket, "RCPT TO: $bcc_address\r\n" );
			server_parse( $socket, "250" );
		}
	}
	@reset( $cc );
	while( list( , $cc_address ) = each( $cc ))
	{
		//
		// Add an additional bit of error checking to cc header
		//
		$cc_address = trim( $cc_address );
		if ( preg_match('/.+\@.+/', $cc_address) )
		{
			fputs($socket, "RCPT TO: $cc_address\r\n");
			server_parse($socket, "250");
		}
	}
	// Ok now we tell the server we are ready to start sending data
	fputs($socket, "DATA\r\n");

	// This is the last response code we look for until the end of the message.
	server_parse($socket, "354");

	// Send the Subject Line...
	fputs($socket, "Subject: $subject\r\n");

	// Now the To Header.
	fputs($socket, "$to_header\r\n");

	// Now any custom headers....
	fputs($socket, "$headers\r\n\r\n");

	// Ok now we are ready for the message...
	fputs($socket, "$message\r\n");

	// Ok the all the ingredients are mixed in let's cook this puppy...
	fputs($socket, ".\r\n");
	server_parse($socket, "250");

	// Now tell the server we are done and close the socket...
	fputs($socket, "quit\r\n");
	fclose($socket);

	return TRUE;
}

?>