xaizek / rocketgit (License: AGPLv3+) (since 2018-12-09)
Light and fast Git hosting solution suitable to serve both as a hub or as a personal code storage with its tickets, pull requests, API and much more.
<root> / tests / keys.php (c68aa721ac810d1704bd6c19804386dc6e2b5ecd) (8,128B) (mode 100644) [raw]
<?php
error_reporting(E_ALL | E_STRICT);
ini_set("track_errors", "On");

$INC = dirname(__FILE__) . "/../inc";
require_once(dirname(__FILE__) . "/config.php");
require_once($INC . "/init.inc.php");
require_once($INC . "/util.inc.php");
require_once($INC . "/keys.inc.php");
require_once($INC . "/sql.inc.php");
require_once($INC . "/struct.inc.php");
require_once($INC . "/fixes.inc.php");

rg_log_set_file("keys.log");

require_once("common.php");

$rg_sql_debug = 1;

// Defaults
$rg_admin_email = "rg@embedromix.ro";

$rg_ui = array("uid" => 1, "is_admin" => 0, "email" => "test@embedromix.ro",
	"confirmed" => 1);

$sql = "DELETE FROM keys";
$res = rg_sql_query($db, $sql);
rg_sql_free_result($res);

// insert a key 1
$key1 = "ssh-dss AAAA\nB3NzaC1kc3MAAACBAJLkWtcoCUbWCRXecE907nO1gSh6IrfkD5bsyobrFOp6xYuJvfteKKpE79HUcbEpzIVFNk3mlQf/+k9cFP2Wy8F34UXFk8cXU4FU7z/TM1iHHOHnqFqvzv59LRaaMw4MaHm/4WKdfJy16KOLgosSBzWif3a1nKMdIZuYeIGso7qFAAAAFQC4JU7YoGu2nZQ0fEXFKaRhq+d9UQAAAIEAhgslkwwID6oBBdWx+mUuaXKt/bZcdCfNyjnejxlsZHPfDnayuqCKIgxlhYpiPS6LwiSK5feL55meF33HanCzX53z7ieoW6Je9z2H8/93sCvzk4LMj7XkeEy3G5UnRuL+uc6qrazF7Pu448cQH0pkh6N0zNueQlPpGL4/lHbIiVgAAACAQJup/h36aD9DprosVCQe40nalp7t4o/M75Y70sV7FNrL0azUQcn1ZL+J8F9l/dDRPG3rST2DABgba9pHGWa96vaNfTLnopy3po/296SYQl7/1nek0YtioEikoB+HQxk7eSwRI6bTpKEFNyUnp2/bcNjJYORKCeYwJJ2KDW6GJro= first\n_key";
rg_state_set($db, 'ssh_key_allow_dsa', 1);
$key_id1 = rg_keys_add($db, $rg_ui, $key1);
if ($key_id1 === FALSE) {
	rg_log("Cannot add key 1 (" . rg_keys_error() . ")!");
	exit(1);
}
// We should not have \n inside the key and comment
$ki = rg_keys_info($key1);
if (strstr($ki['key'], "\n")) {
	rg_log('\n is not allowed in a key body!');
	exit(1);
}
if (strstr($ki['comment'], "\n")) {
	rg_log('\n is not allowed in a key comment!');
	exit(1);
}

// insert a key 2
$rg_ui['uid'] = 2;
$key2 = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+2OHaQiZzdwV4HQF9pCBbSQFaoM5Q0YmmRYDL8BUCjwClDgOLp9lQVN5XksoBx2t9INj6XrobjNc/GUF60c1Ald0FtjRl7nIZdYvKDutlxHcGUy6MHsVnCDviXQJD9Hm9fyuBLdy3/oadSCAaQYE/Tcf9rWt1NmhQ7560bCGmh4pw8N+XXAz2nQBCqvIK8VDoBbOOgFa/HOwBrKCgaGmcTGs5wRWHbw3+h6CO1vqEYcSCSqBPMG1JOMfMTuJ0aTXXEkSNPF+TVva85L4qrQslyHbn2JU1t7/HQsFnGtgF1o2AglIR2RbyMmr6axI51Srf20EB9/c9T3auYQipbw85 second_key";
rg_state_set($db, 'ssh_key_min_bits_rsa', 1024);
$key_id2 = rg_keys_add($db, $rg_ui, $key2);
if ($key_id2 === FALSE) {
	rg_log("Cannot add key 2 (" . rg_keys_error() . ")!");
	exit(1);
}


