uncoupled web frontend (lacre-webgate) from gpg-lacre; moved cron.py from frontend to backend dir and changed name (webgate-cron.py);

This commit is contained in:
muppeth 2022-10-12 16:29:09 +02:00
parent 002e150805
commit 2ebd090d6c
Signed by: muppeth
GPG key ID: 0EBC7B9848D04031
22 changed files with 0 additions and 1252 deletions

View file

@ -1,70 +0,0 @@
gpg-mailgate-web
----------------
gpg-mailgate-web is a web interface designed to allow any web user
to upload their PGP public key and then have all mail sent via
your mail server be encrypted. (Note: this is not meant for email
authentication, only encryption.)
After submitting their key to a web form, the user will be required
to confirm their email address. A cron script will register the
public key with gpg-mailgate (keyhome_only must be set to no
currently, which is the default) after email confirmation. From
then on, email to the specified address will be encrypted with
the public key.
gpg-mailgate-web is useful for two purposes: for a transparent
PGP encryption layer in front of any web application, or simple as
a web interface for gpg-mailgate so that users on your mail server
can easily upload and change their PGP keys.
Note that all processing relating to the mail server is done via the
cron script. This means that gpg-mailgate and the gpgmw cron can
be installed on a different server from the web server. The MySQL
database must be shared between the two applications though.
1. Installation instructions:
1) Install gpg-mailgate.
2) Create a MySQL database for gpg-mailgate.
a) Schema file is located in schema.sql
b) Database name and account goes in /etc/gpg-mailgate.conf (and set enabled = yes)
3) Copy the contents of public_html to your web directory.
4) Move config.sample.php to config.php and edit the configuration file.
5) Copy cron.py to /usr/local/bin/gpgmw-cron.py and set up a cron job
a) Create /etc/cron.d/gpgmw with the contents:
*/3 * * * * nobody /usr/bin/python /usr/local/bin/gpgmw-cron.py > /dev/null
6) Ensure that cron is working and test your new gpg-mailgate-web installation!
----------------------------------------
2. Adding rudimentary HKP Keyserver functionality for submitting public keys from the GPG client
(so far only implemented and tested with lighttpd - basically you just need to make your http server
listen on port 11371, redirect it to your gpg-mailgate-web directory and add a rewrite rule to catch
'pks/add' in the URI)
1) add the following lines to your lighttp.conf file and change the path to your gpg-mailgate-web directory
server.reject-expect-100-with-417 = "disable"
$SERVER["socket"] == ":11371" {
server.document-root = "/var/www/gpgmw"
setenv.add-response-header = ( "Via" => "1.1 yourserver.tld:11371 (lighttpd)" )
accesslog.filename = "/var/log/lighttpd/hkp-access.log"
url.rewrite-once = ( "^/pks/(.*)" => "/index.php?/pks/$1" )
}
2) reload lighttpd: /etc/init.d/lighttpd restart
3) in the index.php add the following line after the other required_once(...) lines:
require_once("include/phphkp.php");
4) change the constants in the include/phphkp.php file!
5) check if it works with a GPG client of your choice pushing a public key to your server's
domain or IP
(HTTP request to http://yourserver.tld:11371/pks/add with the public key in a POST variable 'keytext')

View file

@ -1,54 +0,0 @@
<?php
/*
gpg-mailgate
This file is part of the gpg-mailgate source code.
gpg-mailgate 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, either version 3 of the License, or
(at your option) any later version.
gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
*/
/*
DO NOT EDIT THIS FILE!
Instead, copy over "config.sample.php" to "config.php" and edit settings there.
*/
$config = array();
$config['email_web'] = 'admin@example.com';
$config['email_from'] = 'gpg-mailgate-web@example.com';
$config['email_subject_requestpgp'] = 'Confirm your email address';
$config['site_url'] = 'http://example.com/gpgmw';
$config['site_title'] = 'PGP key management';
$config['language'] = 'english';
$config['debug'] = false;
$config['mail_smtp'] = false;
$config['mail_smtp_host'] = 'localhost';
$config['mail_smtp_port'] = 25;
$config['mail_smtp_username'] = 'gpgmw';
$config['mail_smtp_password'] = '';
$config['db_name'] = 'gpgmw';
$config['db_host'] = 'localhost';
$config['db_username'] = 'gpgmw';
$config['db_password'] = '';
$config['pgpverify_enable'] = false;
$config['pgpverify_tmpdir'] = '/tmp';
$config['pgpverify_allowblank'] = true;
$config['lock_time_initial'] = array('requestpgp' => 10);
$config['lock_count_overload'] = array('requestpgp' => 3);
$config['lock_time_overload'] = array('requestpgp' => 900);
$config['lock_time_reset'] = 300;
$config['lock_time_max'] = 3600;
?>

View file

@ -1,119 +0,0 @@
<?php
/*
gpg-mailgate
This file is part of the gpg-mailgate source code.
gpg-mailgate 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, either version 3 of the License, or
(at your option) any later version.
gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
*/
//
// GENERAL SITE SETTINGS
//
//web team contact
// this email address will be displayed if there is a database error
$config['email_web'] = 'admin@example.com';
//address to send emails from
$config['email_from'] = 'gpg-mailgate-web@example.com';
//this will be used as the subject when a user requests to add a PGP key
$config['email_subject_requestpgp'] = 'Confirm your email address';
//site URL, without trailing slash
$config['site_url'] = 'http://example.com/gpgmw';
//title of the website (displayed on home page)
$config['site_title'] = 'PGP key management';
//language file to use (see language subdirectory)
$config['language'] = 'english';
//whether debug mode should be enabled
$config['debug'] = false;
//
// MAIL SETTINGS
//
//whether to send mail through SMTP (instead of PHP mail function)
$config['mail_smtp'] = false;
//SMTP settings, if mail_smtp is enabled
//this requires Net_SMTP from http://pear.php.net/package/Net_SMTP/ to be installed
$config['mail_smtp_host'] = 'localhost';
$config['mail_smtp_port'] = 25;
$config['mail_smtp_username'] = 'gpgmw';
$config['mail_smtp_password'] = '';
//
// DATABASE SETTINGS
//
//database name (MySQL only); or see include/dbconnect.php
$config['db_name'] = 'gpgmw';
//database host
$config['db_host'] = 'localhost';
//database username
$config['db_username'] = 'gpgmw';
//database password
$config['db_password'] = '';
//
// PGP VERIFICATION SETTINGS
//
//whether to enable immediate verification of PGP keys
// keys will always be verified with the email address in our cron job
// but this will enable verification from the web interface before email confirmation
//for this to work, Crypt_GPG from http://pear.php.net/Crypt_GPG must be installed
// (as well as any of its dependencies), and pgpverify_tmpdir must be set
$config['pgpverify_enable'] = false;
//a temporary directory to use for PGP verification, without trailing slash
// gpgmw will create subdirectories from here to use as temporary gpg home directories
// these directories will (should) be deleted immediately after use
$config['pgpverify_tmpdir'] = '/tmp';
//whether to allow blank "keys"
// this is useful to allow users to delete their key from the keystore
// if they no longer want encryption
$config['pgpverify_allowblank'] = true;
//
// LOCK SETTINGS
//
//the time in seconds a user must wait before trying again; otherwise they get locked out (count not increased)
$config['lock_time_initial'] = array('requestpgp' => 10);
//the number of tries a user has (that passes the lock_time_initial test) before being locked by overload (extended duration)
$config['lock_count_overload'] = array('requestpgp' => 3);
//the time that overloads last
$config['lock_time_overload'] = array('requestpgp' => 900);
//time after which locks no longer apply, assuming the lock isn't active
$config['lock_time_reset'] = 300;
//max time to store locks in the database; this way we can clear old locks with one function
$config['lock_time_max'] = 3600;
?>

View file

@ -1,41 +0,0 @@
<?php
/*
gpg-mailgate
This file is part of the gpg-mailgate source code.
gpg-mailgate 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, either version 3 of the License, or
(at your option) any later version.
gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
*/
require_once("include/config.php");
require_once("include/language.php");
require_once("include/common.php");
require_once("include/dbconnect.php");
require_once("include/pgp.php");
if(isset($_REQUEST['email']) && isset($_REQUEST['confirm'])) {
$result = confirmPGP($_REQUEST['email'], $_REQUEST['confirm']);
if($result === true) {
get_page("home", array('message' => $lang['confirm_success']));
} else {
get_page("home", array('message' => $lang['confirm_fail_general']));
}
} else {
get_page("home");
}
?>

View file

@ -1,273 +0,0 @@
<?php
/*
gpg-mailgate
This file is part of the gpg-mailgate source code.
gpg-mailgate 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, either version 3 of the License, or
(at your option) any later version.
gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
*/
function string_begins_with($string, $search)
{
return (strncmp($string, $search, strlen($search)) == 0);
}
function boolToString($bool) {
return $bool ? 'true' : 'false';
}
//returns an absolute path to the include directory
function includePath() {
$self = __FILE__;
$lastSlash = strrpos($self, "/");
return substr($self, 0, $lastSlash + 1);
}
//returns a relative path to the gpg-mailgate-web web root directory, without trailing slash
function basePath() {
$commonPath = __FILE__;
$requestPath = $_SERVER['SCRIPT_FILENAME'];
//count the number of slashes
// number of .. needed for include level is numslashes(request) - numslashes(common)
// then add one more to get to base
$commonSlashes = substr_count($commonPath, '/');
$requestSlashes = substr_count($requestPath, '/');
$numParent = $requestSlashes - $commonSlashes + 1;
$basePath = ".";
for($i = 0; $i < $numParent; $i++) {
$basePath .= "/..";
}
return $basePath;
}
function uid($length) {
$characters = "0123456789abcdefghijklmnopqrstuvwxyz";
$string = "";
for ($p = 0; $p < $length; $p++) {
$string .= $characters[secure_random() % strlen($characters)];
}
return $string;
}
function get_page($page, $args = array()) {
//let pages use some variables
extract($args);
$config = $GLOBALS['config'];
$lang = $GLOBALS['lang'];
$basePath = basePath();
$themePath = $basePath . "/theme";
$themePageInclude = "$themePath/$page.php";
if(file_exists("$themePath/header.php")) {
include("$themePath/header.php");
}
if(file_exists($themePageInclude)) {
include($themePageInclude);
}
if(file_exists("$themePath/footer.php")) {
include("$themePath/footer.php");
}
}
function isAscii($str) {
return 0 == preg_match('/[^\x00-\x7F]/', $str);
}
//returns random number from 0 to 2^24
function secure_random() {
return hexdec(bin2hex(secure_random_bytes(3)));
}
function recursiveDelete($dirPath) {
foreach(
new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(
$dirPath, FilesystemIterator::SKIP_DOTS
),
RecursiveIteratorIterator::CHILD_FIRST
)
as $path) {
$path->isFile() ? unlink($path->getPathname()) : rmdir($path->getPathname());
}
rmdir($dirPath);
}
function gpgmw_mail($subject, $body, $to) { //returns true=ok, false=notok
$config = $GLOBALS['config'];
$from = filter_var($config['email_from'], FILTER_SANITIZE_EMAIL);
$to = filter_var($to, FILTER_SANITIZE_EMAIL);
if($to === false || $from === false) {
return false;
}
if(isset($config['mail_smtp']) && $config['mail_smtp']) {
require_once "Mail.php";
$host = $config['mail_smtp_host'];
$port = $config['mail_smtp_port'];
$username = $config['mail_smtp_username'];
$password = $config['mail_smtp_password'];
$headers = array ('From' => $from,
'To' => $to,
'Subject' => $subject,
'Content-Type' => 'text/plain');
$smtp = Mail::factory('smtp',
array ('host' => $host,
'port' => $port,
'auth' => true,
'username' => $username,
'password' => $password));
$mail = $smtp->send($to, $headers, $body);
if (PEAR::isError($mail)) {
return false;
} else {
return true;
}
} else {
$headers = "From: $from\r\n";
$headers .= "Content-type: text/plain\r\n";
return mail($to, $subject, $body, $headers);
}
}
//secure_random_bytes from https://github.com/GeorgeArgyros/Secure-random-bytes-in-PHP
/*
* The function is providing, at least at the systems tested :),
* $len bytes of entropy under any PHP installation or operating system.
* The execution time should be at most 10-20 ms in any system.
*/
function secure_random_bytes($len = 10) {
/*
* Our primary choice for a cryptographic strong randomness function is
* openssl_random_pseudo_bytes.
*/
$SSLstr = '4'; // http://xkcd.com/221/
if (function_exists('openssl_random_pseudo_bytes') &&
(version_compare(PHP_VERSION, '5.3.4') >= 0 ||
substr(PHP_OS, 0, 3) !== 'WIN'))
{
$SSLstr = openssl_random_pseudo_bytes($len, $strong);
if ($strong)
return $SSLstr;
}
/*
* If mcrypt extension is available then we use it to gather entropy from
* the operating system's PRNG. This is better than reading /dev/urandom
* directly since it avoids reading larger blocks of data than needed.
* Older versions of mcrypt_create_iv may be broken or take too much time
* to finish so we only use this function with PHP 5.3 and above.
*/
if (function_exists('mcrypt_create_iv') &&
(version_compare(PHP_VERSION, '5.3.0') >= 0 ||
substr(PHP_OS, 0, 3) !== 'WIN'))
{
$str = mcrypt_create_iv($len, MCRYPT_DEV_URANDOM);
if ($str !== false)
return $str;
}
/*
* No build-in crypto randomness function found. We collect any entropy
* available in the PHP core PRNGs along with some filesystem info and memory
* stats. To make this data cryptographically strong we add data either from
* /dev/urandom or if its unavailable, we gather entropy by measuring the
* time needed to compute a number of SHA-1 hashes.
*/
$str = '';
$bits_per_round = 2; // bits of entropy collected in each clock drift round
$msec_per_round = 400; // expected running time of each round in microseconds
$hash_len = 20; // SHA-1 Hash length
$total = $len; // total bytes of entropy to collect
$handle = @fopen('/dev/urandom', 'rb');
if ($handle && function_exists('stream_set_read_buffer'))
@stream_set_read_buffer($handle, 0);
do
{
$bytes = ($total > $hash_len)? $hash_len : $total;
$total -= $bytes;
//collect any entropy available from the PHP system and filesystem
$entropy = rand() . uniqid(mt_rand(), true) . $SSLstr;
$entropy .= implode('', @fstat(@fopen( __FILE__, 'r')));
$entropy .= memory_get_usage();
if ($handle)
{
$entropy .= @fread($handle, $bytes);
}
else
{
// Measure the time that the operations will take on average
for ($i = 0; $i < 3; $i ++)
{
$c1 = microtime(true);
$var = sha1(mt_rand());
for ($j = 0; $j < 50; $j++)
{
$var = sha1($var);
}
$c2 = microtime(true);
$entropy .= $c1 . $c2;
}
// Based on the above measurement determine the total rounds
// in order to bound the total running time.
$rounds = (int)($msec_per_round*50 / (int)(($c2-$c1)*1000000));
// Take the additional measurements. On average we can expect
// at least $bits_per_round bits of entropy from each measurement.
$iter = $bytes*(int)(ceil(8 / $bits_per_round));
for ($i = 0; $i < $iter; $i ++)
{
$c1 = microtime();
$var = sha1(mt_rand());
for ($j = 0; $j < $rounds; $j++)
{
$var = sha1($var);
}
$c2 = microtime();
$entropy .= $c1 . $c2;
}
}
// We assume sha1 is a deterministic extractor for the $entropy variable.
$str .= sha1($entropy, true);
} while ($len > strlen($str));
if ($handle)
@fclose($handle);
return substr($str, 0, $len);
}
?>

