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