// test key file generation
$rg_scripts = "/a";
$rg_ssh_paras = "ssh1,ssh2,ssh3";
$r = rg_keys_regen($db);
if ($r === FALSE) {
	rg_log("Cannot regenerate keys (" . rg_keys_error() . ")!");
	exit(1);
}
$c = @file_get_contents("afile.txt");
if ($c === FALSE) {
	rg_log("Cannot regenerate file (afile.txt not found)!");
	exit(1);
}
$key1b = str_replace("\n", '', $key1); $key1b = str_replace('first_key', 'first _key', $key1b);
$e = "command=\""
	. $rg_scripts . "/scripts/remote.sh 1 $key_id1 N\","
	. $rg_ssh_paras . ' ' . $key1b . "\n"
	. "command=\""
	. $rg_scripts . "/scripts/remote.sh 2 $key_id2 N\","
	. $rg_ssh_paras . ' ' . $key2 . "\n";
if (strcmp($c, $e) != 0) {
	rg_log("Generated file does not seems OK!");
	rg_log("e: $e");
	rg_log("c: $c");
	exit(1);
}

@unlink("afile.txt");


// test max_ssh_keys - must fail because overlimit
rg_state_set($db, 'max_ssh_keys', 1);
$key3 = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUiVHDS3rhn79+9YbXXN+npU9tDTzXZHkXZF9BNqI0GrnASuaBU2oJ/UK2OCgGQ45JOlzUCXcP09hHcyPqd4pZdHQhMAImCnm0iRivQ9VhJRRbl/s8kokoStZGAdcW+ETlhUtRXSQOu8U1PXqwUwZCkeE9asmS4Wg9/OO3eDuTMvE3yiNpHKt6TcVYlU6PlsiTFVJrAuIEbXRs5b5luuM+nM17caos0mn6w+kZ3QD9AnX+9pN4VgXKxEHGfWpOCtRDOQb9mTk2bX6MBJrcKtkAPnyYDiaRs1ANG7L4AP6to/gy3A9w6flTAD94gFAm833earIZJnCiavx3/dUWWt3L third_key';
$key_id3 = rg_keys_add($db, $rg_ui, $key3);
if ($key_id3 !== FALSE) {
	rg_log("Seems we can add more keys than allowed! Not good!");
	exit(1);
}
rg_state_set($db, 'max_ssh_keys', 10);

rg_log('');
rg_log_enter('Uploading a RSA key that is forbidden');
rg_state_set($db, 'ssh_key_min_bits_rsa', 4096);
$_key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDHotZMHPSwhVDwV5xOroZ21kzgFuBaXk3xXIT9hHM9WKD3jw0/C6TotbOoghTfJxdQtOG1t0t7eUUCJXR/3BLqamxIyAXTH2qIxf9ySIVLylKXriHQZoOa0GVhnF0ZYxR7Ot5GkIuXsjtSLrvw9p2BPf41EoR1ZZ74QYQdKfDiGw== root@host';
$r = rg_keys_add($db, $rg_ui, $_key);
if ($r !== FALSE) {
	rg_log('Seems we can add forbidden keys (rsa-1024)!');
	exit(1);
}
rg_state_set($db, 'ssh_key_min_bits_rsa', 2048);

// delete a key
$rg_ui['uid'] = 1;
$list = array($key_id1 => 'junk');
$r = rg_keys_remove($db, $rg_ui, $list);
if ($r === FALSE) {
	rg_log("Cannot remove key (" . rg_keys_error() . ")!");
	exit(1);
}


rg_log_ml("\n\nTesting a good key");
$type = 'ssh-dss';
$body = 'AAAAB3NzaC1kc3MAAACBAJLkWtcoCUbWCRXecE907nO1gSh6IrfkD5bsyobrFOp6xYuJvfteKKpE79HUcbEpzIVFNk3mlQf/+k9cFP2Wy8F34UXFk8cXU4FU7z/TM1iHHOHnqFqvzv59LRaaMw4MaHm/4WKdfJy16KOLgosSBzWif3a1nKMdIZuYeIGso7qFAAAAFQC4JU7YoGu2nZQ0fEXFKaRhq+d9UQAAAIEAhgslkwwID6oBBdWx+mUuaXKt/bZcdCfNyjnejxlsZHPfDnayuqCKIgxlhYpiPS6LwiSK5feL55meF33HanCzX53z7ieoW6Je9z2H8/93sCvzk4LMj7XkeEy3G5UnRuL+uc6qrazF7Pu448cQH0pkh6N0zNueQlPpGL4/lHbIiVgAAACAQJup/h36aD9DprosVCQe40nalp7t4o/M75Y70sV7FNrL0azUQcn1ZL+J8F9l/dDRPG3rST2DABgba9pHGWa96vaNfTLnopy3po/296SYQl7/1nek0YtioEikoB+HQxk7eSwRI6bTpKEFNyUnp2/bcNjJYORKCeYwJJ2KDW6GJro=';
$comment = 'comment';
$key = $type . ' ' . $body . ' ' . $comment;
$r = rg_keys_info($key);
if ($r['ok'] != 1) {
	rg_log("Error for a valid key: " . rg_keys_error() . "!");
	exit(1);
}