View file

@ -1,31 +0,0 @@
<?php
/*
gpg-mailgate
This file is part of the gpg-mailgate source code.
gpg-mailgate 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, either version 3 of the License, or
(at your option) any later version.
gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
*/
require_once(dirname(__FILE__) . '/../config.default.php');
if(file_exists(dirname(__FILE__) . '/../config.php')) {
require_once(dirname(__FILE__) . '/../config.php');
} else {
die("Server configuration error: config.php does not exist.");
}
?>

View file

@ -1,76 +0,0 @@
<?php
/*
gpg-mailgate
This file is part of the gpg-mailgate source code.
gpg-mailgate 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, either version 3 of the License, or
(at your option) any later version.
gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
*/
function dieDatabaseError($ex = NULL) {
global $config;
if($ex == NULL) {
$pre = "Encountered database error.";
} else {
$pre = "Encountered database error: " . $ex->getMessage() . ".";
}
die($pre . " If this is unexpected, consider <a href=\"mailto:{$config['email_web']}\">reporting it to our web team</a>. Otherwise, <a href=\"/\">click here to return to the home page.</a>");
}
try {
$database = new PDO('mysql:host=' . $config['db_host'] . ';dbname=' . $config['db_name'], $config['db_username'], $config['db_password'], array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
} catch(PDOException $ex) {
dieDatabaseError($ex);
}
function databaseQuery($command, $array = array(), $assoc = false) {
global $database;
if(!is_array($array)) {
dieDatabaseError();
}
try {
$query = $database->prepare($command);
if(!$query) {
print_r($database->errorInfo());
dieDatabaseError();
}
//set fetch mode depending on parameter
if($assoc) {
$query->setFetchMode(PDO::FETCH_ASSOC);
} else {
$query->setFetchMode(PDO::FETCH_NUM);
}
$success = $query->execute($array);
if(!$success) {
print_r($query->errorInfo());
dieDatabaseError();
}
return $query;
} catch(PDOException $ex) {
dieDatabaseError($ex);
}
}
?>

View file

@ -1,85 +0,0 @@
<?php
/*
gpg-mailgate
This file is part of the gpg-mailgate source code.
gpg-mailgate 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, either version 3 of the License, or
(at your option) any later version.
gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
*/
//uses gpg to verify that a key belongs to a given email address
function verifyPGPKey($content, $email) {
global $config;
//allow blank "keys" if this is set
//this means that encryption for $email will be disabled by the cron if it
// was enabled originally
if($config['pgpverify_allowblank'] && trim($content) == '') {
return true;
}
require_once("Crypt/GPG.php");
//try to create a random subdirectory of $config['pgpverify_tmpdir']
do {
$path = $config['pgpverify_tmpdir'] . '/' . uid(16);
} while(file_exists($path));
$result = @mkdir($path);
if($result === false) {
if($config['debug']) {
die("Failed to create directory [" . $path . "] for PGP verification.");
} else {
return false;
}
}
$gpg = new Crypt_GPG(array('homedir' => $path));
//import the key to our GPG temp directory
try {
$gpg->importKey($content);
} catch(Crypt_GPG_NoDataException $e) {
//user supplied an invalid key!
recursiveDelete($path);
return false;
}
//verify the email address matches
$keys = $gpg->getKeys();
if(count($keys) != 1) {
if($config['debug']) {
die("Error in PGP verification: key count is " . count($keys) . "!");
} else {
recursiveDelete($path);
return false;
}
}
$userIds = $keys[0]->getUserIds();
if(count($userIds) != 1 || strtolower($userIds[0]->getEmail()) != strtolower($email)) {
recursiveDelete($path);
return false;
}
recursiveDelete($path);
return true;
}
?>

View file

@ -1,25 +0,0 @@
<?php
/*
gpg-mailgate
This file is part of the gpg-mailgate source code.
gpg-mailgate 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, either version 3 of the License, or
(at your option) any later version.
gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
*/
require_once(dirname(__FILE__) . '/../language/' . $config['language'] . '.php');
?>

View file

@ -1,124 +0,0 @@
<?php
/*
gpg-mailgate
This file is part of the gpg-mailgate source code.
gpg-mailgate 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, either version 3 of the License, or
(at your option) any later version.
gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
*/
//lock.php is basic spam-submit prevention
//lock_time_initial, lock_time_overload, lock_count_overload, lock_time_reset, and lock_time_max should be defined in $config
//returns boolean: true=proceed, false=lock up; the difference between this and lockAction is that this can be used for repeated tasks, like admin
// then, only if action was unsuccessful would lockAction be called
function checkLock($action) {
global $config;
$lock_time_initial = $config['lock_time_initial'];
$lock_time_overload = $config['lock_time_overload'];
$lock_count_overload = $config['lock_count_overload'];
$lock_time_reset = $config['lock_time_reset'];
$lock_time_max = $config['lock_time_max'];
if(!isset($lock_time_initial[$action])) {
return true; //well we can't do anything...
}
$ip = $_SERVER['REMOTE_ADDR'];
$result = databaseQuery("SELECT id, time, num FROM gpgmw_locks WHERE ip = ? AND action = ?", array($ip, $action), true);
if($row = $result->fetch()) {
$id = $row['id'];
$time = $row['time'];
$count = $row['num']; //>=0 count means it's a regular initial lock; -1 count means overload lock
if($count >= 0) {
if(time() <= $time + $lock_time_initial[$action]) {
return false;
}
} else {
if(time() <= $time + $lock_time_overload[$action]) {
return false;
}
}
}
return true;
}
//returns boolean: true=proceed, false=lock up
function lockAction($action) {
global $config;
$lock_time_initial = $config['lock_time_initial'];
$lock_time_overload = $config['lock_time_overload'];
$lock_count_overload = $config['lock_count_overload'];
$lock_time_reset = $config['lock_time_reset'];
$lock_time_max = $config['lock_time_max'];
if(!isset($lock_time_initial[$action])) {
return true; //well we can't do anything...
}
$ip = $_SERVER['REMOTE_ADDR'];
$replace_id = -1;
//first find records with ip/action
$result = databaseQuery("SELECT id, time, num FROM gpgmw_locks WHERE ip = ? AND action = ?", array($ip, $action), true);
if($row = $result->fetch()) {
$id = $row['id'];
$time = $row['time'];
$count = $row['num']; //>=0 count means it's a regular initial lock; -1 count means overload lock
if($count >= 0) {
if(time() <= $time + $lock_time_initial[$action]) {
return false;
} else if(time() > $time + $lock_time_reset) {
//this entry is old, but use it to replace
$replace_id = $id;
} else {
//increase the count; maybe initiate an OVERLOAD
$count = $count + 1;
if($count >= $lock_count_overload[$action]) {
databaseQuery("UPDATE gpgmw_locks SET num = '-1', time = ? WHERE ip = ?", array(time(), $ip));
return false;
} else {
databaseQuery("UPDATE gpgmw_locks SET num = ?, time = ? WHERE ip = ?", array($count, time(), $ip));
}
}
} else {
if(time() <= $time + $lock_time_overload[$action]) {
return false;
} else {
//their overload is over, so this entry is old
$replace_id = $id;
}
}
} else {
databaseQuery("INSERT INTO gpgmw_locks (ip, time, action, num) VALUES (?, ?, ?, '1')", array($ip, time(), $action));
}
if($replace_id != -1) {
databaseQuery("UPDATE gpgmw_locks SET num = '1', time = ? WHERE id = ?", array(time(), $replace_id));
}
//some housekeeping
$delete_time = time() - $lock_time_max;
databaseQuery("DELETE FROM gpgmw_locks WHERE time <= ?", array($delete_time));
return true;
}
?>

View file

@ -1,100 +0,0 @@
<?php
/*
gpg-mailgate
This file is part of the gpg-mailgate source code.
gpg-mailgate 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, either version 3 of the License, or
(at your option) any later version.
gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
*/
//returns true on success or error message on failure
function requestPGP($email, $key) {
require_once(includePath() . "/lock.php");
global $config, $lang;
if(!checkLock('requestpgp')) {
return $lang['submit_error_trylater'];
}
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
return $lang['submit_error_bademail'];
}
if(strlen($email) > 256 || strlen($key) > 1024 * 32) {
return $lang['submit_error_toolong'];
}
if(!isAscii($key)) {
return $lang['submit_error_nonascii'];
}
//housekeeping
databaseQuery("DELETE FROM gpgmw_keys WHERE time < DATE_SUB(NOW(), INTERVAL 48 HOUR) AND confirm != '' AND status = 0");
//if we already have an unaccepted key for this user, only replace if one day has elapsed since the last request
// this may prevent spam
$result = databaseQuery("SELECT HOUR(TIMEDIFF(time, NOW())), id FROM gpgmw_keys WHERE email = ? AND status = 0", array($email));
if($row = $result->fetch()) {
if($row[0] < 24) {
return $lang['submit_error_alreadyqueue'];
} else {
databaseQuery('DELETE FROM gpgmw_keys WHERE id = ?', array($row[1]));
}
}
//if PGP key verification is enabled, do it
if($config['pgpverify_enable']) {
require_once(includePath() . "/gpg.php");
if(!verifyPGPKey($key, $email)) {
return $lang['submit_error_badkey'];
}
}
//well, it looks good, let's submit it
lockAction('requestpgp');
$confirm = uid(32);
$confirm_link = "{$config['site_url']}/confirm.php?email=" . urlencode($email) . "&confirm=$confirm";
$result = gpgmw_mail($config['email_subject_requestpgp'], sprintf($lang['mail_confirm'], $confirm_link), $email);
if(!$result) {
return $lang['submit_error_emailfail'];
}
databaseQuery("INSERT INTO gpgmw_keys (email, publickey, confirm) VALUES (?, ?, ?)", array($email, $key, $confirm));
return true;
}
//returns false on failure or true on success
function confirmPGP($email, $confirm) {
require_once(includePath() . "/lock.php");
if(!lockAction('confirmpgp')) {
return false;
}
$result = databaseQuery("SELECT id FROM gpgmw_keys WHERE confirm = ? AND email = ?", array($confirm, $email));
if($row = $result->fetch()) {
databaseQuery("UPDATE gpgmw_keys SET confirm = '' WHERE id = ?", array($row[0]));
return true;
}
return false;
}
?>

