<?php
/**************************************************************/
/*  PHP-GPG Keyring Admin v2.2
/*  Copyright 2005 Nathan Ho | TheosLogic Productions
/*  http://www.theoslogic.com/scripts/pgkadmin/
/*  All Rights Reserved.
/*  You are free to use this code as you will, as long as you 
/*  leave this copyright information intact.
/**************************************************************/

/**************************************************************
*  SPECIFIC VARIABLES FOR THIS INSTALLATION
**************************************************************/

// unless another location is specified, assume their keyring is stored in their document root
$gpgkeyloc $_SERVER['DOCUMENT_ROOT']."/.gnupg";
putenv("GNUPGHOME=$gpgkeyloc");
$gpgoutput $gpgkeyloc."/.tmpgpgout";
/*
// Alternatively, you can hard-code the location of your installed GPG binary if you wish
$gpgbin = "/usr/bin/gpg";
*/
$gpgbin escapeshellcmd(shell_exec("which gpg"));
// see if the file was detected properly - if not, try and set it manually
if (!$gpgbin) {
  
$gpgbin "/usr/bin/gpg";
}
// if auto-detection and manual declaration have failed, stop the script
if (!is_file($gpgbin)) {
  echo 
"I'm sorry, but I was not able to locate the GPG program on your server.  Please either set this value manually in the script, or check with your hosting provider!\n";
  exit();
}
$gpgcmd $gpgbin." --no-secmem-warning --homedir ".$gpgkeyloc;

/***************************************************************/
/* If you want this page to require a username and password,
/* then uncomment the next three lines and set the user and pass
/* values accordingly
/***************************************************************/

// $authentication_enabled = "yes";
// $valid_admin_user = "pgkadmin";
// $valid_admin_pwd  = "pkgadmin";

/***************************************************************/
 
function fix_date($bdate) {
   
$dbits explode("-",$bdate);
   
$new_date date ('M j, Y'mktime (0,0,0,date($dbits['1']),date($dbits['2']),date($dbits['0'])));
   return 
$new_date;
 }

/**************************************************************
* AUTHENTICATE THE USER, if enabled
***************************************************************/
if ($authentication_enabled == "yes") {
 IF (!isset(
$_SERVER['PHP_AUTH_USER'])) {
        
// IF EMPTY, SEND HEADER, CAUSING DIALOG BOX TO APPEAR
        
header('WWW-Authenticate: Basic realm="Conference Admin"');
        
header('HTTP/1.0 401 Unauthorized');
        echo 
"Authorization required";
        exit;
 } ELSE {
        IF (
$_SERVER['PHP_AUTH_USER']!=$valid_admin_user OR $_SERVER['PHP_AUTH_PW']!=$valid_admin_pwd) {
                
header('WWW-Authenticate: Basic Realm="Conference Admin"');
                
header('HTTP/1.0 401 Unauthorized');
                echo 
"Authorization required";
                exit;
        }
 }
}
// first thing's first - check to make sure that they have a GPG keyring setup, or that the base directory exists
if ($gpgkeyloc == "") {
  
$gpgkeyloc $_SERVER['DOCUMENT_ROOT']."/.gnupg";
}
if (!
file_exists("$gpgkeyloc")) {
  
shell_exec("mkdir ".$_SERVER['DOCUMENT_ROOT']."/.gnupg");
  
shell_exec("chmod 0700 ".$_SERVER['DOCUMENT_ROOT']."/.gnupg");
}

if (
$_GET['dlkey']) {
  
$downloadkey shell_exec($gpgcmd." --armor --export 0x".$_GET['dlkey']." > ".$gpgoutput);
  
$target_name "0x".$_GET['dlkey'].".asc";
  
header('Content-Description: File Transfer');
  
header('Content-Type: application/force-download');
  
header('Content-Disposition: attachment; filename=' $target_name);
  
readfile($gpgoutput);
  
unlink($gpgoutput);
  exit();
}

