mango r186 - in trunk: . lib
- From: ovitters svn gnome org
- To: svn-commits-list gnome org,gnome-sysadmin gnome org
- Subject: mango r186 - in trunk: . lib
- Date: Mon, 2 Jun 2008 18:51:38 +0000 (UTC)
Author: ovitters
Date: Mon Jun 2 18:51:38 2008
New Revision: 186
URL: http://svn.gnome.org/viewvc/mango?rev=186&view=rev
Log:
* lib/util.php: Parse the SSH public key data to determine the real
bit length. Change the is_valid_ssh_pub_key function to give more
feedback (array instead of just 'false').
* lib/account.php: Adapt to is_valid_ssh_pub_key return changes.
* lib/user.php: Adapt to is_valid_ssh_pub_key return changes.
Modified:
trunk/ChangeLog
trunk/lib/account.php
trunk/lib/user.php
trunk/lib/util.php
Modified: trunk/lib/account.php
==============================================================================
--- trunk/lib/account.php (original)
+++ trunk/lib/account.php Mon Jun 2 18:51:38 2008
@@ -204,7 +204,8 @@
$error[] = 'keys';
} else {
foreach($this->authorizationkeys as $authorizedKey) {
- if (!is_valid_ssh_pub_key($authorizedKey)) {
+ $l = is_valid_ssh_pub_key($authorizedKey);
+ if (!$l[0]) {
$error[] = 'keys';
break;
}
Modified: trunk/lib/user.php
==============================================================================
--- trunk/lib/user.php (original)
+++ trunk/lib/user.php Mon Jun 2 18:51:38 2008
@@ -306,9 +306,9 @@
foreach($keys as $key) {
$keychanges['authorizedKey'][] = $key;
- $fingerprint = is_valid_ssh_pub_key($key, False, True);
- if ($fingerprint !== false) {
- $changes[] = array('id'=>$desc_key, "key"=>$key, "fingerprint"=>$fingerprint);
+ $ssh = is_valid_ssh_pub_key($key, False, True);
+ if ($ssh[0] !== false) {
+ $changes[] = array('id'=>$desc_key, "key"=>$key, "fingerprint"=>"$ssh[1] $ssh[2] $ssh[3] $ssh[4]");
} else {
$changes[] = array('id'=>$desc_key, "key"=>$key);
}
@@ -454,9 +454,9 @@
$node->appendChild($dom->createTextNode($this->description));
foreach($this->authorizedKeys as $authorizedKey) {
$node = $formnode->appendChild($dom->createElement("authorizedKey"));
- $fingerprint = is_valid_ssh_pub_key($authorizedKey, False, True);
- if ($fingerprint !== false) {
- $node->setAttribute("fingerprint", $fingerprint);
+ $ssh = is_valid_ssh_pub_key($authorizedKey, False, True);
+ if ($ssh[0] !== false) {
+ $node->setAttribute("fingerprint", "$ssh[1] $ssh[2] $ssh[3] $ssh[4]");
}
$node->appendChild($dom->createTextNode($authorizedKey));
}
@@ -478,9 +478,10 @@
$errors[] = "mail";
foreach($this->authorizedKeys as $authorizedKey) {
- if (!is_valid_ssh_pub_key($authorizedKey)) {
- $errors[] = 'keys';
- break;
+ $ssh = is_valid_ssh_pub_key($authorizedKey);
+ if (!$ssh[0]) {
+ $errors[] = 'keys';
+ break;
}
}
Modified: trunk/lib/util.php
==============================================================================
--- trunk/lib/util.php (original)
+++ trunk/lib/util.php Mon Jun 2 18:51:38 2008
@@ -3,38 +3,111 @@
require_once('Mail.php');
require_once('Mail/mime.php');
+class SSHMessage {
+
+ private
+ $idx,
+ $data_len,
+ $data;
+
+ function __construct($data) {
+ $this->idx = 0;
+ $this->data = $data;
+ $this->data_len = strlen($data);
+ }
+
+ function _get_bytes($nr) {
+ if (($this->idx + $nr) > $this->data_len)
+ throw Exception('Not enough bytes available in SSH message');
+
+ $this->idx += $nr;
+ return substr($this->data, $this->idx - $nr, $nr);
+ }
+
+ function get_int() {
+ # XXX - Weird
+ $arr = unpack('N', $this->_get_bytes(4));
+ return $arr[1];
+ }
+
+ function get_string() {
+ return $this->_get_bytes($this->get_int());
+ }
+}
+
+function bit_length($data) {
+ $hbyte = ord($data[0]);
+ $bitlen = strlen($data) * 8;
+ $check = 0x80;
+ while ($check && !($hbyte & $check)) {
+ $check >>= 1;
+ $bitlen -= 1;
+ }
+ return $bitlen;
+}
+
+
function is_valid_ssh_pub_key($key, $check_length = True, $return_fingerprint = false) {
+ $keytype = '';
+ $length = 0;
+ $hash = '';
+ $comment = '';
+
if(empty($key) || substr($key, 0, 4) != "ssh-")
- return false;
+ return array(false, $keytype, $length, $hash, $comment);
# Split the data
list($format, $data, $comment) = explode(" ", $key, 3);
# Format should be DSA or RSA
if ($format != "ssh-dss" && $format != "ssh-rsa")
- return false;
+ return array(false, $keytype, $length, $hash, $comment);
+
+ $keytype = $format == 'ssh-dss' ? 'DSA' : 'RSA';
# Data should be a base64 encoded string
$certificate = base64_decode($data);
if ($certificate == $data)
- return false;
+ return array(false, $keytype, $length, $hash, $comment);
+
+ $hash = rtrim(chunk_split(md5($certificate), 2, ':'), ':');
+
+ if ($check_length or $return_fingerprint) {
+ try {
+ $msg = new SSHMessage($certificate);
+ $type = $msg->get_string();
+
+ if ($type != $format)
+ return array(false, $keytype, $length, $hash, $comment);
+
+ if ($format == 'ssh-rsa') {
+ $e = $msg->get_string();
+ $n = $msg->get_string();
+ $length = bit_length($n);
+ }
+ else {
+ $p = $msg->get_string();
+ $q = $msg->get_string();
+ $g = $msg->get_string();
+ $y = $msg->get_string();
+ $length = bit_length($p);
+ }
+ } catch (Exception $e) {
+ return array(false, $keytype, $length, $hash, $comment);
+ }
+ }
if ($check_length) {
- # DSA certificate data is exactly 433 bytes (always 1024 bits, comparable to 1536 RSA key, has 305 of other data)
- # RSA has to be >= 277 bytes (2048 bits, 21 bytes of other data)
- #
- # However, old ssh-keugen versions allowed DSA keys with != 1024 bits...
- $cert_length = strlen($certificate);
- if (($format == "ssh-dss" && $cert_length < 433)
- || ($format == "ssh-rsa" && $cert_length < 277))
+ if (($format == "ssh-dss" && $length != 1024)
+ || ($format == "ssh-rsa" && $length < 2048))
{
# Either invalid, or not enough bits in the public key
- return false;
+ return array(false, $keytype, $length, $hash, $comment);
}
}
# All seems ok
- return $return_fingerprint ? rtrim(chunk_split(md5($certificate), 2, ':'), ':') . ' ' . $comment : true;
+ return array(true, $keytype, $length, $hash, $comment);
}
function array_same($array1, $array2) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]