Indefero

Indefero Commit Details


Date:2010-08-24 16:30:12 (14 years 3 months ago)
Author:Thomas Keller
Branch:develop, feature-issue_links, feature.better-home, feature.content-md5, feature.diff-whitespace, feature.download-md5, feature.issue-links, feature.issue-of-others, feature.issue-summary, feature.search-filter, feature.webrepos, feature.wiki-default-page, master, release-1.1, release-1.2, release-1.3
Commit:7f32a5679d01fb89b5bbdb0f3a75ff6cc23f0421
Parents: a442fd588ee2bc3bd25c9c9cea0c472e7e86681d
Message:* removed `type` field in IDF_Key on request of Loic and automatically detect and validate raw key data * reworked the parseMonotoneKeyData() function to parse ssh and monotone keys * tweak help texts and exception strings

Changes:

File differences

src/IDF/Form/Admin/UserCreate.php
8989
9090
9191
92
92
9393
94
95
96
97
98
99
100
101
10294
10395
10496
......
143135
144136
145137
146
138
147139
148140
149141
150142
151
152143
153144
154145
......
214205
215206
216207
217
218
219
220
208
221209
222210
223
224
211
225212
226
213
227214
228215
'widget_attrs' => array('rows' => 3,
'cols' => 40),
'widget' => 'Pluf_Form_Widget_TextareaInput',
'help_text' => __('Be careful to provide the public key and not the private key!')
'help_text' => __('Paste a SSH or monotone public key. Be careful to not provide your private key here!')
));
$this->fields['public_key_type'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Key type'),
'initial' => 'ssh',
'widget_attrs' => array('choices' => IDF_Key::getAvailableKeyTypes()),
'widget' => 'Pluf_Form_Widget_SelectInput',
));
}
/**
$params = array('user' => $user);
Pluf_Signal::send('Pluf_User::passwordUpdated',
'IDF_Form_Admin_UserCreate', $params);
// Create the ssh key as needed
// Create the public key as needed
if ('' !== $this->cleaned_data['public_key']) {
$key = new IDF_Key();
$key->user = $user;
$key->content = $this->cleaned_data['public_key'];
$key->type = $this->cleaned_data['public_key_type'];
$key->create();
}
// Send an email to the user with the password
return $this->cleaned_data['login'];
}
/**
* Checks whether any given public key is valid
*/
public function clean()
public function clean_public_key()
{
$this->cleaned_data['public_key'] =
IDF_Form_UserAccount::checkPublicKey($this->cleaned_data['public_key'],
$this->cleaned_data['public_key_type']);
IDF_Form_UserAccount::checkPublicKey($this->cleaned_data['public_key']);
return $this->cleaned_data;
return $this->cleaned_data['public_key'];
}
}
src/IDF/Form/UserAccount.php
9999
100100
101101
102
102
103103
104
105
106
107
108
109
110
111
112104
113105
114106
......
161153
162154
163155
164
165156
166157
167158
......
203194
204195
205196
206
207197
208198
209199
210
200
211201
212202
213203
214204
215205
216206
217
207
218208
219
220
221
222
223
224
225
209
226210
211
227212
228213
229214
230215
231216
232217
218
233219
234220
235
236
221
222
237223
238224
239225
240226
241
242
243
244
245
246
247
248
227
249228
229
250230
251231
252232
......
258238
259239
260240
261
262
241
242
263243
264244
265245
266246
267
268
269
247
248
249
250
270251
271252
272253
273254
274255
275256
276
257
277258
278259
279260
......
317298
318299
319300
301
302
303
304
305
306
307
308
320309
321
322
310
323311
324312
325313
......
332320
333321
334322
335
336
337
338
339
340323
341324
342325
'widget_attrs' => array('rows' => 3,
'cols' => 40),
'widget' => 'Pluf_Form_Widget_TextareaInput',
'help_text' => __('Be careful to provide your public key and not your private key!')
'help_text' => __('Paste a SSH or monotone public key. Be careful to not provide your private key here!')
));
$this->fields['public_key_type'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Key type'),
'initial' => 'ssh',
'widget_attrs' => array('choices' => IDF_Key::getAvailableKeyTypes()),
'widget' => 'Pluf_Form_Widget_SelectInput',
));
}
/**
$key = new IDF_Key();
$key->user = $this->user;
$key->content = $this->cleaned_data['public_key'];
$key->type = $this->cleaned_data['public_key_type'];
if ($commit) {
$key->create();
}
* validate the key.
*
* @param $key string The key
* @param $key string The type ('ssh' or 'mtn')
* @param $user int The user id of the user of the key (0)
* @return string The clean key
*/
public static function checkPublicKey($key, $type, $user=0)
public static function checkPublicKey($key, $user=0)
{
$key = trim($key);
if (strlen($key) == 0) {
return '';
}
if ($type == 'ssh') {
if (preg_match('#^ssh\-[a-z]{3}\s\S+\s\S+$#', $key)) {
$key = str_replace(array("\n", "\r"), '', $key);
if (!preg_match('#^ssh\-[a-z]{3}\s\S+\s\S+$#', $key)) {
throw new Pluf_Form_Invalid(
__('The format of the key is not valid. It must start '.
'with ssh-dss or ssh-rsa, a long string on a single '.
'line and at the end a comment.')
);
}
if (Pluf::f('idf_strong_key_check', false)) {
$tmpfile = Pluf::f('tmp_folder', '/tmp').'/'.$user.'-key';
file_put_contents($tmpfile, $key, LOCK_EX);
$cmd = Pluf::f('idf_exec_cmd_prefix', '').
'ssh-keygen -l -f '.escapeshellarg($tmpfile).' > /dev/null 2>&1';
exec($cmd, $out, $return);
unlink($tmpfile);
if ($return != 0) {
throw new Pluf_Form_Invalid(
__('Please check the key as it does not appears '.
'to be a valid key.')
__('Please check the key as it does not appear '.
'to be a valid SSH public key.')
);
}
}
}
else if ($type == 'mtn') {
if (!preg_match('#^\[pubkey [^\]]+\]\s*\S+\s*\[end\]$#', $key)) {
throw new Pluf_Form_Invalid(
__('The format of the key is not valid. It must start '.
'with [pubkey KEYNAME], contain a long string on a single '.
'line and end with [end] in the final third line.')
);
}
else if (preg_match('#^\[pubkey [^\]]+\]\s*\S+\s*\[end\]$#', $key)) {
if (Pluf::f('idf_strong_key_check', false)) {
// if monotone can read it, it should be valid
$mtn_opts = implode(' ', Pluf::f('mtn_opts', array()));
$cmd = Pluf::f('idf_exec_cmd_prefix', '').
if ($return != 0) {
throw new Pluf_Form_Invalid(
__('Please check the key as it does not appears '.
'to be a valid key.')
__('Please check the key as it does not appear '.
'to be a valid monotone public key.')
);
}
}
}
else
{
throw new Pluf_Form_Invalid(__('Unknown key type'));
else {
throw new Pluf_Form_Invalid(
__('Public key looks neither like a SSH '.
'nor monotone public key.'));
}
// If $user, then check if not the same key stored
if ($user) {
$ruser = Pluf::factory('Pluf_User', $user);
if ($ruser->id > 0) {
$sql = new Pluf_SQL('content=%s AND type=%s', array($key, $type));
$sql = new Pluf_SQL('content=%s', array($key));
$keys = Pluf::factory('IDF_Key')->getList(array('filter' => $sql->gen()));
if (count($keys) > 0) {
throw new Pluf_Form_Invalid(
return $this->cleaned_data['email'];
}
function clean_public_key()
{
$this->cleaned_data['public_key'] =
self::checkPublicKey($this->cleaned_data['public_key'],
$this->user->id);
return $this->cleaned_data['public_key'];
}
/**
* Check to see if the 2 passwords are the same and if any
* given public key is valid
* Check to see if the 2 passwords are the same
*/
public function clean()
{
}
}
$this->cleaned_data['public_key'] =
self::checkPublicKey($this->cleaned_data['public_key'],
$this->cleaned_data['public_key_type'],
$this->user->id);
return $this->cleaned_data;
}
}
src/IDF/Key.php
5454
5555
5656
57
58
59
60
61
62
63
6457
6558
6659
......
8275
8376
8477
85
78
8679
87
88
80
81
82
83
84
85
8986
90
91
92
87
88
9389
94
90
91
92
93
94
95
96
97
98
9599
96100
97101
98
99
102
100103
101104
102105
103
106
104107
105
108
106109
107110
108111
......
116119
117120
118121
119
122
120123
121
124
125
126
122127
123128
124129
......
174179
175180
176181
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192182
'blank' => false,
'verbose' => __('public key'),
),
'type' =>
array(
'type' => 'Pluf_DB_Field_Varchar',
'size' => 3,
'blank' => false,
'verbose' => __('key type'),
),
);
// WARNING: Not using getSqlTable on the Pluf_User object to
// avoid recursion.
return Pluf_Template::markSafe(Pluf_esc(substr($this->content, 0, 25)).' [...] '.Pluf_esc(substr($this->content, -55)));
}
private function parseMonotoneKeyData()
private function parseContent()
{
if ($this->type != "mtn")
throw new IDF_Exception("key is not a monotone key type");
if (preg_match('#^\[pubkey ([^\]]+)\]\s*(\S+)\s*\[end\]$#', $this->content, $m)) {
return array('mtn', $m[1], $m[2]);
}
else if (preg_match('#^ssh\-[a-z]{3}\s(\S+)\s(\S+)$#', $this->content, $m)) {
return array('ssh', $m[2], $m[1]);
}
preg_match("#^\[pubkey ([^\]]+)\]\s*(\S+)\s*\[end\]$#", $this->content, $m);
if (count($m) != 3)
throw new IDF_Exception("invalid key data detected");
throw new IDF_Exception('invalid or unknown key data detected');
}
return array($m[1], $m[2]);
/**
* Returns the type of the public key
*
* @return string 'ssh' or 'mtn'
*/
function getType()
{
list($type, , ) = $this->parseContent();
return $type;
}
/**
* Returns the key name of the key, i.e. most of the time the email
* address, which not neccessarily has to be unique across a project.
* Returns the key name of the key
*
* @return string
*/
function getMonotoneKeyName()
function getName()
{
list($keyName, ) = $this->parseMonotoneKeyData();
list(, $keyName, ) = $this->parseContent();
return $keyName;
}
*
* @return string
*/
function getMonotoneKeyId()
function getMtnId()
{
list($keyName, $keyData) = $this->parseMonotoneKeyData();
list($type, $keyName, $keyData) = $this->parseContent();
if ($type != 'mtn')
throw new IDF_Exception('key is not a monotone public key');
return sha1($keyName.":".$keyData);
}
Pluf_Signal::send('IDF_Key::preDelete',
'IDF_Key', $params);
}
/**
* Returns an associative array with available key types for this
* idf installation, ready for consumption for a <select> widget
*
* @return array
*/
public static function getAvailableKeyTypes()
{
$key_types = array(__("SSH") => 'ssh');
if (array_key_exists('mtn', Pluf::f('allowed_scm', array()))) {
$key_types[__("monotone")] = 'mtn';
}
return $key_types;
}
}
src/IDF/Migrations/16KeyType.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 CĂ©ondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Add the type column in the keys table.
*/
function IDF_Migrations_16KeyType_up($params=null)
{
$table = Pluf::factory('IDF_Key')->getSqlTable();
$sql = array();
$sql['PostgreSQL'] = 'ALTER TABLE '.$table.' ADD COLUMN "type" VARCHAR(3) DEFAULT \'ssh\'';
$sql['MySQL'] = 'ALTER TABLE '.$table.' ADD COLUMN `type` VARCHAR(3) DEFAULT \'ssh\'';
$db = Pluf::db();
$engine = Pluf::f('db_engine');
if (!isset($sql[$engine])) {
throw new Exception('SQLite complex migration not supported.');
}
$db->execute($sql[$engine]);
}
function IDF_Migrations_16KeyType_down($params=null)
{
$table = Pluf::factory('IDF_Key')->getSqlTable();
$sql = array();
$sql['PostgreSQL'] = 'ALTER TABLE '.$table.' DROP COLUMN "type"';
$sql['MySQL'] = 'ALTER TABLE '.$table.' DROP COLUMN `type`';
$db = Pluf::db();
$engine = Pluf::f('db_engine');
if (!isset($sql[$engine])) {
throw new Exception('SQLite complex migration not supported.');
}
$db->execute($sql[$engine]);
}
src/IDF/Plugin/SyncGit/Cron.php
4848
4949
5050
51
52
51
5352
5453
5554
$out = '';
$keys = Pluf::factory('IDF_Key')->getList(array('view'=>'join_user'));
foreach ($keys as $key) {
if ($key->type == 'ssh' && strlen($key->content) > 40 // minimal check
and preg_match('/^[a-zA-Z][a-zA-Z0-9_.-]*(@[a-zA-Z][a-zA-Z0-9.-]*)?$/', $key->login)) {
if ($key->getType() == 'ssh' and preg_match('/^[a-zA-Z][a-zA-Z0-9_.-]*(@[a-zA-Z][a-zA-Z0-9.-]*)?$/', $key->login)) {
$content = trim(str_replace(array("\n", "\r"), '', $key->content));
$out .= sprintf($template, $cmd, $key->login, $content)."\n";
}
src/IDF/templates/idf/gadmin/users/create.html
4646
4747
4848
49
50
51
52
53
49
5450
5551
5652
<th>{$form.f.public_key.labelTag}:</th>
<td>{if $form.f.public_key.errors}{$form.f.public_key.fieldErrors}{/if}
{$form.f.public_key|unsafe}<br />
{$form.f.public_key_type.labelTag} {$form.f.public_key_type|unsafe}<br />
<span class="helptext">
{$form.f.public_key.help_text}
{$form.f.public_key_type.help_text}
</span>
<span class="helptext">{$form.f.public_key.help_text}</span>
</td>
</tr>
<tr>
src/IDF/templates/idf/user/myaccount.html
5757
5858
5959
60
61
62
63
64
60
6561
6662
6763
<th>{$form.f.public_key.labelTag}:</th>
<td>{if $form.f.public_key.errors}{$form.f.public_key.fieldErrors}{/if}
{$form.f.public_key|unsafe}<br />
{$form.f.public_key_type.labelTag} {$form.f.public_key_type|unsafe}<br />
<span class="helptext">
{$form.f.public_key.help_text}
{$form.f.public_key_type.help_text}
</span>
<span class="helptext">{$form.f.public_key.help_text}</span>
</td>
</tr>
<tr class="pass-info" id="extra-password">

Archive Download the corresponding diff file

Page rendered in 0.10304s using 13 queries.