[aur-dev] [PATCH v2] Add field for PGP key in profile information

Lukas Fleischer archlinux at cryptocrack.de
Sat Mar 24 05:39:43 EDT 2012


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 at cryptocrack.de>
---
Use "VARCHAR" instead of "CHAR". Thanks, Dan!

 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..40d4485 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 VARCHAR(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..726fd2f 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 VARCHAR(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



More information about the aur-dev mailing list