00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00040 class Mail
00041 {
00042 var $from = '';
00043 var $to = '';
00044 var $bcc = '';
00045 var $cc = '';
00046 var $subject = '';
00047 var $text = '';
00048 var $header = array();
00049 var $nl = '';
00050
00057 var $error = array();
00058
00065 var $debug = true;
00066
00067
00076 function Mail( $to,$text,$xy='' )
00077 {
00078 global $conf;
00079
00080
00081 $this->nl = chr(13).chr(10);
00082
00083 if ( !empty($conf['mail']['from']) )
00084 $this->from = $this->header_encode($conf['mail']['from']);
00085
00086
00087 if ( !empty($conf['mail']['priority']) )
00088 $this->header[] = 'X-Priority: '.$conf['mail']['priority'];
00089
00090 $this->header[] = 'X-Mailer: '.$this->header_encode(OR_TITLE.' '.OR_VERSION);
00091 $this->header[] = 'Content-Type: text/plain; charset='.lang( 'CHARSET' );
00092 $this->subject = $this->header_encode(lang( 'mail_subject_'.$text ));
00093 $this->to = $this->header_encode($to);
00094
00095 $this->text = $this->nl.wordwrap(str_replace(';',$this->nl,lang('mail_text_'.$text)),70,$this->nl).$this->nl;
00096
00097
00098 if ( !empty($conf['mail']['signature']) )
00099 {
00100 $this->text .= $this->nl.'-- '.$this->nl;
00101 $this->text .= str_replace(';',$this->nl,$conf['mail']['signature']);
00102 $this->text .= $this->nl;
00103 }
00104
00105
00106 if ( !empty($conf['mail']['cc']) )
00107 $this->cc = $this->header_encode($conf['mail']['cc']);
00108
00109
00110 if ( !empty($conf['mail']['bcc']) )
00111 $this->bcc = $this->header_encode($conf['mail']['bcc']);
00112 }
00113
00114
00115
00122 function quoted_printable_encode( $text )
00123 {
00124 $text = str_replace(' ','=20',$text);
00125
00126 for( $i=128; $i<=255; $i++ )
00127 {
00128 $text = str_replace( chr($i),'='.dechex($i),$text );
00129 }
00130
00131 return $text;
00132 }
00133
00134
00135
00139 function setVar( $varName,$varInhalt)
00140 {
00141 $this->text = str_replace( '{'.$varName.'}', $varInhalt, $this->text );
00142 }
00143
00144
00151 function send()
00152 {
00153 global $conf;
00154
00155
00156 if ( !empty($this->from ) )
00157 $this->header[] = 'From: '.$this->from;
00158
00159 if ( !empty($this->cc ) )
00160 $this->header[] = 'Cc: '.$this->cc;
00161
00162 if ( !empty($this->bcc ) )
00163 $this->header[] = 'Bcc: '.$this->bcc;
00164
00165
00166 if ( strtolower(@$conf['mail']['client']) == 'php' )
00167 {
00168
00169 $result = @mail( $this->to,
00170 $this->subject,
00171 $this->text,
00172
00173
00174 implode("\n",$this->header) );
00175 if ( !$result )
00176
00177
00178
00179 $this->error[] = 'Mail was NOT accepted by mail()';
00180
00181 return $result;
00182 }
00183 else
00184 {
00185
00186 $smtpConf = $conf['mail']['smtp'];
00187
00188 if ( !empty($smtpConf['host']))
00189 {
00190
00191 $mxHost = $smtpConf['host'];
00192 $mxPort = intval($smtpConf['port']);
00193 }
00194 else
00195 {
00196
00197 $mxHost = $this->getMxHost($this->to);
00198
00199 if ( empty($mxHost) )
00200 {
00201 $this->error[] = "No MX-Entry found. Mail could not be sent.";
00202 return false;
00203 }
00204
00205 if ($smtpConf['ssl'])
00206 $mxPort = 465;
00207 else
00208 $mxPort = 25;
00209 }
00210
00211
00212 if ( !empty($smtpConf['localhost']))
00213 {
00214 $myHost = $smtpConf['localhost'];
00215 }
00216 else
00217 {
00218 $myHost = gethostbyaddr(getenv('REMOTE_ADDR'));
00219 }
00220
00221 if ( $smtpConf['ssl'])
00222 $proto = 'ssl';
00223 else
00224 $proto = 'tcp';
00225
00226
00227 $smtpSocket = fsockopen($proto.'://'.$mxHost,$mxPort, $errno, $errstr, intval($smtpConf['timeout']));
00228
00229 if ( !is_resource($smtpSocket) )
00230 {
00231 $this->error[] = 'Connection failed to: '.$proto.'://'.$mxHost.':'.$mxPort.' ('.$errstr.'/'.$errno.')';
00232 return false;
00233 }
00234
00235 $smtpResponse = fgets($smtpSocket, 4096);
00236 if ( $this->debug)
00237 $this->error[] = trim($smtpResponse);
00238
00239 if ( substr($smtpResponse,0,3) != '220' )
00240 {
00241 $this->error[] = trim($smtpResponse);
00242 return false;
00243 }
00244
00245 if ( !is_resource($smtpSocket) )
00246 {
00247 $this->error[] = 'Connection failed to: '.$smtpConf['host'].':'.$smtpConf['port'].' ('.$smtpResponse.')';
00248 return false;
00249 }
00250
00251
00252 $smtpResponse = $this->sendSmtpCommand($smtpSocket,'HELO '.$myHost);
00253
00254 if ( substr($smtpResponse,0,3) != '250' )
00255 {
00256 $this->error[] = "No 2xx after HELO, server says: ".$smtpResponse;
00257 $this->sendSmtpQuit($smtpSocket);
00258 return false;
00259 }
00260
00261 if ( $smtpConf['tls'] )
00262 {
00263 $smtpResponse = $this->sendSmtpCommand($smtpSocket,'STARTTLS');
00264 if ( substr($smtpResponse,0,3) == '220' )
00265 {
00266
00267
00268 $smtpResponse = $this->sendSmtpCommand($smtpSocket,'HELO '.$myHost);
00269
00270 if ( substr($smtpResponse,0,3) != '250' )
00271 {
00272 $this->error[] = "No 2xx after HELO, server says: ".$smtpResponse;
00273 $this->sendSmtpQuit($smtpSocket);
00274 return false;
00275 }
00276 }
00277 else
00278 {
00279
00280 }
00281 }
00282
00283
00284 if ( isset($smtpConf['auth_username']) && !empty($smtpConf['host']) && !empty($smtpConf['auth_username']))
00285 {
00286 $smtpResponse = $this->sendSmtpCommand($smtpSocket,"AUTH LOGIN");
00287 if ( substr($smtpResponse,0,3) != '334' )
00288 {
00289 $this->error[] = "No 334 after AUTH_LOGIN, server says: ".$smtpResponse;
00290 $this->sendSmtpQuit($smtpSocket);
00291 return false;
00292 }
00293
00294 if ( $this->debug)
00295 $this->error[] = 'Login for '.$smtpConf['auth_username'];
00296
00297
00298 $smtpResponse = $this->sendSmtpCommand($smtpSocket, base64_encode($smtpConf['auth_username']));
00299 if ( substr($smtpResponse,0,3) != '334' )
00300 {
00301 $this->error[] = "No 3xx after setting username, server says: ".$smtpResponse;
00302 $this->sendSmtpQuit($smtpSocket);
00303 return false;
00304 }
00305
00306
00307 $smtpResponse = $this->sendSmtpCommand($smtpSocket, base64_encode($smtpConf['auth_password']));
00308 if ( substr($smtpResponse,0,3) != '235' )
00309 {
00310 $this->error[] = "No 235 after sending password, server says: ".$smtpResponse;
00311 $this->sendSmtpQuit($smtpSocket);
00312 return false;
00313 }
00314 }
00315
00316
00317 $smtpResponse = $this->sendSmtpCommand($smtpSocket, 'MAIL FROM: <'.$conf['mail']['from'].'>');
00318 if ( substr($smtpResponse,0,3) != '250' )
00319 {
00320 $this->error[] = "No 2xx after MAIL_FROM, server says: ".$smtpResponse;
00321 $this->sendSmtpQuit($smtpSocket);
00322 return false;
00323 }
00324
00325
00326 $smtpResponse = $this->sendSmtpCommand($smtpSocket, 'RCPT TO: <'.$this->to.'>');
00327 if ( substr($smtpResponse,0,3) != '250' )
00328 {
00329 $this->error[] = "No 2xx after RCPT_TO, server says: ".$smtpResponse;
00330 $this->sendSmtpQuit($smtpSocket);
00331 return false;
00332 }
00333
00334
00335 $smtpResponse = $this->sendSmtpCommand($smtpSocket, "DATA");
00336 if ( substr($smtpResponse,0,3) != '354' )
00337 {
00338 $this->error[] = "No 354 after DATA, server says: ".$smtpResponse;
00339 $this->sendSmtpQuit($smtpSocket);
00340 return false;
00341 }
00342
00343 $this->header[] = 'To: '.$this->to;
00344 $this->header[] = 'Subject: '.$this->subject;
00345 $this->header[] = 'Date: '.date('r');
00346 $this->header[] = 'Message-Id: '.'<'.getenv('REMOTE_ADDR').'.'.time().'.openrat@'.getenv('SERVER_NAME').'.'.getenv('HOSTNAME').'>';
00347
00348
00349 $smtpResponse = $this->sendSmtpCommand($smtpSocket, implode($this->nl,$this->header).$this->nl.$this->nl.$this->text.$this->nl.'.');
00350 if ( substr($smtpResponse,0,3) != '250' )
00351 {
00352 $this->error[] = "No 2xx after putting DATA, server says: ".$smtpResponse;
00353 $this->sendSmtpQuit($smtpSocket);
00354 return false;
00355 }
00356
00357
00358 $this->sendSmtpQuit($smtpSocket);
00359 return true;
00360 }
00361 }
00362
00363
00372 function sendSmtpCommand( $socket,$cmd )
00373 {
00374 if ( $this->debug )
00375 $this->error[] = 'CLIENT: >>> '.trim($cmd);
00376 if ( !is_resource($socket) )
00377 {
00378
00379
00380
00381
00382 $this->error[] = "Connection lost";
00383 return;
00384 }
00385
00386 fputs($socket,$cmd.$this->nl);
00387 $response = trim(fgets($socket, 4096));
00388 if ( $this->debug )
00389 $this->error[] = 'SERVER: <<< '.$response;
00390 return $response;
00391 }
00392
00393
00394
00401 function sendSmtpQuit( $socket )
00402 {
00403
00404 if ( $this->debug )
00405 $this->error[] = "CLIENT: >>> QUIT";
00406 if ( !is_resource($socket) )
00407 return;
00408
00409
00410
00411
00412 fputs($socket,'QUIT'.$this->nl);
00413 $response = trim(fgets($socket, 4096));
00414 if ( $this->debug )
00415 $this->error[] = 'SERVER: <<< '.$response;
00416
00417 if ( substr($response,0,3) != '221' )
00418 $this->error[] = 'QUIT FAILED: '.$response;
00419
00420 fclose($socket);
00421 }
00422
00423
00424
00432 function header_encode( $text )
00433 {
00434 global $conf;
00435
00436 if ( empty($conf['mail']['header_encoding']) )
00437 return $text;
00438
00439 $woerter = explode(' ',$text);
00440 $neu = array();
00441
00442
00443 foreach( $woerter as $wort )
00444 {
00445 $type = strtolower(substr($conf['mail']['header_encoding'],0,1));
00446 $neu_wort = '';
00447
00448 if ( $type == 'b' )
00449 $neu_wort = base64_encode($wort);
00450 elseif ( $type == 'q' )
00451 $neu_wort = $this->quoted_printable_encode($wort);
00452 else
00453 Logger::error( 'Mail-Configuratin broken: UNKNOWN Header-Encoding type: '.$type);
00454
00455 if ( strlen($wort)==strlen($neu_wort) )
00456 $neu[] = $wort;
00457 else
00458 $neu[] = '=?'.lang('CHARSET').'?'.$type.'?'.$neu_wort.'?=';
00459 }
00460
00461 return implode(' ',$neu);
00462 }
00463
00464
00472 function getMxHost( $to )
00473 {
00474 list($user,$host) = explode('@',$to.'@');
00475
00476 if ( empty($host) )
00477 {
00478 $this->error[] = 'Illegal mail address - No hostname found.';
00479 return "";
00480 }
00481
00482 list($host) = explode('>',$host);
00483
00484 $mxHostsName = array();
00485 $mxHostsPrio = array();
00486 getmxrr($host,$mxHostsName,$mxHostsPrio);
00487
00488 $mxList = array();
00489 foreach( $mxHostsName as $id=>$mxHostName )
00490 {
00491 $mxList[$mxHostName] = $mxHostsPrio[$id];
00492 }
00493 asort($mxList);
00494 return key($mxList);
00495 }
00496 }
00497
00498
00499 ?>