View file

@ -1,55 +0,0 @@
<?php
/*
*
* HKP Keyserver Interface for submitting public keys
* to the gpg-mailgate-web database directly from
* an OpenPGP client
*
* loosely based on ElTramo's phkp code
* http://el-tramo.be/software/phkp
*
* 2014 by Kiritan Flux
*
* Licensed under the GNU General Public License.
*
* check the README for necessary prerequisites
*
*/
//! OpenPGP client command
$PGP_COMMAND="gpg";
//! A dir where the PHP script has write access
$PGP_HOME="/var/gpg/.phkp";
//! The maximum size (in characters) of a submitted key.
//! Set to '0' to disable receiving of keys, and '-1' for no limit.
$MAX_KEYSIZE=102400;
if (preg_match("/pks\/add/",$_SERVER['REQUEST_URI']))
{
if ($MAX_KEYSIZE == -1 || strlen($_POST['keytext']) <= $MAX_KEYSIZE)
{
//write key into temporary file
file_put_contents( "$PGP_HOME/tmp", $_POST['keytext'] );
//run gpg --with-fingerprint to retreive information about the key from the keyfile
$result = shell_exec("$PGP_COMMAND --homedir $PGP_HOME --with-fingerprint $PGP_HOME/tmp");
//extract email addresses from the information
$pattern = '/[a-z0-9_\-\+]+@[a-z0-9\-]+\.([a-z]{2,3})(?:\.[a-z]{2})?/i';
preg_match_all($pattern, $result, $matches);
//for each email address assigned to the key, put intformation into the DB and send confirmation emails
foreach($matches[0] as $match)
{
//echo $match.': '.$_POST['keytext'];
requestPGP($match, $_POST['keytext']);
}
}
else
{
header("HTTP/1.0 403 Forbidden");
}
}
?>

