This is handy for verifying the PGP key of new Trusted Users. Also, this
could potentially used as a basis to allow signed package uploads in the
future.
Implements FS#29028.
Signed-off-by: Lukas Fleischer <archlinux(a)cryptocrack.de>
---
UPGRADING | 3 ++
support/schema/aur-schema.sql | 1 +
web/html/account.php | 13 ++++----
web/lib/acctfuncs.inc.php | 67 ++++++++++++++++++++++++++++++++++++-----
4 files changed, 71 insertions(+), 13 deletions(-)
diff --git a/UPGRADING b/UPGRADING
index 6557b95..6f87944 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -6,7 +6,10 @@ From 1.9.1 to 2.0.0
1. Add new "Users" table login date column:
+----
ALTER TABLE Users ADD COLUMN LastLogin BIGINT NOT NULL DEFAULT 0;
+ALTER TABLE Users ADD COLUMN PGPKey CHAR(40) NULL DEFAULT NULL;
+----
From 1.9.0 to 1.9.1
-------------------
diff --git a/support/schema/aur-schema.sql b/support/schema/aur-schema.sql
index 6c8feca..ca7ddbe 100644
--- a/support/schema/aur-schema.sql
+++ b/support/schema/aur-schema.sql
@@ -31,6 +31,7 @@ CREATE TABLE Users (
RealName VARCHAR(64) NOT NULL DEFAULT '',
LangPreference VARCHAR(5) NOT NULL DEFAULT 'en',
IRCNick VARCHAR(32) NOT NULL DEFAULT '',
+ PGPKey CHAR(40) NULL DEFAULT NULL,
LastVoted BIGINT UNSIGNED NOT NULL DEFAULT 0,
LastLogin BIGINT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (ID),
diff --git a/web/html/account.php b/web/html/account.php
index d94d711..339316b 100644
--- a/web/html/account.php
+++ b/web/html/account.php
@@ -33,7 +33,8 @@ if (isset($_COOKIE["AURSID"])) {
#
search_results_page($atype, in_request("O"), in_request("SB"),
in_request("U"), in_request("T"), in_request("S"),
- in_request("E"), in_request("R"), in_request("I"));
+ in_request("E"), in_request("R"), in_request("I"),
+ in_request("K"));
} else {
# a non-privileged user is trying to access the search page
@@ -64,7 +65,7 @@ if (isset($_COOKIE["AURSID"])) {
display_account_form($atype, "UpdateAccount", $row["Username"],
$row["AccountType"], $row["Suspended"], $row["Email"],
"", "", $row["RealName"], $row["LangPreference"],
- $row["IRCNick"], $row["ID"]);
+ $row["IRCNick"], $row["PGPKey"], $row["ID"]);
}
}
@@ -82,7 +83,7 @@ if (isset($_COOKIE["AURSID"])) {
$row = mysql_fetch_assoc($result);
display_account_info($row["Username"],
$row["AccountType"], $row["Email"], $row["RealName"],
- $row["IRCNick"], $row["LastVoted"]);
+ $row["IRCNick"], $row["PGPKey"], $row["LastVoted"]);
}
} elseif ($action == "UpdateAccount") {
@@ -92,7 +93,7 @@ if (isset($_COOKIE["AURSID"])) {
in_request("U"), in_request("T"), in_request("S"),
in_request("E"), in_request("P"), in_request("C"),
in_request("R"), in_request("L"), in_request("I"),
- in_request("ID"));
+ in_request("K"), in_request("ID"));
} else {
@@ -127,7 +128,7 @@ if (isset($_COOKIE["AURSID"])) {
display_account_form($atype, "UpdateAccount", $row["Username"],
$row["AccountType"], $row["Suspended"], $row["Email"],
"", "", $row["RealName"], $row["LangPreference"],
- $row["IRCNick"], $row["ID"]);
+ $row["IRCNick"], $row["PGPKey"], $row["ID"]);
}
}
}
@@ -143,7 +144,7 @@ if (isset($_COOKIE["AURSID"])) {
process_account_form("","new", "NewAccount",
in_request("U"), 1, 0, in_request("E"),
in_request("P"), in_request("C"), in_request("R"),
- in_request("L"), in_request("I"));
+ in_request("L"), in_request("I"), in_request("K"));
} else {
# display the account request form
diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php
index 512e66c..8246cc9 100644
--- a/web/lib/acctfuncs.inc.php
+++ b/web/lib/acctfuncs.inc.php
@@ -8,10 +8,28 @@ function in_request($name) {
return "";
}
+# Format PGP key fingerprint
+function html_format_pgp_fingerprint($fingerprint) {
+ if (strlen($fingerprint) != 40 || !ctype_xdigit($fingerprint)) {
+ return $fingerprint;
+ }
+
+ return htmlspecialchars(substr($fingerprint, 0, 4) . " " .
+ substr($fingerprint, 4, 4) . " " .
+ substr($fingerprint, 8, 4) . " " .
+ substr($fingerprint, 12, 4) . " " .
+ substr($fingerprint, 16, 4) . " " .
+ substr($fingerprint, 20, 4) . " " .
+ substr($fingerprint, 24, 4) . " " .
+ substr($fingerprint, 28, 4) . " " .
+ substr($fingerprint, 32, 4) . " " .
+ substr($fingerprint, 36, 4) . " ", ENT_QUOTES);
+}
+
# Display the standard Account form, pass in default values if any
function display_account_form($UTYPE,$A,$U="",$T="",$S="",
- $E="",$P="",$C="",$R="",$L="",$I="",$UID=0) {
+ $E="",$P="",$C="",$R="",$L="",$I="",$K="",$UID=0) {
# UTYPE: what user type the form is being displayed for
# A: what "form" name to use
# U: value to display for username
@@ -113,6 +131,12 @@ function display_account_form($UTYPE,$A,$U="",$T="",$S="",
print "</tr>\n";
print "<tr>";
+ print "<td align='left'>".__("PGP Key Fingerprint").":</td>";
+ print "<td align='left'><input type='text' size='30' maxlength='50'";
+ print " name='K' value='".html_format_pgp_fingerprint($K)."' /></td>";
+ print "</tr>\n";
+
+ print "<tr>";
print "<td align='left'>".__("Language").":</td>";
print "<td align='left'><select name=L>\n";
@@ -152,7 +176,7 @@ function display_account_form($UTYPE,$A,$U="",$T="",$S="",
# process form input from a new/edit account form
#
function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="",
- $P="",$C="",$R="",$L="",$I="",$UID=0) {
+ $P="",$C="",$R="",$L="",$I="",$K="",$UID=0) {
# UTYPE: The user's account type
# TYPE: either "edit" or "new"
# A: what parent "form" name to use
@@ -215,6 +239,11 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="",
if (!$error && !valid_email($E)) {
$error = __("The email address is invalid.");
}
+
+ if (!$error && $K != '' && !valid_pgp_fingerprint($K)) {
+ $error = __("The PGP key fingerprint is invalid.");
+ }
+
if ($UTYPE == "Trusted User" && $T == 3) {
$error = __("A Trusted User cannot assign Developer status.");
}
@@ -260,17 +289,17 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="",
if ($error) {
print "<span class='error'>".$error."</span><br/>\n";
display_account_form($UTYPE, $A, $U, $T, $S, $E, "", "",
- $R, $L, $I, $UID);
+ $R, $L, $I, $K, $UID);
} else {
if ($TYPE == "new") {
# no errors, go ahead and create the unprivileged user
$salt = generate_salt();
$P = salted_hash($P, $salt);
$escaped = array_map('db_escape_string',
- array($U, $E, $P, $salt, $R, $L, $I));
+ array($U, $E, $P, $salt, $R, $L, $I, str_replace(" ", "", $K)));
$q = "INSERT INTO Users (" .
"AccountTypeID, Suspended, Username, Email, Passwd, Salt" .
- ", RealName, LangPreference, IRCNick) " .
+ ", RealName, LangPreference, IRCNick, PGPKey) " .
"VALUES (1, 0, '" . implode("', '", $escaped) . "')";
$result = db_query($q, $dbh);
if (!$result) {
@@ -308,6 +337,7 @@ function process_account_form($UTYPE,$TYPE,$A,$U="",$T="",$S="",$E="",
$q.= ", RealName = '".db_escape_string($R)."'";
$q.= ", LangPreference = '".db_escape_string($L)."'";
$q.= ", IRCNick = '".db_escape_string($I)."'";
+ $q.= ", PGPKey = '".db_escape_string(str_replace(" ", "", $K))."'";
$q.= " WHERE ID = ".intval($UID);
$result = db_query($q, $dbh);
if (!$result) {
@@ -333,7 +363,7 @@ function search_accounts_form() {
# search results page
#
function search_results_page($UTYPE,$O=0,$SB="",$U="",$T="",
- $S="",$E="",$R="",$I="") {
+ $S="",$E="",$R="",$I="",$K="") {
# UTYPE: what account type the user belongs to
# O: what row offset we're at
# SB: how to sort the results
@@ -388,6 +418,10 @@ function search_results_page($UTYPE,$O=0,$SB="",$U="",$T="",
$q.= "AND IRCNick LIKE '%".db_escape_like($I)."%' ";
$search_vars[] = "I";
}
+ if ($K) {
+ $q.= "AND PGPKey LIKE '%".db_escape_like(str_replace(" ", "", $K))."%' ";
+ $search_vars[] = "K";
+ }
switch ($SB) {
case 't':
$q.= "ORDER BY AccountTypeID, Username ";
@@ -429,6 +463,8 @@ function search_results_page($UTYPE,$O=0,$SB="",$U="",$T="",
print "<th class='header'>";
print "<span class='f2'>".__("IRC Nick")."</span></th>";
print "<th class='header'>";
+ print "<span class='f2'>".__("PGP Key Fingerprint")."</span></th>";
+ print "<th class='header'>";
print "<span class='f2'>".__("Last Voted")."</span></th>";
print "<th class='header'>";
print "<span class='f2'>".__("Edit Account")."</span></th>";
@@ -460,6 +496,9 @@ function search_results_page($UTYPE,$O=0,$SB="",$U="",$T="",
$row["IRCNick"] ? print htmlspecialchars($row["IRCNick"],ENT_QUOTES) : print " ";
print "</span></td>";
print "<td class='".$c."'><span class='f5'>";
+ $row["PGPKey"] ? print html_format_pgp_fingerprint($row["PGPKey"]) : print " ";
+ print "</span></td>";
+ print "<td class='".$c."'><span class='f5'>";
$row["LastVoted"]
? print date("Y-m-d", $row["LastVoted"])
: print __("Never");
@@ -526,7 +565,7 @@ function search_results_page($UTYPE,$O=0,$SB="",$U="",$T="",
# Display non-editable account info
#
-function display_account_info($U="", $T="", $E="", $R="", $I="", $LV="") {
+function display_account_info($U="", $T="", $E="", $R="", $I="", $K="", $LV="") {
# U: value to display for username
# T: value to display for account type
# E: value to display for email address
@@ -575,6 +614,11 @@ function display_account_info($U="", $T="", $E="", $R="", $I="", $LV="") {
print " </tr>\n";
print " <tr>\n";
+ print " <td align='left'>".__("PGP Key Fingerprint").":</td>\n";
+ print " <td align='left'>".html_format_pgp_fingerprint($K)."</td>\n";
+ print " </tr>\n";
+
+ print " <tr>\n";
print " <td align='left'>".__("Last Voted").":</td>\n";
print " <td align='left'>";
print $LV ? date("Y-m-d", $LV) : __("Never");
@@ -784,6 +828,15 @@ function valid_passwd( $userID, $passwd, $dbh )
}
/*
+ * Checks if the PGP key fingerprint is valid (must be 40 hexadecimal digits).
+ */
+function valid_pgp_fingerprint ( $fingerprint )
+{
+ $fingerprint = str_replace(" ", "", $fingerprint);
+ return (strlen($fingerprint) == 40 && ctype_xdigit($fingerprint));
+}
+
+/*
* Is the user account suspended?
*/
function user_suspended( $id, $dbh )
--
1.7.9.4