File TODO changed (mode: 100644) (index 1d7461a..f9df6b6) |
1 |
1 |
== Where I stopped last time == |
== Where I stopped last time == |
2 |
|
[ ] retest login by token |
|
|
2 |
|
[ ] totp: login by token in http_totp.php seems to not work. |
|
3 |
|
check server logs. |
|
4 |
|
[ ] unit test: do not check for "invalid user ..." - it may change |
|
5 |
|
test that we landed on the home page! |
|
6 |
|
[ ] totp: should we update at once, and verify that the token is really unused? |
|
7 |
|
(do not delay till event processing?) |
|
8 |
|
[ ] totp: store last ts used, and do not allow reuse. |
|
9 |
|
The problem is if both session sends the same token (the attacker and |
|
10 |
|
the good user). |
|
11 |
|
[ ] totp: update last_use also by ssh! |
|
12 |
|
[ ] unit tests fails. |
3 |
13 |
[ ] |
[ ] |
4 |
14 |
|
|
5 |
15 |
== BEFORE NEXT RELEASE == |
== BEFORE NEXT RELEASE == |
|
16 |
|
[ ] Extend rg_cache_count for the other rg_cache_* commands. |
|
17 |
|
[ ] Restart the cache daemon when an upgrade takes place. |
|
18 |
|
Done, test. |
|
19 |
|
[ ] Report number of lines of code (and how much it worth) and number of other |
|
20 |
|
type of documents. |
|
21 |
|
[ ] Add some flags for users: "Coming from GitHub", to be able to give |
|
22 |
|
tailored hints. |
|
23 |
|
[ ] totp: take care of the race: simultaneously login with the same token. |
|
24 |
|
[ ] totp: warn user that if a token is not validated for 1 month will be deleted? |
|
25 |
|
[ ] totp: allow prefix for IP addresses. |
|
26 |
|
[ ] totp: think about authorizing a push, not the ip (ip may be dynamic). |
|
27 |
|
Somethig like, allow the push as pending, but ask for authorization |
|
28 |
|
to be sent back: |
|
29 |
|
ssh ... totp val-push <push_id> <token> |
|
30 |
|
and remove the push from pending. |
|
31 |
|
[ ] "repo was changed": nothing interesting?! |
|
32 |
|
If nothing changed, do not send the mail. |
|
33 |
|
[ ] The URL to the repo presnet in mail is rocketgit.com. We may want to use |
|
34 |
|
the http host name in there. |
|
35 |
|
[ ] bugs: if none present, just go to 'Add' page. |
|
36 |
|
[ ] Seems 'push' is denied for owner! |
|
37 |
|
Seems I have the key on both 'admin' user and 'catab'! |
|
38 |
|
Do something about this? |
|
39 |
|
[ ] features: 'Lightest': Add a note describing that is lightest also with |
|
40 |
|
the browser. |
|
41 |
|
[ ] Document how to deny non ascii filenames using repo_path. |
|
42 |
|
[ ] When a right denies access, also output the description of that right. |
|
43 |
|
[ ] Tell clear that rg can be used also for books, articles, documentation etc. |
|
44 |
|
[ ] Include uid in namespace path to avoid clashes with other users? |
|
45 |
|
[ ] ssh: show the fingerprint of the used key? |
|
46 |
|
[ ] Detect when a user is cloning a repo and update stats? Seems I cannot do |
|
47 |
|
this easily becasue I just call git-shell. |
|
48 |
|
But, at least the fetch can be recorded in stats. |
|
49 |
|
[ ] Add cache in rg_git_log. |
|
50 |
|
[ ] unit test for login by token |
|
51 |
|
[ ] Unit test for fetching by ssh a public repo regarding TOTP |
6 |
52 |
[ ] Do I need to update last time used for login_tokens when accessing by ssh? |
[ ] Do I need to update last time used for login_tokens when accessing by ssh? |
7 |
53 |
Pretty sure, yes. |
Pretty sure, yes. |
8 |
54 |
[ ] history: add 2fa ssh validation. |
[ ] history: add 2fa ssh validation. |
9 |
55 |
[ ] ionut: Check this to not be send X-PHP-Originating-Script: 0:user.inc.php |
[ ] ionut: Check this to not be send X-PHP-Originating-Script: 0:user.inc.php |
10 |
|
[ ] Test if IPv4/IPv6 address is shown at login time. |
|
|
56 |
|
[ ] VM: Test if IPv4/IPv6 address is shown at login time. |
11 |
57 |
[ ] When listing repos on user homepage, we should not add also the user. |
[ ] When listing repos on user homepage, we should not add also the user. |
12 |
58 |
Check rg_repo_list. |
Check rg_repo_list. |
13 |
59 |
[ ] totp for ssh is not finished yet. remember, totp for ssh seems to be only |
[ ] totp for ssh is not finished yet. remember, totp for ssh seems to be only |
|
22 |
68 |
[ ] Add history for totp enrollment. |
[ ] Add history for totp enrollment. |
23 |
69 |
[ ] Add history for logins/logouts/API. |
[ ] Add history for logins/logouts/API. |
24 |
70 |
[ ] Add max_requests per hour for plans and enforce them. |
[ ] Add max_requests per hour for plans and enforce them. |
25 |
|
[ ] When setting last used, we need to pass the timestamp to the event and |
|
26 |
|
we msut not use 'time()' because event may happen at a latter time! |
|
27 |
71 |
[ ] Protect login by country/ua? |
[ ] Protect login by country/ua? |
28 |
72 |
[ ] Improve input forms to be friendly with mobile phones: give html5 hints. |
[ ] Improve input forms to be friendly with mobile phones: give html5 hints. |
29 |
73 |
[ ] Use guestmount when building VM images? |
[ ] Use guestmount when building VM images? |
|
40 |
84 |
[ ] totp: update 'utime' for login tokens |
[ ] totp: update 'utime' for login tokens |
41 |
85 |
[ ] totp: mark last timestamp used for ok login to not be able to reuse the |
[ ] totp: mark last timestamp used for ok login to not be able to reuse the |
42 |
86 |
token; what if the time is in the future? we will not cache it. |
token; what if the time is in the future? we will not cache it. |
43 |
|
[ ] totp: login: prevent auto filling/caching of login token |
|
44 |
|
switch to 'password' type? |
|
|
87 |
|
Better, do not allow the same ts. |
|
88 |
|
[ ] totp: switch to 'password' type for login_token (login page)? |
45 |
89 |
[ ] totp: hints: |
[ ] totp: hints: |
46 |
|
only for admin: install qrencode package... |
|
47 |
90 |
AWS asks for two consecutive codes. why? |
AWS asks for two consecutive codes. why? |
48 |
91 |
Google also provides a list of backup tokens to be printed. |
Google also provides a list of backup tokens to be printed. |
49 |
92 |
"If you want to activate the TOTP extra step, follow the instructions: |
"If you want to activate the TOTP extra step, follow the instructions: |
|
52 |
95 |
Instruct user to remove the token if the phone is lost. But, remind |
Instruct user to remove the token if the phone is lost. But, remind |
53 |
96 |
user that the account may not be compromised without pass. |
user that the account may not be compromised without pass. |
54 |
97 |
[ ] totp: think about loosing the phone. |
[ ] totp: think about loosing the phone. |
55 |
|
[ ] totp: how to set it up: |
|
56 |
|
press a menu to activate it, show QR code if possible, show base32 key |
|
57 |
|
also, ask user to enter the token to finish the activation. |
|
58 |
|
warn about time desync; maybe ask the user to press the 'sync' in |
|
|
98 |
|
[ ] totp: warn about time desync; maybe ask the user to press the 'sync' in |
59 |
99 |
the mobile app. |
the mobile app. |
60 |
|
[ ] totp: we may validate the login on one ip and keep ip for x hours. |
|
61 |
100 |
[ ] totp: what if I encrypt key with the password and decrypt only at login? |
[ ] totp: what if I encrypt key with the password and decrypt only at login? |
62 |
101 |
(If somebody steals the database, will not have the keys). |
(If somebody steals the database, will not have the keys). |
|
102 |
|
Cannot do. We need it also at push by ssh. |
63 |
103 |
[ ] totp: hints for ssh |
[ ] totp: hints for ssh |
64 |
104 |
[ ] totp: Implement 2 factor auth |
[ ] totp: Implement 2 factor auth |
65 |
105 |
(check https://korg.wiki.kernel.org/userdoc/gitolite_2fa) |
(check https://korg.wiki.kernel.org/userdoc/gitolite_2fa) |
|
70 |
110 |
Change ids to be protected from interference. |
Change ids to be protected from interference. |
71 |
111 |
[ ] Use bintray.com to distribute isos? |
[ ] Use bintray.com to distribute isos? |
72 |
112 |
[ ] When session expires and I press logout, no message is shown. |
[ ] When session expires and I press logout, no message is shown. |
73 |
|
[ ] When creating an account, seems the email is cached, not the username! |
|
|
113 |
|
[ ] When creating an account, seems the email is used as the username in |
|
114 |
|
browser cache, not the username! |
74 |
115 |
Check! |
Check! |
75 |
|
[ ] Users should be able to check the plans. |
|
76 |
116 |
[ ] After login, show the last ip and date of the last login? |
[ ] After login, show the last ip and date of the last login? |
|
117 |
|
[ ] Users should be able to check the plans. |
77 |
118 |
[ ] I should show some 'plan' islands when you create the account |
[ ] I should show some 'plan' islands when you create the account |
78 |
119 |
so the user will know the disk space and bandwidth. |
so the user will know the disk space and bandwidth. |
79 |
120 |
[ ] In a table, if nothing can be deleted, do not show the delete button. |
[ ] In a table, if nothing can be deleted, do not show the delete button. |
80 |
|
[ ] Add IP address in /etc/issue (or /etc/motd), somehow to appear, maybe using |
|
81 |
|
a systemd script that runs before terminal? |
|
82 |
|
[ ] web hooks: start with a http post to a custom server. |
|
|
121 |
|
[ ] web hooks: start with a http post to a user server. |
|
122 |
|
warn the user if is not working? |
83 |
123 |
[ ] When giving some users rights to your repo, do not spam them with |
[ ] When giving some users rights to your repo, do not spam them with |
84 |
124 |
messages. The user must agree to be spammed. Best, no notification |
messages. The user must agree to be spammed. Best, no notification |
85 |
125 |
is ever issued. User may go to project to activate them if s/he wants. |
is ever issued. User may go to project to activate them if s/he wants. |
File inc/cache.inc.php changed (mode: 100644) (index 2e5a2c5..f54ff89) |
... |
... |
if (!isset($rg_cache_enable)) |
13 |
13 |
// timeout in miliseconds |
// timeout in miliseconds |
14 |
14 |
$rg_cache_timeout = 100; |
$rg_cache_timeout = 100; |
15 |
15 |
|
|
|
16 |
|
$rg_cache_count = 0; |
|
17 |
|
$rg_cache_tries = 3; |
|
18 |
|
|
16 |
19 |
if (!isset($rg_cache_socket)) |
if (!isset($rg_cache_socket)) |
17 |
20 |
$rg_cache_socket = "/var/lib/rocketgit/sockets/cache.sock"; |
$rg_cache_socket = "/var/lib/rocketgit/sockets/cache.sock"; |
18 |
21 |
|
|
|
... |
... |
$rg_cache = array(); |
21 |
24 |
$rg_cache_error = ""; |
$rg_cache_error = ""; |
22 |
25 |
|
|
23 |
26 |
if (!isset($rg_cache_debug)) |
if (!isset($rg_cache_debug)) |
24 |
|
$rg_cache_debug = TRUE; |
|
|
27 |
|
$rg_cache_debug = FALSE; |
25 |
28 |
|
|
26 |
29 |
function rg_cache_set_error($str) |
function rg_cache_set_error($str) |
27 |
30 |
{ |
{ |
|
... |
... |
function rg_cache_core_adump($ns_var) |
281 |
284 |
/********************************* Client side functions */ |
/********************************* Client side functions */ |
282 |
285 |
|
|
283 |
286 |
/* |
/* |
284 |
|
* Returns a variable from the cache daemon |
|
285 |
|
* @timeout_in_ms is the connection timeout not variable timeout. |
|
|
287 |
|
* Prepares a string to be send to the wire |
286 |
288 |
*/ |
*/ |
287 |
|
function rg_cache_get($ns_var) |
|
|
289 |
|
function rg_cache_prepare($s) |
|
290 |
|
{ |
|
291 |
|
$x = serialize($s); |
|
292 |
|
return addcslashes($x, "\n\r\\"); |
|
293 |
|
} |
|
294 |
|
|
|
295 |
|
/* |
|
296 |
|
* Helps to send and to decode a command |
|
297 |
|
*/ |
|
298 |
|
function rg_cache_send($cmd, $para, $flags) |
288 |
299 |
{ |
{ |
|
300 |
|
global $rg_cache_enable; |
289 |
301 |
global $rg_cache_socket; |
global $rg_cache_socket; |
290 |
302 |
global $rg_cache_timeout; |
global $rg_cache_timeout; |
291 |
|
global $rg_cache_enable; |
|
|
303 |
|
global $rg_cache_tries; |
|
304 |
|
global $rg_cache_count; |
292 |
305 |
global $rg_cache_debug; |
global $rg_cache_debug; |
293 |
306 |
|
|
294 |
|
rg_prof_start("cache_get"); |
|
|
307 |
|
if ($rg_cache_enable === FALSE) |
|
308 |
|
return FALSE; |
|
309 |
|
|
|
310 |
|
$rg_cache_count++; |
|
311 |
|
|
|
312 |
|
$f = ''; |
|
313 |
|
if ($flags & RG_SOCKET_NO_WAIT) |
|
314 |
|
$f .= 'W'; |
|
315 |
|
|
|
316 |
|
$xcmd = $cmd . ' F=' . $f . ' I=' . $rg_cache_count . ' ' . $para; |
|
317 |
|
if ($rg_cache_debug) |
|
318 |
|
rg_log('Sending [' . $xcmd . ']...'); |
|
319 |
|
$ret = rg_socket($rg_cache_socket, $xcmd . "\n", |
|
320 |
|
$rg_cache_timeout, $rg_cache_tries, $flags); |
295 |
321 |
if ($rg_cache_debug) |
if ($rg_cache_debug) |
296 |
|
rg_log_enter("cache_get: $ns_var"); |
|
|
322 |
|
rg_log('Received [' . $ret . ']'); |
|
323 |
|
if ($ret === FALSE) |
|
324 |
|
return FALSE; |
297 |
325 |
|
|
298 |
|
$ret = FALSE; |
|
299 |
|
while (1) { |
|
300 |
|
$ret = rg_cache_core_get($ns_var); |
|
301 |
|
if ($ret !== FALSE) { |
|
302 |
|
if ($rg_cache_debug) |
|
303 |
|
rg_log('Found in core. Good!'); |
|
304 |
|
break; |
|
|
326 |
|
if ($flags & RG_SOCKET_NO_WAIT) |
|
327 |
|
return TRUE; |
|
328 |
|
|
|
329 |
|
$a = explode("\n", $ret); |
|
330 |
|
foreach ($a as $line) { |
|
331 |
|
if ($rg_cache_debug) |
|
332 |
|
rg_log('Parsing line [' . $line . ']'); |
|
333 |
|
|
|
334 |
|
$t = explode(' ', $line, 3); |
|
335 |
|
if (!isset($t[1])) |
|
336 |
|
return FALSE; |
|
337 |
|
|
|
338 |
|
$id = intval($t[1]); |
|
339 |
|
if ($id < $rg_cache_count) { |
|
340 |
|
rg_log('DEBUG: id: ' . $id . ' < ' . $rg_cache_count); |
|
341 |
|
continue; |
305 |
342 |
} |
} |
|
343 |
|
rg_log('DEBUG: id: ' . $id . ' == ' . $rg_cache_count); |
306 |
344 |
|
|
307 |
|
if ($rg_cache_enable === FALSE) |
|
308 |
|
break; |
|
|
345 |
|
if (strcmp($t[0], 'OK') != 0) { |
|
346 |
|
rg_log('DEBUG: not an OK answer: ' . $t[0]); |
|
347 |
|
return FALSE; |
|
348 |
|
} |
309 |
349 |
|
|
310 |
|
$c = rg_socket($rg_cache_socket, |
|
311 |
|
"GET F= " . $ns_var . "\n", $rg_cache_timeout, 1, 0); |
|
312 |
|
if ($c === FALSE) |
|
313 |
|
break; |
|
|
350 |
|
if (!isset($t[2])) |
|
351 |
|
return TRUE; |
|
352 |
|
|
|
353 |
|
return trim(stripcslashes($t[2])); |
|
354 |
|
break; |
|
355 |
|
} |
|
356 |
|
} |
314 |
357 |
|
|
315 |
|
$t = explode(" ", $c, 2); |
|
316 |
|
if (strcmp($t[0], "OK") != 0) |
|
|
358 |
|
/* |
|
359 |
|
* Returns a variable from the cache daemon |
|
360 |
|
* @timeout_in_ms is the connection timeout not variable timeout. |
|
361 |
|
*/ |
|
362 |
|
function rg_cache_get($ns_var) |
|
363 |
|
{ |
|
364 |
|
rg_prof_start('cache_get'); |
|
365 |
|
|
|
366 |
|
$ret = FALSE; |
|
367 |
|
while (1) { |
|
368 |
|
$ret = rg_cache_core_get($ns_var); |
|
369 |
|
if ($ret !== FALSE) |
317 |
370 |
break; |
break; |
318 |
371 |
|
|
319 |
|
if (!isset($t[1])) |
|
|
372 |
|
$flags = 0; |
|
373 |
|
$r = rg_cache_send('GET', $ns_var, $flags); |
|
374 |
|
if ($r === FALSE) |
320 |
375 |
break; |
break; |
321 |
376 |
|
|
322 |
|
$x = trim(stripcslashes($t[1])); |
|
323 |
|
$ret = @unserialize($x); |
|
|
377 |
|
$ret = @unserialize($r); |
324 |
378 |
if ($ret === FALSE) { |
if ($ret === FALSE) { |
325 |
|
rg_internal_error("Cannot userialize [$x]!"); |
|
|
379 |
|
rg_internal_error("Cannot userialize [$r]!"); |
326 |
380 |
break; |
break; |
327 |
381 |
} |
} |
328 |
382 |
|
|
329 |
383 |
rg_cache_core_set($ns_var, $ret); |
rg_cache_core_set($ns_var, $ret); |
330 |
|
|
|
331 |
384 |
break; |
break; |
332 |
385 |
} |
} |
333 |
386 |
|
|
334 |
|
if ($rg_cache_debug) { |
|
335 |
|
rg_log("ret=" . rg_array2string($ret)); |
|
336 |
|
rg_log_exit(); |
|
337 |
|
} |
|
338 |
|
rg_prof_end("cache_get"); |
|
|
387 |
|
rg_prof_end('cache_get'); |
339 |
388 |
return $ret; |
return $ret; |
340 |
389 |
} |
} |
341 |
390 |
|
|
342 |
|
/* |
|
343 |
|
* Prepares a string to be send to the wire |
|
344 |
|
*/ |
|
345 |
|
function rg_cache_prepare($s) |
|
346 |
|
{ |
|
347 |
|
$x = serialize($s); |
|
348 |
|
return addcslashes($x, "\n\r\\"); |
|
349 |
|
} |
|
350 |
|
|
|
351 |
391 |
/* |
/* |
352 |
392 |
* Sets a variable in the cache daemon |
* Sets a variable in the cache daemon |
353 |
393 |
*/ |
*/ |
354 |
394 |
function rg_cache_set($ns_var, $value, $flags) |
function rg_cache_set($ns_var, $value, $flags) |
355 |
395 |
{ |
{ |
356 |
|
global $rg_cache_socket; |
|
357 |
|
global $rg_cache_timeout; |
|
358 |
|
global $rg_cache_enable; |
|
359 |
|
global $rg_cache_debug; |
|
|
396 |
|
rg_prof_start('cache_set'); |
360 |
397 |
|
|
361 |
|
rg_prof_start("cache_set"); |
|
362 |
|
if ($rg_cache_debug) |
|
363 |
|
rg_log_ml_enter("cache_set: flags=$flags" |
|
364 |
|
. " $ns_var = " . print_r($value, TRUE)); |
|
365 |
|
|
|
366 |
|
$ret = FALSE; |
|
367 |
398 |
while (1) { |
while (1) { |
368 |
399 |
rg_cache_core_set($ns_var, $value); |
rg_cache_core_set($ns_var, $value); |
369 |
400 |
|
|
370 |
|
if ($rg_cache_enable === FALSE) |
|
371 |
|
break; |
|
372 |
|
|
|
373 |
|
$f = ''; |
|
374 |
|
if ($flags & RG_SOCKET_NO_WAIT) |
|
375 |
|
$f .= 'W'; |
|
376 |
|
|
|
377 |
|
$c = rg_socket($rg_cache_socket, "SET F=$f " . $ns_var . "=" |
|
378 |
|
. rg_cache_prepare($value) . "\n", $rg_cache_timeout, 3, $flags); |
|
379 |
|
if ($c === FALSE) |
|
380 |
|
break; |
|
381 |
|
|
|
382 |
|
if ($flags & RG_SOCKET_NO_WAIT) { |
|
383 |
|
$ret = TRUE; |
|
384 |
|
break; |
|
385 |
|
} |
|
386 |
|
|
|
387 |
|
if (strncmp($c, "OK", 2) != 0) |
|
|
401 |
|
$para = $ns_var . '=' . rg_cache_prepare($value); |
|
402 |
|
$ret = rg_cache_send('SET', $para, $flags); |
|
403 |
|
if ($ret === FALSE) |
388 |
404 |
break; |
break; |
389 |
405 |
|
|
390 |
406 |
$ret = TRUE; |
$ret = TRUE; |
391 |
407 |
break; |
break; |
392 |
408 |
} |
} |
393 |
409 |
|
|
394 |
|
if ($rg_cache_debug) |
|
395 |
|
rg_log_exit(); |
|
396 |
|
rg_prof_end("cache_set"); |
|
|
410 |
|
rg_prof_end('cache_set'); |
397 |
411 |
return $ret; |
return $ret; |
398 |
412 |
} |
} |
399 |
413 |
|
|
|
... |
... |
function rg_cache_set($ns_var, $value, $flags) |
402 |
416 |
*/ |
*/ |
403 |
417 |
function rg_cache_inc($ns_var) |
function rg_cache_inc($ns_var) |
404 |
418 |
{ |
{ |
405 |
|
global $rg_cache_socket; |
|
406 |
|
global $rg_cache_timeout; |
|
407 |
|
global $rg_cache_enable; |
|
408 |
|
global $rg_cache_debug; |
|
|
419 |
|
rg_prof_start('cache_inc'); |
409 |
420 |
|
|
410 |
|
rg_prof_start("cache_inc"); |
|
411 |
|
if ($rg_cache_debug) |
|
412 |
|
rg_log_enter("cache_inc($ns_var)"); |
|
|
421 |
|
rg_cache_core_inc($vs_var); |
413 |
422 |
|
|
414 |
|
$ret = FALSE; |
|
415 |
423 |
while (1) { |
while (1) { |
416 |
|
rg_cache_core_inc($vs_var); |
|
417 |
|
|
|
418 |
|
if ($rg_cache_enable === FALSE) |
|
419 |
|
break; |
|
420 |
|
|
|
421 |
|
$c = rg_socket($rg_cache_socket, |
|
422 |
|
"INC F= " . $ns_var . "\n", $rg_cache_timeout, 1, 0); |
|
423 |
|
if ($c === FALSE) |
|
424 |
|
break; |
|
425 |
|
|
|
426 |
|
if (strncmp($c, "OK", 2) != 0) |
|
|
424 |
|
$ret = rg_cache_send('INC', $ns_var, $flags); |
|
425 |
|
if ($ret === FALSE) |
427 |
426 |
break; |
break; |
428 |
|
|
|
429 |
|
$v = strstr($c, " v="); |
|
430 |
|
if ($v === FALSE) |
|
|
427 |
|
if ($ret === TRUE) |
431 |
428 |
break; |
break; |
432 |
429 |
|
|
433 |
|
$ret = intval($v); |
|
|
430 |
|
$ret = intval($ret); |
434 |
431 |
break; |
break; |
435 |
432 |
} |
} |
436 |
433 |
|
|
437 |
|
if ($rg_cache_debug) |
|
438 |
|
rg_log_exit(); |
|
439 |
|
rg_prof_end("cache_inc"); |
|
|
434 |
|
rg_prof_end('cache_inc'); |
440 |
435 |
return $ret; |
return $ret; |
441 |
436 |
} |
} |
442 |
437 |
|
|
|
... |
... |
function rg_cache_inc($ns_var) |
445 |
440 |
*/ |
*/ |
446 |
441 |
function rg_cache_unset($ns_var, $flags) |
function rg_cache_unset($ns_var, $flags) |
447 |
442 |
{ |
{ |
448 |
|
global $rg_cache_socket; |
|
449 |
|
global $rg_cache_timeout; |
|
450 |
|
global $rg_cache_enable; |
|
451 |
|
global $rg_cache_debug; |
|
452 |
|
|
|
453 |
|
rg_prof_start("cache_unset"); |
|
454 |
|
if ($rg_cache_debug) |
|
455 |
|
rg_log_enter("cache_unset($ns_var) flags=$flags" |
|
456 |
|
. " enable=" . ($rg_cache_enable ? "true" : "false")); |
|
|
443 |
|
rg_prof_start('cache_unset'); |
457 |
444 |
|
|
458 |
|
$ret = FALSE; |
|
459 |
|
while (1) { |
|
460 |
|
rg_cache_core_unset($ns_var); |
|
461 |
|
|
|
462 |
|
if ($rg_cache_enable === FALSE) |
|
463 |
|
break; |
|
464 |
|
|
|
465 |
|
$f = ''; |
|
466 |
|
if ($flags & RG_SOCKET_NO_WAIT) |
|
467 |
|
$f .= 'W'; |
|
468 |
|
|
|
469 |
|
$ret = rg_socket($rg_cache_socket, |
|
470 |
|
"UNSET F=$f " . $ns_var . "\n", $rg_cache_timeout, 1, $flags); |
|
471 |
|
if ($ret === FALSE) |
|
472 |
|
break; |
|
473 |
|
|
|
474 |
|
if ($flags & RG_SOCKET_NO_WAIT) { |
|
475 |
|
$ret = TRUE; |
|
476 |
|
break; |
|
477 |
|
} |
|
|
445 |
|
rg_cache_core_unset($ns_var); |
|
446 |
|
$ret = rg_cache_send('UNSET', $ns_var, $flags); |
478 |
447 |
|
|
479 |
|
if (strncmp($ret, "NOT_FOUND", 9) == 0) |
|
480 |
|
break; |
|
481 |
|
|
|
482 |
|
// TODO: return old value? |
|
483 |
|
if (strncmp($ret, "OK", 2) != 0) { |
|
484 |
|
rg_internal_error("Invalid answer: $ret"); |
|
485 |
|
break; |
|
486 |
|
} |
|
487 |
|
|
|
488 |
|
$ret = TRUE; |
|
489 |
|
break; |
|
490 |
|
} |
|
491 |
|
|
|
492 |
|
if ($rg_cache_debug) { |
|
493 |
|
rg_log($ret === TRUE ? "success" : "fail"); |
|
494 |
|
rg_log_exit(); |
|
495 |
|
} |
|
496 |
|
rg_prof_end("cache_unset"); |
|
|
448 |
|
rg_prof_end('cache_unset'); |
497 |
449 |
return $ret; |
return $ret; |
498 |
450 |
} |
} |
499 |
451 |
|
|
|
... |
... |
function rg_cache_unset($ns_var, $flags) |
502 |
454 |
*/ |
*/ |
503 |
455 |
function rg_cache_merge($ns_var, $list, $flags) |
function rg_cache_merge($ns_var, $list, $flags) |
504 |
456 |
{ |
{ |
505 |
|
global $rg_cache_socket; |
|
506 |
|
global $rg_cache_timeout; |
|
507 |
|
global $rg_cache_enable; |
|
508 |
|
global $rg_cache_debug; |
|
509 |
|
|
|
510 |
|
rg_prof_start("cache_merge"); |
|
511 |
|
if ($rg_cache_debug) |
|
512 |
|
rg_log_ml_enter("cache_merge: flags=$flags" |
|
513 |
|
. " $ns_var = " . print_r($list, TRUE)); |
|
514 |
|
|
|
515 |
|
$ret = FALSE; |
|
516 |
|
while (1) { |
|
517 |
|
rg_cache_core_merge($ns_var, $list); |
|
518 |
|
|
|
519 |
|
if ($rg_cache_enable === FALSE) |
|
520 |
|
break; |
|
|
457 |
|
rg_prof_start('cache_merge'); |
521 |
458 |
|
|
522 |
|
$f = ''; |
|
523 |
|
if ($flags & RG_SOCKET_NO_WAIT) |
|
524 |
|
$f .= 'W'; |
|
|
459 |
|
rg_cache_core_merge($ns_var, $list); |
525 |
460 |
|
|
526 |
|
$c = rg_socket($rg_cache_socket, "MERGE F=$f " . $ns_var . "=" |
|
527 |
|
. rg_cache_prepare($list) . "\n", $rg_cache_timeout, |
|
528 |
|
1, $flags); |
|
529 |
|
if ($c === FALSE) |
|
530 |
|
break; |
|
531 |
|
|
|
532 |
|
if ($flags & RG_SOCKET_NO_WAIT) { |
|
533 |
|
$ret = TRUE; |
|
534 |
|
break; |
|
535 |
|
} |
|
536 |
|
|
|
537 |
|
if (strncmp($c, "OK", 2) != 0) |
|
538 |
|
break; |
|
|
461 |
|
$para = $ns_var . '=' . rg_cache_prepare($list); |
|
462 |
|
$ret = rg_cache_send('MERGE', $para, $flags); |
539 |
463 |
|
|
540 |
|
$ret = TRUE; |
|
541 |
|
break; |
|
542 |
|
} |
|
543 |
|
|
|
544 |
|
if ($rg_cache_debug) |
|
545 |
|
rg_log_exit(); |
|
546 |
|
rg_prof_end("cache_merge"); |
|
|
464 |
|
rg_prof_end('cache_merge'); |
547 |
465 |
return $ret; |
return $ret; |
548 |
466 |
} |
} |
549 |
467 |
|
|
|
... |
... |
function rg_cache_merge($ns_var, $list, $flags) |
552 |
470 |
*/ |
*/ |
553 |
471 |
function rg_cache_apush($ns_var, $value, $flags) |
function rg_cache_apush($ns_var, $value, $flags) |
554 |
472 |
{ |
{ |
555 |
|
global $rg_cache_socket; |
|
556 |
|
global $rg_cache_timeout; |
|
557 |
|
global $rg_cache_enable; |
|
558 |
|
global $rg_cache_debug; |
|
|
473 |
|
rg_prof_start('cache_apush'); |
559 |
474 |
|
|
560 |
|
rg_prof_start("cache_apush"); |
|
561 |
|
if ($rg_cache_debug) |
|
562 |
|
rg_log_ml_enter("cache_apush: flags=$flags" |
|
563 |
|
. " $ns_var = " . print_r($value, TRUE)); |
|
|
475 |
|
rg_cache_core_apush($ns_var, $value); |
564 |
476 |
|
|
565 |
|
$ret = FALSE; |
|
566 |
|
while (1) { |
|
567 |
|
rg_cache_core_apush($ns_var, $value); |
|
568 |
|
|
|
569 |
|
if ($rg_cache_enable === FALSE) |
|
570 |
|
break; |
|
|
477 |
|
$para = $ns_var . '=' . rg_cache_prepare($value); |
|
478 |
|
$ret = rg_cache_send('APUSH', $para, $flags); |
571 |
479 |
|
|
572 |
|
$f = ''; |
|
573 |
|
if ($flags & RG_SOCKET_NO_WAIT) |
|
574 |
|
$f .= 'W'; |
|
575 |
|
|
|
576 |
|
$c = rg_socket($rg_cache_socket, "APUSH F=$f " . $ns_var . "=" |
|
577 |
|
. rg_cache_prepare($value) . "\n", $rg_cache_timeout, 3, $flags); |
|
578 |
|
if ($c === FALSE) |
|
579 |
|
break; |
|
|
480 |
|
rg_prof_end('cache_apush'); |
|
481 |
|
return $ret; |
|
482 |
|
} |
580 |
483 |
|
|
581 |
|
if ($flags & RG_SOCKET_NO_WAIT) { |
|
582 |
|
$ret = TRUE; |
|
583 |
|
break; |
|
584 |
|
} |
|
|
484 |
|
/* |
|
485 |
|
* Restarts the cache daemon |
|
486 |
|
*/ |
|
487 |
|
function rg_cache_restart() |
|
488 |
|
{ |
|
489 |
|
$flags = 0; |
|
490 |
|
$para = ''; |
|
491 |
|
$ret = rg_cache_send('SHUTDOWN', $para, $flags); |
|
492 |
|
if ($ret === FALSE) |
|
493 |
|
return FALSE; |
585 |
494 |
|
|
586 |
|
if (strncmp($c, "OK", 2) != 0) |
|
587 |
|
break; |
|
|
495 |
|
rg_log('Cache restarted.'); |
|
496 |
|
return TRUE; |
|
497 |
|
} |
588 |
498 |
|
|
589 |
|
$ret = TRUE; |
|
590 |
|
break; |
|
591 |
|
} |
|
|
499 |
|
/* |
|
500 |
|
* Just to debug stuff |
|
501 |
|
*/ |
|
502 |
|
function rg_cache_sleep() |
|
503 |
|
{ |
|
504 |
|
$flags = RG_SOCKET_NO_WAIT; |
|
505 |
|
$para = ''; |
|
506 |
|
$ret = rg_cache_send('SLEEP', $para, $flags); |
|
507 |
|
if ($ret === FALSE) |
|
508 |
|
return FALSE; |
592 |
509 |
|
|
593 |
|
if ($rg_cache_debug) |
|
594 |
|
rg_log_exit(); |
|
595 |
|
rg_prof_end("cache_apush"); |
|
596 |
|
return $ret; |
|
|
510 |
|
return TRUE; |
597 |
511 |
} |
} |
598 |
512 |
|
|
599 |
513 |
?> |
?> |
File inc/git.inc.php changed (mode: 100644) (index c8dbf68..cc1da62) |
... |
... |
function rg_git_files($old, $new) |
880 |
880 |
rg_prof_start("git_files"); |
rg_prof_start("git_files"); |
881 |
881 |
rg_log_enter("rg_git_files old=$old new=$new"); |
rg_log_enter("rg_git_files old=$old new=$new"); |
882 |
882 |
|
|
883 |
|
// TODO: Here we can deny non ascii file names. Move to update_branch? |
|
884 |
|
// git diff --cached --name-only --diff-filter=A -z $against | LC_ALL=C tr -d '[ -~]\0') |
|
885 |
|
|
|
886 |
883 |
$ret = FALSE; |
$ret = FALSE; |
887 |
884 |
while (1) { |
while (1) { |
888 |
885 |
if (strcmp($old, $rg_git_zero) == 0) |
if (strcmp($old, $rg_git_zero) == 0) |
889 |
886 |
$old = $rg_git_empty; |
$old = $rg_git_empty; |
890 |
887 |
|
|
891 |
|
$cmd = "git diff --name-only " . escapeshellarg($old) . " " . escapeshellarg($new); |
|
|
888 |
|
$cmd = 'git diff --name-only ' . escapeshellarg($old) |
|
889 |
|
. ' ' . escapeshellarg($new); |
892 |
890 |
$a = rg_exec($cmd); |
$a = rg_exec($cmd); |
893 |
891 |
if ($a['ok'] != 1) { |
if ($a['ok'] != 1) { |
894 |
892 |
rg_git_set_error("error on git diff (" . $a['errmsg'] . ")"); |
rg_git_set_error("error on git diff (" . $a['errmsg'] . ")"); |
|
... |
... |
function rg_git_update_tag($db, $a) |
1143 |
1141 |
// If we do not have a namespace, we let git to update the ref. |
// If we do not have a namespace, we let git to update the ref. |
1144 |
1142 |
// Not clear when we do not have a namespace. |
// Not clear when we do not have a namespace. |
1145 |
1143 |
if (!empty($a['namespace'])) { |
if (!empty($a['namespace'])) { |
1146 |
|
// Update the main namespace |
|
|
1144 |
|
// Update the main ref (not a namespace) |
1147 |
1145 |
$reason = $a['login_username'] . ' pushed tag ' . $a['refname']; |
$reason = $a['login_username'] . ' pushed tag ' . $a['refname']; |
1148 |
1146 |
$r = rg_git_update_ref($a['refname'], $a['old_rev'], |
$r = rg_git_update_ref($a['refname'], $a['old_rev'], |
1149 |
1147 |
$a['new_rev'], $reason); |
$a['new_rev'], $reason); |
|
... |
... |
function rg_git_update_tag($db, $a) |
1151 |
1149 |
rg_git_fatal($a['refname'] . "\nCannot update ref (" |
rg_git_fatal($a['refname'] . "\nCannot update ref (" |
1152 |
1150 |
. rg_git_error() . ")"); |
. rg_git_error() . ")"); |
1153 |
1151 |
} |
} |
1154 |
|
|
|
1155 |
|
// We can clean now the tmp namespace - TODO |
|
1156 |
1152 |
} |
} |
1157 |
1153 |
|
|
1158 |
1154 |
rg_repo_history_insert($db, $history); |
rg_repo_history_insert($db, $history); |
|
... |
... |
function rg_git_update_branch($db, $a) |
1199 |
1195 |
break; |
break; |
1200 |
1196 |
} |
} |
1201 |
1197 |
|
|
1202 |
|
// If we have 'H' (anonymous push), we have also create branch |
|
|
1198 |
|
// If we have 'H' (anonymous push), we have also 'create branch' right |
1203 |
1199 |
$check_fast_forward = 1; |
$check_fast_forward = 1; |
1204 |
1200 |
if (strcmp($a['old_rev'], $rg_git_zero) == 0) { // create |
if (strcmp($a['old_rev'], $rg_git_zero) == 0) { // create |
1205 |
1201 |
$x = $_x; |
$x = $_x; |
|
... |
... |
function rg_git_update_branch($db, $a) |
1249 |
1245 |
. "\n" . $w); |
. "\n" . $w); |
1250 |
1246 |
} |
} |
1251 |
1247 |
|
|
1252 |
|
// Check repo_path rights TODO |
|
|
1248 |
|
rg_log_enter('DEBUG: Checking repo_path rights'); |
1253 |
1249 |
$r = rg_git_files($a['old_rev'], $a['new_rev']); |
$r = rg_git_files($a['old_rev'], $a['new_rev']); |
1254 |
1250 |
if ($r === FALSE) |
if ($r === FALSE) |
1255 |
1251 |
rg_git_fatal($a['refname'] . "\nInternal error, try again later\n"); |
rg_git_fatal($a['refname'] . "\nInternal error, try again later\n"); |
|
... |
... |
function rg_git_update_branch($db, $a) |
1273 |
1269 |
} |
} |
1274 |
1270 |
} |
} |
1275 |
1271 |
} |
} |
|
1272 |
|
rg_log_exit(); |
1276 |
1273 |
|
|
1277 |
1274 |
$x = $_x; |
$x = $_x; |
1278 |
1275 |
$x['type'] = 'repo_refs'; |
$x['type'] = 'repo_refs'; |
1279 |
1276 |
$x['needed_rights'] = 'P'; |
$x['needed_rights'] = 'P'; |
1280 |
1277 |
$x['misc'] = $a['refname']; |
$x['misc'] = $a['refname']; |
1281 |
1278 |
if (rg_rights_allow($db, $x) !== TRUE) { |
if (rg_rights_allow($db, $x) !== TRUE) { |
1282 |
|
rg_log("Push is not allowed, let's see the anon one"); |
|
|
1279 |
|
rg_log("DEBUG: Push is not allowed, let's see the anon one"); |
1283 |
1280 |
$x['needed_rights'] = 'H'; |
$x['needed_rights'] = 'H'; |
1284 |
1281 |
if (rg_rights_allow($db, $x) !== TRUE) { |
if (rg_rights_allow($db, $x) !== TRUE) { |
1285 |
1282 |
$_z = array(); |
$_z = array(); |
|
... |
... |
function rg_git_update_branch($db, $a) |
1295 |
1292 |
. "_" . str_replace('rg_', '', $a['namespace']); |
. "_" . str_replace('rg_', '', $a['namespace']); |
1296 |
1293 |
$reason = $a['login_username'] . ' pushed a merge request' |
$reason = $a['login_username'] . ' pushed a merge request' |
1297 |
1294 |
. ' for ref ' . $a['refname'] |
. ' for ref ' . $a['refname'] |
1298 |
|
. ' into namespace ' . $a['namespace']; |
|
|
1295 |
|
. ' into namespace ' . $mr; |
1299 |
1296 |
$r = rg_git_update_ref($mr, "", $a['new_rev'], $reason); |
$r = rg_git_update_ref($mr, "", $a['new_rev'], $reason); |
1300 |
1297 |
if ($r !== TRUE) { |
if ($r !== TRUE) { |
1301 |
1298 |
rg_log("Cannot update-ref: " . rg_git_error()); |
rg_log("Cannot update-ref: " . rg_git_error()); |
1302 |
1299 |
rg_git_fatal($a['refname'] . ": Cannot set refs/mr/." |
rg_git_fatal($a['refname'] . ": Cannot set refs/mr/." |
1303 |
1300 |
. " Try again later."); |
. " Try again later."); |
1304 |
1301 |
} |
} |
1305 |
|
// TODO: here or inside below function we should record |
|
1306 |
|
// a hisotry event that an anon push was done. |
|
1307 |
1302 |
$r = rg_mr_queue_add($a['repo_id'], $a['namespace'], |
$r = rg_mr_queue_add($a['repo_id'], $a['namespace'], |
1308 |
1303 |
$a['old_rev'], $a['new_rev'], $a['refname'], $a['ip']); |
$a['old_rev'], $a['new_rev'], $a['refname'], $a['ip']); |
1309 |
1304 |
if ($r !== TRUE) |
if ($r !== TRUE) |
|
... |
... |
function rg_git_update_branch($db, $a) |
1314 |
1309 |
|
|
1315 |
1310 |
$history['history_category'] = REPO_CAT_GIT_BRANCH_ANON_PUSH; |
$history['history_category'] = REPO_CAT_GIT_BRANCH_ANON_PUSH; |
1316 |
1311 |
$history['history_message'] = 'Anonymous push to ref ' |
$history['history_message'] = 'Anonymous push to ref ' |
1317 |
|
. $a['refname']; |
|
|
1312 |
|
. $a['refname'] . ' into namespace ' . $mr; |
1318 |
1313 |
|
|
1319 |
1314 |
// TODO: we should notify by e-mail that a merge request is |
// TODO: we should notify by e-mail that a merge request is |
1320 |
1315 |
// waiting. |
// waiting. |
1321 |
1316 |
} else { |
} else { |
1322 |
|
rg_log("We are allowed to push."); |
|
|
1317 |
|
rg_log("DEBUG: We are allowed to push."); |
1323 |
1318 |
|
|
1324 |
1319 |
// If we do not have a namespace, we let git to update the ref. |
// If we do not have a namespace, we let git to update the ref. |
1325 |
1320 |
// Not clear when we do not have a namespace. |
// Not clear when we do not have a namespace. |
1326 |
1321 |
if (!empty($a['namespace'])) { |
if (!empty($a['namespace'])) { |
1327 |
|
// Update the main namespace |
|
|
1322 |
|
// Updating main ref (not a namespace) |
1328 |
1323 |
$reason = $a['login_username'] |
$reason = $a['login_username'] |
1329 |
1324 |
. ' pushed ref ' . $a['refname']; |
. ' pushed ref ' . $a['refname']; |
1330 |
1325 |
$r = rg_git_update_ref($a['refname'], $a['old_rev'], |
$r = rg_git_update_ref($a['refname'], $a['old_rev'], |
1331 |
1326 |
$a['new_rev'], $reason); |
$a['new_rev'], $reason); |
1332 |
1327 |
if ($r !== TRUE) { |
if ($r !== TRUE) { |
1333 |
|
rg_git_fatal($a['refname'] . "\nCannot update ref (" |
|
|
1328 |
|
rg_git_fatal($a['refname'] |
|
1329 |
|
. "\nCannot update ref (" |
1334 |
1330 |
. rg_git_error() . ")"); |
. rg_git_error() . ")"); |
1335 |
1331 |
} |
} |
1336 |
1332 |
|
|
1337 |
|
// We can clean now the tmp namespace - TODO |
|
|
1333 |
|
// Here, the namespace ref is not yet updated |
1338 |
1334 |
} |
} |
1339 |
1335 |
|
|
1340 |
1336 |
if (strcmp($a['old_rev'], $rg_git_zero) == 0) { |
if (strcmp($a['old_rev'], $rg_git_zero) == 0) { |
|
... |
... |
function rg_git_update_branch($db, $a) |
1350 |
1346 |
} |
} |
1351 |
1347 |
} |
} |
1352 |
1348 |
rg_repo_history_insert($db, $history); |
rg_repo_history_insert($db, $history); |
|
1349 |
|
break; |
1353 |
1350 |
} |
} |
1354 |
1351 |
|
|
1355 |
1352 |
rg_log_exit(); |
rg_log_exit(); |
File inc/rights.inc.php changed (mode: 100644) (index 559a846..d9a4d32) |
... |
... |
function rg_rights_get($db, $obj_id, $type, $owner, $uid, $right_id) |
276 |
276 |
global $rg_rights; |
global $rg_rights; |
277 |
277 |
global $rg_rights_inject; |
global $rg_rights_inject; |
278 |
278 |
|
|
279 |
|
rg_prof_start("rights_get"); |
|
|
279 |
|
rg_prof_start('rights_get'); |
280 |
280 |
rg_log_enter("rg_rights_get: obj_id=$obj_id type=$type owner=$owner" |
rg_log_enter("rg_rights_get: obj_id=$obj_id type=$type owner=$owner" |
281 |
281 |
. " uid=$uid right_id=$right_id"); |
. " uid=$uid right_id=$right_id"); |
282 |
282 |
|
|
|
... |
... |
function rg_rights_get($db, $obj_id, $type, $owner, $uid, $right_id) |
287 |
287 |
$key = "rights_by_obj_id::$obj_id::$type"; |
$key = "rights_by_obj_id::$obj_id::$type"; |
288 |
288 |
$r = rg_cache_get($key); |
$r = rg_cache_get($key); |
289 |
289 |
if ($r === FALSE) { |
if ($r === FALSE) { |
290 |
|
rg_log("CHECK: rights_get: key not found in cache! Search in DB."); |
|
|
290 |
|
//rg_log("CHECK: rights_get: key not found in cache! Search in DB."); |
291 |
291 |
|
|
292 |
292 |
$r = array(); |
$r = array(); |
293 |
293 |
|
|
|
... |
... |
function rg_rights_get($db, $obj_id, $type, $owner, $uid, $right_id) |
309 |
309 |
rg_rights_cosmetic($db, $a); |
rg_rights_cosmetic($db, $a); |
310 |
310 |
|
|
311 |
311 |
$r[] = $a; |
$r[] = $a; |
312 |
|
rg_log_ml("rights_get: inject all rights for owner"); |
|
|
312 |
|
//rg_log_ml("rights_get: inject all rights for owner"); |
313 |
313 |
} |
} |
314 |
314 |
|
|
315 |
315 |
// Inject specific rights |
// Inject specific rights |
316 |
316 |
if (isset($rg_rights_inject[$type])) { |
if (isset($rg_rights_inject[$type])) { |
317 |
317 |
$f = $rg_rights_inject[$type]; |
$f = $rg_rights_inject[$type]; |
318 |
318 |
$rows = $f($db, $obj_id, $type, $owner, $uid); |
$rows = $f($db, $obj_id, $type, $owner, $uid); |
319 |
|
rg_log_ml("CHECK: inject function for '$type' [$f] returned: " . print_r($rows, TRUE)); |
|
|
319 |
|
//rg_log_ml("CHECK: inject function for '$type' [$f] returned: " . print_r($rows, TRUE)); |
320 |
320 |
foreach ($rows as $row) { |
foreach ($rows as $row) { |
321 |
321 |
rg_rights_cosmetic($db, $row); |
rg_rights_cosmetic($db, $row); |
322 |
|
rg_log_ml("rights_get: inject specific rights: " . print_r($row, TRUE)); |
|
|
322 |
|
//rg_log_ml("rights_get: inject specific rights: " . print_r($row, TRUE)); |
323 |
323 |
$r[] = $row; |
$r[] = $row; |
324 |
324 |
} |
} |
325 |
325 |
} |
} |
|
... |
... |
function rg_rights_get($db, $obj_id, $type, $owner, $uid, $right_id) |
333 |
333 |
// We store the big list |
// We store the big list |
334 |
334 |
rg_cache_set($key, $r, RG_SOCKET_NO_WAIT); |
rg_cache_set($key, $r, RG_SOCKET_NO_WAIT); |
335 |
335 |
} else { |
} else { |
336 |
|
rg_log("CHECK: rights returned from cache for key $key"); |
|
|
336 |
|
//rg_log("CHECK: rights returned from cache for key $key"); |
337 |
337 |
} |
} |
338 |
338 |
|
|
339 |
339 |
// now, filter by uid and right_id |
// now, filter by uid and right_id |
|
... |
... |
function rg_rights_get($db, $obj_id, $type, $owner, $uid, $right_id) |
349 |
349 |
break; |
break; |
350 |
350 |
} |
} |
351 |
351 |
|
|
352 |
|
rg_log("rights_get: rights=" . rg_array2string($ret['list'])); |
|
|
352 |
|
//rg_log("rights_get: rights=" . rg_array2string($ret['list'])); |
353 |
353 |
|
|
354 |
354 |
rg_log_exit(); |
rg_log_exit(); |
355 |
|
rg_prof_end("rights_get"); |
|
|
355 |
|
rg_prof_end('rights_get'); |
356 |
356 |
return $ret; |
return $ret; |
357 |
357 |
} |
} |
358 |
358 |
|
|
|
... |
... |
function rg_rights_test_ip($list, $ip) |
634 |
634 |
/* |
/* |
635 |
635 |
* Returns TRUE if all 'needed_rights' are included in 'rights' |
* Returns TRUE if all 'needed_rights' are included in 'rights' |
636 |
636 |
* @list - an array of rights |
* @list - an array of rights |
637 |
|
* needed_rights: rights letters; you can use "ab|cd" = (a AND B) OR (C AND d) |
|
|
637 |
|
* @needed_rights: rights letters; you can use "ab|cd" = (a AND B) OR (C AND d) |
638 |
638 |
*/ |
*/ |
639 |
639 |
function rg_rights_test($list, $needed_rights, $ip, $misc) |
function rg_rights_test($list, $needed_rights, $ip, $misc) |
640 |
640 |
{ |
{ |
|
... |
... |
function rg_rights_test($list, $needed_rights, $ip, $misc) |
664 |
664 |
continue; |
continue; |
665 |
665 |
} |
} |
666 |
666 |
|
|
|
667 |
|
// Test 'misc' match |
|
668 |
|
if (!empty($v['misc'])) { |
|
669 |
|
$cmp_func = $rg_rights_cmp_func[$v['type']]; |
|
670 |
|
$r = $cmp_func($v['misc'], $misc); |
|
671 |
|
if ($r !== TRUE) { |
|
672 |
|
rg_log("DEBUG: cmp function returned !TRUE"); |
|
673 |
|
continue; |
|
674 |
|
} |
|
675 |
|
} |
|
676 |
|
|
|
677 |
|
if (strlen($v['rights']) == 0) { |
|
678 |
|
rg_log('DEBUG: rights field is empty' |
|
679 |
|
. ', stop processing!'); |
|
680 |
|
break; |
|
681 |
|
} |
|
682 |
|
|
667 |
683 |
// Test rights |
// Test rights |
668 |
684 |
$have_a_match = FALSE; |
$have_a_match = FALSE; |
669 |
685 |
foreach ($needed as $needed1) { |
foreach ($needed as $needed1) { |
670 |
686 |
$r = rg_rights_mask($v['rights'], $needed1); |
$r = rg_rights_mask($v['rights'], $needed1); |
671 |
687 |
if (strcmp($r, $needed1) != 0) { |
if (strcmp($r, $needed1) != 0) { |
672 |
|
rg_log("rights_test: [$r] != [$needed1]! Continue."); |
|
|
688 |
|
rg_log("[$r] != [$needed1]! Continue."); |
673 |
689 |
continue; |
continue; |
674 |
690 |
} |
} |
675 |
|
rg_log("rights_test: [$r] = [$needed1]! Allow."); |
|
|
691 |
|
//rg_log("[$r] = [$needed1]! Allow."); |
676 |
692 |
$have_a_match = TRUE; |
$have_a_match = TRUE; |
677 |
693 |
break; |
break; |
678 |
694 |
} |
} |
679 |
695 |
if ($have_a_match === FALSE) |
if ($have_a_match === FALSE) |
680 |
696 |
continue; |
continue; |
681 |
697 |
|
|
682 |
|
// Test 'misc' match |
|
683 |
|
if (!empty($v['misc'])) { |
|
684 |
|
$cmp_func = $rg_rights_cmp_func[$v['type']]; |
|
685 |
|
$r = $cmp_func($v['misc'], $misc); |
|
686 |
|
if ($r !== TRUE) { |
|
687 |
|
rg_log("DEBUG: cmp function returned !TRUE"); |
|
688 |
|
continue; |
|
689 |
|
} |
|
690 |
|
} |
|
691 |
|
|
|
692 |
698 |
$ret = TRUE; |
$ret = TRUE; |
693 |
699 |
break; |
break; |
694 |
700 |
} |
} |
695 |
701 |
|
|
696 |
702 |
break; |
break; |
697 |
703 |
} |
} |
698 |
|
rg_log("DEBUG: rights_test returns " . ($ret === FALSE ? "!allow" : "allow")); |
|
|
704 |
|
//rg_log("DEBUG: rights_test returns " . ($ret === FALSE ? "!allow" : "allow")); |
699 |
705 |
|
|
700 |
706 |
rg_log_exit(); |
rg_log_exit(); |
701 |
707 |
return $ret; |
return $ret; |
|
... |
... |
function rg_rights_test($list, $needed_rights, $ip, $misc) |
703 |
709 |
|
|
704 |
710 |
/* |
/* |
705 |
711 |
* Returns TRUE if all 'needed_rights' are included in 'rights' |
* Returns TRUE if all 'needed_rights' are included in 'rights' |
706 |
|
* needed_rights: rights letters; you can use "ab|cd" = (a AND B) OR (C AND d) |
|
|
712 |
|
* @a[needed_rights]: rights letters; you can use "ab|cd" = (a AND B) OR (C AND d) |
707 |
713 |
*/ |
*/ |
708 |
714 |
function rg_rights_allow($db, $a) |
function rg_rights_allow($db, $a) |
709 |
715 |
{ |
{ |
File inc/ssh.inc.php changed (mode: 100644) (index 9a4be66..5f2797c) |
... |
... |
function rg_ssh_repo($db, $uid, $paras) |
88 |
88 |
/* |
/* |
89 |
89 |
* Deal with TOTP stuff |
* Deal with TOTP stuff |
90 |
90 |
*/ |
*/ |
91 |
|
function rg_ssh_totp($db, $uid, $paras) |
|
|
91 |
|
function rg_ssh_totp($db, $ip, $uid, $paras) |
92 |
92 |
{ |
{ |
93 |
93 |
rg_prof_start('ssh_totp'); |
rg_prof_start('ssh_totp'); |
94 |
|
rg_log_enter('ssh_totp uid=' . $uid . ' paras=' . rg_array2string($paras)); |
|
95 |
|
|
|
96 |
|
$ssh_client = getenv("SSH_CLIENT"); |
|
97 |
|
$_t = explode(" ", $ssh_client); |
|
98 |
|
$ip = $_t[0]; |
|
|
94 |
|
rg_log_enter('ssh_totp ip=' . $ip . ' uid=' . $uid |
|
95 |
|
. ' paras=' . rg_array2string($paras)); |
99 |
96 |
|
|
100 |
97 |
$cmd = array_shift($paras); |
$cmd = array_shift($paras); |
101 |
98 |
switch ($cmd) { |
switch ($cmd) { |
|
... |
... |
function rg_ssh_totp($db, $uid, $paras) |
178 |
175 |
break; |
break; |
179 |
176 |
|
|
180 |
177 |
case 'list-val': |
case 'list-val': |
181 |
|
$r = rg_totp_list_ip($db, $uid); |
|
|
178 |
|
$r = rg_totp_verify_ip($db, $uid, $ip); |
182 |
179 |
if ($r['ok'] != 1) { |
if ($r['ok'] != 1) { |
183 |
|
echo "An internal error occured; please try again later.\n"; |
|
|
180 |
|
echo 'RocketGit: Error: ' . rg_totp_error() . ".\n"; |
184 |
181 |
break; |
break; |
185 |
182 |
} |
} |
186 |
|
|
|
187 |
|
// we provide the list only from a validated ip |
|
188 |
|
$found = FALSE; |
|
189 |
|
foreach ($r['list'] as $t) { |
|
190 |
|
if (strcmp($t['ip'], $ip) == 0) { |
|
191 |
|
$found = TRUE; |
|
192 |
|
break; |
|
193 |
|
} |
|
194 |
|
} |
|
195 |
|
|
|
196 |
|
if (!$found || empty($r['list'])) { |
|
197 |
|
echo "No validated IPs are pesent.\n"; |
|
|
183 |
|
if ($r['enrolled'] == 0) { |
|
184 |
|
echo 'RocketGit: Info: You are not enrolled.' . ".\n"; |
198 |
185 |
break; |
break; |
199 |
186 |
} |
} |
200 |
187 |
|
|
|
... |
... |
function rg_ssh_totp($db, $uid, $paras) |
224 |
211 |
$a = array($v['id'] => ''); |
$a = array($v['id'] => ''); |
225 |
212 |
$r = rg_totp_remove($db, $uid, $a); |
$r = rg_totp_remove($db, $uid, $a); |
226 |
213 |
if ($r !== TRUE) { |
if ($r !== TRUE) { |
227 |
|
echo "Error: " . rg_totp_error() . "\n"; |
|
|
214 |
|
echo "Error: " . rg_totp_error() . ".\n"; |
228 |
215 |
break; |
break; |
229 |
216 |
} |
} |
230 |
217 |
|
|
|
... |
... |
function rg_ssh_totp($db, $uid, $paras) |
239 |
226 |
|
|
240 |
227 |
$del_ip = array_shift($paras); |
$del_ip = array_shift($paras); |
241 |
228 |
|
|
242 |
|
$r = rg_totp_list_ip($db, $uid); |
|
|
229 |
|
$r = rg_totp_verify_ip($db, $uid, $ip); |
243 |
230 |
if ($r['ok'] != 1) { |
if ($r['ok'] != 1) { |
244 |
|
echo "An internal error occured; please try again later.\n"; |
|
|
231 |
|
echo 'RocketGit: Error: ' . rg_totp_error() . ".\n"; |
245 |
232 |
break; |
break; |
246 |
233 |
} |
} |
247 |
|
|
|
248 |
|
// we allow the deletion only from a validated ip |
|
249 |
|
$found = FALSE; |
|
250 |
|
foreach ($r['list'] as $t) { |
|
251 |
|
if (strcmp($t['ip'], $ip) == 0) { |
|
252 |
|
$found = TRUE; |
|
253 |
|
break; |
|
254 |
|
} |
|
255 |
|
} |
|
256 |
|
if (!$found) { |
|
257 |
|
echo "You are not allowed to delete the IPs." |
|
258 |
|
. " Try 'val' command first.\n"; |
|
|
234 |
|
if ($r['enrolled'] == 0) { |
|
235 |
|
echo 'RocketGit: Info: You are not enrolled.' . ".\n"; |
259 |
236 |
break; |
break; |
260 |
237 |
} |
} |
261 |
238 |
|
|
262 |
239 |
$r = rg_totp_del_ip($db, $uid, $del_ip); |
$r = rg_totp_del_ip($db, $uid, $del_ip); |
263 |
240 |
if ($r !== TRUE) { |
if ($r !== TRUE) { |
264 |
|
echo "Error: " . rg_totp_error() . "!\n"; |
|
|
241 |
|
echo "Error: " . rg_totp_error() . ".\n"; |
265 |
242 |
break; |
break; |
266 |
243 |
} |
} |
267 |
244 |
|
|
|
... |
... |
function rg_ssh_totp($db, $uid, $paras) |
270 |
247 |
|
|
271 |
248 |
default: |
default: |
272 |
249 |
echo "Posible TOTP commands:\n"; |
echo "Posible TOTP commands:\n"; |
273 |
|
echo " enroll [token] - adds a new device in the system\n"; |
|
|
250 |
|
echo " enroll <token> - adds a new device in the system\n"; |
274 |
251 |
echo " val [X(m|h|d)] - adds your IP to the allow list for X time\n"; |
echo " val [X(m|h|d)] - adds your IP to the allow list for X time\n"; |
275 |
252 |
echo " default is 24 hours;\n"; |
echo " default is 24 hours;\n"; |
276 |
253 |
echo " you can specify m for minutes, h for hours and d for days\n"; |
echo " you can specify m for minutes, h for hours and d for days\n"; |
277 |
254 |
echo " list-val - list the already validated IPs\n"; |
echo " list-val - list the already validated IPs\n"; |
278 |
255 |
echo " inval ip|all - Invalidate IP address(es)\n"; |
echo " inval ip|all - Invalidate IP address(es)\n"; |
279 |
|
echo " unenroll token - remove a device from TOTP system\n"; |
|
|
256 |
|
echo " unenroll <token> - remove a device from TOTP system\n"; |
280 |
257 |
break; |
break; |
281 |
258 |
} |
} |
282 |
259 |
|
|
|
... |
... |
function rg_ssh_totp($db, $uid, $paras) |
284 |
261 |
rg_prof_end('ssh_totp'); |
rg_prof_end('ssh_totp'); |
285 |
262 |
} |
} |
286 |
263 |
|
|
287 |
|
function rg_ssh_dispatch($db, $uid, $cmd) |
|
|
264 |
|
function rg_ssh_dispatch($db, $ip, $uid, $orig_cmd) |
288 |
265 |
{ |
{ |
289 |
|
$paras = explode(' ', $cmd); |
|
|
266 |
|
rg_log('ssh_dispatch orig_cmd=[' . $orig_cmd . ']'); |
|
267 |
|
|
|
268 |
|
$paras = explode(' ', $orig_cmd); |
290 |
269 |
$cmd = array_shift($paras); |
$cmd = array_shift($paras); |
291 |
270 |
|
|
|
271 |
|
// some commands are not executed here |
|
272 |
|
switch ($cmd) { |
|
273 |
|
case 'git-upload-pack'; return; |
|
274 |
|
case 'git-receive-pack': return; |
|
275 |
|
} |
|
276 |
|
|
292 |
277 |
echo "\n== Welcome to RocketGit! ==\n"; |
echo "\n== Welcome to RocketGit! ==\n"; |
293 |
278 |
|
|
|
279 |
|
$ui = rg_user_info($db, $uid, '', ''); |
|
280 |
|
if ($ui['exists'] == 1) |
|
281 |
|
echo 'RocketGit: You are connecting as user' |
|
282 |
|
. ' \'' . $ui['username'] . '\'.' . "\n"; |
|
283 |
|
|
|
284 |
|
echo 'RocketGit: You are connecting from IP ' . $ip . ".\n"; |
|
285 |
|
|
|
286 |
|
// First, test if the IP is validated |
|
287 |
|
switch ($cmd) { |
|
288 |
|
case '': break; |
|
289 |
|
case 'totp': break; // totp will verify the ip only for some commands |
|
290 |
|
default: |
|
291 |
|
$r = rg_totp_verify_ip($db, $uid, $ip); |
|
292 |
|
if ($r['ok'] != 1) { |
|
293 |
|
echo 'RocketGit: Error: ' . rg_totp_error() . ".\n"; |
|
294 |
|
exit(0); |
|
295 |
|
} |
|
296 |
|
break; |
|
297 |
|
} |
|
298 |
|
|
|
299 |
|
// Now, we can safely execute the command |
294 |
300 |
switch ($cmd) { |
switch ($cmd) { |
295 |
|
case 'status': rg_ssh_status($db, $uid); break; |
|
296 |
|
case 'repos': rg_ssh_repos($db, $uid); break; |
|
297 |
|
case 'repo': rg_ssh_repo($db, $uid, $paras); break; |
|
298 |
|
case 'totp': rg_ssh_totp($db, $uid, $paras); break; |
|
299 |
|
default: |
|
|
301 |
|
case 'status': rg_ssh_status($db, $uid); |
|
302 |
|
case 'repos': rg_ssh_repos($db, $uid); exit(0); |
|
303 |
|
case 'repo': rg_ssh_repo($db, $uid, $paras); exit(0); |
|
304 |
|
case 'totp': rg_ssh_totp($db, $ip, $uid, $paras); exit(0); |
|
305 |
|
case '': |
300 |
306 |
echo "Available commmands:\n" |
echo "Available commmands:\n" |
301 |
307 |
. " status - show some status about the user\n" |
. " status - show some status about the user\n" |
302 |
308 |
. " repos - list repos and information about them\n" |
. " repos - list repos and information about them\n" |
303 |
309 |
. " repo - list info about a repo\n" |
. " repo - list info about a repo\n" |
304 |
310 |
. " totp - two-factor authentication commands\n"; |
. " totp - two-factor authentication commands\n"; |
305 |
|
break; |
|
|
311 |
|
exit(0); |
306 |
312 |
} |
} |
307 |
313 |
|
|
308 |
|
exit(0); |
|
|
314 |
|
// Do not exit(0) from this function because a fetch or push will be |
|
315 |
|
// executed after this function's exit. |
309 |
316 |
} |
} |
310 |
317 |
|
|
311 |
318 |
?> |
?> |
File inc/totp.inc.php changed (mode: 100644) (index b3006ab..57048d2) |
1 |
1 |
<?php |
<?php |
|
2 |
|
$INC = isset($INC) ? $INC : dirname(__FILE__); |
|
3 |
|
require_once($INC . "/util.inc.php"); |
|
4 |
|
require_once($INC . "/log.inc.php"); |
|
5 |
|
require_once($INC . "/sql.inc.php"); |
|
6 |
|
require_once($INC . "/events.inc.php"); |
2 |
7 |
|
|
3 |
8 |
$rg_totp_error = ''; |
$rg_totp_error = ''; |
4 |
9 |
|
|
|
... |
... |
function rg_totp_set_error($str) |
6 |
11 |
{ |
{ |
7 |
12 |
global $rg_totp_error; |
global $rg_totp_error; |
8 |
13 |
$rg_totp_error = $str; |
$rg_totp_error = $str; |
9 |
|
rg_log('set_error: ' . $str); |
|
|
14 |
|
rg_log('totp_set_error: ' . $str); |
10 |
15 |
} |
} |
11 |
16 |
|
|
12 |
17 |
function rg_totp_error() |
function rg_totp_error() |
|
... |
... |
function rg_totp_compute($key, $tc, $digits) |
93 |
98 |
return sprintf("%0" . $digits . "u", $i % pow(10, $digits)); |
return sprintf("%0" . $digits . "u", $i % pow(10, $digits)); |
94 |
99 |
} |
} |
95 |
100 |
|
|
|
101 |
|
/* |
|
102 |
|
* Verifies a tokens based on a specified 'tc' |
|
103 |
|
* Returns 'tc' if ok, FALSE on error |
|
104 |
|
*/ |
96 |
105 |
function rg_totp_verify_tc($key, $tc, $token) |
function rg_totp_verify_tc($key, $tc, $token) |
97 |
106 |
{ |
{ |
98 |
107 |
$t = rg_totp_compute($key, $tc, 6); |
$t = rg_totp_compute($key, $tc, 6); |
|
108 |
|
//rg_log('DEBUG: compute[tc=' . $tc . ']=' . $t); |
99 |
109 |
if (strcmp($token, $t) == 0) |
if (strcmp($token, $t) == 0) |
100 |
|
return TRUE; |
|
|
110 |
|
return $tc; |
101 |
111 |
|
|
102 |
112 |
return FALSE; |
return FALSE; |
103 |
113 |
} |
} |
104 |
114 |
|
|
105 |
115 |
/* |
/* |
106 |
116 |
* Verifies if a login token is valid |
* Verifies if a login token is valid |
107 |
|
* We try 2 tcs before currend ts and after current ts |
|
|
117 |
|
* We try 2 tcs before current ts and after current ts |
|
118 |
|
* Returns FALSE if token is not valid or 'tc' of the token if is valid. |
108 |
119 |
*/ |
*/ |
109 |
|
function rg_totp_verify($key, $token) |
|
|
120 |
|
function rg_totp_verify($key, $ts, $token) |
110 |
121 |
{ |
{ |
111 |
122 |
rg_prof_start('totp_verify'); |
rg_prof_start('totp_verify'); |
|
123 |
|
rg_log_enter('totp_verify ts=' . $ts . ', token=' . $token); |
112 |
124 |
|
|
113 |
|
$tc = intval(time() / 30); |
|
114 |
|
while (1) { |
|
|
125 |
|
$tc = intval($ts / 30); |
|
126 |
|
$list = array($tc, $tc - 1, $tc - 2, $tc + 1, $tc + 2); |
|
127 |
|
foreach ($list as $tc) { |
115 |
128 |
$ret = rg_totp_verify_tc($key, $tc, $token); |
$ret = rg_totp_verify_tc($key, $tc, $token); |
116 |
|
if ($ret === TRUE) |
|
117 |
|
break; |
|
118 |
|
|
|
119 |
|
$ret = rg_totp_verify_tc($key, $tc - 1, $token); |
|
120 |
|
if ($ret === TRUE) |
|
121 |
|
break; |
|
122 |
|
|
|
123 |
|
$ret = rg_totp_verify_tc($key, $tc - 2, $token); |
|
124 |
|
if ($ret === TRUE) |
|
125 |
|
break; |
|
126 |
|
|
|
127 |
|
$ret = rg_totp_verify_tc($key, $tc + 1, $token); |
|
128 |
|
if ($ret === TRUE) |
|
129 |
|
break; |
|
130 |
|
|
|
131 |
|
$ret = rg_totp_verify_tc($key, $tc + 2, $token); |
|
132 |
|
if ($ret === TRUE) |
|
|
129 |
|
//rg_log('DEBUG: using tc ' . $tc . ', ret=' . $ret); |
|
130 |
|
if ($ret !== FALSE) |
133 |
131 |
break; |
break; |
134 |
|
|
|
135 |
|
$ret = FALSE; |
|
136 |
|
break; |
|
137 |
132 |
} |
} |
138 |
133 |
|
|
|
134 |
|
rg_log_exit(); |
139 |
135 |
rg_prof_end('totp_verify'); |
rg_prof_end('totp_verify'); |
140 |
136 |
return $ret; |
return $ret; |
141 |
137 |
} |
} |
|
... |
... |
function rg_totp_cosmetic(&$row) |
201 |
197 |
/* |
/* |
202 |
198 |
* Sets when a login token was last used |
* Sets when a login token was last used |
203 |
199 |
*/ |
*/ |
204 |
|
function rg_totp_set_last_use($db, $uid, $id, $ts) |
|
|
200 |
|
function rg_totp_set_last_use($db, $uid, $id, $tc, $ts) |
205 |
201 |
{ |
{ |
206 |
202 |
rg_prof_start('totp_set_last_use'); |
rg_prof_start('totp_set_last_use'); |
207 |
|
rg_log_enter('totp_set_last_use uid=' . $uid . ' id=' . $id); |
|
|
203 |
|
rg_log_enter('totp_set_last_use uid=' . $uid . ' id=' . $id |
|
204 |
|
. ' tc=' . $tc); |
208 |
205 |
|
|
209 |
206 |
$ret = FALSE; |
$ret = FALSE; |
210 |
207 |
while (1) { |
while (1) { |
211 |
208 |
$params = array('uid' => $uid, |
$params = array('uid' => $uid, |
212 |
209 |
'id' => $id, |
'id' => $id, |
213 |
|
'used' => $ts); |
|
|
210 |
|
'used' => $ts, |
|
211 |
|
'last_used_tc' => $tc, |
|
212 |
|
'conf' => 't'); |
214 |
213 |
$sql = 'UPDATE login_tokens SET used = @@used@@' |
$sql = 'UPDATE login_tokens SET used = @@used@@' |
|
214 |
|
. ', last_used_tc = @@last_used_tc@@' |
|
215 |
|
. ', conf = @@conf@@' |
215 |
216 |
. ' WHERE uid = @@uid@@' |
. ' WHERE uid = @@uid@@' |
216 |
|
. ' AND id = @@id@@' |
|
217 |
|
. ' AND used != @@used@@'; |
|
|
217 |
|
. ' AND id = @@id@@'; |
218 |
218 |
$res = rg_sql_query_params($db, $sql, $params); |
$res = rg_sql_query_params($db, $sql, $params); |
219 |
219 |
if ($res === FALSE) { |
if ($res === FALSE) { |
220 |
220 |
rg_user_set_error('cannot update last used (' . rg_sql_error()); |
rg_user_set_error('cannot update last used (' . rg_sql_error()); |
|
... |
... |
function rg_totp_set_last_use($db, $uid, $id, $ts) |
223 |
223 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
224 |
224 |
|
|
225 |
225 |
$key = 'user' . '::' . $uid . '::' . 'login_tokens' |
$key = 'user' . '::' . $uid . '::' . 'login_tokens' |
226 |
|
. '::' . 'list' . '::' . $id . '::' . 'used'; |
|
227 |
|
$a = array('used' => $ts); |
|
|
226 |
|
. '::' . 'list' . '::' . $id; |
|
227 |
|
$a = array('used' => $ts, 'last_used_tc' => $tc, 'conf' => 't'); |
228 |
228 |
rg_totp_cosmetic($a); |
rg_totp_cosmetic($a); |
229 |
229 |
rg_cache_merge($key, $a, RG_SOCKET_NO_WAIT); |
rg_cache_merge($key, $a, RG_SOCKET_NO_WAIT); |
230 |
230 |
|
|
|
... |
... |
function rg_totp_set_last_use($db, $uid, $id, $ts) |
237 |
237 |
return $ret; |
return $ret; |
238 |
238 |
} |
} |
239 |
239 |
|
|
|
240 |
|
/* |
|
241 |
|
* Returns a list of login tokens from database |
|
242 |
|
*/ |
|
243 |
|
function rg_totp_list($db, $uid) |
|
244 |
|
{ |
|
245 |
|
rg_prof_start('totp_list'); |
|
246 |
|
rg_log_enter('totp_list'); |
|
247 |
|
|
|
248 |
|
while (1) { |
|
249 |
|
$key = 'user' . '::' . $uid . '::' . 'login_tokens'; |
|
250 |
|
$ret = rg_cache_get($key); |
|
251 |
|
if ($ret !== FALSE) { |
|
252 |
|
$ret['ok'] = 1; |
|
253 |
|
break; |
|
254 |
|
} |
|
255 |
|
|
|
256 |
|
$ret = array(); |
|
257 |
|
$ret['ok'] = 0; |
|
258 |
|
|
|
259 |
|
$params = array('uid' => $uid); |
|
260 |
|
$sql = 'SELECT * FROM login_tokens' |
|
261 |
|
. ' WHERE uid = @@uid@@' |
|
262 |
|
. ' ORDER BY itime'; |
|
263 |
|
$res = rg_sql_query_params($db, $sql, $params); |
|
264 |
|
if ($res === FALSE) { |
|
265 |
|
rg_totp_set_error('cannot load login tokens'); |
|
266 |
|
break; |
|
267 |
|
} |
|
268 |
|
|
|
269 |
|
$ret['list'] = array(); |
|
270 |
|
while (($row = rg_sql_fetch_array($res))) { |
|
271 |
|
$id = $row['id']; |
|
272 |
|
|
|
273 |
|
rg_totp_cosmetic($row); |
|
274 |
|
|
|
275 |
|
$ret['list'][$id] = $row; |
|
276 |
|
} |
|
277 |
|
rg_sql_free_result($res); |
|
278 |
|
|
|
279 |
|
unset($ret['ok']); // we do not need it in cache |
|
280 |
|
rg_cache_set($key, $ret, RG_SOCKET_NO_WAIT); |
|
281 |
|
$ret['ok'] = 1; |
|
282 |
|
break; |
|
283 |
|
} |
|
284 |
|
|
|
285 |
|
rg_log_exit(); |
|
286 |
|
rg_prof_end('totp_list'); |
|
287 |
|
return $ret; |
|
288 |
|
} |
|
289 |
|
|
240 |
290 |
/* |
/* |
241 |
291 |
* Validates a token |
* Validates a token |
242 |
292 |
* Also, it marks the tokens as 'confirmed' if needed |
* Also, it marks the tokens as 'confirmed' if needed |
|
... |
... |
function rg_totp_verify_all($db, $uid, $token) |
246 |
296 |
rg_prof_start('totp_verify_all'); |
rg_prof_start('totp_verify_all'); |
247 |
297 |
rg_log_enter('totp_verify_all token=' . $token); |
rg_log_enter('totp_verify_all token=' . $token); |
248 |
298 |
|
|
|
299 |
|
$now = time(); |
|
300 |
|
|
249 |
301 |
$ret = array(); |
$ret = array(); |
250 |
302 |
$ret['ok'] = 0; |
$ret['ok'] = 0; |
251 |
303 |
while (1) { |
while (1) { |
252 |
|
if (strlen($token) < 6) |
|
253 |
|
break; |
|
254 |
|
|
|
255 |
304 |
$lt = rg_totp_list($db, $uid); |
$lt = rg_totp_list($db, $uid); |
256 |
305 |
if ($lt['ok'] != 1) |
if ($lt['ok'] != 1) |
257 |
306 |
break; |
break; |
258 |
307 |
|
|
259 |
308 |
$ret['ok'] = 1; |
$ret['ok'] = 1; |
260 |
|
$ret['enrolled'] = 0; |
|
|
309 |
|
$ret['enrolled'] = empty($lt['list']) ? 0 : 1; |
261 |
310 |
$ret['id'] = 0; |
$ret['id'] = 0; |
262 |
311 |
$ret['conf_error'] = 0; |
$ret['conf_error'] = 0; |
263 |
|
foreach ($lt['list'] as $_id => $t) { |
|
264 |
|
$ret['enrolled'] = 1; |
|
|
312 |
|
$ret['tc'] = 0; |
|
313 |
|
|
|
314 |
|
if (strlen($token) < 6) |
|
315 |
|
break; |
265 |
316 |
|
|
266 |
|
$_r = rg_totp_verify($t['secret'], $token); |
|
267 |
|
if ($_r !== TRUE) |
|
|
317 |
|
foreach ($lt['list'] as $_id => $t) { |
|
318 |
|
$tc = rg_totp_verify($t['secret'], $now, $token); |
|
319 |
|
if ($tc === FALSE) |
268 |
320 |
continue; |
continue; |
269 |
321 |
|
|
|
322 |
|
if ($tc <= $t['last_used_tc']) { |
|
323 |
|
rg_totp_set_error('cannot reuse the login token'); |
|
324 |
|
break; |
|
325 |
|
} |
|
326 |
|
|
270 |
327 |
$ret['id'] = $t['id']; |
$ret['id'] = $t['id']; |
271 |
|
if (strcmp($t['conf'], 't') != 0) { |
|
272 |
|
$x = rg_totp_conf($db, $uid, $t['id']); |
|
273 |
|
if ($x !== TRUE) { |
|
274 |
|
$ret['conf_error'] = 1; |
|
275 |
|
break; |
|
276 |
|
} |
|
|
328 |
|
$ret['tc'] = $tc; |
|
329 |
|
|
|
330 |
|
// Mark it as used and update 'conf' status |
|
331 |
|
// TODO: Should we give error if we cannot update it? |
|
332 |
|
$r = rg_totp_set_last_use($db, $uid, $t['id'], $tc, $now); |
|
333 |
|
if ($r !== TRUE) { |
|
334 |
|
$ret['ok'] = 0; |
|
335 |
|
break; |
277 |
336 |
} |
} |
|
337 |
|
|
278 |
338 |
break; |
break; |
279 |
339 |
} |
} |
280 |
340 |
|
|
|
... |
... |
function rg_totp_enroll($db, $uid, $name, $secret, $ip, $conf) |
298 |
358 |
while (1) { |
while (1) { |
299 |
359 |
$params = array('uid' => $uid, 'name' => $name, |
$params = array('uid' => $uid, 'name' => $name, |
300 |
360 |
'secret' => $secret, |
'secret' => $secret, |
301 |
|
'itime' => time(), 'ip' => $ip, 'conf' => $conf); |
|
|
361 |
|
'itime' => time(), 'ip' => $ip, 'conf' => $conf, |
|
362 |
|
'last_used_tc' => 0); |
302 |
363 |
$sql = 'INSERT INTO login_tokens (uid, itime, name, secret, ip' |
$sql = 'INSERT INTO login_tokens (uid, itime, name, secret, ip' |
303 |
|
. ', conf)' |
|
|
364 |
|
. ', conf, last_used_tc)' |
304 |
365 |
. ' VALUES (@@uid@@, @@itime@@, @@name@@' |
. ' VALUES (@@uid@@, @@itime@@, @@name@@' |
305 |
|
. ', @@secret@@, @@ip@@, @@conf@@)' |
|
|
366 |
|
. ', @@secret@@, @@ip@@, @@conf@@, @@last_used_tc@@)' |
306 |
367 |
. ' RETURNING id'; |
. ' RETURNING id'; |
307 |
368 |
$res = rg_sql_query_params($db, $sql, $params); |
$res = rg_sql_query_params($db, $sql, $params); |
308 |
369 |
if ($res === FALSE) { |
if ($res === FALSE) { |
|
... |
... |
function rg_totp_del_ip($db, $uid, $ip) |
409 |
470 |
return $ret; |
return $ret; |
410 |
471 |
} |
} |
411 |
472 |
|
|
412 |
|
/* |
|
413 |
|
* Confirm a SSH enrollment process |
|
414 |
|
*/ |
|
415 |
|
function rg_totp_conf($db, $uid, $id) |
|
416 |
|
{ |
|
417 |
|
rg_prof_start('totp_conf'); |
|
418 |
|
rg_log_enter('totp_conf id=' . $id); |
|
419 |
|
|
|
420 |
|
$ret = FALSE; |
|
421 |
|
while (1) { |
|
422 |
|
$params = array('uid' => $uid, 'id' => $id, 'conf' => 't'); |
|
423 |
|
$sql = 'UPDATE login_tokens SET conf = @@conf@@' |
|
424 |
|
. ' WHERE uid = @@uid@@' |
|
425 |
|
. ' AND id = @@id@@' |
|
426 |
|
. ' AND conf != @@conf@@'; |
|
427 |
|
$res = rg_sql_query_params($db, $sql, $params); |
|
428 |
|
if ($res === FALSE) { |
|
429 |
|
rg_totp_set_error('cannot confirm login token; try again later'); |
|
430 |
|
break; |
|
431 |
|
} |
|
432 |
|
rg_sql_free_result($res); |
|
433 |
|
|
|
434 |
|
$key = 'user' . '::' . $uid . '::' . 'login_tokens' |
|
435 |
|
. '::' . 'list' . '::' . $params['id']; |
|
436 |
|
$a = array('conf' => 't'); |
|
437 |
|
rg_totp_cosmetic($params); |
|
438 |
|
rg_cache_merge($key, $a, RG_SOCKET_NO_WAIT); |
|
439 |
|
|
|
440 |
|
$ret = TRUE; |
|
441 |
|
break; |
|
442 |
|
} |
|
443 |
|
|
|
444 |
|
rg_log_exit(); |
|
445 |
|
rg_prof_end('totp_conf'); |
|
446 |
|
return $ret; |
|
447 |
|
} |
|
448 |
|
|
|
449 |
|
/* |
|
450 |
|
* Returns a list of login tokens from database |
|
451 |
|
*/ |
|
452 |
|
function rg_totp_list($db, $uid) |
|
453 |
|
{ |
|
454 |
|
rg_prof_start('totp_list'); |
|
455 |
|
rg_log_enter('totp_list'); |
|
456 |
|
|
|
457 |
|
while (1) { |
|
458 |
|
$key = 'user' . '::' . $uid . '::' . 'login_tokens'; |
|
459 |
|
$ret = rg_cache_get($key); |
|
460 |
|
if ($ret !== FALSE) { |
|
461 |
|
$ret['ok'] = 1; |
|
462 |
|
break; |
|
463 |
|
} |
|
464 |
|
|
|
465 |
|
$ret = array(); |
|
466 |
|
$ret['ok'] = 0; |
|
467 |
|
|
|
468 |
|
$params = array('uid' => $uid); |
|
469 |
|
$sql = 'SELECT * FROM login_tokens' |
|
470 |
|
. ' WHERE uid = @@uid@@' |
|
471 |
|
. ' ORDER BY itime'; |
|
472 |
|
$res = rg_sql_query_params($db, $sql, $params); |
|
473 |
|
if ($res === FALSE) { |
|
474 |
|
rg_totp_set_error('cannot load login tokens'); |
|
475 |
|
break; |
|
476 |
|
} |
|
477 |
|
|
|
478 |
|
$ret['list'] = array(); |
|
479 |
|
while (($row = rg_sql_fetch_array($res))) { |
|
480 |
|
$id = $row['id']; |
|
481 |
|
|
|
482 |
|
rg_totp_cosmetic($row); |
|
483 |
|
|
|
484 |
|
$ret['list'][$id] = $row; |
|
485 |
|
} |
|
486 |
|
rg_sql_free_result($res); |
|
487 |
|
|
|
488 |
|
rg_cache_set($key, $ret, RG_SOCKET_NO_WAIT); |
|
489 |
|
$ret['ok'] = 1; |
|
490 |
|
break; |
|
491 |
|
} |
|
492 |
|
|
|
493 |
|
rg_log_exit(); |
|
494 |
|
rg_prof_end('totp_list'); |
|
495 |
|
return $ret; |
|
496 |
|
} |
|
497 |
|
|
|
498 |
473 |
/* |
/* |
499 |
474 |
* Remove a list of login tokens |
* Remove a list of login tokens |
500 |
475 |
*/ |
*/ |
|
... |
... |
function rg_totp_list_ip($db, $uid) |
601 |
576 |
return $ret; |
return $ret; |
602 |
577 |
} |
} |
603 |
578 |
|
|
|
579 |
|
/* |
|
580 |
|
* Verifies that an IP is in the 'validated' list |
|
581 |
|
* Returns -1 on error, 0 if no IP were present and 1 if all is OK |
|
582 |
|
*/ |
|
583 |
|
function rg_totp_verify_ip($db, $uid, $ip) |
|
584 |
|
{ |
|
585 |
|
rg_prof_start('totp_verify_ip'); |
|
586 |
|
rg_log_enter('totp_verify_ip ip=' . $ip); |
|
587 |
|
|
|
588 |
|
$ret = array(); |
|
589 |
|
$ret['ok'] = -1; |
|
590 |
|
$ret['enrolled'] = 1; |
|
591 |
|
while (1) { |
|
592 |
|
// we will return OK if user is not enrolled |
|
593 |
|
$r = rg_totp_list($db, $uid); |
|
594 |
|
if ($r['ok'] != 1) |
|
595 |
|
break; |
|
596 |
|
if (empty($r['list'])) { |
|
597 |
|
$ret['ok'] = 1; |
|
598 |
|
$ret['enrolled'] = 0; |
|
599 |
|
break; |
|
600 |
|
} |
|
601 |
|
|
|
602 |
|
$r = rg_totp_list_ip($db, $uid); |
|
603 |
|
if ($r['ok'] != 1) |
|
604 |
|
break; |
|
605 |
|
|
|
606 |
|
$ret['ok'] = 0; |
|
607 |
|
foreach ($r['list'] as $t) { |
|
608 |
|
if (strcasecmp($t['ip'], $ip) == 0) { |
|
609 |
|
$ret['list'] = $r['list']; |
|
610 |
|
$ret['ok'] = 1; |
|
611 |
|
break; |
|
612 |
|
} |
|
613 |
|
} |
|
614 |
|
|
|
615 |
|
if ($ret['ok'] == 0) |
|
616 |
|
rg_totp_set_error('you have no IP validated;' |
|
617 |
|
. ' run \'ssh ... totp\' for help'); |
|
618 |
|
|
|
619 |
|
break; |
|
620 |
|
} |
|
621 |
|
|
|
622 |
|
rg_log_exit(); |
|
623 |
|
rg_prof_end('totp_verify_ip'); |
|
624 |
|
return $ret; |
|
625 |
|
} |
|
626 |
|
|
604 |
627 |
/* |
/* |
605 |
628 |
* High-level function for listing tokens |
* High-level function for listing tokens |
606 |
629 |
*/ |
*/ |
|
... |
... |
function rg_totp_high_level($db, $rg) |
658 |
681 |
rg_prof_start('totp_high_level'); |
rg_prof_start('totp_high_level'); |
659 |
682 |
rg_log_enter('totp_high_level'); |
rg_log_enter('totp_high_level'); |
660 |
683 |
|
|
|
684 |
|
$now = time(); |
|
685 |
|
|
661 |
686 |
$rg['totp'] = array(); |
$rg['totp'] = array(); |
662 |
687 |
|
|
663 |
688 |
$ret = ''; |
$ret = ''; |
|
... |
... |
function rg_totp_high_level($db, $rg) |
691 |
716 |
break; |
break; |
692 |
717 |
} |
} |
693 |
718 |
|
|
694 |
|
$r = rg_totp_verify($secret, $ver); |
|
|
719 |
|
$r = rg_totp_verify($secret, $now, $ver); |
695 |
720 |
if ($r === FALSE) { |
if ($r === FALSE) { |
696 |
721 |
$errmsg[] = rg_template('user/settings/totp/ver_error.html', |
$errmsg[] = rg_template('user/settings/totp/ver_error.html', |
697 |
722 |
$rg, TRUE /*xss*/); |
$rg, TRUE /*xss*/); |
File inc/user.inc.php changed (mode: 100644) (index 0874f6b..6ca3783) |
... |
... |
function rg_user_event_login($db, $event) |
78 |
78 |
if ($r !== TRUE) |
if ($r !== TRUE) |
79 |
79 |
break; |
break; |
80 |
80 |
|
|
81 |
|
if ($event['used_login_token_id'] > 0) { |
|
82 |
|
$r = rg_totp_set_last_use($db, $event['uid'], |
|
83 |
|
$event['used_login_token_id'], $event['ts']); |
|
84 |
|
if ($r !== TRUE) |
|
85 |
|
break; |
|
86 |
|
} |
|
87 |
|
|
|
88 |
81 |
$ret = array(); |
$ret = array(); |
89 |
82 |
break; |
break; |
90 |
83 |
} |
} |
|
... |
... |
function rg_user_edit($db, $d) |
517 |
510 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
518 |
511 |
|
|
519 |
512 |
if ($d['uid'] == 0) { // add |
if ($d['uid'] == 0) { // add |
520 |
|
rg_cache_set('user::' . $d['uid'], $d, RG_SOCKET_NO_WAIT); |
|
|
513 |
|
rg_cache_set('user' . '::' . $d['uid'] . '::' . ':info', |
|
514 |
|
$d, RG_SOCKET_NO_WAIT); |
521 |
515 |
|
|
522 |
516 |
$event = array('category' => 2000, 'prio' => 50, |
$event = array('category' => 2000, 'prio' => 50, |
523 |
517 |
'ui' => array( |
'ui' => array( |
|
... |
... |
function rg_user_edit($db, $d) |
540 |
534 |
if (!$update_pass) |
if (!$update_pass) |
541 |
535 |
unset($d['pass']); |
unset($d['pass']); |
542 |
536 |
unset($d['pass2']); // not needed in cache |
unset($d['pass2']); // not needed in cache |
543 |
|
rg_cache_merge('user::' . $d['uid'], $d, RG_SOCKET_NO_WAIT); |
|
|
537 |
|
rg_cache_merge('user' . '::' . $d['uid'] . '::' . 'info', |
|
538 |
|
$d, RG_SOCKET_NO_WAIT); |
544 |
539 |
} |
} |
545 |
540 |
|
|
546 |
541 |
// TODO: should we cache here the user_by_uid and user_by_name |
// TODO: should we cache here the user_by_uid and user_by_name |
|
... |
... |
function rg_user_remove($db, $rg, $uid) |
586 |
581 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
587 |
582 |
|
|
588 |
583 |
// invalidate cache |
// invalidate cache |
589 |
|
rg_cache_unset('user::' . $uid, RG_SOCKET_NO_WAIT); |
|
|
584 |
|
rg_cache_unset('user' . '::' . $uid . 'info', RG_SOCKET_NO_WAIT); |
590 |
585 |
|
|
591 |
586 |
$ret = TRUE; |
$ret = TRUE; |
592 |
587 |
break; |
break; |
|
... |
... |
function rg_user_info($db, $uid, $user, $email) |
617 |
612 |
"email" => $email); |
"email" => $email); |
618 |
613 |
|
|
619 |
614 |
if ($uid > 0) { |
if ($uid > 0) { |
620 |
|
$c = rg_cache_get("user::" . $uid); |
|
|
615 |
|
// We will get all info about fthe user not only 'info' |
|
616 |
|
// to populate the cache with all info. |
|
617 |
|
$c = rg_cache_get('user' . '::' . $uid); |
621 |
618 |
if ($c !== FALSE) { |
if ($c !== FALSE) { |
622 |
|
$ret = $c; |
|
623 |
|
break; |
|
|
619 |
|
if (isset($c['info'])) { |
|
620 |
|
$ret = $c['info']; |
|
621 |
|
break; |
|
622 |
|
} |
624 |
623 |
} |
} |
625 |
624 |
|
|
626 |
625 |
$sql = "SELECT * FROM users WHERE uid = @@uid@@"; |
$sql = "SELECT * FROM users WHERE uid = @@uid@@"; |
|
... |
... |
function rg_user_info($db, $uid, $user, $email) |
668 |
667 |
$ret = array_merge($ret, $row); |
$ret = array_merge($ret, $row); |
669 |
668 |
$ret['exists'] = 1; |
$ret['exists'] = 1; |
670 |
669 |
|
|
671 |
|
rg_cache_set("user::" . $ret['uid'], $ret, RG_SOCKET_NO_WAIT); |
|
|
670 |
|
rg_cache_set('user' . '::' . $ret['uid'] . '::' . 'info', |
|
671 |
|
$ret, RG_SOCKET_NO_WAIT); |
672 |
672 |
rg_cache_set('username_to_uid::' . $ret['username'], |
rg_cache_set('username_to_uid::' . $ret['username'], |
673 |
673 |
$ret['uid'], RG_SOCKET_NO_WAIT); |
$ret['uid'], RG_SOCKET_NO_WAIT); |
674 |
674 |
rg_cache_set('email_to_uid::' . $ret['email'], $ret['uid'], |
rg_cache_set('email_to_uid::' . $ret['email'], $ret['uid'], |
|
... |
... |
function rg_user_set_last_seen($db, $uid, $ts, $ip) |
704 |
704 |
} |
} |
705 |
705 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
706 |
706 |
|
|
707 |
|
rg_cache_merge("user::" . $uid, $params, RG_SOCKET_NO_WAIT); |
|
|
707 |
|
rg_cache_merge('user' . '::' . $uid . '::' . 'info', |
|
708 |
|
$params, RG_SOCKET_NO_WAIT); |
708 |
709 |
|
|
709 |
710 |
$ret = TRUE; |
$ret = TRUE; |
710 |
711 |
break; |
break; |
|
... |
... |
function rg_user_login_by_sid($db, &$rg) |
767 |
768 |
*/ |
*/ |
768 |
769 |
function rg_user_pass_valid($db, $uid, $pass) |
function rg_user_pass_valid($db, $uid, $pass) |
769 |
770 |
{ |
{ |
770 |
|
rg_log_enter("user_pass_valid: uid=$uid, pass=$pass..."); |
|
|
771 |
|
rg_log_enter("user_pass_valid: uid=$uid"); |
771 |
772 |
|
|
772 |
773 |
$ret = FALSE; |
$ret = FALSE; |
773 |
774 |
while (1) { |
while (1) { |
|
... |
... |
function rg_user_login_by_user_pass($db, $user, $pass, $login_token, $lock_ip, |
857 |
858 |
&$ui) |
&$ui) |
858 |
859 |
{ |
{ |
859 |
860 |
rg_prof_start("user_login_by_user_pass"); |
rg_prof_start("user_login_by_user_pass"); |
860 |
|
rg_log_enter("user_login_by_user_pass: user=$user, pass=$pass" |
|
|
861 |
|
rg_log_enter("user_login_by_user_pass: user=$user" |
861 |
862 |
. " login_token=$login_token lock_ip=$lock_ip"); |
. " login_token=$login_token lock_ip=$lock_ip"); |
862 |
863 |
|
|
863 |
864 |
$ui = array(); |
$ui = array(); |
|
... |
... |
function rg_user_login_by_user_pass($db, $user, $pass, $login_token, $lock_ip, |
868 |
869 |
$ret = FALSE; |
$ret = FALSE; |
869 |
870 |
while (1) { |
while (1) { |
870 |
871 |
if (empty($user) || empty($pass)) { |
if (empty($user) || empty($pass)) { |
871 |
|
rg_user_set_error("invalid user, pass or login_token"); |
|
|
872 |
|
rg_user_set_error("invalid user, pass or login token"); |
872 |
873 |
rg_log("user or pass are empty"); |
rg_log("user or pass are empty"); |
873 |
874 |
break; |
break; |
874 |
875 |
} |
} |
|
... |
... |
function rg_user_login_by_user_pass($db, $user, $pass, $login_token, $lock_ip, |
877 |
878 |
if ($ui0['ok'] != 1) |
if ($ui0['ok'] != 1) |
878 |
879 |
break; |
break; |
879 |
880 |
if ($ui0['exists'] != 1) { |
if ($ui0['exists'] != 1) { |
880 |
|
rg_user_set_error("invalid user, pass or login_token"); |
|
|
881 |
|
rg_user_set_error("invalid user, pass or login token"); |
881 |
882 |
rg_log("user doesn't exists"); |
rg_log("user doesn't exists"); |
882 |
883 |
break; |
break; |
883 |
884 |
} |
} |
884 |
885 |
|
|
885 |
886 |
if ($ui0['suspended'] > 0) { |
if ($ui0['suspended'] > 0) { |
886 |
|
rg_user_set_error("invalid user, pass or login_token"); |
|
|
887 |
|
rg_user_set_error("invalid user, pass or login token"); |
887 |
888 |
rg_log("account is suspended"); |
rg_log("account is suspended"); |
888 |
889 |
break; |
break; |
889 |
890 |
} |
} |
890 |
891 |
|
|
891 |
892 |
if ($ui0['confirmed'] == 0) { |
if ($ui0['confirmed'] == 0) { |
892 |
|
rg_user_set_error("invalid user, pass or login_token"); |
|
|
893 |
|
rg_user_set_error("invalid user, pass or login token"); |
893 |
894 |
rg_log("account is not confirmed"); |
rg_log("account is not confirmed"); |
894 |
895 |
break; |
break; |
895 |
896 |
} |
} |
|
... |
... |
function rg_user_login_by_user_pass($db, $user, $pass, $login_token, $lock_ip, |
906 |
907 |
rg_user_set_error('login token error: ' . rg_totp_error()); |
rg_user_set_error('login token error: ' . rg_totp_error()); |
907 |
908 |
break; |
break; |
908 |
909 |
} |
} |
|
910 |
|
//rg_log_ml('DEBUG: vi: ' . print_r($vi, TRUE)); |
909 |
911 |
if (($vi['enrolled'] == 1) && ($vi['id'] == 0)) { |
if (($vi['enrolled'] == 1) && ($vi['id'] == 0)) { |
910 |
|
rg_user_set_error('invalid user, pass or login_token'); |
|
|
912 |
|
rg_user_set_error('invalid user, pass or login token'); |
911 |
913 |
rg_log('invalid token'); |
rg_log('invalid token'); |
912 |
914 |
break; |
break; |
913 |
915 |
} |
} |
|
... |
... |
function rg_user_login_by_user_pass($db, $user, $pass, $login_token, $lock_ip, |
916 |
918 |
'category' => 2001, |
'category' => 2001, |
917 |
919 |
'prio' => 100, |
'prio' => 100, |
918 |
920 |
'uid' => $ui0['uid'], |
'uid' => $ui0['uid'], |
919 |
|
'used_login_token_id' => $vi['id'], |
|
920 |
921 |
'ts' => time()); |
'ts' => time()); |
921 |
922 |
$r = rg_event_add($db, $event); |
$r = rg_event_add($db, $event); |
922 |
923 |
if ($r !== TRUE) { |
if ($r !== TRUE) { |
|
... |
... |
function rg_user_suspend($db, $rg, $uid, $op) |
979 |
980 |
|
|
980 |
981 |
// update cache |
// update cache |
981 |
982 |
// TODO: what if we cannot update? |
// TODO: what if we cannot update? |
982 |
|
rg_cache_set("user::" . $uid . "::suspended", $v, RG_SOCKET_NO_WAIT); |
|
|
983 |
|
rg_cache_set('user' . '::' . $uid . '::' . 'info' |
|
984 |
|
. '::' . 'suspended', $v, RG_SOCKET_NO_WAIT); |
983 |
985 |
|
|
984 |
986 |
break; |
break; |
985 |
987 |
} |
} |
|
... |
... |
function rg_user_make_admin($db, $rg, $uid, $op) |
1021 |
1023 |
} |
} |
1022 |
1024 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
1023 |
1025 |
|
|
1024 |
|
rg_cache_set("user::" . $uid . "::is_admin", 1, RG_SOCKET_NO_WAIT); |
|
|
1026 |
|
rg_cache_set('user' . '::' . $uid . '::' . 'info' |
|
1027 |
|
. '::' . 'is_admin', 1, RG_SOCKET_NO_WAIT); |
1025 |
1028 |
|
|
1026 |
1029 |
$ret = TRUE; |
$ret = TRUE; |
1027 |
1030 |
break; |
break; |
|
... |
... |
function rg_user_forgot_pass_destroy($db, $uid) |
1306 |
1309 |
function rg_user_set_pass($db, $uid, $pass) |
function rg_user_set_pass($db, $uid, $pass) |
1307 |
1310 |
{ |
{ |
1308 |
1311 |
rg_prof_start("user_set_pass"); |
rg_prof_start("user_set_pass"); |
1309 |
|
rg_log_enter("user_set_pass: uid=$uid pass=$pass"); |
|
|
1312 |
|
rg_log_enter("user_set_pass: uid=$uid"); |
1310 |
1313 |
|
|
1311 |
1314 |
$ret = FALSE; |
$ret = FALSE; |
1312 |
1315 |
while (1) { |
while (1) { |
|
... |
... |
function rg_user_set_pass($db, $uid, $pass) |
1327 |
1330 |
} |
} |
1328 |
1331 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
1329 |
1332 |
|
|
1330 |
|
rg_cache_merge('user::' . $uid, $params, RG_SOCKET_NO_WAIT); |
|
|
1333 |
|
rg_cache_merge('user' . '::' . $uid . '::' . 'info', |
|
1334 |
|
$params, RG_SOCKET_NO_WAIT); |
1331 |
1335 |
|
|
1332 |
1336 |
$ret = TRUE; |
$ret = TRUE; |
1333 |
1337 |
break; |
break; |
|
... |
... |
function rg_user_confirm($db, $token) |
1385 |
1389 |
} |
} |
1386 |
1390 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
1387 |
1391 |
|
|
1388 |
|
rg_cache_merge('user::' . $uid, $params, RG_SOCKET_NO_WAIT); |
|
|
1392 |
|
rg_cache_merge('user' . '::' . $uid . '::' . 'info', |
|
1393 |
|
$params, RG_SOCKET_NO_WAIT); |
1389 |
1394 |
|
|
1390 |
1395 |
$ret = $uid; |
$ret = $uid; |
1391 |
1396 |
break; |
break; |
File inc/util.inc.php changed (mode: 100644) (index 1671051..94d70e8) |
... |
... |
function rg_copy_tree($src, $dst, $mask) |
1147 |
1147 |
global $php_errormsg; |
global $php_errormsg; |
1148 |
1148 |
|
|
1149 |
1149 |
rg_prof_start("copy_tree"); |
rg_prof_start("copy_tree"); |
1150 |
|
rg_log_enter("rg_copy_tree($src, $dst, $mask)"); |
|
|
1150 |
|
rg_log_enter("copy_tree($src, $dst, $mask)"); |
1151 |
1151 |
|
|
1152 |
1152 |
$ret = FALSE; |
$ret = FALSE; |
1153 |
1153 |
while (1) { |
while (1) { |
1154 |
1154 |
if (!is_dir($dst)) { |
if (!is_dir($dst)) { |
1155 |
|
$r = @mkdir($dst, $mask); |
|
|
1155 |
|
$r = @mkdir($dst, $mask, TRUE); |
1156 |
1156 |
if ($r !== TRUE) { |
if ($r !== TRUE) { |
1157 |
1157 |
rg_log("ERROR: Cannot mkdir [$dst] ($php_errormsg)."); |
rg_log("ERROR: Cannot mkdir [$dst] ($php_errormsg)."); |
1158 |
1158 |
break; |
break; |
|
... |
... |
function rg_copy_tree($src, $dst, $mask) |
1198 |
1198 |
return $ret; |
return $ret; |
1199 |
1199 |
} |
} |
1200 |
1200 |
|
|
|
1201 |
|
/* |
|
1202 |
|
* Recursively deletes a tree |
|
1203 |
|
*/ |
|
1204 |
|
function rg_del_tree($dst) |
|
1205 |
|
{ |
|
1206 |
|
global $php_errormsg; |
|
1207 |
|
|
|
1208 |
|
rg_prof_start('del_tree'); |
|
1209 |
|
rg_log_enter('del_tree(' . $dst . ')'); |
|
1210 |
|
|
|
1211 |
|
$ret = FALSE; |
|
1212 |
|
while (1) { |
|
1213 |
|
if (!is_dir($dst)) |
|
1214 |
|
break; |
|
1215 |
|
|
|
1216 |
|
$d = rg_dir_load($dst); |
|
1217 |
|
$err = FALSE; |
|
1218 |
|
foreach ($d as $obj) { |
|
1219 |
|
if (is_dir($dst . '/' . $obj)) { |
|
1220 |
|
$r = rg_del_tree($dst . '/' . $obj); |
|
1221 |
|
if ($r !== TRUE) { |
|
1222 |
|
$err = TRUE; |
|
1223 |
|
break; |
|
1224 |
|
} |
|
1225 |
|
} else { |
|
1226 |
|
$r = @unlink($dst . '/' . $obj); |
|
1227 |
|
if ($r !== TRUE) { |
|
1228 |
|
rg_log("ERROR: Cannot del file ($php_errormsg)."); |
|
1229 |
|
$err = TRUE; |
|
1230 |
|
break; |
|
1231 |
|
} |
|
1232 |
|
} |
|
1233 |
|
} |
|
1234 |
|
|
|
1235 |
|
$r = @rmdir($dst); |
|
1236 |
|
if ($r !== TRUE) { |
|
1237 |
|
rg_log("ERROR: Cannot del dir ($php_errormsg)."); |
|
1238 |
|
$err = TRUE; |
|
1239 |
|
break; |
|
1240 |
|
} |
|
1241 |
|
|
|
1242 |
|
if (!$err) |
|
1243 |
|
$ret = TRUE; |
|
1244 |
|
break; |
|
1245 |
|
} |
|
1246 |
|
|
|
1247 |
|
rg_log_exit(); |
|
1248 |
|
rg_prof_end('del_tree'); |
|
1249 |
|
return $ret; |
|
1250 |
|
} |
|
1251 |
|
|
1201 |
1252 |
/* |
/* |
1202 |
1253 |
* Called by PHP in case of error |
* Called by PHP in case of error |
1203 |
1254 |
*/ |
*/ |
|
... |
... |
function rg_mail_template($template, $more) |
1290 |
1341 |
. base64_encode($rg_admin_name) . "?="; |
. base64_encode($rg_admin_name) . "?="; |
1291 |
1342 |
|
|
1292 |
1343 |
$subject = rg_template($template . ".subj.txt", $more, FALSE /* xss */); |
$subject = rg_template($template . ".subj.txt", $more, FALSE /* xss */); |
1293 |
|
$subject = "=?UTF-8?B?" . base64_encode(trim($subject)) . "?="; |
|
|
1344 |
|
$subject = trim($subject); |
|
1345 |
|
$subject = str_replace("\r", '', $subject); |
|
1346 |
|
$subject = str_replace("\n", '', $subject); |
|
1347 |
|
// TODO: do not encode it as UTF-8 if not needed |
|
1348 |
|
$subject = "=?UTF-8?B?" . base64_encode($subject) . "?="; |
|
1349 |
|
|
1294 |
1350 |
$header = rg_template("mail/common.head.txt", $more, FALSE /* xss */); |
$header = rg_template("mail/common.head.txt", $more, FALSE /* xss */); |
1295 |
1351 |
$header .= rg_template($template . ".head.txt", $more, FALSE /* xss */); |
$header .= rg_template($template . ".head.txt", $more, FALSE /* xss */); |
1296 |
1352 |
$header = trim($header); |
$header = trim($header); |
|
1353 |
|
|
1297 |
1354 |
$body = rg_template($template . ".body.txt", $more, FALSE /* xss */); |
$body = rg_template($template . ".body.txt", $more, FALSE /* xss */); |
1298 |
1355 |
|
|
1299 |
1356 |
rg_log("CHECK: mail_template(" . $more['ui']['email'] . ", |
rg_log("CHECK: mail_template(" . $more['ui']['email'] . ", |
|
... |
... |
function rg_socket_recv_wait($socket, $wait, $timeout) |
1349 |
1406 |
$tv_usec = ($timeout % 1000) * 1000; |
$tv_usec = ($timeout % 1000) * 1000; |
1350 |
1407 |
} |
} |
1351 |
1408 |
|
|
1352 |
|
$ret_buf = ""; |
|
|
1409 |
|
$ret_buf = ''; |
1353 |
1410 |
while (1) { |
while (1) { |
1354 |
1411 |
$reads = array($socket); $writes = array(); $ex = array(); |
$reads = array($socket); $writes = array(); $ex = array(); |
1355 |
1412 |
$r = @socket_select($reads, $writes, $ex, $tv_sec, $tv_usec); |
$r = @socket_select($reads, $writes, $ex, $tv_sec, $tv_usec); |
1356 |
1413 |
if ($r === FALSE) { |
if ($r === FALSE) { |
1357 |
|
rg_log("Cannot select(" . socket_strerror(socket_last_error()) . ")!"); |
|
|
1414 |
|
rg_log('Cannot select(' . socket_strerror(socket_last_error()) . ')!'); |
1358 |
1415 |
break; |
break; |
1359 |
1416 |
} |
} |
1360 |
1417 |
|
|
1361 |
1418 |
if ($r === 0) { // timeout |
if ($r === 0) { // timeout |
1362 |
|
rg_log("Timeout in reading!"); |
|
|
1419 |
|
rg_log('Timeout in reading!'); |
1363 |
1420 |
break; |
break; |
1364 |
1421 |
} |
} |
1365 |
1422 |
|
|
1366 |
1423 |
if (!in_array($socket, $reads)) { |
if (!in_array($socket, $reads)) { |
1367 |
|
rg_log("Select returned > 0 and my socket is not in reads"); |
|
|
1424 |
|
rg_log('Select returned > 0 and my socket is not in reads'); |
1368 |
1425 |
break; |
break; |
1369 |
1426 |
} |
} |
1370 |
1427 |
|
|
1371 |
1428 |
$r = @socket_recv($socket, $buf, 32 * 4096, 0); |
$r = @socket_recv($socket, $buf, 32 * 4096, 0); |
1372 |
1429 |
if ($r === FALSE) { |
if ($r === FALSE) { |
1373 |
|
rg_log("Cannot receive(" . socket_strerror(socket_last_error()) . ")!"); |
|
|
1430 |
|
rg_log('Cannot receive (' . socket_strerror(socket_last_error()) . ')!'); |
1374 |
1431 |
break; |
break; |
1375 |
1432 |
} |
} |
1376 |
1433 |
//rg_log("Received [$buf]"); |
//rg_log("Received [$buf]"); |
File scripts/cache.php changed (mode: 100644) (index bd7e87d..6acc008) |
... |
... |
function rg_handle_command($k, &$conn_table, $cmd) |
47 |
47 |
|
|
48 |
48 |
$s = &$conn_table['conns'][$k]; |
$s = &$conn_table['conns'][$k]; |
49 |
49 |
|
|
50 |
|
$a = explode(" ", $cmd, 3); |
|
|
50 |
|
$a = explode(' ', $cmd, 4); |
51 |
51 |
$buf = "ER Invalid command\n"; |
$buf = "ER Invalid command\n"; |
52 |
52 |
$no_wait = FALSE; |
$no_wait = FALSE; |
53 |
53 |
while (1) { |
while (1) { |
54 |
|
// We must have at least 2 parameters: cmd and flags |
|
55 |
|
if (!isset($a[1])) |
|
|
54 |
|
// We must have at least 2 parameters: cmd and flags and I |
|
55 |
|
if (!isset($a[2])) |
56 |
56 |
break; |
break; |
57 |
57 |
|
|
58 |
58 |
$cmd = trim($a[0]); |
$cmd = trim($a[0]); |
|
59 |
|
|
59 |
60 |
$flags = trim($a[1]); |
$flags = trim($a[1]); |
60 |
61 |
if (strncmp($flags, 'F=', 2) != 0) { |
if (strncmp($flags, 'F=', 2) != 0) { |
61 |
62 |
rg_log('Invalid command (no flags): $cmd'); |
rg_log('Invalid command (no flags): $cmd'); |
|
... |
... |
function rg_handle_command($k, &$conn_table, $cmd) |
65 |
66 |
if (strstr($flags, 'W')) |
if (strstr($flags, 'W')) |
66 |
67 |
$no_wait = TRUE; |
$no_wait = TRUE; |
67 |
68 |
|
|
|
69 |
|
$id = trim($a[2]); |
|
70 |
|
if (strncmp($id, 'I=', 2) != 0) { |
|
71 |
|
rg_log('Invalid command (no id): $cmd'); |
|
72 |
|
break; |
|
73 |
|
} |
|
74 |
|
$id = substr($id, 2); |
|
75 |
|
|
68 |
76 |
/* From here, commands with no parameters */ |
/* From here, commands with no parameters */ |
|
77 |
|
/* none yet */ |
69 |
78 |
|
|
70 |
79 |
/* From here, at least 1 para */ |
/* From here, at least 1 para */ |
71 |
|
if (!isset($a[2])) |
|
|
80 |
|
if (!isset($a[3])) |
72 |
81 |
break; |
break; |
73 |
|
$para1 = trim($a[2]); |
|
|
82 |
|
$para1 = trim($a[3]); |
74 |
83 |
|
|
75 |
84 |
if (strcmp($cmd, "SET") == 0) { |
if (strcmp($cmd, "SET") == 0) { |
76 |
85 |
$ns_var_value = explode("=", $para1, 2); |
$ns_var_value = explode("=", $para1, 2); |
|
... |
... |
function rg_handle_command($k, &$conn_table, $cmd) |
81 |
90 |
$value = unserialize(stripcslashes($value)); |
$value = unserialize(stripcslashes($value)); |
82 |
91 |
if ($value !== FALSE) { |
if ($value !== FALSE) { |
83 |
92 |
rg_cache_core_set("normal::" . $ns_var, $value); |
rg_cache_core_set("normal::" . $ns_var, $value); |
84 |
|
$buf = "OK\n"; |
|
|
93 |
|
$buf = 'OK ' . $id . "\n"; |
85 |
94 |
} else { |
} else { |
86 |
|
$buf = "ER cannot unserialize data\n"; |
|
|
95 |
|
$buf = 'ER ' . $id . ' cannot unserialize data' . "\n"; |
87 |
96 |
} |
} |
88 |
97 |
break; |
break; |
89 |
98 |
} |
} |
|
... |
... |
function rg_handle_command($k, &$conn_table, $cmd) |
99 |
108 |
$ret = rg_cache_core_merge("normal::" . $ns_var, |
$ret = rg_cache_core_merge("normal::" . $ns_var, |
100 |
109 |
$value); |
$value); |
101 |
110 |
if ($ret === FALSE) |
if ($ret === FALSE) |
102 |
|
$buf = "NOT_FOUND\n"; |
|
|
111 |
|
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
103 |
112 |
else |
else |
104 |
|
$buf = "OK\n"; |
|
|
113 |
|
$buf = 'OK ' . $id . "\n"; |
105 |
114 |
} else { |
} else { |
106 |
|
$buf = "ER cannot unserialize data\n"; |
|
|
115 |
|
$buf = 'ER ' . $id . 'cannot unserialize data' . "\n"; |
107 |
116 |
} |
} |
108 |
117 |
break; |
break; |
109 |
118 |
} |
} |
110 |
119 |
|
|
111 |
120 |
if (strcmp($cmd, "INC") == 0) { |
if (strcmp($cmd, "INC") == 0) { |
112 |
121 |
$v = rg_cache_core_inc("normal::" . $para1); |
$v = rg_cache_core_inc("normal::" . $para1); |
113 |
|
$buf = "OK v=$v\n"; |
|
|
122 |
|
$buf = 'OK ' . $id . ' v=' . $v . "\n"; |
114 |
123 |
break; |
break; |
115 |
124 |
} |
} |
116 |
125 |
|
|
117 |
126 |
if (strcmp($cmd, "GET") == 0) { |
if (strcmp($cmd, "GET") == 0) { |
118 |
127 |
$ret = rg_cache_core_get("normal::" . $para1); |
$ret = rg_cache_core_get("normal::" . $para1); |
119 |
128 |
if ($ret === FALSE) |
if ($ret === FALSE) |
120 |
|
$buf = "NOT_FOUND\n"; |
|
|
129 |
|
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
121 |
130 |
else |
else |
122 |
|
$buf = "OK " . rg_cache_prepare($ret) . "\n"; |
|
|
131 |
|
$buf = 'OK ' . $id . ' ' . rg_cache_prepare($ret) . "\n"; |
123 |
132 |
break; |
break; |
124 |
133 |
} |
} |
125 |
134 |
|
|
126 |
135 |
if (strcmp($cmd, "UNSET") == 0) { |
if (strcmp($cmd, "UNSET") == 0) { |
127 |
136 |
$ret = rg_cache_core_unset("normal::" . $para1); |
$ret = rg_cache_core_unset("normal::" . $para1); |
128 |
137 |
if ($ret === FALSE) |
if ($ret === FALSE) |
129 |
|
$buf = "NOT_FOUND\n"; |
|
|
138 |
|
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
130 |
139 |
else |
else |
131 |
|
$buf = "OK\n"; |
|
|
140 |
|
$buf = 'OK ' . $id . "\n"; |
132 |
141 |
break; |
break; |
133 |
142 |
} |
} |
134 |
143 |
|
|
135 |
144 |
if (strcmp($cmd, "ADUMP") == 0) { |
if (strcmp($cmd, "ADUMP") == 0) { |
136 |
145 |
$ret = rg_cache_core_adump("normal::" . $para1); |
$ret = rg_cache_core_adump("normal::" . $para1); |
137 |
146 |
if ($ret === FALSE) |
if ($ret === FALSE) |
138 |
|
$buf = "NOT_FOUND\n"; |
|
|
147 |
|
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
139 |
148 |
else |
else |
140 |
|
$buf = "OK " . rg_cache_prepare($ret) . "\n"; |
|
|
149 |
|
$buf = 'OK ' . $id . ' ' . rg_cache_prepare($ret) . "\n"; |
141 |
150 |
break; |
break; |
142 |
151 |
} |
} |
143 |
152 |
|
|
|
... |
... |
function rg_handle_command($k, &$conn_table, $cmd) |
150 |
159 |
$value = unserialize(stripcslashes($value)); |
$value = unserialize(stripcslashes($value)); |
151 |
160 |
if ($value !== FALSE) { |
if ($value !== FALSE) { |
152 |
161 |
rg_cache_core_apush("normal::" . $ns_var, $value); |
rg_cache_core_apush("normal::" . $ns_var, $value); |
153 |
|
$buf = "OK\n"; |
|
|
162 |
|
$buf = 'OK ' . $id . "\n"; |
154 |
163 |
} else { |
} else { |
155 |
|
$buf = "ER cannot unserialize data\n"; |
|
|
164 |
|
$buf = 'ER ' . $id . ' cannot unserialize data' . "\n"; |
156 |
165 |
} |
} |
157 |
166 |
break; |
break; |
158 |
167 |
} |
} |
|
... |
... |
function rg_handle_command($k, &$conn_table, $cmd) |
160 |
169 |
if (strcmp($cmd, "APOP") == 0) { |
if (strcmp($cmd, "APOP") == 0) { |
161 |
170 |
$ret = rg_cache_core_apop("normal::" . $para1); |
$ret = rg_cache_core_apop("normal::" . $para1); |
162 |
171 |
if ($ret === FALSE) |
if ($ret === FALSE) |
163 |
|
$buf = "NOT_FOUND\n"; |
|
|
172 |
|
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
164 |
173 |
else |
else |
165 |
|
$buf = "OK " . $ret . "\n"; |
|
|
174 |
|
$buf = 'OK ' . $id . ' ' . $ret . "\n"; |
166 |
175 |
break; |
break; |
167 |
176 |
} |
} |
168 |
177 |
|
|
169 |
178 |
if (strcmp($cmd, "ASHIFT") == 0) { |
if (strcmp($cmd, "ASHIFT") == 0) { |
170 |
179 |
$ret = rg_cache_core_ashift("normal::" . $para1); |
$ret = rg_cache_core_ashift("normal::" . $para1); |
171 |
180 |
if ($ret === FALSE) |
if ($ret === FALSE) |
172 |
|
$buf = "NOT_FOUND\n"; |
|
|
181 |
|
$buf = 'ER ' . $id . ' NOT_FOUND' . "\n"; |
173 |
182 |
else |
else |
174 |
|
$buf = "OK " . $ret . "\n"; |
|
|
183 |
|
$buf = 'OK ' . $id . ' ' . $ret . "\n"; |
175 |
184 |
break; |
break; |
176 |
185 |
} |
} |
177 |
186 |
|
|
|
187 |
|
if (strcmp($cmd, "SHUTDOWN") == 0) { |
|
188 |
|
rg_log('Shutting down...'); |
|
189 |
|
exit(0); |
|
190 |
|
} |
|
191 |
|
|
|
192 |
|
if (strcmp($cmd, "SLEEP") == 0) { |
|
193 |
|
rg_log('Sleeping...'); |
|
194 |
|
$buf = 'OK ' . $id . "\n"; |
|
195 |
|
sleep(1); |
|
196 |
|
} |
|
197 |
|
|
178 |
198 |
break; |
break; |
179 |
199 |
} |
} |
180 |
200 |
|
|
File scripts/remote.php changed (mode: 100644) (index abcc609..75d88ff) |
1 |
1 |
<?php |
<?php |
2 |
|
// This is called by a remote client that does push or fetch |
|
|
2 |
|
// It is called by a remote client that does a push/fetch by git/ssh. |
3 |
3 |
error_reporting(E_ALL); |
error_reporting(E_ALL); |
4 |
4 |
ini_set("track_errors", "On"); |
ini_set("track_errors", "On"); |
5 |
5 |
|
|
|
... |
... |
function info($str) |
40 |
40 |
|
|
41 |
41 |
function fatal($str) |
function fatal($str) |
42 |
42 |
{ |
{ |
43 |
|
info("FATAL ERROR: $str"); |
|
|
43 |
|
info("Error: $str"); |
44 |
44 |
exit(1); |
exit(1); |
45 |
45 |
} |
} |
46 |
46 |
|
|
|
... |
... |
if (isset($_SERVER['SSH_CONNECTION'])) { |
67 |
67 |
rg_log("SSH connection: " . $_SERVER['SSH_CONNECTION']); |
rg_log("SSH connection: " . $_SERVER['SSH_CONNECTION']); |
68 |
68 |
|
|
69 |
69 |
// we do not have host info |
// we do not have host info |
70 |
|
$host = ""; |
|
|
70 |
|
$host = ''; |
71 |
71 |
|
|
72 |
72 |
// first parameter must be uid of the user |
// first parameter must be uid of the user |
73 |
73 |
$login_uid = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : 0; |
$login_uid = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : 0; |
|
... |
... |
if (isset($_SERVER['SSH_CONNECTION'])) { |
85 |
85 |
$cmd_repo = ""; |
$cmd_repo = ""; |
86 |
86 |
else |
else |
87 |
87 |
$cmd_repo = trim($_SERVER['SSH_ORIGINAL_COMMAND']); |
$cmd_repo = trim($_SERVER['SSH_ORIGINAL_COMMAND']); |
88 |
|
rg_ssh_dispatch($db, $login_uid, $cmd_repo); |
|
89 |
88 |
|
|
90 |
89 |
$ssh_client = getenv("SSH_CLIENT"); |
$ssh_client = getenv("SSH_CLIENT"); |
91 |
90 |
$_t = explode(" ", $ssh_client); |
$_t = explode(" ", $ssh_client); |
92 |
91 |
$ip = $_t[0]; |
$ip = $_t[0]; |
93 |
92 |
|
|
|
93 |
|
rg_ssh_dispatch($db, $ip, $login_uid, $cmd_repo); |
|
94 |
|
|
94 |
95 |
// TODO: This should be put in a queue for performance reasons |
// TODO: This should be put in a queue for performance reasons |
|
96 |
|
// At the same time, update stats? |
95 |
97 |
$_r = rg_keys_update_use($db, $key_id, $ip); |
$_r = rg_keys_update_use($db, $key_id, $ip); |
96 |
98 |
if ($_r !== TRUE) |
if ($_r !== TRUE) |
97 |
99 |
rg_internal_error("Cannot update key last_use!"); |
rg_internal_error("Cannot update key last_use!"); |
|
... |
... |
if (isset($_SERVER['SSH_CONNECTION'])) { |
102 |
104 |
$login_uid = 0; |
$login_uid = 0; |
103 |
105 |
$key_id = 0; |
$key_id = 0; |
104 |
106 |
|
|
105 |
|
$f = @fopen("php://stdin", "r"); |
|
106 |
|
if ($f === FALSE) |
|
107 |
|
fatal("Cannot open stdin!"); |
|
108 |
|
$line = @fread($f, 8000); |
|
109 |
|
if ($line === FALSE) |
|
110 |
|
fatal("Cannot read!"); |
|
111 |
|
fclose($f); |
|
|
107 |
|
$line = @fread(STDIN, 8000); |
112 |
108 |
$line_len = strlen($line); |
$line_len = strlen($line); |
113 |
|
|
|
114 |
109 |
rg_log("line=[$line]"); |
rg_log("line=[$line]"); |
115 |
110 |
if ($line_len < 4) |
if ($line_len < 4) |
116 |
111 |
fatal("Line is too short!"); |
fatal("Line is too short!"); |
|
... |
... |
if (isset($_SERVER['SSH_CONNECTION'])) { |
124 |
119 |
$cmd_repo = trim($v[0]); |
$cmd_repo = trim($v[0]); |
125 |
120 |
$host = isset($v[1]) ? trim(substr($v[1], 5)) : ""; |
$host = isset($v[1]) ? trim(substr($v[1], 5)) : ""; |
126 |
121 |
|
|
|
122 |
|
if (strcasecmp($host, $rg_git_host) != 0) |
|
123 |
|
info('Warn: Please use ' . $rg_git_host |
|
124 |
|
. ' instead of ' . $host . '.'); |
|
125 |
|
|
127 |
126 |
$ip = getenv("REMOTE_HOST"); |
$ip = getenv("REMOTE_HOST"); |
128 |
127 |
} |
} |
129 |
128 |
|
|
|
... |
... |
if (strcmp($_t[0], "user") == 0) { |
159 |
158 |
|
|
160 |
159 |
rg_log("host=[$host] cmd=[$cmd] prefix=[$prefix] user=[$user] repo=[$repo]."); |
rg_log("host=[$host] cmd=[$cmd] prefix=[$prefix] user=[$user] repo=[$repo]."); |
161 |
160 |
|
|
162 |
|
// TODO: if $host does not match $rg_git_host, give a warning to the user to |
|
163 |
|
// update the config. |
|
164 |
|
|
|
165 |
161 |
// validity/security checks |
// validity/security checks |
166 |
162 |
// Load info about the owner |
// Load info about the owner |
167 |
163 |
if (rg_user_ok($user) !== TRUE) |
if (rg_user_ok($user) !== TRUE) |
|
... |
... |
if ($login_uid > 0) { |
177 |
173 |
$conn_ui = rg_user_info($db, $login_uid, "", ""); |
$conn_ui = rg_user_info($db, $login_uid, "", ""); |
178 |
174 |
if ($conn_ui['exists'] != 1) |
if ($conn_ui['exists'] != 1) |
179 |
175 |
fatal("User does not exists (conn)."); |
fatal("User does not exists (conn)."); |
|
176 |
|
info('you are connecting as user \'' . $conn_ui['username'] . '\'.'); |
180 |
177 |
} else { |
} else { |
181 |
178 |
$conn_ui = array('uid' => 0, 'username' => ''); |
$conn_ui = array('uid' => 0, 'username' => ''); |
|
179 |
|
info('you are connecting as anonymous.'); |
182 |
180 |
} |
} |
183 |
181 |
|
|
184 |
182 |
// Loading info about the repository |
// Loading info about the repository |
|
... |
... |
$ret = rg_rights_allow($db, $x); |
210 |
208 |
if ($ret !== TRUE) |
if ($ret !== TRUE) |
211 |
209 |
fatal("You have no rights to access this repo!"); |
fatal("You have no rights to access this repo!"); |
212 |
210 |
|
|
|
211 |
|
// If we are enrolled, ask for login token |
|
212 |
|
// For push we always ask for it, for fetch only if repo is NOT public |
|
213 |
|
// And we can ask only if we have a ssh connection. For git protocol we cannot |
|
214 |
|
// because we do not have the username/uid of the connecting user. |
|
215 |
|
if (isset($_SERVER['SSH_CONNECTION'])) { |
|
216 |
|
if (($ri['public'] == 0) || ($push == 1)) { |
|
217 |
|
$r = rg_totp_verify_ip($db, $conn_ui['uid'], $ip); |
|
218 |
|
if ($r['ok'] != 1) |
|
219 |
|
fatal(rg_totp_error() . '.'); |
|
220 |
|
} |
|
221 |
|
} |
|
222 |
|
|
213 |
223 |
// TODO: limit per connection |
// TODO: limit per connection |
214 |
224 |
// TODO: limit time and/or cpu |
// TODO: limit time and/or cpu |
215 |
225 |
// TODO: limit cpuset |
// TODO: limit cpuset |
|
... |
... |
if ($push == 1) { |
239 |
249 |
// "No refs in common and none specified; doing nothing. |
// "No refs in common and none specified; doing nothing. |
240 |
250 |
// Perhaps you should specify a branch such as 'master'." |
// Perhaps you should specify a branch such as 'master'." |
241 |
251 |
$dst = $repo_path . "/refs/namespaces/" . $namespace . "/refs/heads"; |
$dst = $repo_path . "/refs/namespaces/" . $namespace . "/refs/heads"; |
242 |
|
$ret = @mkdir($dst, 0755, TRUE); |
|
243 |
|
if ($ret === FALSE) |
|
244 |
|
fatal("Internal error (namespace dir)"); |
|
245 |
|
// copy refs |
|
246 |
252 |
$r = rg_copy_tree($repo_path . "/refs/heads", $dst . "/", 0755); |
$r = rg_copy_tree($repo_path . "/refs/heads", $dst . "/", 0755); |
247 |
253 |
if ($r !== TRUE) |
if ($r !== TRUE) |
248 |
254 |
fatal("Internal error (cannot copy refs)"); |
fatal("Internal error (cannot copy refs)"); |
File tests/http.inc.php changed (mode: 100644) (index fcc73ba..d87fb47) |
... |
... |
function do_req($url, &$data, &$headers) |
54 |
54 |
$ret['body'] = substr($r, $header_size); |
$ret['body'] = substr($r, $header_size); |
55 |
55 |
curl_close($c); |
curl_close($c); |
56 |
56 |
|
|
|
57 |
|
// Check for XSS |
|
58 |
|
if (stristr($ret['body'], '<xss>')) { |
|
59 |
|
file_put_contents('http_xss.out', $ret['body']); |
|
60 |
|
rg_log("Found <xss> token! Check http_xss.out. Not good!"); |
|
61 |
|
exit(1); |
|
62 |
|
} |
|
63 |
|
|
57 |
64 |
// Check with tidy |
// Check with tidy |
58 |
65 |
if (!empty($ret['body'])) { // we may have a redirect |
if (!empty($ret['body'])) { // we may have a redirect |
|
66 |
|
// some fixes |
|
67 |
|
$ret['body'] = str_replace('autocomplete="off"', '', $ret['body']); |
|
68 |
|
$ret['body'] = str_replace('<xss>', '|xss|', $ret['body']); |
59 |
69 |
file_put_contents("http.tidy.in", $ret['body']); |
file_put_contents("http.tidy.in", $ret['body']); |
60 |
70 |
$cmd = "tidy -errors -utf8 -file http.tidy.out http.tidy.in"; |
$cmd = "tidy -errors -utf8 -file http.tidy.out http.tidy.in"; |
61 |
71 |
system($cmd, $ec); |
system($cmd, $ec); |
|
... |
... |
function do_req($url, &$data, &$headers) |
81 |
91 |
$ret['sid'] = $matches[1]; |
$ret['sid'] = $matches[1]; |
82 |
92 |
} |
} |
83 |
93 |
|
|
84 |
|
// Check for XSS |
|
85 |
|
if (stristr($ret['body'], '<xss>')) { |
|
86 |
|
file_put_contents('http_xss.out', $ret['body']); |
|
87 |
|
rg_log("Found <xss> token! Check http_xss.out. Not good!"); |
|
88 |
|
exit(1); |
|
89 |
|
} |
|
90 |
|
|
|
91 |
94 |
$ret['tokens'] = array(); |
$ret['tokens'] = array(); |
92 |
95 |
$x = preg_match_all('/ name="token" value="([a-zA-Z0-9_:]*)"/', $ret['body'], $matches); |
$x = preg_match_all('/ name="token" value="([a-zA-Z0-9_:]*)"/', $ret['body'], $matches); |
93 |
96 |
//rg_log_ml('DEBUG: matches: ' . print_r($matches, TRUE)); |
//rg_log_ml('DEBUG: matches: ' . print_r($matches, TRUE)); |
|
... |
... |
function test_login($url, $rg_ui, &$good_sid) |
179 |
182 |
} |
} |
180 |
183 |
$good_sid = $r['sid']; |
$good_sid = $r['sid']; |
181 |
184 |
|
|
182 |
|
if (strstr($r['body'], "invalid user or pass")) { |
|
|
185 |
|
if (strstr($r['body'], "invalid user")) { |
183 |
186 |
rg_log_ml(print_r($r, TRUE)); |
rg_log_ml(print_r($r, TRUE)); |
184 |
187 |
rg_log("Login invalid. Check above!"); |
rg_log("Login invalid. Check above!"); |
185 |
188 |
return FALSE; |
return FALSE; |
|
... |
... |
function test_restore($db) |
207 |
210 |
} |
} |
208 |
211 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
209 |
212 |
|
|
210 |
|
rg_cache_unset('user::4', RG_SOCKET_NO_WAIT); |
|
|
213 |
|
rg_cache_unset('user::4::info', RG_SOCKET_NO_WAIT); |
211 |
214 |
} |
} |
212 |
215 |
|
|
213 |
216 |
/* |
/* |
File tests/http_settings.php changed (mode: 100644) (index 931bcb2..93a3b0d) |
... |
... |
$rg_cache_enable = TRUE; |
22 |
22 |
|
|
23 |
23 |
$now = time(); |
$now = time(); |
24 |
24 |
|
|
25 |
|
rg_log("Test if caching works cache_enable=" . ($rg_cache_enable ? "true" : "false")); |
|
|
25 |
|
rg_log("Testing if caching works: cache_enable=" . ($rg_cache_enable ? "true" : "false")); |
26 |
26 |
rg_cache_set("test::a", "1", 0); |
rg_cache_set("test::a", "1", 0); |
27 |
27 |
$r = rg_cache_get("test::a"); |
$r = rg_cache_get("test::a"); |
28 |
28 |
if (strcmp($r, "1") != 0) { |
if (strcmp($r, "1") != 0) { |
|
... |
... |
if ($r === FALSE) { |
45 |
45 |
exit(1); |
exit(1); |
46 |
46 |
} |
} |
47 |
47 |
|
|
|
48 |
|
rg_log(''); |
48 |
49 |
rg_log("Loading change pass form"); |
rg_log("Loading change pass form"); |
49 |
50 |
$data = array(); |
$data = array(); |
50 |
51 |
$headers = array("Cookie: sid=" . $good_sid); |
$headers = array("Cookie: sid=" . $good_sid); |
51 |
52 |
$r = do_req($test_url . "/op/settings/change_pass?t=load_change_pass_form", $data, $headers); |
$r = do_req($test_url . "/op/settings/change_pass?t=load_change_pass_form", $data, $headers); |
52 |
53 |
if (!strstr($r['body'], "action=\"/op/settings/change_pass\"")) { |
if (!strstr($r['body'], "action=\"/op/settings/change_pass\"")) { |
|
54 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
53 |
55 |
rg_log("Cannot load change pass form!"); |
rg_log("Cannot load change pass form!"); |
54 |
56 |
exit(1); |
exit(1); |
55 |
57 |
} |
} |
56 |
58 |
$good_token = $r['tokens']['set_pass']; |
$good_token = $r['tokens']['set_pass']; |
57 |
59 |
|
|
|
60 |
|
rg_log(''); |
58 |
61 |
rg_log("Posting change pass form"); |
rg_log("Posting change pass form"); |
59 |
62 |
$data = array( |
$data = array( |
60 |
63 |
"doit" => 1, |
"doit" => 1, |
|
... |
... |
$data = array( |
66 |
69 |
$headers = array("Cookie: sid=" . $good_sid); |
$headers = array("Cookie: sid=" . $good_sid); |
67 |
70 |
$r = do_req($test_url . "/op/settings/change_pass?t=post_change_pass_form", $data, $headers); |
$r = do_req($test_url . "/op/settings/change_pass?t=post_change_pass_form", $data, $headers); |
68 |
71 |
if (!strstr($r['body'], "Password was updated with success")) { |
if (!strstr($r['body'], "Password was updated with success")) { |
|
72 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
69 |
73 |
rg_log("Cannot change pass!"); |
rg_log("Cannot change pass!"); |
70 |
74 |
exit(1); |
exit(1); |
71 |
75 |
} |
} |
72 |
76 |
|
|
73 |
77 |
|
|
|
78 |
|
rg_log(''); |
74 |
79 |
rg_log("Now, try to login with the old password"); |
rg_log("Now, try to login with the old password"); |
75 |
80 |
$r2 = test_login($test_url, $rg_ui, $junk); |
$r2 = test_login($test_url, $rg_ui, $junk); |
76 |
81 |
if ($r2 !== FALSE) { |
if ($r2 !== FALSE) { |
77 |
82 |
rg_log("Seems we were able to login with the old password!"); |
rg_log("Seems we were able to login with the old password!"); |
78 |
83 |
exit(1); |
exit(1); |
|
84 |
|
|
79 |
85 |
} |
} |
80 |
86 |
|
|
81 |
87 |
|
|
|
88 |
|
rg_log(''); |
82 |
89 |
rg_log("Change back the password"); |
rg_log("Change back the password"); |
83 |
90 |
$data = array(); |
$data = array(); |
84 |
91 |
$headers = array("Cookie: sid=" . $good_sid); |
$headers = array("Cookie: sid=" . $good_sid); |
|
... |
... |
$data = array( |
98 |
105 |
$headers = array("Cookie: sid=" . $good_sid); |
$headers = array("Cookie: sid=" . $good_sid); |
99 |
106 |
$r = do_req($test_url . "/op/settings/change_pass?t=change_back_the_password", $data, $headers); |
$r = do_req($test_url . "/op/settings/change_pass?t=change_back_the_password", $data, $headers); |
100 |
107 |
if ($r === FALSE) { |
if ($r === FALSE) { |
|
108 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
101 |
109 |
rg_log("Cannot change back the pass to aaaa!"); |
rg_log("Cannot change back the pass to aaaa!"); |
102 |
110 |
exit(1); |
exit(1); |
103 |
111 |
} |
} |
104 |
112 |
|
|
105 |
113 |
|
|
|
114 |
|
rg_log(''); |
106 |
115 |
rg_log("Testing edit info section"); |
rg_log("Testing edit info section"); |
107 |
116 |
|
|
|
117 |
|
rg_log(''); |
108 |
118 |
rg_log("Loading edit info form"); |
rg_log("Loading edit info form"); |
109 |
119 |
$data = array(); |
$data = array(); |
110 |
120 |
$headers = array("Cookie: sid=" . $good_sid); |
$headers = array("Cookie: sid=" . $good_sid); |
111 |
121 |
$r = do_req($test_url . "/op/settings/edit_info?t=load_edit_info_form", $data, $headers); |
$r = do_req($test_url . "/op/settings/edit_info?t=load_edit_info_form", $data, $headers); |
112 |
122 |
if ($r === FALSE) { |
if ($r === FALSE) { |
|
123 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
113 |
124 |
rg_log("Cannot load form!"); |
rg_log("Cannot load form!"); |
114 |
125 |
exit(1); |
exit(1); |
115 |
126 |
} |
} |
116 |
127 |
|
|
|
128 |
|
rg_log(''); |
117 |
129 |
rg_log("Posting edit info form"); |
rg_log("Posting edit info form"); |
118 |
130 |
$session_time = intval($now / 393956); |
$session_time = intval($now / 393956); |
119 |
131 |
$data = array( |
$data = array( |
|
... |
... |
$data = array( |
128 |
140 |
$headers = array("Cookie: sid=" . $good_sid); |
$headers = array("Cookie: sid=" . $good_sid); |
129 |
141 |
$r = do_req($test_url . "/op/settings/edit_info?t=post_edit_info_form", $data, $headers); |
$r = do_req($test_url . "/op/settings/edit_info?t=post_edit_info_form", $data, $headers); |
130 |
142 |
if (!strstr($r['body'], "Information was updated with success")) { |
if (!strstr($r['body'], "Information was updated with success")) { |
|
143 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
131 |
144 |
rg_log("Cannot change back the pass to aaaa!"); |
rg_log("Cannot change back the pass to aaaa!"); |
132 |
145 |
exit(1); |
exit(1); |
133 |
146 |
} |
} |
134 |
147 |
|
|
|
148 |
|
rg_log(''); |
135 |
149 |
rg_log("Verify against database"); |
rg_log("Verify against database"); |
136 |
150 |
$sql = "SELECT * FROM users WHERE username = '" . $rg_ui['username'] . "'"; |
$sql = "SELECT * FROM users WHERE username = '" . $rg_ui['username'] . "'"; |
137 |
151 |
$res = rg_sql_query($db, $sql); |
$res = rg_sql_query($db, $sql); |
138 |
152 |
$row = rg_sql_fetch_array($res); |
$row = rg_sql_fetch_array($res); |
139 |
153 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
140 |
154 |
if (strcmp($rg_ui['realname'], $row['realname']) != 0) { |
if (strcmp($rg_ui['realname'], $row['realname']) != 0) { |
|
155 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
141 |
156 |
rg_log_ml("realname was not changed: " . print_r($row, TRUE)); |
rg_log_ml("realname was not changed: " . print_r($row, TRUE)); |
142 |
157 |
exit(1); |
exit(1); |
143 |
158 |
} |
} |
144 |
159 |
if ($row['plan_id'] != 5) { |
if ($row['plan_id'] != 5) { |
|
160 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
145 |
161 |
rg_log_ml("plan_id was not changed: " . print_r($row, TRUE)); |
rg_log_ml("plan_id was not changed: " . print_r($row, TRUE)); |
146 |
162 |
exit(1); |
exit(1); |
147 |
163 |
} |
} |
148 |
164 |
if ($row['session_time'] != $session_time) { |
if ($row['session_time'] != $session_time) { |
|
165 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
149 |
166 |
rg_log_ml("session_time was not changed: " . print_r($row, TRUE)); |
rg_log_ml("session_time was not changed: " . print_r($row, TRUE)); |
150 |
167 |
exit(1); |
exit(1); |
151 |
168 |
} |
} |
152 |
169 |
|
|
153 |
170 |
|
|
|
171 |
|
rg_log(''); |
154 |
172 |
rg_log("Testing SSH keys"); |
rg_log("Testing SSH keys"); |
155 |
173 |
rg_log("Loading ssh keys form"); |
rg_log("Loading ssh keys form"); |
156 |
174 |
$data = array(); |
$data = array(); |
157 |
175 |
$headers = array("Cookie: sid=" . $good_sid); |
$headers = array("Cookie: sid=" . $good_sid); |
158 |
176 |
$r = do_req($test_url . "/op/settings/keys?t=load_key_form_add", $data, $headers); |
$r = do_req($test_url . "/op/settings/keys?t=load_key_form_add", $data, $headers); |
159 |
177 |
if ($r === FALSE) { |
if ($r === FALSE) { |
|
178 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
160 |
179 |
rg_log("Cannot load form!"); |
rg_log("Cannot load form!"); |
161 |
180 |
exit(1); |
exit(1); |
162 |
181 |
} |
} |
163 |
182 |
if (empty($r['tokens']['keys'])) { |
if (empty($r['tokens']['keys'])) { |
|
183 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
164 |
184 |
rg_log("token not found!"); |
rg_log("token not found!"); |
165 |
185 |
exit(1); |
exit(1); |
166 |
186 |
} |
} |
|
... |
... |
if ($r === FALSE) { |
175 |
195 |
exit(1); |
exit(1); |
176 |
196 |
} |
} |
177 |
197 |
// the key upload stuff will change < and > to empty. |
// the key upload stuff will change < and > to empty. |
178 |
|
$sql = "SELECT * FROM keys WHERE key = '" . $key . " xss" . $rg_ui['uid'] . "'"; |
|
|
198 |
|
$sql = "SELECT * FROM keys WHERE key = '" . $key . " " . $comment . "'"; |
179 |
199 |
$res = rg_sql_query($db, $sql); |
$res = rg_sql_query($db, $sql); |
180 |
200 |
$rows = rg_sql_num_rows($res); |
$rows = rg_sql_num_rows($res); |
181 |
201 |
if ($rows > 0) |
if ($rows > 0) |
182 |
202 |
$row = rg_sql_fetch_array($res); |
$row = rg_sql_fetch_array($res); |
183 |
203 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
184 |
204 |
if ($rows == 0) { |
if ($rows == 0) { |
|
205 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
185 |
206 |
rg_log("Key was not uploaded!"); |
rg_log("Key was not uploaded!"); |
186 |
207 |
exit(1); |
exit(1); |
187 |
208 |
} |
} |
188 |
209 |
$key_id = $row['key_id']; |
$key_id = $row['key_id']; |
189 |
210 |
|
|
|
211 |
|
rg_log(''); |
190 |
212 |
rg_log("Now, testing deletion: key_id=$key_id"); |
rg_log("Now, testing deletion: key_id=$key_id"); |
191 |
213 |
rg_log("Loading ssh keys form"); |
rg_log("Loading ssh keys form"); |
192 |
214 |
$data = array(); |
$data = array(); |
193 |
215 |
$headers = array("Cookie: sid=" . $good_sid); |
$headers = array("Cookie: sid=" . $good_sid); |
194 |
216 |
$r = do_req($test_url . "/op/settings/keys?t=load_key_form_del", $data, $headers); |
$r = do_req($test_url . "/op/settings/keys?t=load_key_form_del", $data, $headers); |
195 |
217 |
if ($r === FALSE) { |
if ($r === FALSE) { |
|
218 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
196 |
219 |
rg_log("Cannot load ssh key form!"); |
rg_log("Cannot load ssh key form!"); |
197 |
220 |
exit(1); |
exit(1); |
198 |
221 |
} |
} |
|
... |
... |
$data = array("delete" => 1, "token" => $r['tokens']['keys'], "key_delete_ids[$k |
201 |
224 |
$headers = array("Cookie: sid=" . $good_sid); |
$headers = array("Cookie: sid=" . $good_sid); |
202 |
225 |
$r = do_req($test_url . "/op/settings/keys?t=post_key_form_del", $data, $headers); |
$r = do_req($test_url . "/op/settings/keys?t=post_key_form_del", $data, $headers); |
203 |
226 |
if (!strstr($r['body'], "Selected keys were removed with success.")) { |
if (!strstr($r['body'], "Selected keys were removed with success.")) { |
|
227 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
204 |
228 |
rg_log("Cannot delete key!"); |
rg_log("Cannot delete key!"); |
205 |
229 |
exit(1); |
exit(1); |
206 |
230 |
} |
} |
|
... |
... |
$res = rg_sql_query($db, $sql); |
209 |
233 |
$rows = rg_sql_num_rows($res); |
$rows = rg_sql_num_rows($res); |
210 |
234 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
211 |
235 |
if ($rows == 1) { |
if ($rows == 1) { |
|
236 |
|
rg_log_ml('r: ' . print_r($r, TRUE)); |
212 |
237 |
rg_log("key $key_id was not deleted!"); |
rg_log("key $key_id was not deleted!"); |
213 |
238 |
exit(1); |
exit(1); |
214 |
239 |
} |
} |
File tests/http_totp.php copied from file tests/http_admin.php (similarity 54%) (mode: 100644) (index 789ce9a..9ca337f) |
1 |
1 |
<?php |
<?php |
|
2 |
|
// |
|
3 |
|
// Will test the login by TOTP |
|
4 |
|
// |
|
5 |
|
|
2 |
6 |
error_reporting(E_ALL | E_STRICT); |
error_reporting(E_ALL | E_STRICT); |
3 |
7 |
ini_set("track_errors", "On"); |
ini_set("track_errors", "On"); |
4 |
8 |
|
|
|
... |
... |
require_once($INC . "/util.inc.php"); |
9 |
13 |
require_once("helpers.inc.php"); |
require_once("helpers.inc.php"); |
10 |
14 |
require_once("http.inc.php"); |
require_once("http.inc.php"); |
11 |
15 |
|
|
12 |
|
rg_log_set_file("http_admin.log"); |
|
|
16 |
|
rg_log_set_file("http_totp.log"); |
13 |
17 |
|
|
14 |
18 |
$rg_sql = "host=localhost user=rocketgit dbname=rocketgit connect_timeout=10"; |
$rg_sql = "host=localhost user=rocketgit dbname=rocketgit connect_timeout=10"; |
15 |
19 |
$rg_no_db = TRUE; |
$rg_no_db = TRUE; |
16 |
20 |
require_once("common.php"); |
require_once("common.php"); |
17 |
21 |
|
|
18 |
|
$_testns = 'http_admin'; |
|
|
22 |
|
$_testns = 'http_totp'; |
19 |
23 |
$rg_cache_enable = TRUE; |
$rg_cache_enable = TRUE; |
20 |
24 |
|
|
21 |
25 |
$rg_user_max_len = 60; |
$rg_user_max_len = 60; |
22 |
26 |
|
|
23 |
|
$rg_ui = array('is_admin' => 1); |
|
24 |
27 |
rg_test_create_user($db, $rg_ui); |
rg_test_create_user($db, $rg_ui); |
25 |
28 |
|
|
|
29 |
|
// Add an totp token to this account |
|
30 |
|
$key = 'ACHCBCCVQ7AK4RGM'; |
|
31 |
|
|
|
32 |
|
$r = rg_totp_enroll($db, $rg_ui['uid'], 'test', $key, '127.0.0.1', TRUE); |
|
33 |
|
if ($r !== TRUE) { |
|
34 |
|
rg_log('cannot enroll!'); |
|
35 |
|
exit(1); |
|
36 |
|
} |
|
37 |
|
|
|
38 |
|
// Now test the login without and with login_token |
|
39 |
|
$lt = rg_totp_compute($key, time() / 30, 6); |
|
40 |
|
|
26 |
41 |
// First we need to load the form so we can get the token |
// First we need to load the form so we can get the token |
27 |
42 |
// We provide an old cookie to test if we generate a new pre-login one |
// We provide an old cookie to test if we generate a new pre-login one |
28 |
43 |
$r = do_req($test_url . "/op/login", $data, $headers); |
$r = do_req($test_url . "/op/login", $data, $headers); |
|
... |
... |
$good_sid = $r['sid']; |
34 |
49 |
$good_token = $r['tokens']['login']; |
$good_token = $r['tokens']['login']; |
35 |
50 |
|
|
36 |
51 |
|
|
37 |
|
rg_log("Do the login (sid=$good_sid token=$good_token)..."); |
|
|
52 |
|
rg_log("Do the login (sid=$good_sid token=$good_token" |
|
53 |
|
. " login_token=$lt)..."); |
38 |
54 |
$data = array( |
$data = array( |
39 |
55 |
"doit" => 1, |
"doit" => 1, |
40 |
56 |
"token" => $good_token, |
"token" => $good_token, |
41 |
57 |
"user" => $rg_ui['username'], |
"user" => $rg_ui['username'], |
42 |
58 |
"pass" => $rg_ui['pass'], |
"pass" => $rg_ui['pass'], |
|
59 |
|
"login_token" => $lt, |
43 |
60 |
"lock_ip" => 0); |
"lock_ip" => 0); |
44 |
61 |
$headers = array("Cookie: sid=" . $good_sid); |
$headers = array("Cookie: sid=" . $good_sid); |
45 |
62 |
$r = do_req($test_url . "/op/login", $data, $headers); |
$r = do_req($test_url . "/op/login", $data, $headers); |
|
... |
... |
if ($r === FALSE) { |
47 |
64 |
rg_log_ml("Cannot login: " . print_r($r, TRUE)); |
rg_log_ml("Cannot login: " . print_r($r, TRUE)); |
48 |
65 |
exit(1); |
exit(1); |
49 |
66 |
} |
} |
50 |
|
if (strstr($r['body'], "invalid user or pass")) { |
|
|
67 |
|
if (strstr($r['body'], "invalid user")) { |
51 |
68 |
rg_log_ml("Login invalid. r=" . print_r($r, TRUE)); |
rg_log_ml("Login invalid. r=" . print_r($r, TRUE)); |
52 |
69 |
exit(1); |
exit(1); |
53 |
70 |
} |
} |
54 |
71 |
|
|
55 |
|
rg_log("Loading invites form..."); |
|
56 |
|
$url = "/op/admin/invites"; |
|
57 |
|
$data = array(); |
|
58 |
|
$r = do_req($test_url . $url, $data, $headers); |
|
59 |
|
if ($r === FALSE) { |
|
60 |
|
rg_log("Cannot load add bug form."); |
|
61 |
|
exit(1); |
|
62 |
|
} |
|
63 |
|
if (!isset($r['tokens']['admin_invites_hl'])) { |
|
64 |
|
rg_log("No admin_invites_hl token!"); |
|
65 |
|
exit(1); |
|
66 |
|
} |
|
67 |
|
$token = $r['tokens']['admin_invites_hl']; |
|
68 |
|
|
|
69 |
|
rg_log("Posting invites form (token=$token)..."); |
|
70 |
|
$data = array('doit' => 1, 'token' => $token, |
|
71 |
|
'inv::list' => "a@embedromix.ro|a\nb@embedromix.ro|b b2 b3<xss>\n", |
|
72 |
|
'inv::subject' => 'Invite 1 - hello {NAME}<xss>', |
|
73 |
|
'inv::body' => "Hello {NAME}!\n\nYou are invited, {NAME}!<xss>"); |
|
74 |
|
$r = do_req($test_url . $url, $data, $headers); |
|
75 |
|
if ($r === FALSE) { |
|
76 |
|
rg_log("Cannot post bug request."); |
|
77 |
|
exit(1); |
|
78 |
|
} |
|
79 |
|
// test invites here |
|
80 |
|
/* |
|
81 |
|
if ($row['state'] != 1) { |
|
82 |
|
rg_log("State is not 1 but " . $row['state']); |
|
83 |
|
exit(1); |
|
84 |
|
} |
|
85 |
|
*/ |
|
86 |
|
|
|
87 |
72 |
rg_prof_log(); |
rg_prof_log(); |
88 |
73 |
rg_log("OK!"); |
rg_log("OK!"); |
89 |
74 |
?> |
?> |
File tests/rights.php changed (mode: 100644) (index 8673c28..707a4d1) |
... |
... |
$sql = "DELETE FROM rights"; |
25 |
25 |
$res = rg_sql_query($db, $sql); |
$res = rg_sql_query($db, $sql); |
26 |
26 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
27 |
27 |
|
|
|
28 |
|
rg_log(''); |
28 |
29 |
rg_log("test if combine works correctly (1)"); |
rg_log("test if combine works correctly (1)"); |
29 |
30 |
$a = "AF"; $b = "AD"; $e = "AFD"; |
$a = "AF"; $b = "AD"; $e = "AFD"; |
30 |
31 |
$r = rg_rights_combine($a, $b); |
$r = rg_rights_combine($a, $b); |
|
... |
... |
if (strcmp($r, $e) != 0) { |
33 |
34 |
exit(1); |
exit(1); |
34 |
35 |
} |
} |
35 |
36 |
|
|
|
37 |
|
rg_log(''); |
36 |
38 |
rg_log("test if combine works correctly (2)"); |
rg_log("test if combine works correctly (2)"); |
37 |
39 |
$a = ""; $b = ""; $e = ""; |
$a = ""; $b = ""; $e = ""; |
38 |
40 |
$r = rg_rights_combine($a, $b); |
$r = rg_rights_combine($a, $b); |
|
... |
... |
if (strcmp($r, $e) != 0) { |
41 |
43 |
exit(1); |
exit(1); |
42 |
44 |
} |
} |
43 |
45 |
|
|
|
46 |
|
rg_log(''); |
44 |
47 |
rg_log("test if combine works correctly (3)"); |
rg_log("test if combine works correctly (3)"); |
45 |
48 |
$a = "AXUJUNFUUFU"; $b = ""; $e = $a; |
$a = "AXUJUNFUUFU"; $b = ""; $e = $a; |
46 |
49 |
$r = rg_rights_combine($a, $b); |
$r = rg_rights_combine($a, $b); |
|
... |
... |
if (strcmp($r, $e) != 0) { |
49 |
52 |
exit(1); |
exit(1); |
50 |
53 |
} |
} |
51 |
54 |
|
|
|
55 |
|
rg_log(''); |
52 |
56 |
rg_log("testing mask..."); |
rg_log("testing mask..."); |
53 |
57 |
$a = "ABCDE"; $mask = "AEZ"; $e = "AE"; |
$a = "ABCDE"; $mask = "AEZ"; $e = "AE"; |
54 |
58 |
$r = rg_rights_mask($a, $mask); |
$r = rg_rights_mask($a, $mask); |
|
... |
... |
if (strcmp($e, $e) != 0) { |
57 |
61 |
exit(1); |
exit(1); |
58 |
62 |
} |
} |
59 |
63 |
|
|
|
64 |
|
rg_log(''); |
60 |
65 |
rg_log("rights: testing 'test'..."); |
rg_log("rights: testing 'test'..."); |
61 |
66 |
$rights = array(array("rights" => "ABC", "ip" => "")); |
$rights = array(array("rights" => "ABC", "ip" => "")); |
62 |
67 |
$needed_rights = "BCD"; |
$needed_rights = "BCD"; |
|
... |
... |
if ($r !== FALSE) { |
68 |
73 |
exit(1); |
exit(1); |
69 |
74 |
} |
} |
70 |
75 |
|
|
|
76 |
|
rg_log(''); |
71 |
77 |
rg_log("rights: testing rg_rights_set..."); |
rg_log("rights: testing rg_rights_set..."); |
72 |
78 |
$a = array(); |
$a = array(); |
73 |
79 |
$a['right_id'] = 0; |
$a['right_id'] = 0; |
|
... |
... |
if ($r !== TRUE) { |
98 |
104 |
exit(1); |
exit(1); |
99 |
105 |
} |
} |
100 |
106 |
|
|
|
107 |
|
rg_log(''); |
101 |
108 |
rg_log("Testing rg_rights_get..."); |
rg_log("Testing rg_rights_get..."); |
102 |
109 |
$right_id = 0; |
$right_id = 0; |
103 |
110 |
$r = rg_rights_get($db, $a['obj_id'], "type1", $a['who'], $a['uid'], $right_id); |
$r = rg_rights_get($db, $a['obj_id'], "type1", $a['who'], $a['uid'], $right_id); |
|
... |
... |
if (($r['ok'] !== 1) || (strcmp($r['list'][1]['rights'], "d") != 0)) { |
115 |
122 |
} |
} |
116 |
123 |
$for_delete_list = $r['list']; |
$for_delete_list = $r['list']; |
117 |
124 |
|
|
|
125 |
|
rg_log(''); |
118 |
126 |
rg_log("Testing allow with @USER@ token..."); |
rg_log("Testing allow with @USER@ token..."); |
119 |
127 |
$x = array(); |
$x = array(); |
120 |
128 |
$x['obj_id'] = $a['obj_id']; |
$x['obj_id'] = $a['obj_id']; |
|
... |
... |
if ($r === FALSE) { |
131 |
139 |
exit(1); |
exit(1); |
132 |
140 |
} |
} |
133 |
141 |
|
|
|
142 |
|
|
|
143 |
|
rg_log(''); |
|
144 |
|
rg_log('Testing if we can found out if anybody can fetch - deny'); |
|
145 |
|
$list = array(); |
|
146 |
|
$list[] = array('rights' => 'PH', 'ip' => '', 'misc' => ''); |
|
147 |
|
$list[] = array('rights' => '', 'ip' => '', 'misc' => ''); |
|
148 |
|
$list[] = array('rights' => 'F', 'ip' => '', 'misc' => ''); |
|
149 |
|
$needed_rights = 'F'; |
|
150 |
|
$ip = '1.2.3.4'; |
|
151 |
|
$misc = ''; |
|
152 |
|
$r = rg_rights_test($list, $needed_rights, $ip, $misc); |
|
153 |
|
if ($r !== FALSE) { |
|
154 |
|
rg_log('We must not be allowed because rule 2 denies everything!'); |
|
155 |
|
exit(1); |
|
156 |
|
} |
|
157 |
|
|
|
158 |
|
|
|
159 |
|
rg_log(''); |
|
160 |
|
rg_log('Testing if we can found out if anybody can fetch - allow'); |
|
161 |
|
$list = array(); |
|
162 |
|
$list[] = array('rights' => 'PH', 'ip' => '', 'misc' => ''); |
|
163 |
|
$list[] = array('rights' => 'F', 'ip' => '', 'misc' => ''); |
|
164 |
|
$needed_rights = 'F'; |
|
165 |
|
$ip = '1.2.3.4'; |
|
166 |
|
$misc = ''; |
|
167 |
|
$r = rg_rights_test($list, $needed_rights, $ip, $misc); |
|
168 |
|
if ($r !== TRUE) { |
|
169 |
|
rg_log('We must be allowed because rule 2 allows fetch!'); |
|
170 |
|
exit(1); |
|
171 |
|
} |
|
172 |
|
|
|
173 |
|
|
|
174 |
|
rg_log(''); |
134 |
175 |
rg_log("Testing delete_list..."); |
rg_log("Testing delete_list..."); |
135 |
176 |
$list = array(); |
$list = array(); |
136 |
177 |
foreach ($for_delete_list as $junk => $i) |
foreach ($for_delete_list as $junk => $i) |
|
... |
... |
if (($r['ok'] !== 1) || (count($r['list']) > 0)) { |
148 |
189 |
exit (1); |
exit (1); |
149 |
190 |
} |
} |
150 |
191 |
|
|
|
192 |
|
rg_log(''); |
151 |
193 |
rg_log("Testing IP match part - test1"); |
rg_log("Testing IP match part - test1"); |
152 |
194 |
$list = "1.2.3.4/24 10.0.0.0/8 fd00::/64" |
$list = "1.2.3.4/24 10.0.0.0/8 fd00::/64" |
153 |
195 |
. " 1234:5678:aaaa:bbbb:cccc:dddd:eeee::/120" |
. " 1234:5678:aaaa:bbbb:cccc:dddd:eeee::/120" |