summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Fleischer <archlinux@cryptocrack.de>2014-06-03 16:37:50 +0200
committerLukas Fleischer <archlinux@cryptocrack.de>2014-12-27 12:42:12 +0100
commit253e76d8cc718acef6bab802c76c4a70623b59cc (patch)
treedf58aad0e2846690f12a23b56e1a5472602d6721
parent1af375828f7c4ef11e63e09e1070a9f77b679d71 (diff)
downloadaurweb-253e76d8cc718acef6bab802c76c4a70623b59cc.tar.xz
Add support for adding SSH public keys to profiles
Users can now add an SSH public key on the account edit page. This will later be used to authenticate users via SSH. Signed-off-by: Lukas Fleischer <archlinux@cryptocrack.de>
-rw-r--r--schema/aur-schema.sql1
-rw-r--r--upgrading/4.0.0.txt5
-rw-r--r--web/html/account.php5
-rw-r--r--web/lib/acctfuncs.inc.php78
-rw-r--r--web/template/account_edit_form.php5
5 files changed, 85 insertions, 9 deletions
diff --git a/schema/aur-schema.sql b/schema/aur-schema.sql
index 9c57683..dfd158f 100644
--- a/schema/aur-schema.sql
+++ b/schema/aur-schema.sql
@@ -33,6 +33,7 @@ CREATE TABLE Users (
LangPreference VARCHAR(5) NOT NULL DEFAULT 'en',
IRCNick VARCHAR(32) NOT NULL DEFAULT '',
PGPKey VARCHAR(40) NULL DEFAULT NULL,
+ SSHPubKey VARCHAR(4096) NULL DEFAULT NULL,
LastLogin BIGINT UNSIGNED NOT NULL DEFAULT 0,
LastLoginIPAddress INTEGER UNSIGNED NOT NULL DEFAULT 0,
InactivityTS BIGINT UNSIGNED NOT NULL DEFAULT 0,
diff --git a/upgrading/4.0.0.txt b/upgrading/4.0.0.txt
new file mode 100644
index 0000000..543fbac
--- /dev/null
+++ b/upgrading/4.0.0.txt
@@ -0,0 +1,5 @@
+1. Add a field for the SSH public key to the Users table:
+
+----
+ALTER TABLE Users ADD COLUMN SSHPubKey VARCHAR(4096) NULL DEFAULT NULL;
+----
diff --git a/web/html/account.php b/web/html/account.php
index c1a1cd7..3dc8ef0 100644
--- a/web/html/account.php
+++ b/web/html/account.php
@@ -59,7 +59,7 @@ if (isset($_COOKIE["AURSID"])) {
display_account_form("UpdateAccount", $row["Username"],
$row["AccountTypeID"], $row["Suspended"], $row["Email"],
"", "", $row["RealName"], $row["LangPreference"],
- $row["IRCNick"], $row["PGPKey"],
+ $row["IRCNick"], $row["PGPKey"], $row["SSHPubKey"],
$row["InactivityTS"] ? 1 : 0, $row["ID"]);
} else {
print __("You do not have permission to edit this account.");
@@ -98,7 +98,8 @@ 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("K"), in_request("J"), in_request("ID"));
+ in_request("K"), in_request("PK"), in_request("J"),
+ in_request("ID"));
}
} else {
if (has_credential(CRED_ACCOUNT_SEARCH)) {
diff --git a/web/lib/acctfuncs.inc.php b/web/lib/acctfuncs.inc.php
index 2d8dbaf..20ac081 100644
--- a/web/lib/acctfuncs.inc.php
+++ b/web/lib/acctfuncs.inc.php
@@ -53,13 +53,14 @@ function html_format_pgp_fingerprint($fingerprint) {
* @param string $L The language preference of the displayed user
* @param string $I The IRC nickname of the displayed user
* @param string $K The PGP key fingerprint of the displayed user
+ * @param string $PK The SSH public key of the displayed user
* @param string $J The inactivity status of the displayed user
* @param string $UID The user ID of the displayed user
*
* @return void
*/
-function display_account_form($A,$U="",$T="",$S="",
- $E="",$P="",$C="",$R="",$L="",$I="",$K="",$J="", $UID=0) {
+function display_account_form($A,$U="",$T="",$S="",$E="",$P="",$C="",$R="",
+ $L="",$I="",$K="",$PK="",$J="", $UID=0) {
global $SUPPORTED_LANGS;
include("account_edit_form.php");
@@ -82,13 +83,14 @@ function display_account_form($A,$U="",$T="",$S="",
* @param string $L The language preference of the user
* @param string $I The IRC nickname of the user
* @param string $K The PGP fingerprint of the user
+ * @param string $PK The SSH public key of the user
* @param string $J The inactivity status of the user
* @param string $UID The user ID of the modified account
*
* @return string|void Return void if successful, otherwise return error
*/
-function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",
- $P="",$C="",$R="",$L="",$I="",$K="",$J="",$UID=0) {
+function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",$P="",$C="",
+ $R="",$L="",$I="",$K="",$PK="",$J="",$UID=0) {
global $SUPPORTED_LANGS;
$error = '';
@@ -146,6 +148,15 @@ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",
$error = __("The PGP key fingerprint is invalid.");
}
+ if (!$error && !empty($PK)) {
+ if (valid_ssh_pubkey($PK)) {
+ $tokens = explode(" ", $PK);
+ $PK = $tokens[0] . " " . $tokens[1];
+ } else {
+ $error = __("The SSH public key is invalid.");
+ }
+ }
+
if (isset($_COOKIE['AURSID'])) {
$atype = account_from_sid($_COOKIE['AURSID']);
if (($atype == "User" && $T > 1) || ($atype == "Trusted User" && $T > 2)) {
@@ -192,11 +203,29 @@ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",
"<strong>", htmlspecialchars($E,ENT_QUOTES), "</strong>");
}
}
+ if (!$error) {
+ /*
+ * Check whether the SSH public key is available.
+ * TODO: Fix race condition.
+ */
+ $q = "SELECT COUNT(*) FROM Users ";
+ $q.= "WHERE SSHPubKey = " . $dbh->quote($PK);
+ if ($TYPE == "edit") {
+ $q.= " AND ID != " . intval($UID);
+ }
+ $result = $dbh->query($q);
+ $row = $result->fetch(PDO::FETCH_NUM);
+
+ if ($row[0]) {
+ $error = __("The SSH public key, %s%s%s, is already in use.",
+ "<strong>", htmlspecialchars($PK, ENT_QUOTES), "</strong>");
+ }
+ }
if ($error) {
print "<ul class='errorlist'><li>".$error."</li></ul>\n";
display_account_form($A, $U, $T, $S, $E, "", "",
- $R, $L, $I, $K, $J, $UID);
+ $R, $L, $I, $K, $PK, $J, $UID);
return;
}
@@ -218,11 +247,13 @@ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",
$L = $dbh->quote($L);
$I = $dbh->quote($I);
$K = $dbh->quote(str_replace(" ", "", $K));
+ $PK = $dbh->quote($PK);
$q = "INSERT INTO Users (AccountTypeID, Suspended, ";
$q.= "InactivityTS, Username, Email, Passwd, Salt, ";
- $q.= "RealName, LangPreference, IRCNick, PGPKey) ";
+ $q.= "RealName, LangPreference, IRCNick, PGPKey, ";
+ $q.= "SSHPubKey) ";
$q.= "VALUES (1, 0, 0, $U, $E, $P, $salt, $R, $L, ";
- $q.= "$I, $K)";
+ $q.= "$I, $K, $PK)";
$result = $dbh->exec($q);
if (!$result) {
print __("Error trying to create account, %s%s%s.",
@@ -290,6 +321,7 @@ function process_account_form($TYPE,$A,$U="",$T="",$S="",$E="",
$q.= ", LangPreference = " . $dbh->quote($L);
$q.= ", IRCNick = " . $dbh->quote($I);
$q.= ", PGPKey = " . $dbh->quote(str_replace(" ", "", $K));
+ $q.= ", SSHPubKey = " . $dbh->quote($PK);
$q.= ", InactivityTS = " . $inactivity_ts;
$q.= " WHERE ID = ".intval($UID);
$result = $dbh->exec($q);
@@ -800,6 +832,38 @@ function valid_pgp_fingerprint($fingerprint) {
}
/**
+ * Determine if the SSH public key is valid
+ *
+ * @param string $pubkey SSH public key to check
+ *
+ * @return bool True if the SSH public key is valid, otherwise false
+ */
+function valid_ssh_pubkey($pubkey) {
+ $valid_prefixes = array(
+ "ssh-rsa", "ssh-dss", "ecdsa-sha2-nistp256",
+ "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "ssh-ed25519"
+ );
+
+ $has_valid_prefix = false;
+ foreach ($valid_prefixes as $prefix) {
+ if (strpos($pubkey, $prefix . " ") === 0) {
+ $has_valid_prefix = true;
+ break;
+ }
+ }
+ if (!$has_valid_prefix) {
+ return false;
+ }
+
+ $tokens = explode(" ", $pubkey);
+ if (empty($tokens[1])) {
+ return false;
+ }
+
+ return (base64_encode(base64_decode($tokens[1], true)) == $tokens[1]);
+}
+
+/**
* Determine if the user account has been suspended
*
* @param string $id The ID of user to check if suspended
diff --git a/web/template/account_edit_form.php b/web/template/account_edit_form.php
index 17dd937..996c207 100644
--- a/web/template/account_edit_form.php
+++ b/web/template/account_edit_form.php
@@ -98,6 +98,11 @@
</p>
<p>
+ <label for="id_ssh"><?= __("SSH Public Key") ?>:</label>
+ <textarea name="PK" id="id_ssh" rows="5" cols="30"><?= htmlspecialchars($PK) ?></textarea>
+ </p>
+
+ <p>
<label for="id_language"><?= __("Language") ?>:</label>
<select name="L" id="id_language">
<?php