?>
<html>
 <head>
  <style type="text/css">@import url(styles.css);</style>
  <script language="javascript" type="text/javascript">
  <!--//
   function show(which){
    if (document.getElementById && document.createTextNode) {
      // first, switch the style on the active block to show the hidden material
      m=document.getElementById("addchoice");
      trig=m.getElementsByTagName("div").item(which).style.display;
      if (trig=="block") trig="none";
       else if (trig=="" || trig=="none") trig="block";

      // next, switch the OTHER block to be hidden - we only show one at a time
      one=document.getElementById("addblock");
      two=document.getElementById("addfile");
      if (which==0) {
        two.style.display="none";
        two.disabled = true;
      } else if (which==1) {
        one.style.display="none";
        one.disabled = true;
      }

      // switch the +/- sign next to the active element
      m.getElementsByTagName("div").item(which).style.display=trig;
      var    highlighttext="-";
      var    normaltext="+";
      t=m.getElementsByTagName("h5").item(which);
      h=t.getElementsByTagName("a").item(0).firstChild;
      if (trig=="none"){h.nodeValue=h.nodeValue.replace(highlighttext,normaltext);}
      else {h.nodeValue=h.nodeValue.replace(normaltext,highlighttext);}
    }
  } 
  //-->
 </script>
 </head>
<body>

<table width="700" border="0" cellpadding="7" cellspacing="0" style="padding-bottom: 10px; margin-bottom: 20px; border-bottom: 2px solid black;">
<tr><td colspan="2" align="center">
 <span style="font-size: 1.4em; font-weight: bold; padding: 5px; margin: 5px; border: 1px solid black;">
   PHP-GPG Keyring Admin
 </span>
</td></tr>
<tr><td align="right">
<form method="post" action="<?=$_SERVER['PHP_SELF'];?>">
  <input type="hidden" name="gpgact" value="list" />
  <input type="submit" value="List All GPG Keys" />
</form>
</td><td align="left">
<form method="post" action="<?=$_SERVER['PHP_SELF'];?>">
  <input type="hidden" name="gpgact" value="add" />
  <input type="submit" value="Add new GPG Key" />
</form>
</td></tr>
<tr><td colspan="2" align="center">
<form method="post" action="<?=$_SERVER['PHP_SELF'];?>">
<input type="hidden" name="gpgact" value="search" />
<input type="text" name="searchval" size="40" />
<input type="submit" value="Search Keys" />
</form>
</td></tr>
</table>

<?php
$keytest 
shell_exec($gpgcmd." --list-keys --with-colons");
$the_keys explode("\n",$keytest);
$cnt=0;
foreach (
$the_keys as $ckeys) {
  if (
substr($ckeys03) == "pub") {
    
$key_splits explode(":",$ckeys);
    
$keyIDs[] = substr($key_splits['4'], 89);
    
$keyLongIDs[] = $key_splits['4'];
    
$kDate[] = fix_date($key_splits[5]);
    
$name_mail explode("<",$key_splits['9']);
    
$kName[] = $name_mail['0'];
    
$kEmail[] = preg_replace('/>/','',$name_mail['1']);
  }
}
$numKeys count($keyIDs) - 1;

/* error checking
echo "<pre>\n";
  echo "Key IDs<br />\n";
  print_r($keyIDs);
  echo "Long Key IDs<br />\n";
  print_r($keyLongIDs);
  echo "Creation Dates<br />\n";
  print_r($kDate);
  echo "Names<br />\n";
  print_r($kName);
  echo "Emails<br />\n";
  print_r($kEmail);
echo "</pre>\n";
*/