View file

@ -1,43 +0,0 @@
<?php
/*
gpg-mailgate
This file is part of the gpg-mailgate source code.
gpg-mailgate 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, either version 3 of the License, or
(at your option) any later version.
gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
*/
require_once("include/config.php");
require_once("include/language.php");
require_once("include/common.php");
require_once("include/dbconnect.php");
require_once("include/pgp.php");
require_once("include/phphkp.php");
if(isset($_POST['email']) && isset($_POST['key'])) {
$result = requestPGP($_POST['email'], $_POST['key']);
if($result === true) {
get_page("home", array('message' => $lang['submit_success']));
} else {
get_page("home", array('message' => $result));
}
} else {
get_page("home");
}
?>

View file

@ -1,47 +0,0 @@
<?php
/*
gpg-mailgate
This file is part of the gpg-mailgate source code.
gpg-mailgate 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, either version 3 of the License, or
(at your option) any later version.
gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
*/
$lang = array();
$lang['home_text'] = 'Use the form below to submit an ASCII-armored PGP public key. After submission, you will receive an email asking you to confirm your email address. Once confirmation is completed, mail sent to your email address via our mail server will be encrypted with your PGP public key.';
$lang['home_footer'] = '<a href="https://github.com/uakfdotb/gpg-mailgate">gpg-mailgate and gpg-mailgate-web</a> are released under the <a href="https://www.gnu.org/licenses/lgpl-3.0.txt">GNU LGPL</a>.';
$lang['home_emaildesc'] = 'Your email address (must match key)';
$lang['home_keydesc'] = 'ASCII-armored PGP public key';
$lang['home_submitkey'] = 'Submit key';
$lang['submit_success'] = 'Key submission successful. Please check your email to confirm your email address.';
$lang['submit_error_trylater'] = 'Error: please wait a bit before trying again.';
$lang['submit_error_bademail'] = 'Error: invalid email address.';
$lang['submit_error_toolong'] = 'Error: email address or key too long.';
$lang['submit_error_nonascii'] = 'Error: only keys encoded with ASCII armor are accepted (gpg --armor).';
$lang['submit_error_alreadyqueue'] = 'Error: there is already a key in the queue for this email address; please wait twenty-four hours between submitting keys, or confirm the previous key and then resubmit.';
$lang['submit_error_badkey'] = 'Error: your key does not appear to be valid (ensure ASCII armor is enabled and that the email address entered matches the email address of the key).';
$lang['submit_error_emailfail'] = 'Error: failed to send email.';
$lang['submit_error_bademail'] = 'Error: invalid email address.';
$lang['submit_error_bademail'] = 'Error: invalid email address.';
$lang['confirm_success'] = 'Your email address has been confirmed successfully. Within a few minutes, emails from our mail server to you should be encrypted with your PGP public key.';
$lang['confirm_fail_general'] = 'Error: failed to confirm any email address. You may have already confirmed the address, or you may have the wrong confirmation key.';
$lang['mail_confirm'] = "Please confirm your email address to complete the submission process. You can do so by clicking the link below\n\n%s\n\nThanks,\ngpg-mailgate-web";
?>