rg_log_ml("\n\nTesting the recover when the key is full of spaces because of the paste");
$type = 'ssh-dss';
$body = 'AAAAB3Nza' . "\n" . 'C1kc3MAAACB' . ' ' . 'AJLkWtcoCUbWCR' . ' '
	. 'XecE907nO1gSh6IrfkD5bsyobrFOp6xYuJvft' . ' ' . 'eKKpE79HUcbEpzIVFN'
	. 'k3mlQf/+k9cFP2Wy8F34UXFk8cXU4FU7z/TM1iHHOHnqFqvzv59LRaaMw4MaHm/4WK'
	. 'dfJy16KOLgosSBzWif3a1nKMdIZuYeIGso7qFAAAAFQC4JU7YoGu2nZQ0fEXFKaRhq'
	. '+d9UQAAAIEAhgslkwwID6oBBdWx+mUuaXKt/bZcdCfNyjnejxlsZHPfDnayuqCKIgx'
	. 'lhYpiPS6LwiSK5feL55meF33HanCzX53z7ieoW6Je9z2H8/93sCvzk4LMj7XkeEy3G'
	. '5UnRuL+uc6qrazF7Pu448cQH0pkh6N0zNueQlPpGL4/lHbIiVgAAACAQJup/h36aD9'
	. 'DprosVCQe40nalp7t4o/M75Y70sV7FNrL0azUQcn1ZL+J8F9l/dDRPG3rST2DABgba'
	. '9pHGWa96vaNfTLnopy3po/296SYQl7/1nek0YtioEikoB+HQxk7eSwRI6bTpKEFNyU'
	. 'np2/bcNjJYORKCeYwJJ2KDW6' . ' ' . 'GJro=';
$comment = 'comment1 comment2 comment3';
$key = $type . ' ' . $body . ' ' . $comment;
$r = rg_keys_info($key);
if ($r['ok'] != 1) {
	rg_log("Error for a valid key (with spaces): " . rg_keys_error() . "!");
	exit(1);
}

rg_log_ml("\n\nTesting mismatch between types");
$type = 'ssh-rsa';
$comment = 'comment1 comment2 comment3';
$key = $type . ' ' . $body . ' ' . $comment;
$r = rg_keys_info($key);
if ($r['ok'] != 0) {
	rg_log("No error for an invalid key (type mismatch)!");
	exit(1);
}


rg_log_ml("\n\nTesing ecdsa key type");
$type = 'ecdsa-sha2-nistp256';
$body = 'AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDCLAxnMiMaSm+YI+f'
	. '7RNLafBzv1JUWD/4/MeVf4JdMPN4QaNwXlCe9mR9Lmy1eDd/tW2AsEBfobhFbSI8eHtP4=';
$comment = 'comment';
$key = $type . ' ' . $body . ' ' . $comment;
$r = rg_keys_info($key);
if ($r['ok'] != 1) {
	rg_log("Error for a valid key (ecdsa): " . rg_keys_error() . "!");
	exit(1);
}
if (strcasecmp($r['fingerprint_md5'], '85:8f:2f:84:c2:db:88:e5:95:f6:22:b9:8d:91:59:cc') != 0) {
	rg_log_ml("r=" . print_r($r, TRUE));
	rg_log("Invalid md5 fingerprint!");
	exit(1);
}
if (strcasecmp($r['fingerprint_sha256'], 'd0FRDYxeXCcS/ZBd4wGbzCRHnh5VPB2zjoYYJRg5Gwo') != 0) {
	rg_log_ml("r=" . print_r($r, TRUE));
	rg_log("Invalid sha256 fingerprint!");
	exit(1);
}


rg_log_ml("\n\nTesing ed25519 key type");
$type = 'ssh-ed25519';
$body = 'AAAAC3NzaC1lZDI1NTE5AAAAIGYlG3R7u0oMzvy9iAzKB29U26U9o3+mXCXODAQYKEEu';
$comment = 'comment';
$key = $type . ' ' . $body . ' ' . $comment;
$r = rg_keys_info($key);
if ($r['ok'] != 1) {
	rg_log_ml("r=" . print_r($r, TRUE));
	rg_log("Error for a valid key (ed25519): " . rg_keys_error() . "!");
	exit(1);
}
if (strcasecmp($r['fingerprint_md5'], '28:f7:1b:cb:ba:43:0a:41:b8:30:a3:8e:8f:bc:d5:4a') != 0) {
	rg_log_ml("r=" . print_r($r, TRUE));
	rg_log("Invalid fingerprint!");
	exit(1);
}


rg_sql_close($db);

rg_log("OK");
?>
Hints

Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://code.reversed.top/user/xaizek/rocketgit

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@code.reversed.top/user/xaizek/rocketgit

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a pull request:
... clone the repository ...
... make some changes and some commits ...
git push origin master