Code cleanup
[openpgp-sendmail-classes.git] / emailclass.inc.php
1 <?  
2  define("GPG_SYMMETRIC" ,1);
3  define("GPG_ASYMMETRIC",2);
4  
5  class sendmail_base
6  {
7   /*
8    *
9    * Created by Kristian Fiskerstrand
10    * Website: http://www.kfwebs.net
11    * The above Copyright statement shall be kept intact at all times.
12    *
13    * ***************************************************************
14    *
15    */
16
17   protected $to = array();
18   protected $cc = array();
19   protected $bcc = array();
20   protected $tos;
21   protected $ccs;
22   protected $bccs;
23   protected $attachment = array();
24   protected $body = "";
25   protected $from = "";
26   protected $subject = "";
27   protected $debug = 0;
28   
29   protected function add_element(&$arr,$add)
30   {
31    if(is_array($add)){$arr = array_merge($arr,$add);}
32     else{array_push($arr, $add);}
33   }
34
35   public function from($email)
36   {
37         $this->from = $email;
38   }
39   
40   public function subject($text)
41   {
42         $this->subject = $text;
43   }  
44   
45   public function add_to($email)
46   {
47         $this->add_element($this->to,$email);
48   }
49   
50   public function add_cc($email)
51   {
52         $this->add_element($this->cc,$email);
53   }
54
55   public function add_bcc($email)
56   {
57         $this->add_element($this->bcc,$email);
58   }
59   
60   public function body($content)
61   {
62         $this->body .= $content;
63   }
64
65   public function debug()
66   {
67         $this->debug=1;
68   }
69   
70   protected function getmimetype($name)
71   {
72    $b = FALSE;
73    $a = array(
74     ".pdf" => "application/pdf",
75     ".ps"  => "application/postscript",
76     ".eps" => "application/postscript",
77     ".sxw" => "application/vnd.sun.xml.writer",
78     ".sxc" => "application/vnd.sun.xml.calc",
79     ".gif" => "image/gif",
80     ".jpg" => "image/jpg",
81     ".png" => "image/png",
82     ".doc" => "application/msword",
83     ".xls" => "application/vnd.ms-excel",
84     ".txt" => "text/plain"
85    );
86    if(isset($a[".".strtolower(substr($name,-3))])) $b = $a[".".strtolower(substr($name,-3))];
87    if(isset($a[".".strtolower(substr($name,-2))])) $b = $a[".".strtolower(substr($name,-2))];
88    return $b;
89   }
90   
91   protected function getheaders()
92   {  
93    $this->tos = implode(",",$this->to);
94    $this->ccs = implode(",",$this->cc);
95    $this->bccs = implode(",",$this->bcc);
96
97    $headers  = "From: {$this->from}\n";
98    $headers .= "MIME-Version: 1.0\n";
99    $headers .= "X-Sender: KF Webs PHP Mail Class [http://www.kfwebs.net] \n";
100    if(strlen($this->ccs)>0) $headers .= "CC: {$this->ccs}\n";
101    if(strlen($this->bccs)>0) $headers .= "BCC: {$this->bccs}\n";
102    return $headers;
103   }
104   
105   public function attachment($path, $type=1, $filename=1)
106   {
107    $fp = fopen($path, 'r');
108    $contents = fread($fp, filesize($path));
109    fclose($fp);
110    if($filename===1) $filename=basename($path);
111    if($type===1)
112    {
113     $type=$this->getmimetype($path);
114     if($type===FALSE) exit("MIME type required for {$path}");
115    }
116    $this->attachment[] = array(chunk_split(base64_encode($contents)),$type,$filename);
117   }
118  }
119
120  class sendmail_ordinary extends sendmail_base
121  {
122   public function send()
123   {
124    $bound = '-----=' . md5(uniqid(rand()));
125    $headers = $this->getheaders();
126    $headers .= "Content-Type: multipart/mixed; boundary=\"{$bound}\"\n";
127    
128    $mime = "";
129    $mime .= "This is a multi-part message in MIME format.\n\n";
130    $mime .= "--{$bound}\nContent-Type: text/plain;charset=\"utf-8\"\nContent-Transfer-Encoding: base64\nContent-Disposition: inline\n\n".chunk_split(base64_encode($this->body))."\n\n";
131    
132    $ac = count($this->attachment);
133    for($i=0;$i<$ac;$i++)
134    {
135     $mime .= "--{$bound}\nContent-Type: {$this->attachment[$i][1]}\nContent-Transfer-Encoding: base64\nContent-Disposition: attachment; filename=\"{$this->attachment[$i][2]}\"\n\n{$this->attachment[$i][0]}\n\n";
136    }
137    $mime .= "--{$bound}--";
138
139    if($this->debug==1) echo "email sent to\n{$tos}\n\nSubject: {$this->subject}\n\nheaders:\n{$headers}\n\nMessage:\n{$mime}\n";
140    return mail($this->tos,$this->subject,$mime, $headers);
141   }
142  }
143  
144
145  class sendmail_gpgbase extends sendmail_base
146  {
147   protected $gpg_path = "/usr/bin/gpg";
148   protected $gpg_tmpdir = "/tmp";
149   protected $gpg_homedir = "";
150   protected $gpg_version = "1.4";
151   
152   public function gpg_set_path($path){$this->gpg_path=escapeshellcmd($path);}
153   public function gpg_set_homedir($dir){$this->gpg_homedir=$dir;}
154   public function gpg_set_tmp($dir){$this->gpg_tmpdir=escapeshellcmd($dir);}  
155   public function gpg_set_version($ver){$this->gpg_version=$ver;}
156  }
157  
158  class sendmail_gpgsign extends sendmail_gpgbase
159  {
160   protected $gpg_signing_key="";
161   protected $gpg_algo = "sha256";
162   
163   public function gpg_set_signing_key($key){$this->gpg_signing_key=escapeshellcmd($key);}
164   public function gpg_set_algo($algo){$this->gpg_algo=escapeshellcmd($algo);}
165   
166   protected function gpg_sign($var)
167   {
168    $tmp=$this->gpg_tmpdir."/kfmail".md5(uniqid(rand()));
169    file_put_contents($tmp,$var);
170    
171    if($this->gpg_homedir=="") die("You need to specify a homedir to use asymmetrical encryption");
172    
173    $gpg_command = "--batch --homedir {$this->gpg_homedir} ".(($this->gpg_version=="1.4") ? " --trust-model always" : " --always-trust")." --no-tty --comment \"KF Webs PHP Mail Class [http://www.kfwebs.net]\" --command-fd 0 -u {$this->gpg_signing_key} -asbt";
174    $gpg_command_use = $this->gpg_path." {$gpg_command} --digest-algo {$this->gpg_algo}";
175    $gpg_command_use = "cat $tmp | $gpg_command_use > $tmp.asc";
176    $a = `$gpg_command_use`;
177    
178    if($this->debug==1)
179    {
180     echo $a;
181     echo $gpg_command_use;
182    }
183    $out= file_get_contents($tmp.".asc");
184    unlink($tmp);
185    unlink($tmp.".asc");
186    return $out;
187   }
188   
189   public function send()
190   {
191    $bound  = '-----=' . md5(uniqid(rand()));
192    $bound2 = '-----=' . md5(uniqid(rand()));
193    
194    $headers = $this->getheaders();
195    $headers .= "Content-Type: multipart/signed; micalg=pgp-{$this->gpg_algo};\n protocol=\"application/pgp-signature\";\n boundary=\"{$bound}\"\n";
196    
197    $mime = "";
198    $pgpmime="";
199
200    $mime .= "This is an OpenPGP/MIME signed message (RFC 2440 and 3156).\n";
201    $mime .= "--{$bound}\n";
202    
203    $pgpmime .= "Content-Type: multipart/mixed;\n boundary=\"{$bound2}\"\n\nThis is a multi-part message in MIME format.\n";
204    $pgpmime .= "--{$bound2}\nContent-Type: text/plain;charset=\"utf-8\"\nContent-Transfer-Encoding: base64\nContent-Disposition: inline\n\n".chunk_split(base64_encode($this->body))."\n\n";
205    
206    $ac = count($this->attachment);
207    for($i=0;$i<$ac;$i++)
208    {
209     $pgpmime .= "--{$bound2}\nContent-Type: {$this->attachment[$i][1]};name=\"{$this->attachment[$i][2]}\"\nContent-Transfer-Encoding: base64\nContent-Disposition: attachment; filename=\"{$this->attachment[$i][2]}\"\n\n{$this->attachment[$i][0]}\n";
210    }
211    $pgpmime .= "\n--{$bound2}--\n\n";
212    
213    $mime .= $pgpmime;
214    $mime .= "\n--{$bound}\nContent-Type: application/pgp-signature; name=\"signature.asc\"\nContent-Description: OpenPGP digital signature\nContent-Disposition: attachment; filename=\"signature.asc\"\n\n";
215    $mime .= $this->gpg_sign($pgpmime);
216    $mime .= "\n--{$bound}--";
217    if($this->debug==1) echo "email sent to\n{$tos}\n\nSubject: {$this->subject}\n\nheaders:\n{$headers}\n\nMessage:\n{$mime}\n";
218    return mail($this->tos,$this->subject,$mime, $headers);
219   }
220  }
221  
222  class sendmail_gpg extends sendmail_gpgbase
223  {
224   
225   protected $gpg_key = "abcd";
226   protected $gpg_algo = "aes256";
227   protected $gpg_command = "";
228   protected $gpg_command_use = "";  
229   protected $gpg_type = 1; // 1 is symmetrical, 2 is asymmetrical
230   protected $gpg_sign = 0; // 0: NO ; 1: YES
231   protected $gpg_keys = array();
232   protected $gpg_signing_key="";
233
234   public function gpg_set_key($key){$this->gpg_key = escapeshellcmd($key);}
235   public function gpg_set_algo($algo){$this->gpg_algo=escapeshellcmd($algo);}
236   public function gpg_set_type($type){$this->gpg_type=$type;}
237   public function gpg_set_sign($sign){$this->gpg_sign=$sign;}
238   public function gpg_add_key($key){$this->add_element($this->gpg_keys,$key);}  
239   public function gpg_set_signing_key($key)
240   {
241    $this->gpg_signing_key=escapeshellcmd($key);
242    $this->gpg_set_type(2);
243    $this->gpg_set_sign(1);
244   }
245   
246   protected function gpg_encrypt($var)
247   {
248    if(count($this->gpg_keys)<1 && $this->gpg_key != "" && $this->gpg_key != "abcd")
249    {
250     $this->gpg_keys[] = $this->gpg_key;
251    }
252    
253    $tmp=$this->gpg_tmpdir."/kfmail".md5(uniqid(rand()));
254    file_put_contents($tmp,$var);
255    if($this->gpg_type==2)
256    {
257     $gpg_key_list = "";
258     if($this->gpg_homedir=="") die("You need to specify a homedir to use asymmetrical encryption");
259     $this->gpg_command = "--batch --homedir {$this->gpg_homedir} ".(($this->gpg_version=="1.4") ? " --trust-model always" : " --always-trust")." --no-tty --comment \"KF Webs PHP Mail Class [http://www.kfwebs.net]\" --command-fd 0 ".(($this->gpg_signing_key!="") ? " -u {$this->gpg_signing_key} " : "")."-a".(($this->gpg_sign==1) ? "s" : "")."e";
260     foreach($this->gpg_keys as $abcd)
261     {
262      $gpg_key_list .= " -r {$abcd}";
263     }
264     $this->gpg_command_use = $this->gpg_path." --cipher-algo ".$this->gpg_algo." ".$this->gpg_command." {$gpg_key_list} ".$tmp." 2>&1";
265    }
266    else
267    {
268     $this->gpg_command = "--batch --homedir /tmp/ --no-tty --comment \"KF Webs PHP Mail Class [http://www.kfwebs.net]\" --command-fd 0 -ac";
269     $this->gpg_command_use = "echo \"{$this->gpg_key}\" | ".$this->gpg_path." --cipher-algo ".$this->gpg_algo." ".$this->gpg_command." ".$tmp." 2>&1";
270    }
271    $a = `$this->gpg_command_use`;
272    if($this->debug==1) echo $a;
273    $out= file_get_contents($tmp.".asc");
274    unlink($tmp);
275    unlink($tmp.".asc");
276    return $out;
277   }
278
279   public function send()
280   {
281    $bound  = '-----=' . md5(uniqid(rand()));
282    $bound2 = '-----=' . md5(uniqid(rand()));
283    
284    $headers = $this->getheaders();
285    $headers .= "Content-Type: multipart/encrypted; protocol=\"application/pgp-encrypted\"; boundary=\"{$bound}\"\n";
286    
287    $mime = "";
288    $pgpmime="";
289
290    $mime .= "This is an OpenPGP/MIME encrypted message (RFC 2440 and 3156).\n";
291    
292    $mime .= "--{$bound}\nContent-Type: application/pgp-encrypted\nContent-Description: PGP/MIME version identification\n\nVersion: 1\n\n";
293    $mime .= "--{$bound}\nContent-Type: application/octet-stream; name=\"encrypted.asc\"\nContent-Description: OpenPGP encrypted message\nContent-Disposition: inline; filename=\"encrypted.asc\"\n\n";
294    $pgpmime .= "Content-Type: multipart/mixed;boundary=\"{$bound2}\"\n\nThis is a multi-part message in MIME format.\n\n";
295    $pgpmime .= "--{$bound2}\nContent-Type: text/plain;charset=\"utf-8\"\nContent-Transfer-Encoding: base64\nContent-Disposition: inline\n\n".chunk_split(base64_encode($this->body))."\n\n";
296    
297    $ac = count($this->attachment);
298    for($i=0;$i<$ac;$i++)
299    {
300     $pgpmime .= "--{$bound2}\nContent-Type: {$this->attachment[$i][1]};name=\"{$this->attachment[$i][2]}\"\nContent-Transfer-Encoding: base64\nContent-Disposition: attachment; filename=\"{$this->attachment[$i][2]}\"\n\n{$this->attachment[$i][0]}\n";
301    }
302    $pgpmime .= "\n--{$bound2}--\n\n";
303    $mime .= $this->gpg_encrypt($pgpmime);
304    $mime .= "\n--{$bound}--";
305    if($this->debug==1) echo "email sent to\n{$tos}\n\nSubject: {$this->subject}\n\nheaders:\n{$headers}\n\nMessage:\n{$mime}\n";
306    return mail($this->tos,$this->subject,$mime, $headers);
307   }
308  }
309  class sendmail extends sendmail_gpg{} // For easability
310 ?>