if ($_POST) {
  if (
$_POST['gpgact'] == "list") {
    for (
$x=0;$x<=$numKeys;$x++) {
     echo 
"<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n";
     echo 
"<td width=\"60\" align=\"center\"><form method=\"POST\" action=\"\"><input type=\"hidden\" name=\"gpgact\" value=\"del\" /><input type=\"hidden\" name=\"id\" value=\"".$keyIDs[$x]."\" /><input type=\"submit\" value=\"DEL\" /></form></td>\n";
     echo 
"<td width=\"60\" align=\"center\"><form method=\"POST\" action=\"\"><input type=\"hidden\" name=\"gpgact\" value=\"view\" /><input type=\"hidden\" name=\"id\" value=\"".$keyIDs[$x]."\" /><input type=\"submit\" value=\"VIEW\" /></form></td>\n";
     echo 
"<td width=\"120\" class=\"lable\">0x".$keyIDs[$x]."</td>\n";
     echo 
"<td width=\"120\" class=\"date\">".$kDate[$x]."</td>\n";
     echo
"<td width=\"340\" class=\"email\" align=\"right\">".$kEmail[$x]."</td></table><br />\n";
    }
  } else if (
$_POST['gpgact'] == "search") {
    if (
$_POST['searchval'] == "") {
     echo 
"<div class=\"error\">I'm sorry, you cannot search for a blank string.  Please input a search value.</div>";
    } else {
     for (
$x=0;$x<=$numKeys;$x++) {
      if (
       
strstrstrtolower($keyIDs[$x]), strtolower($_POST['searchval']) ) ||
       
strstrstrtolower($kDate[$x]), strtolower($_POST['searchval']) ) ||
       
strstrstrtolower($kEmail[$x]), strtolower($_POST['searchval']) )
         ) {
        echo 
"<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n";
        echo 
"<td width=\"60\" align=\"center\"><form method=\"POST\" action=\"\"><input type=\"hidden\" name=\"gpgact\" value=\"del\" /><input type=\"hidden\" name=\"id\" value=\"".$keyIDs[$x]."\" /><input type=\"submit\" value=\"DEL\" /></form></td>\n";
        echo 
"<td width=\"60\" align=\"center\"><form method=\"POST\" action=\"\"><input type=\"hidden\" name=\"gpgact\" value=\"view\" /><input type=\"hidden\" name=\"id\" value=\"".$keyIDs[$x]."\" /><input type=\"submit\" value=\"VIEW\" /></form></td>\n";
        echo 
"<td width=\"120\" class=\"lable\">0x".$keyIDs[$x]."</td>\n";
        echo 
"<td width=\"120\" class=\"date\">".$kDate[$x]."</td>\n";
        echo
"<td width=\"340\" class=\"email\" align=\"right\">".$kEmail[$x]."</td></table><br />\n";
        
$found "yes";
      } else {
        if (
$found != "yes") {
          
$found "no";
        }
      }
    }
      if (
$found == "no") {
        unset(
$found);
        echo 
"<div class=\"error\">I'm sorry, but there are no keys with the string \"<b>".$_POST['searchval']."</b>\" in them.  Please try again!</div>\n";
      }
    }
  } else if (
$_POST['gpgact'] == "add") {
    if (!
$_POST['yn_new_key']) {
?>
   <!-- Backward compatibility hacks -->
   <noscript>
     <style type="text/css">#addchoice div{display:block;}</style>
   </noscript>    
   <script language="JavaScript">
   <!--
   if (!document.getElementById && !document.createTextNode){
     document.write('<style type="text/css">#addchoice div{display:block;}</style>')
   }
   //-->
   </script>

   <p>
   <h4>Please choose one of the following:</h4>
   <div id="addchoice">
   <form method="POST" name="addnewkeyform" action="<?=$_SERVER['PHP_SELF'];?>" enctype="multipart/form-data">
   <input type="hidden" name="yn_new_key" value="yes" />
   <input type="hidden" name="gpgact" value="add" />

     <h5 class="addchblock"> <a href="#" onclick="show(0);">+ I want to submit a key block</a></h5>
     <div id="addblock"><b>Copy and Paste your PGP/GPG keyblock into this box:</b><br />
     <textarea name="new_keyblock" rows="8" cols="60"></textarea></div>

     <h5 class="addchblock"> <a href="#" onclick="show(1);">+ I want to upload a key (.asc) file</a></h5>
     <div id="addfile"><b>Please select the PGP/GPG ASCII-armored key file to add:</b><br /><br />
     <input type="file" name="new_keyfile" size="60" /></div>

   </div>

   <br /><br />
   <div style="width: 500px; text-align: center;"><input type="submit" value="Add This Key!" /></div>

   </form>
<?php
    
} else {
     
// if we're uploading a new key or keys, first figure out what method was used and import the key appropriately
     
if ($_FILES && (!$_POST['new_keyblock'])) {
    switch (
$_FILES['new_keyfile']['error'])
     {  case 
1:
           print 
'<p> The file is bigger than this PHP installation allows - ';
           break;
        case 
2:
           print 
'<p> The file is bigger than this form allows - ';
           break;
        case 
3:
           print 
'<p> Only part of the file was uploaded - ';
           break;
        case 
4:
           print 
'<p> No file was uploaded - ';
           break;
     }
    if (
move_uploaded_file($_FILES['new_keyfile']['tmp_name'], $gpgkeyloc.$_FILES['new_keyfile']['name'])) {
      
//import the new key
      
$add_new_key shell_exec($gpgcmd." --import --verbose ".$gpgkeyloc.$_FILES['new_keyfile']['name']." 2> ".$gpgoutput);
    } else {
      echo 
"Problem adding key<br />\n";
    }
     } else {
    
$filename $gpgkeyloc."/temp.asc";
    if (!
$handle fopen($filename'w')) {
           echo 
"Cannot open file ($filename)";
           exit;
    }
    if (
fwrite($handle$_POST['new_keyblock']) === FALSE) {
           echo 
"Cannot write to file ($filename)";
             exit;
    }
    
$add_new_keys shell_exec($gpgcmd." --import --verbose ".$filename." 2> ".$gpgoutput);
     }
    
$handle fopen($gpgoutput"r");
    
$add_new_keys fread($handlefilesize($gpgoutput));
    
fclose($handle);
    
$added_keys explode("\n",$add_new_keys);
    
unlink($gpgoutput);
    
//parse the verbose output to get the new keyID 
    
foreach ($added_keys as $findIDs) {
      if (
strstr($findIDs,"gpg: key")) {
        
$tempID substr($findIDs,9,8);
      } else if (
strstr($findIDs,"Total number processed:")) {
        
$ttl_newkeys substr($findIDs,-1,1);
      } else if (
strstr($findIDs,"unchanged")) {
        
$unchanged substr($findIDs,-1,1);
      } else if (
strstr($findIDs,"imported")) {
        
$newchange substr($findIDs,-1,1);
      } 
    }
    
$getTheLongID shell_exec($gpgcmd." --with-colons --list-keys 0x".$tempID);
    
$getLongID explode("\n",$getTheLongID);
    foreach(
$getLongID as $longID) {
      if (
substr($longID,0,3) == "pub") {
        
$splitFind explode(":"$longID);
        
$trustKey $splitFind['4'];
        
// set the new key to be trusted ultimately
        
$skt_string $gpgcmd." --update-trustdb --trusted-key ".$trustKey;
        
$setTrust shell_exec($skt_string);
      } 
    }
           if (
$unchanged || $newchange) {
      if (
$unchanged && !$newchange) {
        
$report "<div style=\"width: 650px; text-align: center;\"> No changes have been made to your GPG keyring.<br />";
      } else {
        
$report "<div style=\"width: 650px; text-align: center;\"> GPG keyring has been updated!<br />";
      } 
      if (
$unchanged) { 
        if (
$unchanged 1) {
          
$report .= $unchanged." PGP keys unchanged. "
        } else {
          
$report .= $unchanged." PGP key unchanged. "
        }
      }
      if (
$newchange) { 
        if (
$newchange 1) {
          
$report .= $newchange." PGP keys added. "
        } else {
          
$report .= $newchange." PGP key added. ";
        }
      }
      
$report .="</div><br />\n";
    } else {
      
$report "<div style=\"width: 650px; text-align: center;\">No changes have been made to your GPG keyring.</div><br />\n";
    }
    echo 
$report
    if ((
$_FILES) && (!$_POST['new_keyblock'])) {
      
unlink($gpgkeyloc $_FILES['new_keyfile']['name']);
    } else {
      
unlink($filename);
    }
     }
  } else if (
$_POST['gpgact'] == "view") {
      
$showkey shell_exec($gpgcmd." --armor --export 0x".$_POST['id']);
      echo 
"<a href=\"".$_SERVER['PHP_SELF']."?key=".$_POST['id']."\"> Emailable Link</a><br />\n";
      echo 
"<a href=\"".$_SERVER['PHP_SELF']."?dlkey=".$_POST['id']."\">Download ASC File</a><br />\n";
      echo 
"<p><pre style=\"margin-left: 40px;\">\n\n".$showkey."\n</pre>\n";
  } else if (
$_POST['gpgact'] == "del") {
    if (!
$_POST['del_verified']) {
      
$delkeyidx array_search($_POST['id'], $keyIDs);
      echo 
"<div align=\"center\" style=\"width: 500px;\"><p>Are you *sure* that you want to delete this key?<br /><br />\n";
      echo 
"<blockquote>\n";
    echo 
"<table border=\"0\" width=\"500\" cellspacing=\"7\">\n";
        echo 
"<tr><td class=\"lable\">Key ID</td><td>0x".$keyIDs[$delkeyidx]." </td></tr>\n";
        echo 
"<tr><td class=\"lable\">Creation Date</td><td>".$kDate[$delkeyidx]."</td></tr>\n";
        echo 
"<tr><td class=\"lable\">Name</td><td>".$kName[$delkeyidx]."</td></tr>\n";
    echo 
"<tr><td class=\"lable\">Email</td><td>".$kEmail[$delkeyidx]."</td></tr></table>\n";
    echo 
"</div>\n";
      echo 
"</blockquote>\n";
      echo 
"<br /><p><div style=\"width: 300px; text-align: center; float: left;\">\n";
      echo 
"<form method=\"POST\" action=\"".$_SERVER['PHP_SELF']."\">\n";
      echo 
"<input type=\"hidden\" name=\"gpgact\" value=\"del\" />\n";
      echo 
"<input type=\"hidden\" name=\"id\" value=\"".$_POST['id']."\" />\n";
      echo 
"<input type=\"hidden\" name=\"del_verified\" value=\"yes\" />\n";
      echo 
"<input type=\"submit\" value=\"Yes - Delete this key\" />\n";
      echo 
"</form>\n";
      echo 
"</div>\n";
      echo 
"<div style=\"width: 200px; text-align: center; float: left;\">\n";
      echo 
"<form method=\"POST\" action=\"".$_SERVER['PHP_SELF']."\">\n";
      echo 
"<input type=\"hidden\" name=\"gpgact\" value=\"list\" />\n";
      echo 
"<input type=\"submit\" value=\"No - keep this key\">\n";
      echo 
"</form>\n";
      echo 
"</div>\n";
      echo 
"</div>\n";
    } else {
      
$key_delete =  shell_exec($gpgcmd." --delete-key --batch --yes 0x".$_POST['id']);
      echo 
"<div style=\"width: 600px; text-align: center;\">Key deleted successfully!</div><br />\n";
    }
  }
} else if (
$_GET['key']) {
    
$showkey shell_exec($gpgcmd." --armor --export 0x".$_GET['key']);
     echo 
"<a href=\"".$_SERVER['PHP_SELF']."?key=".$_GET['key']."\">Emailable Link</a><br />\n";
     echo 
"<a href=\"".$_SERVER['PHP_SELF']."?dlkey=".$_GET['key']."\">Download ASC File</a><br />\n";
     echo 
"<p><pre>\n\n".$showkey."\n</pre>\n";
} else {
    for (
$x=0;$x<=$numKeys;$x++) {
     echo 
"<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n";
     echo 
"<td width=\"60\" align=\"center\"><form method=\"POST\" action=\"\"><input type=\"hidden\" name=\"gpgact\" value=\"del\" /><input type=\"hidden\" name=\"id\" value=\"".$keyIDs[$x]."\" /><input type=\"submit\" value=\"DEL\" /></form></td>\n";
     echo 
"<td width=\"60\" align=\"center\"><form method=\"POST\" action=\"\"><input type=\"hidden\" name=\"gpgact\" value=\"view\" /><input type=\"hidden\" name=\"id\" value=\"".$keyIDs[$x]."\" /><input type=\"submit\" value=\"VIEW\" /></form></td>\n";
     echo 
"<td width=\"120\" class=\"lable\">0x".$keyIDs[$x]."</td>\n";
     echo 
"<td width=\"120\" class=\"date\">".$kDate[$x]."</td>\n";
     echo
"<td width=\"340\" class=\"email\" align=\"right\">".$kEmail[$x]."</td></table><br />\n";
    }

}

?>

</body>
</html>