bug 1200: Fix missing dollar sign before error handling
[cacert-devel.git] / www / gpg.php
1 <? /*
2 LibreSSL - CAcert web application
3 Copyright (C) 2004-2008 CAcert Inc.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; version 2 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */ ?>
18 <?
19 require_once("../includes/loggedin.php");
20 require_once("../includes/lib/general.php");
21
22 $id = 0; if(array_key_exists('id',$_REQUEST)) $id=intval($_REQUEST['id']);
23 $oldid = $_REQUEST['oldid'] = array_key_exists('oldid',$_REQUEST) ? intval($_REQUEST['oldid']) : 0;
24
25 if($_SESSION['profile']['points'] < 50)
26 {
27 header("location: /account.php");
28 exit;
29 }
30
31 loadem("account");
32
33
34
35 $CSR=""; if(array_key_exists('CSR',$_REQUEST)) $CSR=stripslashes($_REQUEST['CSR']);
36
37
38 if($oldid == "0")
39 {
40 if(array_key_exists('process',$_REQUEST) && $_REQUEST['process'] != "" && $CSR == "")
41 {
42 $_SESSION['_config']['errmsg'] = _("You failed to paste a valid GPG/PGP key.");
43 $id = $oldid;
44 $oldid=0;
45 }
46 }
47
48 $keyid="";
49
50 if(0)
51 {
52 if($_SESSION["profile"]["id"] != 5897)
53 {
54 showheader(_("Welcome to CAcert.org"));
55 echo "The OpenPGP signing system is currently shutdown due to a maintenance. We hope to get it fixed within the next few hours. We are very sorry for the inconvenience.";
56
57 exit(0);
58 }
59 }
60
61
62 function verifyName($name)
63 {
64 if($name == "") return 0;
65 if($name == $_SESSION['profile']['fname']." ".$_SESSION['profile']['lname']) return 1;
66 if($name == $_SESSION['profile']['fname']." ".$_SESSION['profile']['mname']." ".$_SESSION['profile']['lname']) return 1;
67 if($name == $_SESSION['profile']['fname']." ".$_SESSION['profile']['lname']." ".$_SESSION['profile']['suffix']) return 1;
68 if($name == $_SESSION['profile']['fname']." ".$_SESSION['profile']['mname']." ".$_SESSION['profile']['lname']." ".$_SESSION['profile']['suffix']) return 1;
69 return 0;
70
71 }
72
73 function verifyEmail($email)
74 {
75 if($email == "") return 0;
76 if(mysql_num_rows(mysql_query("select * from `email` where `memid`='".$_SESSION['profile']['id']."' and `email`='".mysql_real_escape_string($email)."' and `deleted`=0 and `hash`=''")) > 0) return 1;
77 return 0;
78 }
79
80
81
82 $ToBeDeleted=array();
83 $state=0;
84 if($oldid == "0" && $CSR != "")
85 {
86 $err = runCommand('mktemp --directory /tmp/cacert_gpg.XXXXXXXXXX',
87 "",
88 $tmpdir);
89 if (!$tmpdir)
90 {
91 $err = true;
92 }
93
94 if (!$err)
95 {
96 $err = runCommand("gpg --with-colons --homedir $tmpdir 2>&1",
97 clean_gpgcsr($CSR),
98 $gpg);
99
100 `rm -r $tmpdir`;
101 }
102
103 if ($err)
104 {
105 showheader(_("Welcome to CAcert.org"));
106
107 echo "<p style='color:#ff0000'>"._("There was an error parsing your key.")."</p>";
108 unset($_REQUEST['process']);
109 $id = $oldid;
110 unset($oldid);
111 exit();
112 }
113
114 $lines = "";
115 $gpgarr = explode("\n", trim($gpg));
116 foreach($gpgarr as $line)
117 {
118 #echo "Line[]: $line <br/>\n";
119 if(substr($line, 0, 3) == "pub" || substr($line, 0, 3) == "uid")
120 {
121 if($lines != "")
122 $lines .= "\n";
123 $lines .= $line;
124 }
125 }
126 $gpg = $lines;
127 $expires = 0;
128 $nerr=0; $nok=0;
129 $multiple = 0;
130
131 $resulttable=_("The following UIDs were found in your key:")."<br/><table border='1'><tr><td>#</td><td>"._("Name")."</td><td>"._("Email")."</td><td>Result</td>";
132 $i=0;
133 $lastvalidemail="";
134 $npubs=0;
135 foreach(explode("\n", $gpg) as $line)
136 {
137 $bits = explode(":", $line);
138 $resulttable.="<tr><td>".++$i."</td>";
139 $name = $comment = "";
140 if($bits[0] == "pub")
141 {
142 $npubs++;
143 }
144 if($npubs>1)
145 {
146 showheader(_("Welcome to CAcert.org"));
147 echo "<font color='#ff0000'>"._("Please upload only one key at a time.")."</font>";
148 unset($_REQUEST['process']);
149 $id = $oldid;
150 unset($oldid);
151 exit();
152 }
153 if($bits[0] == "pub" && (!$keyid || !$when))
154 {
155 $keyid = $bits[4];
156 $when = $bits[5];
157 if($bits[6] != "")
158 $expires = 1;
159 }
160 $name="";
161 $comm="";
162 $mail="";
163 $uidformatwrong=0;
164
165 if(sizeof($bits)<10) $uidformatwrong=1;
166
167 if(preg_match("/\@.*\@/",$bits[9]))
168 {
169 showheader(_("Welcome to CAcert.org"));
170
171 echo "<font color='#ff0000'>"._("Multiple Email Adresses per UID are not allowed.")."</font>";
172 unset($_REQUEST['process']);
173 $id = $oldid;
174 unset($oldid);
175 exit();
176 }
177
178 // Name (Comment) <Email>
179 if(preg_match("/^([^\(\)\[@<>]+) \(([^\(\)@<>]*)\) <([\w=\/%.-]*\@[\w.-]*|[\w.-]*\![\w=\/%.-]*)>/",$bits[9],$matches))
180 {
181 $name=trim(hex2bin($matches[1]));
182 $nocomment=0;
183 $comm=trim(hex2bin($matches[2]));
184 $mail=trim(hex2bin($matches[3]));
185 }
186 // Name <EMail>
187 elseif(preg_match("/^([^\(\)\[@<>]+) <([\w=\/%.-]*\@[\w.-]*|[\w.-]*\![\w=\/%.-]*)>/",$bits[9],$matches))
188 {
189 $name=trim(hex2bin($matches[1]));
190 $nocomment=1;
191 $comm="";
192 $mail=trim(hex2bin($matches[2]));
193 }
194 // Unrecognized format
195 else
196 {
197 $nocomment=1;
198 $uidformatwrong=1;
199 }
200 $nameok=verifyName($name);
201 $emailok=verifyEmail($mail);
202
203
204 if($comm != "")
205 $comment[] = $comm;
206
207 $resulttable.="<td bgcolor='#".($nameok?"c0ffc0":"ffc0c0")."'>".sanitizeHTML($name)."</td>";
208 $resulttable.="<td bgcolor='#".($emailok?"c0ffc0":"ffc0c0")."'>".sanitizeHTML($mail)."</td>";
209
210 $uidok=0;
211 if($bits[1]=="r")
212 {
213 $rmessage=_("Error: UID is revoked");
214 }
215 elseif($uidformatwrong==1)
216 {
217 $rmessage=_("The format of the UID was not recognized. Please use 'Name (comment) &lt;email@domain>'");
218 }
219 elseif($mail=="" and $name=="")
220 {
221 $rmessage=_("Error: Both Name and Email address are empty");
222 }
223 elseif($emailok and $nameok)
224 {
225 $uidok=1;
226 $rmessage=_("Name and Email OK.");
227 }
228 elseif(!$emailok and !$nameok)
229 {
230 $rmessage=_("Name and Email both cannot be matched with your account.");
231 }
232 elseif($emailok and $name=="")
233 {
234 $uidok=1;
235 $rmessage=_("The email is OK. The name is empty.");
236 }
237 elseif($nameok and $mail=="")
238 {
239 $uidok=1;
240 $rmessage=_("The name is OK. The email is empty.");
241 }
242 elseif(!$emailok)
243 {
244 $rmessage=_("The email address has not been registered and verified in your account. Please add the email address to your account first.");
245 }
246 elseif(!$nameok)
247 {
248 $rmessage=_("The name in the UID does not match the name in your account. Please verify the name.");
249 }
250
251 else
252 {
253 $rmessage=_("Error");
254 }
255 if($uidok)
256 {
257 $nok++;
258 $resulttable.="<td>$rmessage</td>";
259 $lastvalidemail=$mail;
260 }
261 else
262 {
263 $nerr++;
264 //$ToBeDeleted[]=$i;
265 //echo "Adding UID $i\n";
266 $resulttable.="<td bgcolor='#ffc0c0'>$rmessage</td>";
267 }
268 $resulttable.="</tr>\n";
269
270 if($emailok) $multiple++;
271 }
272 $resulttable.="</table>";
273
274 if($nok==0)
275 {
276 showheader(_("Welcome to CAcert.org"));
277 echo $resulttable;
278
279 echo "<font color='#ff0000'>"._("No valid UIDs found on your key")."</font>";
280 unset($_REQUEST['process']);
281 $id = $oldid;
282 unset($oldid);
283 exit();
284 }
285 elseif($nerr)
286 {
287 $resulttable.=_("The unverified UIDs have been removed, the verified UIDs have been signed.");
288 }
289
290
291 }
292
293
294 if($oldid == "0" && $CSR != "")
295 {
296 //set variable for comment
297 if(trim($_REQUEST['description']) == ""){
298 $description= "";
299 }else{
300 $description= trim(mysql_real_escape_string(stripslashes($_REQUEST['description'])));
301 }
302
303 $query = "insert into `gpg` set `memid`='".intval($_SESSION['profile']['id'])."',
304 `email`='".mysql_real_escape_string($lastvalidemail)."',
305 `level`='1',
306 `expires`='".mysql_real_escape_string($expires)."',
307 `multiple`='".mysql_real_escape_string($multiple)."',
308 `keyid`='".mysql_real_escape_string($keyid)."',
309 `description`='".mysql_real_escape_string($description)."'";
310 mysql_query($query);
311 $id = mysql_insert_id();
312
313
314 $cwd = '/tmp/gpgspace'.$id;
315 mkdir($cwd,0755);
316
317 $fp = fopen("$cwd/gpg.csr", "w");
318 fputs($fp, clean_gpgcsr($CSR));
319 fclose($fp);
320
321
322 system("gpg --homedir $cwd --import $cwd/gpg.csr");
323
324
325 $gpg = trim(`gpg --homedir $cwd --with-colons --fixed-list-mode --list-keys $keyid 2>&1`);
326 $lines = "";
327 $gpgarr = explode("\n", $gpg);
328 foreach($gpgarr as $line)
329 {
330 //echo "Line[]: $line <br/>\n";
331 if(substr($line, 0, 4) == "uid:")
332 {
333 $name = $comment = "";
334 $bits = explode(":", $line);
335
336 $pos = strpos($bits[9], "(") - 1;
337 $nocomment = 0;
338 if($pos < 0)
339 {
340 $nocomment = 1;
341 $pos = strpos($bits[9], "<") - 1;
342 }
343 if($pos < 0)
344 {
345 $pos = strlen($bits[9]);
346 }
347
348 $name = trim(hex2bin(trim(substr($bits[9], 0, $pos))));
349 $nameok=verifyName($name);
350 if($nocomment == 0)
351 {
352 $pos += 2;
353 $pos2 = strpos($bits[9], ")");
354 $comm = trim(hex2bin(trim(substr($bits[9], $pos, $pos2 - $pos))));
355 if($comm != "")
356 $comment[] = $comm;
357 $pos = $pos2 + 3;
358 } else {
359 $pos = strpos($bits[9], "<") + 1;
360 }
361
362 $mail="";
363 if (preg_match("/<([\w.-]*\@[\w.-]*)>/", $bits[9],$match)) {
364 //echo "Found: ".$match[1];
365 $mail = trim(hex2bin($match[1]));
366 }
367 else
368 {
369 //echo "Not found!\n";
370 }
371
372 $emailok=verifyEmail($mail);
373
374 $uidid=$bits[7];
375
376 if($bits[1]=="r")
377 {
378 $ToBeDeleted[]=$uidid;
379 }
380 elseif($mail=="" and $name=="")
381 {
382 //echo "$uidid will be deleted\n";
383 $ToBeDeleted[]=$uidid;
384 }
385 elseif($emailok and $nameok)
386 {
387 }
388 elseif($emailok and $name=="")
389 {
390 }
391 elseif($nameok and $mail=="")
392 {
393 }
394 elseif(!$emailok and !$nameok)
395 {
396 //echo "$uidid will be deleted\n";
397 $ToBeDeleted[]=$uidid;
398 }
399 elseif(!$emailok)
400 {
401 //echo "$uidid will be deleted\n";
402 $ToBeDeleted[]=$uidid;
403 }
404 elseif(!$nameok)
405 {
406 //echo "$uidid will be deleted\n";
407 $ToBeDeleted[]=$uidid;
408 }
409
410 }
411 }
412
413 if(count($ToBeDeleted)>0)
414 {
415 $descriptorspec = array(
416 0 => array("pipe", "r"), // stdin is a pipe that the child will read from
417 1 => array("pipe", "w"), // stdout is a pipe that the child will write to
418 2 => array("pipe", "w") // stderr is a file to write to
419 );
420
421 $stderr = fopen('php://stderr', 'w');
422
423 //echo "Keyid: $keyid\n";
424
425 $process = proc_open("/usr/bin/gpg --homedir $cwd --no-tty --command-fd 0 --status-fd 1 --logger-fd 2 --edit-key $keyid", $descriptorspec, $pipes);
426
427 //echo "Process: $process\n";
428 //fputs($stderr,"Process: $process\n");
429
430 if (is_resource($process)) {
431 //echo("it is a resource\n");
432 // $pipes now looks like this:
433 // 0 => writeable handle connected to child stdin
434 // 1 => readable handle connected to child stdout
435 // Any error output will be appended to /tmp/error-output.txt
436 while (!feof($pipes[1]))
437 {
438 $buffer = fgets($pipes[1], 4096);
439 //echo $buffer;
440
441 if($buffer == "[GNUPG:] GET_BOOL keyedit.sign_all.okay\n")
442 {
443 fputs($pipes[0],"yes\n");
444 }
445 elseif($buffer == "[GNUPG:] GOT_IT\n")
446 {
447 }
448 elseif(ereg("^\[GNUPG:\] GET_BOOL keyedit\.remove\.uid\.okay\s*",$buffer))
449 {
450 fputs($pipes[0],"yes\n");
451 }
452 elseif(ereg("^\[GNUPG:\] GET_LINE keyedit\.prompt\s*",$buffer))
453 {
454 if(count($ToBeDeleted)>0)
455 {
456 $delthisuid=array_pop($ToBeDeleted);
457 //echo "Deleting an UID $delthisuid\n";
458 fputs($pipes[0],"uid ".$delthisuid."\n");
459 }
460 else
461 {
462 //echo "Saving\n";
463 fputs($pipes[0],$state?"save\n":"deluid\n");
464 $state++;
465 }
466 }
467 elseif($buffer == "[GNUPG:] GOOD_PASSPHRASE\n")
468 {
469 }
470 elseif(ereg("^\[GNUPG:\] KEYEXPIRED ",$buffer))
471 {
472 echo "Key expired!\n";
473 exit;
474 }
475 elseif($buffer == "")
476 {
477 //echo "Empty!\n";
478 }
479 else
480 {
481 echo "ERROR: UNKNOWN $buffer\n";
482 }
483
484
485 }
486 //echo "Fertig\n";
487 fclose($pipes[0]);
488
489 //echo stream_get_contents($pipes[1]);
490 fclose($pipes[1]);
491
492 // It is important that you close any pipes before calling
493 // proc_close in order to avoid a deadlock
494 $return_value = proc_close($process);
495
496 //echo "command returned $return_value\n";
497 }
498 else
499 {
500 echo "Keine ressource!\n";
501 }
502
503
504 }
505
506
507 $csrname=generatecertpath("csr","gpg",$id);
508 $do=`gpg --homedir $cwd --batch --export-options export-minimal --export $keyid >$csrname`;
509
510 mysql_query("update `gpg` set `csr`='$csrname' where `id`='$id'");
511 waitForResult('gpg', $id);
512
513 showheader(_("Welcome to CAcert.org"));
514 echo $resulttable;
515 $query = "select * from `gpg` where `id`='$id' and `crt`!=''";
516 $res = mysql_query($query);
517 if(mysql_num_rows($res) <= 0)
518 {
519 echo _("Your certificate request has failed to be processed correctly, please try submitting it again.")."<br>\n";
520 echo _("If this is a re-occuring problem, please send a copy of the key you are trying to signed to support@cacert.org. Thank you.");
521 } else {
522 echo "<pre>";
523 readfile(generatecertpath("crt","gpg",$id));
524 echo "</pre>";
525 }
526
527 showfooter();
528 exit;
529 }
530
531 if($oldid == 2 && array_key_exists('change',$_REQUEST) && $_REQUEST['change'] != "")
532 {
533 showheader(_("My CAcert.org Account!"));
534 foreach($_REQUEST as $id => $val)
535 {
536 if(substr($id,0,14)=="check_comment_")
537 {
538 $cid = intval(substr($id,14));
539 $comment=trim(mysql_real_escape_string(stripslashes($_REQUEST['comment_'.$cid])));
540 mysql_query("update `gpg` set `description`='$comment' where `id`='$cid' and `memid`='".$_SESSION['profile']['id']."'");
541 }
542 }
543 echo(_("Certificate settings have been changed.")."<br/>\n");
544 showfooter();
545 exit;
546 }
547
548 $id = intval($id);
549
550 showheader(_("Welcome to CAcert.org"));
551 includeit($id, "gpg");
552 showfooter();
553 ?>