View file

@ -1,25 +0,0 @@
<?php
/*
gpg-mailgate
This file is part of the gpg-mailgate source code.
gpg-mailgate 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, either version 3 of the License, or
(at your option) any later version.
gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
*/
?>
</body>
</html>

View file

@ -1,28 +0,0 @@
<?php
/*
gpg-mailgate
This file is part of the gpg-mailgate source code.
gpg-mailgate 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, either version 3 of the License, or
(at your option) any later version.
gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
*/
?>
<html>
<head>
<title>gpg-mailgate-web</title>
</head>
<body>

View file

@ -1,46 +0,0 @@
<?php
/*
gpg-mailgate
This file is part of the gpg-mailgate source code.
gpg-mailgate 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, either version 3 of the License, or
(at your option) any later version.
gpg-mailgate source code 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 gpg-mailgate source code. If not, see <http://www.gnu.org/licenses/>.
*/
?>
<h1><?= $config['site_title'] ?></h1>
<? if(!empty($message)) { ?>
<p><b><i><?= htmlspecialchars($message) ?></i></b></p>
<? } ?>
<p><?= $lang['home_text'] ?></p>
<form method="POST">
<table>
<tr>
<td><?= $lang['home_emaildesc'] ?></td>
<td><input type="text" name="email" /></td>
</tr>
<tr>
<td><?= $lang['home_keydesc'] ?></td>
<td><textarea name="key" rows="10" cols="80"></textarea></td>
</tr>
</table>
<input type="submit" value="<?= $lang['home_submitkey'] ?>" />
</form>
<p><?= $lang['home_footer'] ?></p>

View file

@ -1,10 +0,0 @@
-- confirm is empty once an email address has been confirmed, and otherwise is the confirmation key
-- status
-- initializes to 0
-- is set to 1 after a public key with (confirm='', status=0) has been imported
-- is set to 2 if a key should be deleted (will be deleted based on email address)
-- publickey is the ASCII-armored PGP public key; can be cleared to save space if status > 0
CREATE TABLE gpgmw_keys (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, email VARCHAR(256), publickey TEXT, confirm VARCHAR(32), status INT NOT NULL DEFAULT 0, time TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
-- see include/lock.php for documentation
CREATE TABLE gpgmw_locks (id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, ip VARCHAR(16), time INT, action VARCHAR(16), num INT);