File compare.csv changed (mode: 100644) (index c403f2d..878b8e5) |
16 |
16 |
"IPv6","Yes","Yes","?","Yes","Yes","?","?" |
"IPv6","Yes","Yes","?","Yes","Yes","?","?" |
17 |
17 |
"Submodules {Are Git submodules supported?}","?","?","?","?","?","?","?" |
"Submodules {Are Git submodules supported?}","?","?","?","?","?","?","?" |
18 |
18 |
"Usable with lynx","Yes","Yes","Yes","n/a","Yes","Yes","?" |
"Usable with lynx","Yes","Yes","Yes","n/a","Yes","Yes","?" |
19 |
|
"2fa (two-factor authentication)","Yes","Yes","Yes (see 2)","Yes","No","?","?" |
|
|
19 |
|
"SSH OTP 2fa (two-factor authentication)","Yes","No {Only in Premium}","Yes (see 2)","Yes","No","?","?" |
|
20 |
|
"Web OTP 2fa (two-factor authentication)","Yes","Yes","Yes","?","?","?","?" |
20 |
21 |
"Web Hooks","Yes","Yes","Yes","No","Yes","Yes","?" |
"Web Hooks","Yes","Yes","Yes","No","Yes","Yes","?" |
21 |
22 |
"Web Hooks - provide client certs","Yes","No","No","n/a","?","No","?" |
"Web Hooks - provide client certs","Yes","No","No","n/a","?","No","?" |
22 |
23 |
"Web Hooks - authenticate server (CA cert)","Yes","No","No","n/a","?","No","?" |
"Web Hooks - authenticate server (CA cert)","Yes","No","No","n/a","?","No","?" |
23 |
|
"OpenSSH AuthorizedKeysCommand","Yes","Yes","Yes","?","No","?","?" |
|
|
24 |
|
"OpenSSH FIDO2 basic support","Yes","No","Yes","Yes","?","?","?" |
|
25 |
|
"OpenSSH FIDO2 touch eforcing","Yes","No","?","?","?","?","?" |
|
26 |
|
"OpenSSH FIDO2 verify-required enforcing","Yes","?","?","?","?","?","?" |
|
27 |
|
"OpenSSH AuthorizedKeysCommand {better performance}","Yes","Yes","Yes","?","No","?","?" |
24 |
28 |
"OpenSSH filter by key type and bits {Can it disable the keys based on types and number of bits?}","Yes","Yes","?","No","No","Yes","?" |
"OpenSSH filter by key type and bits {Can it disable the keys based on types and number of bits?}","Yes","Yes","?","No","No","Yes","?" |
25 |
29 |
"Detailed info about the SSH keys {Can it show: type, number of bits, when it was uploaded, when it was first/last used, how many times was used and last command?}","Yes","No","?","No","No","?","?" |
"Detailed info about the SSH keys {Can it show: type, number of bits, when it was uploaded, when it was first/last used, how many times was used and last command?}","Yes","No","?","No","No","?","?" |
26 |
30 |
"LDAP user authentication","Yes","Yes","?","No","No","Yes","?" |
"LDAP user authentication","Yes","Yes","?","No","No","Yes","?" |
File inc/admin.inc.php changed (mode: 100644) (index b930c63..053b9cb) |
... |
... |
function rg_admin_settings_ssh($db, $rg) |
1080 |
1080 |
|
|
1081 |
1081 |
rg_log_enter('admin_settings_ssh'); |
rg_log_enter('admin_settings_ssh'); |
1082 |
1082 |
|
|
|
1083 |
|
$list = array('max_ssh_keys', 'ssh_key_min_bits_rsa', |
|
1084 |
|
'ssh_key_allow_dsa', 'ssh_key_min_bits_ecdsa', |
|
1085 |
|
'AuthorizedKeysCommand', 'fido2_security'); |
|
1086 |
|
|
1083 |
1087 |
$ret = ''; |
$ret = ''; |
1084 |
1088 |
$errmsg = array(); |
$errmsg = array(); |
1085 |
1089 |
$hints = array(); |
$hints = array(); |
|
... |
... |
function rg_admin_settings_ssh($db, $rg) |
1094 |
1098 |
break; |
break; |
1095 |
1099 |
} |
} |
1096 |
1100 |
|
|
1097 |
|
$v = rg_var_uint('max_ssh_keys'); |
|
1098 |
|
$r = rg_state_set($db, 'max_ssh_keys', $v); |
|
1099 |
|
if ($r === FALSE) { |
|
1100 |
|
$errmsg[] = 'cannot set state; try again'; |
|
1101 |
|
break; |
|
1102 |
|
} |
|
1103 |
|
|
|
1104 |
|
$v = rg_var_int('ssh_key_min_bits_rsa'); |
|
1105 |
|
$r = rg_state_set($db, 'ssh_key_min_bits_rsa', $v); |
|
1106 |
|
if ($r === FALSE) { |
|
1107 |
|
$errmsg[] = 'cannot set state; try again'; |
|
1108 |
|
break; |
|
1109 |
|
} |
|
1110 |
|
|
|
1111 |
|
$v = rg_var_int('ssh_key_allow_dsa'); |
|
1112 |
|
$r = rg_state_set($db, 'ssh_key_allow_dsa', $v); |
|
1113 |
|
if ($r === FALSE) { |
|
1114 |
|
$errmsg[] = 'cannot set state; try again'; |
|
1115 |
|
break; |
|
1116 |
|
} |
|
1117 |
|
|
|
1118 |
|
$v = rg_var_int('ssh_key_min_bits_ecdsa'); |
|
1119 |
|
$r = rg_state_set($db, 'ssh_key_min_bits_ecdsa', $v); |
|
1120 |
|
if ($r === FALSE) { |
|
1121 |
|
$errmsg[] = 'cannot set state; try again'; |
|
1122 |
|
break; |
|
|
1101 |
|
$err = FALSE; |
|
1102 |
|
foreach ($list as $k) { |
|
1103 |
|
$v = rg_var_uint($k); |
|
1104 |
|
$r = rg_state_set($db, $k, $v); |
|
1105 |
|
if ($r === FALSE) { |
|
1106 |
|
$err = TRUE; |
|
1107 |
|
break; |
|
1108 |
|
} |
1123 |
1109 |
} |
} |
1124 |
|
|
|
1125 |
|
$v = rg_var_int('AuthorizedKeysCommand'); |
|
1126 |
|
$r = rg_state_set($db, 'AuthorizedKeysCommand', $v); |
|
1127 |
|
if ($r === FALSE) { |
|
|
1110 |
|
if ($err) { |
1128 |
1111 |
$errmsg[] = 'cannot set state; try again'; |
$errmsg[] = 'cannot set state; try again'; |
1129 |
1112 |
break; |
break; |
1130 |
1113 |
} |
} |
1131 |
1114 |
|
|
1132 |
|
|
|
1133 |
1115 |
// Nobody will force the regeneration, so, do it here! |
// Nobody will force the regeneration, so, do it here! |
1134 |
1116 |
$ev = array( |
$ev = array( |
1135 |
1117 |
'category' => 'rg_keys_event_regen', |
'category' => 'rg_keys_event_regen', |
|
... |
... |
function rg_admin_settings_ssh($db, $rg) |
1149 |
1131 |
|
|
1150 |
1132 |
// Load defaults |
// Load defaults |
1151 |
1133 |
while (1) { |
while (1) { |
1152 |
|
$r = rg_state_get_uint($db, 'max_ssh_keys'); |
|
1153 |
|
if ($r === FALSE) { |
|
1154 |
|
$ret = rg_template('admin/settings/load_err.html', |
|
1155 |
|
$rg, TRUE /*xss*/); |
|
1156 |
|
break; |
|
1157 |
|
} |
|
1158 |
|
$rg['max_ssh_keys'] = $r; |
|
1159 |
|
|
|
1160 |
|
$r = rg_state_get_uint($db, 'ssh_key_min_bits_rsa'); |
|
1161 |
|
if ($r === FALSE) { |
|
1162 |
|
$ret = rg_template('admin/settings/load_err.html', |
|
1163 |
|
$rg, TRUE /*xss*/); |
|
1164 |
|
break; |
|
1165 |
|
} |
|
1166 |
|
$rg['ssh_key_min_bits_rsa'] = $r; |
|
1167 |
|
|
|
1168 |
|
$r = rg_state_get_uint($db, 'ssh_key_allow_dsa'); |
|
1169 |
|
if ($r === FALSE) { |
|
1170 |
|
$ret = rg_template('admin/settings/load_err.html', |
|
1171 |
|
$rg, TRUE /*xss*/); |
|
1172 |
|
break; |
|
1173 |
|
} |
|
1174 |
|
$rg['ssh_key_allow_dsa'] = $r; |
|
1175 |
|
|
|
1176 |
|
$r = rg_state_get_uint($db, 'ssh_key_min_bits_ecdsa'); |
|
1177 |
|
if ($r === FALSE) { |
|
1178 |
|
$ret = rg_template('admin/settings/load_err.html', |
|
1179 |
|
$rg, TRUE /*xss*/); |
|
1180 |
|
break; |
|
|
1134 |
|
$err = FALSE; |
|
1135 |
|
foreach ($list as $k) { |
|
1136 |
|
$r = rg_state_get_uint($db, $k); |
|
1137 |
|
if ($r === FALSE) { |
|
1138 |
|
$err = TRUE; |
|
1139 |
|
break; |
|
1140 |
|
} |
|
1141 |
|
$rg[$k] = $r; |
1181 |
1142 |
} |
} |
1182 |
|
$rg['ssh_key_min_bits_ecdsa'] = $r; |
|
1183 |
|
|
|
1184 |
|
$r = rg_state_get_uint($db, 'AuthorizedKeysCommand'); |
|
1185 |
|
if ($r === FALSE) { |
|
|
1143 |
|
if ($err) { |
1186 |
1144 |
$ret = rg_template('admin/settings/load_err.html', |
$ret = rg_template('admin/settings/load_err.html', |
1187 |
1145 |
$rg, TRUE /*xss*/); |
$rg, TRUE /*xss*/); |
1188 |
1146 |
break; |
break; |
1189 |
1147 |
} |
} |
1190 |
|
$rg['AuthorizedKeysCommand'] = $r; |
|
1191 |
1148 |
|
|
1192 |
1149 |
$hints[]['HTML:hint'] = rg_template('admin/settings/ssh/hints.html', |
$hints[]['HTML:hint'] = rg_template('admin/settings/ssh/hints.html', |
1193 |
1150 |
$rg, TRUE /*xss*/); |
$rg, TRUE /*xss*/); |
File inc/keys.inc.php changed (mode: 100644) (index ddaba79..1229097) |
... |
... |
function rg_keys_weak($db, $ki) |
190 |
190 |
|
|
191 |
191 |
/* |
/* |
192 |
192 |
* Extracts info about a ssh key |
* Extracts info about a ssh key |
|
193 |
|
* 'sk' key formats: https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.u2f |
193 |
194 |
*/ |
*/ |
194 |
195 |
function rg_keys_info($key) |
function rg_keys_info($key) |
195 |
196 |
{ |
{ |
|
... |
... |
function rg_keys_info($key) |
221 |
222 |
$ret['type'] = $t[0]; |
$ret['type'] = $t[0]; |
222 |
223 |
|
|
223 |
224 |
if ((strncmp($ret['type'], 'ssh-', 4) != 0) |
if ((strncmp($ret['type'], 'ssh-', 4) != 0) |
224 |
|
&& (strncmp($ret['type'], 'ecdsa-', 6) != 0)) { |
|
|
225 |
|
&& (strncmp($ret['type'], 'sk-ssh-', 7) != 0) |
|
226 |
|
&& (strncmp($ret['type'], 'ecdsa-', 6) != 0) |
|
227 |
|
&& (strncmp($ret['type'], 'sk-ecdsa-', 9) != 0) |
|
228 |
|
) { |
225 |
229 |
rg_log('key: ' . $key); |
rg_log('key: ' . $key); |
226 |
|
rg_keys_set_error("key does not start with ssh- or ecdsa-"); |
|
|
230 |
|
rg_keys_set_error('key does not start with [sk-]ssh-' |
|
231 |
|
. ' or [sk-]ecdsa-'); |
227 |
232 |
break; |
break; |
228 |
233 |
} |
} |
229 |
234 |
|
|
230 |
235 |
// We try to detect the key because spaces may mess up things |
// We try to detect the key because spaces may mess up things |
231 |
236 |
$ret['comment'] = ''; |
$ret['comment'] = ''; |
|
237 |
|
$ret['extra_info'] = ''; |
232 |
238 |
$error = TRUE; |
$error = TRUE; |
233 |
239 |
$off = 0; |
$off = 0; |
234 |
240 |
while (1) { |
while (1) { |
|
... |
... |
function rg_keys_info($key) |
255 |
261 |
continue; |
continue; |
256 |
262 |
} |
} |
257 |
263 |
$d_len = strlen($d); |
$d_len = strlen($d); |
258 |
|
rg_log("d=" . bin2hex($d)); |
|
259 |
|
rg_log("d_len=$d_len"); |
|
|
264 |
|
rg_log('d_len=' . $d_len . ' d:' . bin2hex($d)); |
260 |
265 |
|
|
261 |
|
if (strlen($d) < 4) { |
|
|
266 |
|
if ($d_len < 4) { |
262 |
267 |
rg_keys_set_error("key is too short (< 4)"); |
rg_keys_set_error("key is too short (< 4)"); |
263 |
268 |
continue; |
continue; |
264 |
269 |
} |
} |
265 |
270 |
|
|
266 |
|
// First, we have the length of the string 'ssh-*' |
|
|
271 |
|
// First, we have the length of the string '[sk-]ssh-*' |
267 |
272 |
$_t = unpack('N', $d); |
$_t = unpack('N', $d); |
268 |
273 |
$len = $_t[1]; |
$len = $_t[1]; |
269 |
274 |
rg_log_ml("len=$len"); |
rg_log_ml("len=$len"); |
|
... |
... |
function rg_keys_info($key) |
281 |
286 |
$bits_div = 1; |
$bits_div = 1; |
282 |
287 |
$bits_sub = 1; |
$bits_sub = 1; |
283 |
288 |
$fixes = array(); |
$fixes = array(); |
|
289 |
|
$bits_pos = 2000; // 2000 = not present |
|
290 |
|
$extra_info_pos = 2000; |
284 |
291 |
if (strcasecmp($ret['type'], 'ssh-rsa') == 0) { |
if (strcasecmp($ret['type'], 'ssh-rsa') == 0) { |
285 |
292 |
// OK |
// OK |
286 |
293 |
$count = 2; |
$count = 2; |
|
... |
... |
function rg_keys_info($key) |
296 |
303 |
$bits_pos = 1; |
$bits_pos = 1; |
297 |
304 |
$bits_div = 2; |
$bits_div = 2; |
298 |
305 |
$fixes[528] = 521; |
$fixes[528] = 521; |
|
306 |
|
} else if (strcasecmp($ret['type'], 'sk-ecdsa-sha2-nistp256@openssh.com') == 0) { |
|
307 |
|
// pos 0: len + curve_name [example: "nistp256" ] |
|
308 |
|
// pos 1: len + ec_point Q |
|
309 |
|
// pos 2: len + application (default "ssh:") |
|
310 |
|
$count = 3; |
|
311 |
|
$ret['bits'] = 256; // always 256 |
|
312 |
|
$bits_pos = 2000; |
|
313 |
|
$extra_info_pos = 2; |
299 |
314 |
} else if (strcasecmp($ret['type'], 'ssh-ed25519') == 0) { |
} else if (strcasecmp($ret['type'], 'ssh-ed25519') == 0) { |
300 |
315 |
// Always 256 - OK |
// Always 256 - OK |
301 |
316 |
$count = 1; |
$count = 1; |
302 |
317 |
$bits_pos = 0; |
$bits_pos = 0; |
303 |
318 |
$bits_sub = 0; |
$bits_sub = 0; |
|
319 |
|
} else if (strcasecmp($ret['type'], 'sk-ssh-ed25519@openssh.com') == 0) { |
|
320 |
|
// pos 0: len(32) + public key |
|
321 |
|
// pos 1: len + application (default "ssh:") |
|
322 |
|
// Always 256 |
|
323 |
|
$count = 2; |
|
324 |
|
$bits_pos = 0; |
|
325 |
|
$bits_sub = 0; |
|
326 |
|
$extra_info_pos = 1; |
304 |
327 |
} else { |
} else { |
305 |
328 |
rg_log('Strange key type: ' . $ret['type']); |
rg_log('Strange key type: ' . $ret['type']); |
306 |
|
// Probably this is a new key type, just consider it valid |
|
|
329 |
|
// Probably this is a new key type, just |
|
330 |
|
// consider it valid |
307 |
331 |
$_t = explode(' ', $key, 3); |
$_t = explode(' ', $key, 3); |
308 |
332 |
$ret['key'] = $_t[1]; |
$ret['key'] = $_t[1]; |
309 |
333 |
if (isset($_t[2])) |
if (isset($_t[2])) |
|
... |
... |
function rg_keys_info($key) |
312 |
336 |
break; |
break; |
313 |
337 |
} |
} |
314 |
338 |
|
|
|
339 |
|
rg_log('DEBUG: count=' . $count); |
315 |
340 |
$have_all_chunks = TRUE; |
$have_all_chunks = TRUE; |
316 |
341 |
$used = 4 + $len; |
$used = 4 + $len; |
317 |
342 |
for ($i = 0; $i < $count; $i++) { |
for ($i = 0; $i < $count; $i++) { |
318 |
343 |
if ($d_len < $used + 4) { |
if ($d_len < $used + 4) { |
319 |
|
rg_keys_set_error('key is too short (chunk length)'); |
|
|
344 |
|
rg_keys_set_error('key is too short (chunk ' . $i . '):' |
|
345 |
|
. ' ' . $d_len . ' < ' . ($used + 4)); |
320 |
346 |
$have_all_chunks = FALSE; |
$have_all_chunks = FALSE; |
321 |
347 |
break; |
break; |
322 |
348 |
} |
} |
323 |
|
$_t = unpack('N', substr($d, $used, 4)); |
|
|
349 |
|
$_t = unpack('N', substr($d, $used, 4)); $used += 4; |
324 |
350 |
$xlen = $_t[1]; |
$xlen = $_t[1]; |
325 |
|
rg_log("xlen=$xlen bits_sub=$bits_sub bits_div=$bits_div"); |
|
326 |
|
//rg_log('bin: ' . bin2hex(substr($d, $used + 4, $xlen))); |
|
327 |
|
//rg_log('ascii: ' . substr($d, $used + 4, $xlen)); |
|
328 |
|
if ($d_len < $used + 4 + $xlen) { |
|
329 |
|
rg_keys_set_error("key is too short (chunk body)"); |
|
|
351 |
|
rg_log('DEBUG: xlen=' . $xlen); |
|
352 |
|
//rg_log('DEBUG: bin: ' . bin2hex(substr($d, $used, $xlen))); |
|
353 |
|
//rg_log('DEBUG: ascii: ' . substr($d, $used, $xlen)); |
|
354 |
|
if ($d_len < $used + $xlen) { |
|
355 |
|
rg_keys_set_error('key is too short (chunk ' . $i . '):' |
|
356 |
|
. ' ' . $d_len . ' < ' . ($used + $xlen)); |
330 |
357 |
$have_all_chunks = FALSE; |
$have_all_chunks = FALSE; |
331 |
358 |
break; |
break; |
332 |
359 |
} |
} |
333 |
360 |
|
|
334 |
361 |
if ($i == $bits_pos) { |
if ($i == $bits_pos) { |
|
362 |
|
rg_log("DEBUG: bits_sub=$bits_sub bits_div=$bits_div"); |
335 |
363 |
$ret['bits'] = (($xlen - $bits_sub) / $bits_div) * 8; |
$ret['bits'] = (($xlen - $bits_sub) / $bits_div) * 8; |
336 |
|
if (isset($fixes[$ret['bits']])) |
|
|
364 |
|
if (isset($fixes[$ret['bits']])) { |
|
365 |
|
rg_log('DEBUG: apply fix from ' . $ret['bits'] . ' to ' . $fixes[$ret['bits']]); |
337 |
366 |
$ret['bits'] = $fixes[$ret['bits']]; |
$ret['bits'] = $fixes[$ret['bits']]; |
|
367 |
|
} |
|
368 |
|
} else if ($i == $extra_info_pos) { |
|
369 |
|
$_x = unpack('a*', substr($d, $used, $xlen)); |
|
370 |
|
$ret['extra_info'] = 'application=' . $_x[1]; |
|
371 |
|
rg_log('DEBUG: extra_info set to [' . $ret['extra_info'] . ']'); |
338 |
372 |
} |
} |
339 |
373 |
|
|
340 |
|
$used += 4 + $xlen; |
|
|
374 |
|
$used += $xlen; |
341 |
375 |
} |
} |
342 |
|
if ($have_all_chunks === FALSE) |
|
|
376 |
|
if ($have_all_chunks === FALSE) { |
|
377 |
|
rg_log('DEBUG: not all chunk present, starting over'); |
343 |
378 |
continue; |
continue; |
|
379 |
|
} |
344 |
380 |
|
|
345 |
381 |
$ret['comment'] = trim(substr($t[1], $off)); |
$ret['comment'] = trim(substr($t[1], $off)); |
346 |
382 |
$ret['key'] = trim($ret['key']); |
$ret['key'] = trim($ret['key']); |
|
... |
... |
function rg_keys_max($db) |
469 |
505 |
* Adds a key |
* Adds a key |
470 |
506 |
* Returns the key_id of the key. |
* Returns the key_id of the key. |
471 |
507 |
*/ |
*/ |
472 |
|
function rg_keys_add($db, $ui, $key) |
|
|
508 |
|
function rg_keys_add($db, $ui, $key, $flags) |
473 |
509 |
{ |
{ |
474 |
510 |
rg_prof_start("keys_add"); |
rg_prof_start("keys_add"); |
475 |
|
rg_log_enter("keys_add: key=$key"); |
|
|
511 |
|
rg_log_enter('keys_add: flags=' . $flags . ' key=' . $key); |
476 |
512 |
|
|
477 |
513 |
$ret = FALSE; |
$ret = FALSE; |
478 |
514 |
$do_rollback = 0; |
$do_rollback = 0; |
|
... |
... |
function rg_keys_add($db, $ui, $key) |
516 |
552 |
. ' ' . $ki['comment'], |
. ' ' . $ki['comment'], |
517 |
553 |
'count' => 0, |
'count' => 0, |
518 |
554 |
'first_use' => 0, |
'first_use' => 0, |
519 |
|
'fingerprint_sha256' => $ki['fingerprint_sha256']); |
|
|
555 |
|
'fingerprint_sha256' => $ki['fingerprint_sha256'], |
|
556 |
|
'flags' => $flags); |
520 |
557 |
$sql = "INSERT INTO keys (itime, uid, key" |
$sql = "INSERT INTO keys (itime, uid, key" |
521 |
|
. ", fingerprint_sha256)" |
|
|
558 |
|
. ", fingerprint_sha256, flags)" |
522 |
559 |
. " VALUES (@@itime@@, @@uid@@, @@key@@" |
. " VALUES (@@itime@@, @@uid@@, @@key@@" |
523 |
|
. ", @@fingerprint_sha256@@)" |
|
|
560 |
|
. ", @@fingerprint_sha256@@, @@flags@@)" |
524 |
561 |
. " RETURNING key_id"; |
. " RETURNING key_id"; |
525 |
562 |
$res = rg_sql_query_params($db, $sql, $params); |
$res = rg_sql_query_params($db, $sql, $params); |
526 |
563 |
if ($res === FALSE) { |
if ($res === FALSE) { |
|
... |
... |
function rg_keys_update_use($db, $uid, $key_id, $ip, $cmd) |
656 |
693 |
return $ret; |
return $ret; |
657 |
694 |
} |
} |
658 |
695 |
|
|
|
696 |
|
/* |
|
697 |
|
* Returns flags for keys_output_line function |
|
698 |
|
*/ |
|
699 |
|
function rg_keys_global_flags($db) |
|
700 |
|
{ |
|
701 |
|
$ret = ''; |
|
702 |
|
|
|
703 |
|
$fido2_security = rg_state_get_uint($db, 'fido2_security'); |
|
704 |
|
if ($fido2_security == 2) // PIN required |
|
705 |
|
$ret .= 'V'; |
|
706 |
|
else if ($fido2_security == 0) // no-touch allowed |
|
707 |
|
$ret .= 't'; |
|
708 |
|
|
|
709 |
|
return $ret; |
|
710 |
|
} |
|
711 |
|
|
659 |
712 |
/* |
/* |
660 |
713 |
* Outputs a line for authorized_keys file |
* Outputs a line for authorized_keys file |
661 |
714 |
*/ |
*/ |
662 |
|
function rg_keys_output_line($i) |
|
|
715 |
|
function rg_keys_output_line($i, $flags) |
663 |
716 |
{ |
{ |
664 |
717 |
global $rg_scripts; |
global $rg_scripts; |
665 |
718 |
global $rg_ssh_paras; |
global $rg_ssh_paras; |
666 |
719 |
|
|
667 |
|
return 'command="' |
|
|
720 |
|
$ret = 'command="' |
668 |
721 |
. $rg_scripts . '/scripts/remote.sh' |
. $rg_scripts . '/scripts/remote.sh' |
669 |
722 |
. ' ' . $i['uid'] |
. ' ' . $i['uid'] |
670 |
723 |
. ' ' . $i['key_id'] |
. ' ' . $i['key_id'] |
671 |
724 |
. ' ' . $i['flags'] |
. ' ' . $i['flags'] |
672 |
725 |
. '"' |
. '"' |
673 |
|
. ',' . $rg_ssh_paras |
|
674 |
|
. ' ' . $i['key'] . "\n"; |
|
|
726 |
|
. ',' . $rg_ssh_paras; |
|
727 |
|
|
|
728 |
|
if (strstr($flags, 't')) |
|
729 |
|
$ret .= ',no-touch-required'; |
|
730 |
|
|
|
731 |
|
if (strstr($flags, 'V')) |
|
732 |
|
$ret .= ',verify-required'; |
|
733 |
|
|
|
734 |
|
$ret .= ' ' . $i['key'] . "\n"; |
|
735 |
|
|
|
736 |
|
return $ret; |
675 |
737 |
} |
} |
676 |
738 |
|
|
677 |
739 |
/* |
/* |
|
... |
... |
function rg_keys_regen($db) |
700 |
762 |
break; |
break; |
701 |
763 |
} |
} |
702 |
764 |
|
|
|
765 |
|
$global_flags = rg_keys_global_flags($db); |
|
766 |
|
|
703 |
767 |
// create .ssh folder if does not exists |
// create .ssh folder if does not exists |
704 |
768 |
$dir = dirname($rg_keys_file); |
$dir = dirname($rg_keys_file); |
705 |
769 |
if (!file_exists($dir)) { |
if (!file_exists($dir)) { |
|
... |
... |
function rg_keys_regen($db) |
728 |
792 |
|
|
729 |
793 |
$list = array(); |
$list = array(); |
730 |
794 |
|
|
731 |
|
$sql = "SELECT key_id, uid, key FROM keys ORDER BY count DESC"; |
|
|
795 |
|
$sql = 'SELECT key_id, uid, key, flags' |
|
796 |
|
. ' FROM keys ORDER BY count DESC'; |
732 |
797 |
$res = rg_sql_query($db, $sql); |
$res = rg_sql_query($db, $sql); |
733 |
798 |
if ($res === FALSE) { |
if ($res === FALSE) { |
734 |
799 |
rg_keys_set_error('cannot query keys table'); |
rg_keys_set_error('cannot query keys table'); |
735 |
800 |
break; |
break; |
736 |
801 |
} |
} |
737 |
802 |
while (($row = rg_sql_fetch_array($res))) { |
while (($row = rg_sql_fetch_array($res))) { |
738 |
|
$row['flags'] = 'N'; |
|
|
803 |
|
$row['flags'] .= 'N'; |
739 |
804 |
$list[] = $row; |
$list[] = $row; |
740 |
805 |
} |
} |
741 |
806 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
|
... |
... |
function rg_keys_regen($db) |
772 |
837 |
continue; |
continue; |
773 |
838 |
|
|
774 |
839 |
//rg_log("Writing key [" . $row['key'] . "] for uid " . $row['uid']); |
//rg_log("Writing key [" . $row['key'] . "] for uid " . $row['uid']); |
775 |
|
$buf = rg_keys_output_line($row); |
|
|
840 |
|
$buf = rg_keys_output_line($row, $global_flags); |
776 |
841 |
|
|
777 |
842 |
if (@fwrite($f, $buf) === FALSE) { |
if (@fwrite($f, $buf) === FALSE) { |
778 |
843 |
rg_keys_set_error("cannot write; disk space problems? (" . rg_php_err() . ")"); |
rg_keys_set_error("cannot write; disk space problems? (" . rg_php_err() . ")"); |
|
... |
... |
function rg_keys_search_by_fingerprint($db, $fp) |
886 |
951 |
$ret = array('ok' => 0, 'list' => array()); |
$ret = array('ok' => 0, 'list' => array()); |
887 |
952 |
while (1) { |
while (1) { |
888 |
953 |
$params = array('fp' => $fp); |
$params = array('fp' => $fp); |
889 |
|
$sql = 'SELECT key_id, uid, key FROM keys' |
|
|
954 |
|
$sql = 'SELECT key_id, uid, key, flags FROM keys' |
890 |
955 |
. ' WHERE fingerprint_sha256 = @@fp@@'; |
. ' WHERE fingerprint_sha256 = @@fp@@'; |
891 |
956 |
$res = rg_sql_query_params($db, $sql, $params); |
$res = rg_sql_query_params($db, $sql, $params); |
892 |
957 |
if ($res === FALSE) { |
if ($res === FALSE) { |
|
... |
... |
function rg_keys_search_by_fingerprint($db, $fp) |
894 |
959 |
break; |
break; |
895 |
960 |
} |
} |
896 |
961 |
while (($row = rg_sql_fetch_array($res))) { |
while (($row = rg_sql_fetch_array($res))) { |
897 |
|
$row['flags'] = 'N'; |
|
|
962 |
|
$row['flags'] .= 'N'; |
898 |
963 |
$ret['list'][] = $row; |
$ret['list'][] = $row; |
899 |
964 |
} |
} |
900 |
965 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
|
... |
... |
function rg_keys_search_by_fingerprint($db, $fp) |
925 |
990 |
return $ret; |
return $ret; |
926 |
991 |
} |
} |
927 |
992 |
|
|
928 |
|
?> |
|
File inc/struct.inc.php changed (mode: 100644) (index 2f76ae9..b6dcc89) |
... |
... |
$rg_sql_struct[46]['other'] = array( |
689 |
689 |
); |
); |
690 |
690 |
// Here, 0.73 was released. |
// Here, 0.73 was released. |
691 |
691 |
|
|
692 |
|
// Do not forget to add the new created tables to statistics |
|
693 |
|
// This must be the last line |
|
|
692 |
|
$rg_sql_struct[47] = array(); |
|
693 |
|
$rg_sql_struct[47]['tables'] = array( |
|
694 |
|
'pkg_repos' => 'CREATE TABLE pkg_repos (' |
|
695 |
|
. 'id SERIAL PRIMARY KEY' |
|
696 |
|
. ', uid INT NOT NULL' |
|
697 |
|
. ', itime INT NOT NULL' |
|
698 |
|
. ', name TEXT NOT NULL' |
|
699 |
|
. ', flags TEXT NOT NULL' |
|
700 |
|
. ', rgfs_key TEXT NOT NULL' |
|
701 |
|
. ', gpg_priv_key TEXT NOT NULL' |
|
702 |
|
. ', gpg_pub_key TEXT NOT NULL' |
|
703 |
|
. ', version INT DEFAULT 1)', |
|
704 |
|
'pkg_subrepos' => 'CREATE TABLE pkg_subrepos (' |
|
705 |
|
. 'id SERIAL PRIMARY KEY' |
|
706 |
|
. ', pkg_repo_id INT NOT NULL' |
|
707 |
|
. ', itime INT NOT NULL' |
|
708 |
|
. ', name TEXT NOT NULL' |
|
709 |
|
. ', version INT DEFAULT 1)', |
|
710 |
|
'pkg_maps' => 'CREATE TABLE pkg_maps (' |
|
711 |
|
. 'id SERIAL PRIMARY KEY' |
|
712 |
|
. ', uid INT NOT NULL' |
|
713 |
|
. ', itime INT NOT NULL' |
|
714 |
|
. ', flags TEXT NOT NULL' |
|
715 |
|
. ', prio SMALLINT NOT NULL' |
|
716 |
|
. ', repo TEXT NOT NULL' |
|
717 |
|
. ', ref TEXT NOT NULL' |
|
718 |
|
. ', pkg_subrepo_id INT NOT NULL)' |
|
719 |
|
); |
|
720 |
|
$rg_sql_struct[47]['other'] = array( |
|
721 |
|
'pkg_repos index uid' => |
|
722 |
|
'CREATE INDEX pkg_repos_i_uid on pkg_repos(uid)', |
|
723 |
|
'pkg_subrepos index pkg_repo_id' => |
|
724 |
|
'CREATE INDEX pkg_subrepos_i_pkg_repo_id on pkg_subrepos(pkg_repo_id)', |
|
725 |
|
'pkg_maps index uid' => |
|
726 |
|
'CREATE INDEX pkg_maps_i_uid on pkg_maps(uid)', |
|
727 |
|
'login_uid for conns' => |
|
728 |
|
'ALTER TABLE conns ADD login_uid INT NOT NULL DEFAULT 0', |
|
729 |
|
'disk_used_pkg_repos' => |
|
730 |
|
'ALTER TABLE pkg_repos ADD disk_used_mb INT NOT NULL DEFAULT 0', |
|
731 |
|
'disk_used_pkg_subrepos' => |
|
732 |
|
'ALTER TABLE pkg_subrepos ADD disk_used_mb INT NOT NULL DEFAULT 0', |
|
733 |
|
'pkg_subrepos_distro_info' => |
|
734 |
|
'ALTER TABLE pkg_subrepos ADD distro_info TEXT NOT NULL DEFAULT \'\'', |
|
735 |
|
'pkg_repo password' => |
|
736 |
|
'ALTER TABLE pkg_repos ADD password TEXT NOT NULL DEFAULT \'\'', |
|
737 |
|
'conns bytes' => |
|
738 |
|
'ALTER TABLE conns ADD bytes BIGINT NOT NULL DEFAULT -1', |
|
739 |
|
'keys flags' => |
|
740 |
|
'ALTER TABLE keys ADD flags TEXT NOT NULL DEFAULT \'\'' |
|
741 |
|
); |
|
742 |
|
|
|
743 |
|
// Do not forget to add the new created tables to statistics. |
|
744 |
|
// The next line must be after all rg_sql_struct* definitions. |
694 |
745 |
$rg_sql_schema_ver = count($rg_sql_struct); |
$rg_sql_schema_ver = count($rg_sql_struct); |
695 |
746 |
|
|
696 |
747 |
|
|
File tests/keys.php changed (mode: 100644) (index c68aa72..4669499) |
... |
... |
rg_sql_free_result($res); |
30 |
30 |
// insert a key 1 |
// insert a key 1 |
31 |
31 |
$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"; |
$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"; |
32 |
32 |
rg_state_set($db, 'ssh_key_allow_dsa', 1); |
rg_state_set($db, 'ssh_key_allow_dsa', 1); |
33 |
|
$key_id1 = rg_keys_add($db, $rg_ui, $key1); |
|
|
33 |
|
$key_id1 = rg_keys_add($db, $rg_ui, $key1, ''); |
34 |
34 |
if ($key_id1 === FALSE) { |
if ($key_id1 === FALSE) { |
35 |
35 |
rg_log("Cannot add key 1 (" . rg_keys_error() . ")!"); |
rg_log("Cannot add key 1 (" . rg_keys_error() . ")!"); |
36 |
36 |
exit(1); |
exit(1); |
|
... |
... |
if (strstr($ki['comment'], "\n")) { |
50 |
50 |
$rg_ui['uid'] = 2; |
$rg_ui['uid'] = 2; |
51 |
51 |
$key2 = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+2OHaQiZzdwV4HQF9pCBbSQFaoM5Q0YmmRYDL8BUCjwClDgOLp9lQVN5XksoBx2t9INj6XrobjNc/GUF60c1Ald0FtjRl7nIZdYvKDutlxHcGUy6MHsVnCDviXQJD9Hm9fyuBLdy3/oadSCAaQYE/Tcf9rWt1NmhQ7560bCGmh4pw8N+XXAz2nQBCqvIK8VDoBbOOgFa/HOwBrKCgaGmcTGs5wRWHbw3+h6CO1vqEYcSCSqBPMG1JOMfMTuJ0aTXXEkSNPF+TVva85L4qrQslyHbn2JU1t7/HQsFnGtgF1o2AglIR2RbyMmr6axI51Srf20EB9/c9T3auYQipbw85 second_key"; |
$key2 = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+2OHaQiZzdwV4HQF9pCBbSQFaoM5Q0YmmRYDL8BUCjwClDgOLp9lQVN5XksoBx2t9INj6XrobjNc/GUF60c1Ald0FtjRl7nIZdYvKDutlxHcGUy6MHsVnCDviXQJD9Hm9fyuBLdy3/oadSCAaQYE/Tcf9rWt1NmhQ7560bCGmh4pw8N+XXAz2nQBCqvIK8VDoBbOOgFa/HOwBrKCgaGmcTGs5wRWHbw3+h6CO1vqEYcSCSqBPMG1JOMfMTuJ0aTXXEkSNPF+TVva85L4qrQslyHbn2JU1t7/HQsFnGtgF1o2AglIR2RbyMmr6axI51Srf20EB9/c9T3auYQipbw85 second_key"; |
52 |
52 |
rg_state_set($db, 'ssh_key_min_bits_rsa', 1024); |
rg_state_set($db, 'ssh_key_min_bits_rsa', 1024); |
53 |
|
$key_id2 = rg_keys_add($db, $rg_ui, $key2); |
|
|
53 |
|
$key_id2 = rg_keys_add($db, $rg_ui, $key2, ''); |
54 |
54 |
if ($key_id2 === FALSE) { |
if ($key_id2 === FALSE) { |
55 |
55 |
rg_log("Cannot add key 2 (" . rg_keys_error() . ")!"); |
rg_log("Cannot add key 2 (" . rg_keys_error() . ")!"); |
56 |
56 |
exit(1); |
exit(1); |
|
... |
... |
if (strcmp($c, $e) != 0) { |
90 |
90 |
// test max_ssh_keys - must fail because overlimit |
// test max_ssh_keys - must fail because overlimit |
91 |
91 |
rg_state_set($db, 'max_ssh_keys', 1); |
rg_state_set($db, 'max_ssh_keys', 1); |
92 |
92 |
$key3 = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUiVHDS3rhn79+9YbXXN+npU9tDTzXZHkXZF9BNqI0GrnASuaBU2oJ/UK2OCgGQ45JOlzUCXcP09hHcyPqd4pZdHQhMAImCnm0iRivQ9VhJRRbl/s8kokoStZGAdcW+ETlhUtRXSQOu8U1PXqwUwZCkeE9asmS4Wg9/OO3eDuTMvE3yiNpHKt6TcVYlU6PlsiTFVJrAuIEbXRs5b5luuM+nM17caos0mn6w+kZ3QD9AnX+9pN4VgXKxEHGfWpOCtRDOQb9mTk2bX6MBJrcKtkAPnyYDiaRs1ANG7L4AP6to/gy3A9w6flTAD94gFAm833earIZJnCiavx3/dUWWt3L third_key'; |
$key3 = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUiVHDS3rhn79+9YbXXN+npU9tDTzXZHkXZF9BNqI0GrnASuaBU2oJ/UK2OCgGQ45JOlzUCXcP09hHcyPqd4pZdHQhMAImCnm0iRivQ9VhJRRbl/s8kokoStZGAdcW+ETlhUtRXSQOu8U1PXqwUwZCkeE9asmS4Wg9/OO3eDuTMvE3yiNpHKt6TcVYlU6PlsiTFVJrAuIEbXRs5b5luuM+nM17caos0mn6w+kZ3QD9AnX+9pN4VgXKxEHGfWpOCtRDOQb9mTk2bX6MBJrcKtkAPnyYDiaRs1ANG7L4AP6to/gy3A9w6flTAD94gFAm833earIZJnCiavx3/dUWWt3L third_key'; |
93 |
|
$key_id3 = rg_keys_add($db, $rg_ui, $key3); |
|
|
93 |
|
$key_id3 = rg_keys_add($db, $rg_ui, $key3, ''); |
94 |
94 |
if ($key_id3 !== FALSE) { |
if ($key_id3 !== FALSE) { |
95 |
95 |
rg_log("Seems we can add more keys than allowed! Not good!"); |
rg_log("Seems we can add more keys than allowed! Not good!"); |
96 |
96 |
exit(1); |
exit(1); |
|
... |
... |
rg_log(''); |
101 |
101 |
rg_log_enter('Uploading a RSA key that is forbidden'); |
rg_log_enter('Uploading a RSA key that is forbidden'); |
102 |
102 |
rg_state_set($db, 'ssh_key_min_bits_rsa', 4096); |
rg_state_set($db, 'ssh_key_min_bits_rsa', 4096); |
103 |
103 |
$_key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDHotZMHPSwhVDwV5xOroZ21kzgFuBaXk3xXIT9hHM9WKD3jw0/C6TotbOoghTfJxdQtOG1t0t7eUUCJXR/3BLqamxIyAXTH2qIxf9ySIVLylKXriHQZoOa0GVhnF0ZYxR7Ot5GkIuXsjtSLrvw9p2BPf41EoR1ZZ74QYQdKfDiGw== root@host'; |
$_key = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDHotZMHPSwhVDwV5xOroZ21kzgFuBaXk3xXIT9hHM9WKD3jw0/C6TotbOoghTfJxdQtOG1t0t7eUUCJXR/3BLqamxIyAXTH2qIxf9ySIVLylKXriHQZoOa0GVhnF0ZYxR7Ot5GkIuXsjtSLrvw9p2BPf41EoR1ZZ74QYQdKfDiGw== root@host'; |
104 |
|
$r = rg_keys_add($db, $rg_ui, $_key); |
|
|
104 |
|
$r = rg_keys_add($db, $rg_ui, $_key, ''); |
105 |
105 |
if ($r !== FALSE) { |
if ($r !== FALSE) { |
106 |
106 |
rg_log('Seems we can add forbidden keys (rsa-1024)!'); |
rg_log('Seems we can add forbidden keys (rsa-1024)!'); |
107 |
107 |
exit(1); |
exit(1); |