diff options
Diffstat (limited to 'www/gpg.php')
-rw-r--r-- | www/gpg.php | 495 |
1 files changed, 495 insertions, 0 deletions
diff --git a/www/gpg.php b/www/gpg.php new file mode 100644 index 0000000..38e5426 --- /dev/null +++ b/www/gpg.php @@ -0,0 +1,495 @@ +<? /* + LibreSSL - CAcert web application + Copyright (C) 2004-2008 CAcert Inc. + + 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; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ ?> +<? + require_once("../includes/loggedin.php"); + + $id = 0; if(array_key_exists('id',$_REQUEST)) $id=intval($_REQUEST['id']); + $oldid = $_REQUEST['oldid'] = array_key_exists('oldid',$_REQUEST) ? intval($_REQUEST['oldid']) : 0; + + if($_SESSION['profile']['points'] < 50) + { + header("location: /account.php"); + exit; + } + + loadem("account"); + + + + $CSR=""; if(array_key_exists('CSR',$_REQUEST)) $CSR=stripslashes($_REQUEST['CSR']); + + + if($oldid == "0") + { + if(array_key_exists('process',$_REQUEST) && $_REQUEST['process'] != "" && $CSR == "") + { + $_SESSION['_config']['errmsg'] = _("You failed to paste a valid GPG/PGP key."); + $id = $oldid; + $oldid=0; + } + } + + $keyid=""; + +if(0) +{ + if($_SESSION["profile"]["id"] != 5897) + { + showheader(_("Welcome to CAcert.org")); + 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."; + + exit(0); + } +} + + +function verifyName($name) +{ + if($name == "") return 0; + if($name == $_SESSION['profile']['fname']." ".$_SESSION['profile']['lname']) return 1; + if($name == $_SESSION['profile']['fname']." ".$_SESSION['profile']['mname']." ".$_SESSION['profile']['lname']) return 1; + if($name == $_SESSION['profile']['fname']." ".$_SESSION['profile']['lname']." ".$_SESSION['profile']['suffix']) return 1; + if($name == $_SESSION['profile']['fname']." ".$_SESSION['profile']['mname']." ".$_SESSION['profile']['lname']." ".$_SESSION['profile']['suffix']) return 1; + return 0; + +} + +function verifyEmail($email) +{ + if($email == "") return 0; + 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; + return 0; +} + + + + $ToBeDeleted=array(); + $state=0; + if($oldid == "0" && $CSR != "") + { + $debugkey = $gpgkey = clean_csr($CSR); + $debugpg = $gpg = trim(`echo "$gpgkey"|gpg --with-colons --homedir /tmp 2>&1`); + $lines = ""; + $gpgarr = explode("\n", $gpg); + foreach($gpgarr as $line) + { + #echo "Line[]: $line <br/>\n"; + if(substr($line, 0, 3) == "pub" || substr($line, 0, 3) == "uid") + { + if($lines != "") + $lines .= "\n"; + $lines .= $line; + } + } + $gpg = $lines; + $expires = 0; + $nerr=0; $nok=0; + $multiple = 0; + + $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>"; + $i=0; + $lastvalidemail=""; + foreach(explode("\n", $gpg) as $line) + { + $bits = explode(":", $line); + $resulttable.="<tr><td>".++$i."</td>"; + $name = $comment = ""; + if($bits[0] == "pub" && (!$keyid || !$when)) + { + $keyid = $bits[4]; + $when = $bits[5]; + if($bits[6] != "") + $expires = 1; + } + $name=""; + $comm=""; + $mail=""; + $uidformatwrong=0; + + if(sizeof($bits)<10) $uidformatwrong=1; + + if(preg_match("/\@.*\@/",$bits[9])) + { + showheader(_("Welcome to CAcert.org")); + + echo "<font color='#ff0000'>"._("Multiple Email Adresses per UID are not allowed.")."</font>"; + unset($_REQUEST['process']); + $id = $oldid; + unset($oldid); + exit(); + } + + // Name (Comment) <Email> + if(preg_match("/^([^\(\)\[@<>]+) \(([^\(\)@<>]*)\) <([\w=\/%.-]*\@[\w.-]*|[\w.-]*\![\w=\/%.-]*)>/",$bits[9],$matches)) + { + $name=trim(hex2bin($matches[1])); + $nocomment=0; + $comm=trim(hex2bin($matches[2])); + $mail=trim(hex2bin($matches[3])); + } + // Name <EMail> + elseif(preg_match("/^([^\(\)\[@<>]+) <([\w=\/%.-]*\@[\w.-]*|[\w.-]*\![\w=\/%.-]*)>/",$bits[9],$matches)) + { + $name=trim(hex2bin($matches[1])); + $nocomment=1; + $comm=""; + $mail=trim(hex2bin($matches[2])); + } + // Unrecognized format + else + { + $nocomment=1; + $uidformatwrong=1; + } + $nameok=verifyName($name); + $emailok=verifyEmail($mail); + + + if($comm != "") + $comment[] = $comm; + + $resulttable.="<td bgcolor='#".($nameok?"c0ffc0":"ffc0c0")."'>".sanitizeHTML($name)."</td>"; + $resulttable.="<td bgcolor='#".($emailok?"c0ffc0":"ffc0c0")."'>".sanitizeHTML($mail)."</td>"; + + $uidok=0; + if($bits[1]=="r") + { + $rmessage=_("Error: UID is revoked"); + } + elseif($uidformatwrong==1) + { + $rmessage=_("The format of the UID was not recognized. Please use 'Name (comment) <email@domain>'"); + } + elseif($mail=="" and $name=="") + { + $rmessage=_("Error: Both Name and Email address are empty"); + } + elseif($emailok and $nameok) + { + $uidok=1; + $rmessage=_("Name and Email OK."); + } + elseif(!$emailok and !$nameok) + { + $rmessage=_("Name and Email both cannot be matched with your account."); + } + elseif($emailok and $name=="") + { + $uidok=1; + $rmessage=_("The email is OK. The name is empty."); + } + elseif($nameok and $mail=="") + { + $uidok=1; + $rmessage=_("The name is OK. The email is empty."); + } + elseif(!$emailok) + { + $rmessage=_("The email address has not been registered and verified in your account. Please add the email address to your account first."); + } + elseif(!$nameok) + { + $rmessage=_("The name in the UID does not match the name in your account. Please verify the name."); + } + + else + { + $rmessage=_("Error"); + } + if($uidok) + { + $nok++; + $resulttable.="<td>$rmessage</td>"; + $lastvalidemail=$mail; + } + else + { + $nerr++; + //$ToBeDeleted[]=$i; + //echo "Adding UID $i\n"; + $resulttable.="<td bgcolor='#ffc0c0'>$rmessage</td>"; + } + $resulttable.="</tr>\n"; + + if($emailok) $multiple++; + } + $resulttable.="</table>"; + + + if($nok==0) + { + showheader(_("Welcome to CAcert.org")); + echo $resulttable; + + echo "<font color='#ff0000'>"._("No valid UIDs found on your key")."</font>"; + unset($_REQUEST['process']); + $id = $oldid; + unset($oldid); + $do = `echo "$debugkey\n--\n$debugpg\n--" >> /www/tmp/gpg.debug`; + exit(); + } + elseif($nerr) + { + $resulttable.=_("The unverified UIDs have been removed, the verified UIDs have been signed."); + } + + + } + + + if($oldid == "0" && $CSR != "") + { + $query = "insert into `gpg` set `memid`='".intval($_SESSION['profile']['id'])."', + `email`='".mysql_real_escape_string($lastvalidemail)."', + `level`='1', + `expires`='".mysql_real_escape_string($expires)."', + `multiple`='".mysql_real_escape_string($multiple)."', + `keyid`='".mysql_real_escape_string($keyid)."'"; + mysql_query($query); + $id = mysql_insert_id(); + + + $cwd = '/tmp/gpgspace'.$id; + mkdir($cwd,0755); + + $fp = fopen("$cwd/gpg.csr", "w"); + fputs($fp, clean_csr($CSR)); + fclose($fp); + + + system("gpg --homedir $cwd --import $cwd/gpg.csr"); + + + $debugpg = $gpg = trim(`gpg --homedir $cwd --with-colons --fixed-list-mode --list-keys $keyid 2>&1`); + $lines = ""; + $gpgarr = explode("\n", $gpg); + foreach($gpgarr as $line) + { + //echo "Line[]: $line <br/>\n"; + if(substr($line, 0, 4) == "uid:") + { + $name = $comment = ""; + $bits = explode(":", $line); + + $pos = strpos($bits[9], "(") - 1; + $nocomment = 0; + if($pos < 0) + { + $nocomment = 1; + $pos = strpos($bits[9], "<") - 1; + } + if($pos < 0) + { + $pos = strlen($bits[9]); + } + + $name = trim(hex2bin(trim(substr($bits[9], 0, $pos)))); + $nameok=verifyName($name); + if($nocomment == 0) + { + $pos += 2; + $pos2 = strpos($bits[9], ")"); + $comm = trim(hex2bin(trim(substr($bits[9], $pos, $pos2 - $pos)))); + if($comm != "") + $comment[] = $comm; + $pos = $pos2 + 3; + } else { + $pos = strpos($bits[9], "<") + 1; + } + + $mail=""; + if (preg_match("/<([\w.-]*\@[\w.-]*)>/", $bits[9],$match)) { + //echo "Found: ".$match[1]; + $mail = trim(hex2bin($match[1])); + } + else + { + //echo "Not found!\n"; + } + + $emailok=verifyEmail($mail); + + $uidid=$bits[7]; + + if($bits[1]=="r") + { + $ToBeDeleted[]=$uidid; + } + elseif($mail=="" and $name=="") + { + //echo "$uidid will be deleted\n"; + $ToBeDeleted[]=$uidid; + } + elseif($emailok and $nameok) + { + } + elseif($emailok and $name=="") + { + } + elseif($nameok and $mail=="") + { + } + elseif(!$emailok and !$nameok) + { + //echo "$uidid will be deleted\n"; + $ToBeDeleted[]=$uidid; + } + elseif(!$emailok) + { + //echo "$uidid will be deleted\n"; + $ToBeDeleted[]=$uidid; + } + elseif(!$nameok) + { + //echo "$uidid will be deleted\n"; + $ToBeDeleted[]=$uidid; + } + + } + } + + + + + if(count($ToBeDeleted)>0) + { + + + $descriptorspec = array( + 0 => array("pipe", "r"), // stdin is a pipe that the child will read from + 1 => array("pipe", "w"), // stdout is a pipe that the child will write to + 2 => array("pipe", "w") // stderr is a file to write to + ); + + $stderr = fopen('php://stderr', 'w'); + + + //echo "Keyid: $keyid\n"; + + $process = proc_open("/usr/bin/gpg --homedir $cwd --no-tty --command-fd 0 --status-fd 1 --logger-fd 2 --edit-key $keyid", $descriptorspec, $pipes); + + //echo "Process: $process\n"; + //fputs($stderr,"Process: $process\n"); + + if (is_resource($process)) { + //echo("it is a resource\n"); + // $pipes now looks like this: + // 0 => writeable handle connected to child stdin + // 1 => readable handle connected to child stdout + // Any error output will be appended to /tmp/error-output.txt + while (!feof($pipes[1])) + { + $buffer = fgets($pipes[1], 4096); + //echo $buffer; + + if($buffer == "[GNUPG:] GET_BOOL keyedit.sign_all.okay\n") + { + fputs($pipes[0],"yes\n"); + } + elseif($buffer == "[GNUPG:] GOT_IT\n") + { + } + elseif(ereg("^\[GNUPG:\] GET_BOOL keyedit\.remove\.uid\.okay\s*",$buffer)) + { + fputs($pipes[0],"yes\n"); + } + elseif(ereg("^\[GNUPG:\] GET_LINE keyedit\.prompt\s*",$buffer)) + { + if(count($ToBeDeleted)>0) + { + $delthisuid=array_pop($ToBeDeleted); + //echo "Deleting an UID $delthisuid\n"; + fputs($pipes[0],"uid ".$delthisuid."\n"); + } + else + { + //echo "Saving\n"; + fputs($pipes[0],$state?"save\n":"deluid\n"); + $state++; + } + } + elseif($buffer == "[GNUPG:] GOOD_PASSPHRASE\n") + { + } + elseif(ereg("^\[GNUPG:\] KEYEXPIRED ",$buffer)) + { + echo "Key expired!\n"; + exit; + } + elseif($buffer == "") + { + //echo "Empty!\n"; + } + else + { + echo "ERROR: UNKNOWN $buffer\n"; + } + + + } + //echo "Fertig\n"; + fclose($pipes[0]); + + //echo stream_get_contents($pipes[1]); + fclose($pipes[1]); + + // It is important that you close any pipes before calling + // proc_close in order to avoid a deadlock + $return_value = proc_close($process); + + //echo "command returned $return_value\n"; + } + else + { + echo "Keine ressource!\n"; + } + + + } + + + $csrname=generatecertpath("csr","gpg",$id); + $do=`gpg --homedir $cwd --batch --export-options export-minimal --export $keyid >$csrname`; + + mysql_query("update `gpg` set `csr`='$csrname' where `id`='$id'"); + waitForResult('gpg', $id); + + showheader(_("Welcome to CAcert.org")); + echo $resulttable; + $query = "select * from `gpg` where `id`='$id' and `crt`!=''"; + $res = mysql_query($query); + if(mysql_num_rows($res) <= 0) + { + echo _("Your certificate request has failed to be processed correctly, please try submitting it again.")."<br>\n"; + 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."); + } else { + echo "<pre>"; + readfile(generatecertpath("crt","gpg",$id)); + echo "</pre>"; + } + + showfooter(); + exit; + } + + $id = intval($id); + + showheader(_("Welcome to CAcert.org")); + includeit($id, "gpg"); + showfooter(); +?> |