File Makefile.in changed (mode: 100644) (index 01d625e..56d4299) |
... |
... |
tests: |
20 |
20 |
make -C tests all |
make -C tests all |
21 |
21 |
|
|
22 |
22 |
install: all |
install: all |
23 |
|
@mkdir -p $(I_USR_SHARE)/$(PRJ) |
|
|
23 |
|
@mkdir -pv $(I_USR_SHARE)/$(PRJ) |
24 |
24 |
cp -vdr admin inc hooks root scripts $(I_USR_SHARE)/$(PRJ) |
cp -vdr admin inc hooks root scripts $(I_USR_SHARE)/$(PRJ) |
25 |
|
@mkdir -p $(I_ETC)/xinetd.d |
|
|
25 |
|
@mkdir -pv $(I_ETC)/xinetd.d |
26 |
26 |
cp -vd --no-clobber samples/rg $(I_ETC)/xinetd.d/$(PRJ) |
cp -vd --no-clobber samples/rg $(I_ETC)/xinetd.d/$(PRJ) |
27 |
|
@mkdir -p $(I_ETC)/cron.d |
|
|
27 |
|
@mkdir -pv $(I_ETC)/cron.d |
28 |
28 |
cp -vd samples/cron $(I_ETC)/cron.d/$(PRJ) |
cp -vd samples/cron $(I_ETC)/cron.d/$(PRJ) |
29 |
|
@mkdir -p $(I_ETC)/httpd/conf.d |
|
|
29 |
|
@mkdir -pv $(I_ETC)/httpd/conf.d |
30 |
30 |
cp -vd --no-clobber samples/rg.conf $(I_ETC)/httpd/conf.d/$(PRJ).conf |
cp -vd --no-clobber samples/rg.conf $(I_ETC)/httpd/conf.d/$(PRJ).conf |
31 |
|
@mkdir -p $(I_ETC)/$(PRJ) |
|
|
31 |
|
@mkdir -pv $(I_ETC)/$(PRJ) |
32 |
32 |
cp -vd --no-clobber samples/config.php $(I_ETC)/$(PRJ)/ |
cp -vd --no-clobber samples/config.php $(I_ETC)/$(PRJ)/ |
33 |
33 |
cp -vd samples/config.php $(I_ETC)/$(PRJ)/config.php.sample |
cp -vd samples/config.php $(I_ETC)/$(PRJ)/config.php.sample |
34 |
|
@mkdir -p $(I_ETC)/logrotate.d |
|
|
34 |
|
@mkdir -pv $(I_ETC)/logrotate.d |
35 |
35 |
cp -vd samples/logrotate $(I_ETC)/logrotate.d/$(PRJ) |
cp -vd samples/logrotate $(I_ETC)/logrotate.d/$(PRJ) |
36 |
36 |
@ |
@ |
37 |
37 |
@echo "Installing log stuff..." |
@echo "Installing log stuff..." |
38 |
|
@mkdir -p $(I_VAR_LOG)/$(PRJ) |
|
|
38 |
|
@mkdir -pv $(I_VAR_LOG)/$(PRJ) |
39 |
39 |
@-chown -R rocketgit:rocketgit $(I_VAR_LOG)/$(PRJ) |
@-chown -R rocketgit:rocketgit $(I_VAR_LOG)/$(PRJ) |
40 |
40 |
@-find $(I_VAR_LOG)/$(PRJ) -type d -exec chmod -R 0755 {} \; |
@-find $(I_VAR_LOG)/$(PRJ) -type d -exec chmod -R 0755 {} \; |
41 |
41 |
@-find $(I_VAR_LOG)/$(PRJ) -type f -exec chmod -R 0600 {} \; |
@-find $(I_VAR_LOG)/$(PRJ) -type f -exec chmod -R 0600 {} \; |
42 |
42 |
@ |
@ |
43 |
|
@mkdir -p $(I_VAR_LOG)/$(PRJ)-web |
|
|
43 |
|
@mkdir -pv $(I_VAR_LOG)/$(PRJ)-web |
44 |
44 |
@-chown -R apache:apache $(I_VAR_LOG)/$(PRJ)-web |
@-chown -R apache:apache $(I_VAR_LOG)/$(PRJ)-web |
45 |
45 |
@-find $(I_VAR_LOG)/$(PRJ)-web -type d -exec chmod -R 0755 {} \; |
@-find $(I_VAR_LOG)/$(PRJ)-web -type d -exec chmod -R 0755 {} \; |
46 |
46 |
@-find $(I_VAR_LOG)/$(PRJ)-web -type f -exec chmod -R 0600 {} \; |
@-find $(I_VAR_LOG)/$(PRJ)-web -type f -exec chmod -R 0600 {} \; |
47 |
47 |
@ |
@ |
48 |
48 |
@echo "Installing varlib stuff..." |
@echo "Installing varlib stuff..." |
49 |
|
@mkdir -p $(I_VAR_LIB)/$(PRJ) |
|
50 |
|
@mkdir -p $(I_VAR_LIB)/$(PRJ)/locks |
|
51 |
|
@mkdir -p $(I_VAR_LIB)/$(PRJ)/repos |
|
52 |
|
@mkdir -p $(I_VAR_LIB)/$(PRJ)/q_merge_requests |
|
53 |
|
@mkdir -p $(I_VAR_LIB)/$(PRJ)/qstats |
|
54 |
|
@mkdir -p $(I_VAR_LIB)/$(PRJ)/sockets |
|
|
49 |
|
@mkdir -pv $(I_VAR_LIB)/$(PRJ) |
|
50 |
|
@mkdir -pv $(I_VAR_LIB)/$(PRJ)/locks |
|
51 |
|
@mkdir -pv $(I_VAR_LIB)/$(PRJ)/repos |
|
52 |
|
@mkdir -pv $(I_VAR_LIB)/$(PRJ)/q_merge_requests |
|
53 |
|
@mkdir -pv $(I_VAR_LIB)/$(PRJ)/qstats |
|
54 |
|
@mkdir -pv $(I_VAR_LIB)/$(PRJ)/sockets |
55 |
55 |
@echo "Fixing rights..." |
@echo "Fixing rights..." |
56 |
56 |
@-chown -R rocketgit:rocketgit $(I_VAR_LIB)/$(PRJ) |
@-chown -R rocketgit:rocketgit $(I_VAR_LIB)/$(PRJ) |
57 |
57 |
@-find $(I_VAR_LIB)/$(PRJ) -type d -exec chmod 0755 {} \; |
@-find $(I_VAR_LIB)/$(PRJ) -type d -exec chmod 0755 {} \; |
58 |
58 |
@-find $(I_VAR_LIB)/$(PRJ) -type f -exec chmod 0600 {} \; |
@-find $(I_VAR_LIB)/$(PRJ) -type f -exec chmod 0600 {} \; |
59 |
59 |
@ |
@ |
60 |
60 |
@echo "Installing SELinux stuff..." |
@echo "Installing SELinux stuff..." |
61 |
|
@mkdir -p --mode=0755 $(I_USR_SHARE)/selinux/targeted |
|
|
61 |
|
@mkdir -pv --mode=0755 $(I_USR_SHARE)/selinux/targeted |
62 |
62 |
cp -vd selinux/out/$(PRJ)-targeted.pp $(I_USR_SHARE)/selinux/targeted/$(PRJ).pp |
cp -vd selinux/out/$(PRJ)-targeted.pp $(I_USR_SHARE)/selinux/targeted/$(PRJ).pp |
63 |
63 |
@echo "Done!" |
@echo "Done!" |
File README changed (mode: 100644) (index bf6fa82..4aad5e3) |
25 |
25 |
. Prepare SELinux |
. Prepare SELinux |
26 |
26 |
# setsebool -P \ |
# setsebool -P \ |
27 |
27 |
httpd_can_network_connect_db=on \ |
httpd_can_network_connect_db=on \ |
28 |
|
httpd_can_network_memcache=on \ |
|
29 |
28 |
httpd_can_sendmail=on |
httpd_can_sendmail=on |
30 |
29 |
|
|
31 |
30 |
. Edit /etc/rocketgit/config.php |
. Edit /etc/rocketgit/config.php |
32 |
31 |
. Edit /etc/httpd/conf.d/rocketgit.conf |
. Edit /etc/httpd/conf.d/rocketgit.conf |
33 |
32 |
|
|
|
33 |
|
. PHP |
|
34 |
|
Adjust php.ini to: |
|
35 |
|
- allow enough RAM and execution time |
|
36 |
|
- fix timezone |
|
37 |
|
|
34 |
38 |
. Activate web server |
. Activate web server |
35 |
39 |
# systemctl enable httpd.service |
# systemctl enable httpd.service |
36 |
|
# systemctl start httpd.service |
|
|
40 |
|
# systemctl restart httpd.service |
37 |
41 |
|
|
38 |
42 |
. Activate sshd (for ssh:// access) |
. Activate sshd (for ssh:// access) |
39 |
43 |
# systemctl enable sshd.service |
# systemctl enable sshd.service |
|
54 |
58 |
$ createdb -O rocketgit rocketgit |
$ createdb -O rocketgit rocketgit |
55 |
59 |
|
|
56 |
60 |
. Allow access to PostgreSQL and restart: |
. Allow access to PostgreSQL and restart: |
57 |
|
Add the following lines, before wildcard matches, in pg_hba.conf: |
|
58 |
|
local rocketgit rocketgit 127.0.0.1 trust |
|
59 |
|
local rocketgit rocketgit ::1 trust |
|
|
61 |
|
Add the following lines, before wildcard matches, in |
|
62 |
|
/var/lib/pgsql/data/pg_hba.conf: |
|
63 |
|
local rocketgit rocketgit trust |
|
64 |
|
host rocketgit rocketgit 127.0.0.1/32 trust |
|
65 |
|
host rocketgit rocketgit ::1/128 trust |
60 |
66 |
|
|
61 |
|
systemctl reload postgresql.service |
|
|
67 |
|
systemctl restart postgresql.service |
62 |
68 |
|
|
63 |
69 |
Notes: |
Notes: |
64 |
|
- Check also the config file and set correctly rg_sql string. |
|
|
70 |
|
- Check also the config file (/etc/rocketgit/config.php) and set |
|
71 |
|
correctly the rg_sql string. |
65 |
72 |
- If the web server and the db are not on the same host, you need to |
- If the web server and the db are not on the same host, you need to |
66 |
73 |
replace 127.0.0.1/::1 with your "safe network". You may want to use |
replace 127.0.0.1/::1 with your "safe network". You may want to use |
67 |
74 |
md5 for authentication. Also, you may want to change 'listen_addresses' |
md5 for authentication. Also, you may want to change 'listen_addresses' |
|
70 |
77 |
. Mail |
. Mail |
71 |
78 |
To be able to generate e-mails as other user, you have to: |
To be able to generate e-mails as other user, you have to: |
72 |
79 |
For sendmail: |
For sendmail: |
|
80 |
|
- Enable daemon: systemctl enable sendmail.service |
73 |
81 |
- Edit /etc/mail/trusted-users and add 'rocketgit' and 'apache'. |
- Edit /etc/mail/trusted-users and add 'rocketgit' and 'apache'. |
74 |
82 |
- Restart daemon: 'systemctl restart sendmail.service' (Fedora) |
- Restart daemon: 'systemctl restart sendmail.service' (Fedora) |
75 |
83 |
|
|
|
77 |
85 |
# php /usr/share/rocketgit/admin/init.php |
# php /usr/share/rocketgit/admin/init.php |
78 |
86 |
|
|
79 |
87 |
. Edit firewall to permit ssh, git, http and https ports |
. Edit firewall to permit ssh, git, http and https ports |
80 |
|
In /etc/sysconfig/iptables (IPv4) or ip6tables (IPv6), add something |
|
|
88 |
|
In /etc/sysconfig/iptables (IPv4) and ip6tables (IPv6), add something |
81 |
89 |
like this: |
like this: |
82 |
90 |
-A INPUT -m tcp -p tcp --dport ssh -j ACCEPT |
-A INPUT -m tcp -p tcp --dport ssh -j ACCEPT |
83 |
91 |
-A INPUT -m tcp -p tcp --dport git -j ACCEPT |
-A INPUT -m tcp -p tcp --dport git -j ACCEPT |
84 |
92 |
-A INPUT -m tcp -p tcp --dport http -j ACCEPT |
-A INPUT -m tcp -p tcp --dport http -j ACCEPT |
85 |
93 |
-A INPUT -m tcp -p tcp --dport https -j ACCEPT |
-A INPUT -m tcp -p tcp --dport https -j ACCEPT |
86 |
94 |
|
|
87 |
|
. PHP |
|
88 |
|
Adjust php.ini to: |
|
89 |
|
- allow enough RAM and execution time |
|
90 |
|
- fix timezone |
|
91 |
|
|
|
92 |
95 |
|
|
93 |
96 |
== Thanks == |
== Thanks == |
94 |
97 |
. Special thanks to my family that supported me in this project. |
. Special thanks to my family that supported me in this project. |
95 |
98 |
. Special thanks to my brother that contributed brain and time to this project. |
. Special thanks to my brother that contributed brain and time to this project. |
96 |
99 |
. Special thanks to git people for the best tool to manage the sources. |
. Special thanks to git people for the best tool to manage the sources. |
|
100 |
|
. Special thanks to Petre Bandac for free hosting of rg2 server. |
97 |
101 |
. Special thanks to a lot of people that came with suggestions. |
. Special thanks to a lot of people that came with suggestions. |
98 |
102 |
. Special thanks to gitosys, Gitorious and other projects from where I learned |
. Special thanks to gitosys, Gitorious and other projects from where I learned |
99 |
103 |
things. |
things. |
|
104 |
|
. Special thanks to OWASP for their good documentation on how to write a |
|
105 |
|
web application. |
100 |
106 |
. See AUTHORS file for all the people who contributed to this project. |
. See AUTHORS file for all the people who contributed to this project. |
File TODO changed (mode: 100644) (index a503461..a9b6c99) |
1 |
|
== Important: python moves to github == |
|
2 |
|
Nick Coghlan <ncoghlan-AT-gmail.com> is taking care of this, I should write an |
|
3 |
|
e-mail to him. Or I may comment on LWN or "PEP 474". |
|
4 |
|
|
|
5 |
1 |
== Where I stopped last time == |
== Where I stopped last time == |
6 |
2 |
[ ] Friends will need a way to register an account with a full account type. |
[ ] Friends will need a way to register an account with a full account type. |
7 |
3 |
Find a way to distribute this code and a way to support it in rg. |
Find a way to distribute this code and a way to support it in rg. |
8 |
4 |
Probably I will allow only one plan (Friends) till they all create |
Probably I will allow only one plan (Friends) till they all create |
9 |
5 |
accounts. After this, I will remove this plan? |
accounts. After this, I will remove this plan? |
10 |
|
[ ] CSRF for logout. Seems is not so easy because I need to generate a token |
|
11 |
|
all the time to embed it in the logout link. Another possibility |
|
12 |
|
is to have a form on the logout page. But some people probably will |
|
13 |
|
assume that pressing the logout link is enough and will not press |
|
14 |
|
the logout _button_. A signed token is enough, if I prepare it special |
|
15 |
|
for logout. It is important to work only there. And, I can embed it in |
|
16 |
|
the link. |
|
17 |
|
Anyway, I can link all tokens with the forms and I can store them in |
|
18 |
|
db when they are used, so we cannot use them anymore. This way I do not |
|
19 |
|
have to save them in database at generation time. |
|
20 |
|
What is the problem with the token?! Double post? And using same token |
|
21 |
|
for two forms? |
|
22 |
|
[ ] If email is not confirmed, do not send e-mail! |
|
23 |
|
[ ] Now, we gen generate tokens without storing in database, and store tokens |
|
24 |
|
in db only after they are used. In rg_token_valid, we will check if it |
|
25 |
|
was already used, after we check the signing. |
|
26 |
|
generate_token |
|
27 |
|
user post form |
|
28 |
|
we insert it in db => ok |
|
29 |
|
user post it again |
|
30 |
|
we insert it in db => get error! |
|
31 |
|
this means was already used it |
|
32 |
|
abort |
|
33 |
|
continue work |
|
34 |
|
What I have to change: |
|
35 |
|
- rg_token_get must return a signed token. Maybe we add the form id to |
|
36 |
|
the equation. |
|
37 |
|
- rg_token_valid: we insert it in db as used, return FALSE if we get |
|
38 |
|
an error. We need to know if db failed or we could not |
|
39 |
|
insert because of already present key |
|
40 |
|
- get rid of tokens.used field. What about expiration? |
|
41 |
|
|
|
|
6 |
|
[ ] Mail-ul nu vine corect (embedromix.ro) |
|
7 |
|
[ ] AVC-uri, probabil ca la scrierea authorized_file |
|
8 |
|
[ ] In mail-ul phase1, ar trebui adaugata si misiunea acestui proiect. |
|
9 |
|
[ ] Se pare ca nu se regenereaza authorized_keys file! |
|
10 |
|
[ ] Se pare ca event.php nu reactioneaza corect la signaling. |
|
11 |
|
Pare ca nu reactioneaza la o inserare de cheie, cu toate ca insert |
|
12 |
|
se face in baza de date. Se pare ca fac commit dupa signaling... |
|
13 |
|
In plus, tot apare rahatul cu broken pipe! |
42 |
14 |
[ ] |
[ ] |
43 |
15 |
|
|
44 |
16 |
== BEFORE NEXT RELEASE == |
== BEFORE NEXT RELEASE == |
|
17 |
|
[ ] Permisiile pentru /home/rocketgit/.ssh nu sint corecte! Sint root! |
|
18 |
|
Rezolvat cu chow. Poate vreau sa nu mai rulez cua root keys_regen. |
|
19 |
|
[ ] Logged in as admin, Admin -> Plans is not working (redirects to main page)! |
|
20 |
|
[ ] init.php: do not show the password! |
|
21 |
|
Maybe switch to a web based instalation? |
|
22 |
|
[ ] I must mark that init.php script was not run, and do not start daemons! |
|
23 |
|
Else, timezone nasty messages will appear in the logs and only a |
|
24 |
|
restart will fix the problem. |
|
25 |
|
[ ] HTTP_X_FORWARDED_FOR variable as this data is effectively user input and |
|
26 |
|
therefore susceptible to spoofing. |
|
27 |
|
[ ] Try to remove non critical queries from main page loading. Just schedule |
|
28 |
|
the operations for later. |
|
29 |
|
[ ] We should not delete the tokens. They will be cleaned hourly? |
|
30 |
|
[ ] Remove all texts from code and move them to templates. |
|
31 |
|
At least in forgot.php. |
|
32 |
|
[ ] Storing password in database must apply multiple hashes. Check owasp. |
|
33 |
|
They recommend SHA-256(private_key, salt + pass). Think more. |
|
34 |
|
[ ] Regenerate salt on every succesful login? Or after some pre-defined time? |
|
35 |
|
[ ] Get rid of sessions table and use only hmac! |
|
36 |
|
We may change the encryption key with an algo. |
|
37 |
|
[ ] Should we skip SELECT/INSERT steps for logout (in token_valid)? |
|
38 |
|
[ ] Persistent connection to database? |
45 |
39 |
[ ] Check cache socket is protected agains other users. |
[ ] Check cache socket is protected agains other users. |
|
40 |
|
[ ] token: add form id into equation? |
46 |
41 |
[ ] Ce se intimpla daca un atacator seteaza un cookie pe .com, de exemplu. |
[ ] Ce se intimpla daca un atacator seteaza un cookie pe .com, de exemplu. |
47 |
42 |
El se va trimite si pe rocketgit.com. Deci, daca user-ul viziteaza site-ul |
El se va trimite si pe rocketgit.com. Deci, daca user-ul viziteaza site-ul |
48 |
43 |
atacatorului, se seteaza acest cookie, care apoi va fi trimis catre rg.com. |
atacatorului, se seteaza acest cookie, care apoi va fi trimis catre rg.com. |
|
... |
... |
Daca as lega good.com de a/b, as putea elimina cookie-urile rele. |
54 |
49 |
[ ] "repo_submenu" seems to not be used, remove references. |
[ ] "repo_submenu" seems to not be used, remove references. |
55 |
50 |
[ ] http://nedbatchelder.com/blog/201405/github_monoculture.html |
[ ] http://nedbatchelder.com/blog/201405/github_monoculture.html |
56 |
51 |
[ ] mchapman (subscriber, #66589) (http://lwn.net/Articles/623905/) |
[ ] mchapman (subscriber, #66589) (http://lwn.net/Articles/623905/) |
57 |
|
With a GitHub pull-request-based workflow I need a GitHub account (I've been resisting getting one for myself), I need to make sure I explicitly "fork" the repository within GitHub (simply pushing my copy of the repo to my account won't make pull requests work, as far as I know, because GitHub doesn't know that the original project and my project are "linked"), and I need to use the GitHub web interface to actually generate the pull request and take part in its review. If all of this isn't vendor lock-in, I don't know what is. |
|
58 |
|
I've got bigger problems with the GitHub pull request workflow anyway. If you generate a pull request, discover that changes need to be made, you have two choices: you can create a new pull request, losing all comments from the previous one, or you have to add new commits. If you drop the to-be-pulled branch from your repository and replace it with a different branch with the same name, the pull request loses all of its comments. |
|
59 |
|
No, I find the bigger problems are with pull-request based workflow that GitHub uses -- specifically, how that workflow interacts with code review. If your branch is reviewed and it needs modifications, then these modifications *should* be made to the original commits (not just tacked on as extra commits), which necessarily means the branch will be rebased. GitHub's workflow breaks completely when you rebase branches. |
|
|
52 |
|
With a GitHub pull-request-based workflow I need a GitHub account |
|
53 |
|
(I've been resisting getting one for myself), I need to make sure I |
|
54 |
|
explicitly "fork" the repository within GitHub (simply pushing my copy |
|
55 |
|
of the repo to my account won't make pull requests work, as far as I |
|
56 |
|
know, because GitHub doesn't know that the original project and my |
|
57 |
|
project are "linked"), and I need to use the GitHub web interface to |
|
58 |
|
actually generate the pull request and take part in its review. If all |
|
59 |
|
of this isn't vendor lock-in, I don't know what is. |
|
60 |
|
I've got bigger problems with the GitHub pull request workflow anyway. |
|
61 |
|
If you generate a pull request, discover that changes need to be made, |
|
62 |
|
you have two choices: you can create a new pull request, losing all |
|
63 |
|
comments from the previous one, or you have to add new commits. If |
|
64 |
|
you drop the to-be-pulled branch from your repository and replace it |
|
65 |
|
with a different branch with the same name, the pull request loses all |
|
66 |
|
of its comments. |
|
67 |
|
No, I find the bigger problems are with pull-request based workflow |
|
68 |
|
that GitHub uses -- specifically, how that workflow interacts with |
|
69 |
|
code review. If your branch is reviewed and it needs modifications, |
|
70 |
|
then these modifications *should* be made to the original commits |
|
71 |
|
(not just tacked on as extra commits), which necessarily means the |
|
72 |
|
branch will be rebased. GitHub's workflow breaks completely when you |
|
73 |
|
rebase branches. |
60 |
74 |
[ ] Should we delete previous session when user calls login if the user is |
[ ] Should we delete previous session when user calls login if the user is |
61 |
75 |
already logged-in? |
already logged-in? |
62 |
76 |
[ ] Talk in instalation about a php compiler? |
[ ] Talk in instalation about a php compiler? |
63 |
77 |
[ ] cache_set should wait for an answer? Should we send an answer? |
[ ] cache_set should wait for an answer? Should we send an answer? |
64 |
78 |
[ ] security_violation_no_exit -> security_violation? To not spend resources? |
[ ] security_violation_no_exit -> security_violation? To not spend resources? |
65 |
|
[ ] Ar trebui sa validez si referer-ul. Si sa loghez pagina de pe care s-a facut |
|
66 |
|
request-ul. |
|
67 |
|
[ ] CSRF for logout |
|
68 |
79 |
[ ] We should be able to have multiple logins (think desktop and phone). |
[ ] We should be able to have multiple logins (think desktop and phone). |
69 |
80 |
[ ] Test if cache is faster than postgres. If not, get rid of cache! |
[ ] Test if cache is faster than postgres. If not, get rid of cache! |
70 |
81 |
[ ] Investigate use of persistent prepared sessions. |
[ ] Investigate use of persistent prepared sessions. |
71 |
|
[ ] What happends if we cvannot generate a form token?! |
|
72 |
|
[ ] Add User-Agent to session (tokens?). |
|
|
82 |
|
[ ] What happends if we cannot generate a form token?! |
|
83 |
|
[ ] Add User-Agent to session? |
73 |
84 |
[ ] Check "Content security policy" |
[ ] Check "Content security policy" |
74 |
85 |
[ ] htmlspcialchars does not escape '/'. It may be dangerous: |
[ ] htmlspcialchars does not escape '/'. It may be dangerous: |
75 |
86 |
https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet |
https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet |
|
... |
... |
Deci, as putea stoca uid-ul pe 4 bytes, expire pe 4 bytes, session_time |
80 |
91 |
pe 2 bytes, si ip-ul doar pe un bit in cimpul de flag-uri. |
pe 2 bytes, si ip-ul doar pe un bit in cimpul de flag-uri. |
81 |
92 |
As putea sa fac lock si pe user agent daca user-ul vrea asta. |
As putea sa fac lock si pe user agent daca user-ul vrea asta. |
82 |
93 |
ip-ul si user agent-ul intra in hmac, dar nu se stocheaza in cookie. |
ip-ul si user agent-ul intra in hmac, dar nu se stocheaza in cookie. |
|
94 |
|
Deci, ar fi 2 * (4 + 4 + 2 + 1) + random part + sig = 22 + 8 + 10 = 40 |
|
95 |
|
But, we have a problem with the expiration time! |
83 |
96 |
[ ] Still, a lot of things from |
[ ] Still, a lot of things from |
84 |
97 |
https://www.owasp.org/index.php/Session_Management_Cheat_Sheet |
https://www.owasp.org/index.php/Session_Management_Cheat_Sheet |
85 |
98 |
needs to be implemented. |
needs to be implemented. |
86 |
99 |
[ ] Add "Secure" cookie para when using HTTPS. |
[ ] Add "Secure" cookie para when using HTTPS. |
87 |
100 |
[ ] Warning if user has not enabled cookies? |
[ ] Warning if user has not enabled cookies? |
88 |
101 |
[ ] Seems that Etag is not working for main.css!!! At least. |
[ ] Seems that Etag is not working for main.css!!! At least. |
89 |
|
[ ] X-Frame-Options: DENY |
|
90 |
102 |
[ ] bad_token.html must not be in user/ |
[ ] bad_token.html must not be in user/ |
91 |
103 |
[ ] On create_account page, submenu1 and submenu2 are with @@...@@! |
[ ] On create_account page, submenu1 and submenu2 are with @@...@@! |
92 |
104 |
[ ] The merge request name is not so good. Maybe include also the user? |
[ ] The merge request name is not so good. Maybe include also the user? |
|
... |
... |
ip-ul si user agent-ul intra in hmac, dar nu se stocheaza in cookie. |
179 |
191 |
[ ] Allow specifying base language for a project. |
[ ] Allow specifying base language for a project. |
180 |
192 |
[ ] Allow specifying license for a project. |
[ ] Allow specifying license for a project. |
181 |
193 |
[ ] When changind db structure, invalidate all caches. |
[ ] When changind db structure, invalidate all caches. |
182 |
|
[ ] Check with owasp about html escaping. I do now htmlspecialchars -> |
|
183 |
|
db -> HTML:nl2br() |
|
184 |
194 |
[ ] When we will switch to C, check UTF-8 validation. |
[ ] When we will switch to C, check UTF-8 validation. |
185 |
195 |
[ ] Check http://blog.wikichoon.com/2014/04/github-doesnt-support-pull-request.html |
[ ] Check http://blog.wikichoon.com/2014/04/github-doesnt-support-pull-request.html |
186 |
196 |
[ ] If path for repo_path rights starts with /, it is anchored. |
[ ] If path for repo_path rights starts with /, it is anchored. |
File inc/git.inc.php changed (mode: 100644) (index 338b0f4..7165cb0) |
... |
... |
function rg_git_diff($a, $template_file) |
822 |
822 |
|
|
823 |
823 |
$ret .= "<br />\n"; |
$ret .= "<br />\n"; |
824 |
824 |
|
|
825 |
|
$f = htmlspecialchars($finfo['file']); |
|
|
825 |
|
$f = rg_xss_safe($finfo['file']); |
826 |
826 |
$ret .= "<a name=\"$f\">\n"; |
$ret .= "<a name=\"$f\">\n"; |
827 |
827 |
|
|
828 |
828 |
$ret .= "<table class=\"chunk\" width=\"100%\">\n"; |
$ret .= "<table class=\"chunk\" width=\"100%\">\n"; |
|
... |
... |
function rg_git_diff($a, $template_file) |
882 |
882 |
|
|
883 |
883 |
$v = preg_replace("/@@line_left@@/", $line_left, $v); |
$v = preg_replace("/@@line_left@@/", $line_left, $v); |
884 |
884 |
$v = preg_replace("/@@line_right@@/", $line_right, $v); |
$v = preg_replace("/@@line_right@@/", $line_right, $v); |
885 |
|
$v = preg_replace("/@@left@@/", htmlspecialchars($left), $v); |
|
886 |
|
$v = preg_replace("/@@right@@/", htmlspecialchars($right), $v); |
|
|
885 |
|
$v = preg_replace("/@@left@@/", rg_xss_safe($left), $v); |
|
886 |
|
$v = preg_replace("/@@right@@/", rg_xss_safe($right), $v); |
887 |
887 |
|
|
888 |
888 |
$v = preg_replace("/@@left_color@@/", $left_color, $v); |
$v = preg_replace("/@@left_color@@/", $left_color, $v); |
889 |
889 |
$v = preg_replace("/@@right_color@@/", $right_color, $v); |
$v = preg_replace("/@@right_color@@/", $right_color, $v); |
|
... |
... |
function rg_git_branches_and_tags($repo_dir, $base_url, $current_ref) |
1146 |
1146 |
continue; |
continue; |
1147 |
1147 |
|
|
1148 |
1148 |
foreach ($list as $name) { |
foreach ($list as $name) { |
1149 |
|
$name = htmlspecialchars($name); |
|
|
1149 |
|
$name = rg_xss_safe($name); |
1150 |
1150 |
$ename = preg_replace('/\//', ',', $name); |
$ename = preg_replace('/\//', ',', $name); |
1151 |
1151 |
//rg_log("DEBUG: compare with [" . $o . "/" . $ename . "]"); |
//rg_log("DEBUG: compare with [" . $o . "/" . $ename . "]"); |
1152 |
1152 |
if (strcmp($current, $o . "/" . $ename) == 0) { |
if (strcmp($current, $o . "/" . $ename) == 0) { |
File inc/keys.inc.php changed (mode: 100644) (index 406bda4..d47956d) |
... |
... |
function rg_keys_remove($db, $ui, $list) |
183 |
183 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
184 |
184 |
|
|
185 |
185 |
$event = array("category" => 1001, "prio" => 50, |
$event = array("category" => 1001, "prio" => 50, |
186 |
|
"ui.email" => $ui['email'], |
|
|
186 |
|
"ui.email" => $ui['confirmed'] > 0 ? $ui['email'] : "", |
187 |
187 |
"IP" => rg_var_str("REMOTE_ADDR"), |
"IP" => rg_var_str("REMOTE_ADDR"), |
188 |
188 |
"keys" => implode(",", $my_list)); |
"keys" => implode(",", $my_list)); |
189 |
189 |
$r = rg_event_add($db, $event); |
$r = rg_event_add($db, $event); |
|
... |
... |
function rg_keys_remove($db, $ui, $list) |
192 |
192 |
. " (" . rg_event_error() . ")"); |
. " (" . rg_event_error() . ")"); |
193 |
193 |
break; |
break; |
194 |
194 |
} |
} |
|
195 |
|
rg_event_signal_daemon("", 0); |
195 |
196 |
|
|
196 |
197 |
$ret = TRUE; |
$ret = TRUE; |
197 |
198 |
break; |
break; |
|
... |
... |
function rg_keys_add($db, $ui, $key) |
289 |
290 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
290 |
291 |
|
|
291 |
292 |
$event = array("category" => 1000, "prio" => 50, |
$event = array("category" => 1000, "prio" => 50, |
292 |
|
"ui.email" => $ui['email'], |
|
|
293 |
|
"ui.email" => $ui['confirmed'] > 0 ? $ui['email'] : "", |
293 |
294 |
"IP" => rg_var_str("REMOTE_ADDR"), |
"IP" => rg_var_str("REMOTE_ADDR"), |
294 |
295 |
"key_id" => $key_id); |
"key_id" => $key_id); |
295 |
296 |
$r = rg_event_add($db, $event); |
$r = rg_event_add($db, $event); |
|
... |
... |
function rg_keys_add($db, $ui, $key) |
307 |
308 |
} |
} |
308 |
309 |
$do_rollback = 0; |
$do_rollback = 0; |
309 |
310 |
|
|
|
311 |
|
rg_event_signal_daemon("", 0); |
|
312 |
|
|
310 |
313 |
$ret = $key_id; |
$ret = $key_id; |
311 |
314 |
break; |
break; |
312 |
315 |
} |
} |
|
... |
... |
function rg_keys_regen($db) |
385 |
388 |
rg_keys_set_error("cannot create dir [$dir] ($php_errormsg)"); |
rg_keys_set_error("cannot create dir [$dir] ($php_errormsg)"); |
386 |
389 |
break; |
break; |
387 |
390 |
} |
} |
|
391 |
|
chown($dir, "rocketgit"); |
|
392 |
|
chgrp($dir, "rocketgit"); |
388 |
393 |
} |
} |
389 |
394 |
|
|
390 |
395 |
$tmp = $rg_keys_file . ".tmp"; |
$tmp = $rg_keys_file . ".tmp"; |
|
... |
... |
function rg_keys_regen($db) |
399 |
404 |
fclose($f); |
fclose($f); |
400 |
405 |
break; |
break; |
401 |
406 |
} |
} |
|
407 |
|
chown($tmp, "rocketgit"); |
|
408 |
|
chgrp($tmp, "rocketgit"); |
402 |
409 |
|
|
403 |
410 |
$sql = "SELECT key_id, uid, key FROM keys ORDER BY count DESC"; |
$sql = "SELECT key_id, uid, key FROM keys ORDER BY count DESC"; |
404 |
411 |
$res = rg_sql_query($db, $sql); |
$res = rg_sql_query($db, $sql); |
File inc/prof.inc.php changed (mode: 100644) (index b1eb16a..bb3fb31) |
... |
... |
function rg_prof_start($label) |
32 |
32 |
} else { |
} else { |
33 |
33 |
$rg_prof_tmp[$label] = $rg_prof_state; |
$rg_prof_tmp[$label] = $rg_prof_state; |
34 |
34 |
$rg_prof_tmp[$label]['time_ms'] = sprintf("%u", microtime(TRUE) * 1000); |
$rg_prof_tmp[$label]['time_ms'] = sprintf("%u", microtime(TRUE) * 1000); |
35 |
|
$rg_prof_tmp[$label]['mem'] = memory_get_usage(); |
|
36 |
|
$rg_prof_tmp[$label]['real_mem'] = memory_get_usage(TRUE); |
|
|
35 |
|
$rg_prof_tmp[$label]['mem'] = intval(memory_get_usage() / 1024); |
37 |
36 |
$rg_prof_tmp[$label]['level'] = 1; |
$rg_prof_tmp[$label]['level'] = 1; |
38 |
37 |
$rg_prof_tmp[$label]['runs'] = 1; |
$rg_prof_tmp[$label]['runs'] = 1; |
39 |
38 |
} |
} |
|
... |
... |
function rg_prof_end($label) |
60 |
59 |
$c = $rg_prof_state; |
$c = $rg_prof_state; |
61 |
60 |
$c['time_ms'] = sprintf("%u", microtime(TRUE) * 1000); |
$c['time_ms'] = sprintf("%u", microtime(TRUE) * 1000); |
62 |
61 |
$c['runs'] = $start['runs']; $start['runs'] = 0; |
$c['runs'] = $start['runs']; $start['runs'] = 0; |
63 |
|
$c['mem'] = memory_get_usage(); |
|
64 |
|
$c['real_mem'] = memory_get_usage(TRUE); |
|
|
62 |
|
$c['mem'] = intval(memory_get_usage() / 1024); |
65 |
63 |
$c['level'] = 0; // just to not complain that is not defined |
$c['level'] = 0; // just to not complain that is not defined |
66 |
64 |
|
|
67 |
65 |
// we substract what was before start |
// we substract what was before start |
|
... |
... |
function rg_prof_get() |
92 |
90 |
return $rg_prof_main; |
return $rg_prof_main; |
93 |
91 |
} |
} |
94 |
92 |
|
|
95 |
|
function rg_prof_log($cb) |
|
96 |
|
{ |
|
97 |
|
global $rg_prof_main; |
|
98 |
|
|
|
99 |
|
$cb("Profiling:"); |
|
100 |
|
foreach ($rg_prof_main as $label => $per_label) { |
|
101 |
|
$line = " " . $label . ":"; |
|
102 |
|
|
|
103 |
|
foreach ($per_label as $k => $v) { |
|
104 |
|
if ($v > 0) |
|
105 |
|
$line .= " $k=$v"; |
|
106 |
|
} |
|
107 |
|
$cb($line); |
|
108 |
|
} |
|
109 |
|
} |
|
110 |
|
|
|
111 |
93 |
function rg_prof_html() |
function rg_prof_html() |
112 |
94 |
{ |
{ |
113 |
95 |
global $rg_prof_main; |
global $rg_prof_main; |
|
... |
... |
function rg_prof_html() |
146 |
128 |
return $ret; |
return $ret; |
147 |
129 |
} |
} |
148 |
130 |
|
|
|
131 |
|
function rg_prof_sort($a, $b) |
|
132 |
|
{ |
|
133 |
|
if (!isset($a['time_ms'])) |
|
134 |
|
return 1; |
|
135 |
|
if (!isset($b['time_ms'])) |
|
136 |
|
return 1; |
|
137 |
|
|
|
138 |
|
return $a['time_ms'] > $b['time_ms']; |
|
139 |
|
} |
|
140 |
|
|
149 |
141 |
function rg_prof_text() |
function rg_prof_text() |
150 |
142 |
{ |
{ |
151 |
143 |
global $rg_prof_main; |
global $rg_prof_main; |
|
... |
... |
function rg_prof_text() |
157 |
149 |
foreach ($rg_prof_main as $label => $per_label) |
foreach ($rg_prof_main as $label => $per_label) |
158 |
150 |
foreach ($per_label as $k => $v) |
foreach ($per_label as $k => $v) |
159 |
151 |
$vars[$k] = 1; |
$vars[$k] = 1; |
|
152 |
|
unset($vars['level']); |
|
153 |
|
|
|
154 |
|
// sort by time_ms |
|
155 |
|
uasort($rg_prof_main, "rg_prof_sort"); |
|
156 |
|
|
|
157 |
|
$ret .= str_pad("Profiling:", 22, ' '); |
|
158 |
|
foreach ($vars as $k => $v) |
|
159 |
|
$ret .= "\t" . $k; |
|
160 |
|
$ret .= "\n"; |
160 |
161 |
|
|
161 |
162 |
$add = ""; |
$add = ""; |
162 |
163 |
foreach ($rg_prof_main as $label => $per_label) { |
foreach ($rg_prof_main as $label => $per_label) { |
163 |
164 |
$ret .= $add; |
$ret .= $add; |
164 |
165 |
$add = "\n"; |
$add = "\n"; |
165 |
166 |
|
|
166 |
|
$ret .= $label . ": "; |
|
|
167 |
|
$ret .= str_pad($label, 22, ' '); |
167 |
168 |
|
|
168 |
169 |
foreach ($vars as $k => $junk) { |
foreach ($vars as $k => $junk) { |
169 |
170 |
if (!isset($per_label[$k])) |
if (!isset($per_label[$k])) |
170 |
171 |
$v = 0; |
$v = 0; |
171 |
172 |
else |
else |
172 |
173 |
$v = $per_label[$k]; |
$v = $per_label[$k]; |
173 |
|
$ret .= " $k=$v"; |
|
|
174 |
|
$ret .= "\t$v"; |
174 |
175 |
} |
} |
175 |
176 |
} |
} |
176 |
177 |
|
|
177 |
178 |
return $ret; |
return $ret; |
178 |
179 |
} |
} |
|
180 |
|
|
|
181 |
|
function rg_prof_log() |
|
182 |
|
{ |
|
183 |
|
$p = rg_prof_text(); |
|
184 |
|
rg_log_ml($p); |
|
185 |
|
} |
|
186 |
|
|
179 |
187 |
?> |
?> |
File inc/repo.inc.php changed (mode: 100644) (index d6920df..5017f0c) |
... |
... |
function rg_repo_path_by_name($uid, $repo_name) |
592 |
592 |
*/ |
*/ |
593 |
593 |
function rg_repo_cosmetic(&$row) |
function rg_repo_cosmetic(&$row) |
594 |
594 |
{ |
{ |
595 |
|
$_a = htmlspecialchars($row['description'], ENT_QUOTES); |
|
|
595 |
|
$_a = rg_xss_safe($row['description']); |
596 |
596 |
$row['HTML:description_nice'] = nl2br($_a); |
$row['HTML:description_nice'] = nl2br($_a); |
597 |
597 |
} |
} |
598 |
598 |
|
|
|
... |
... |
function rg_repo_delete($db, $repo_id, $ui) |
712 |
712 |
|
|
713 |
713 |
$event = array("category" => 3001, "prio" => 50, |
$event = array("category" => 3001, "prio" => 50, |
714 |
714 |
"IP" => rg_var_str("REMOTE_ADDR"), |
"IP" => rg_var_str("REMOTE_ADDR"), |
715 |
|
"ui.email" => $ui['email'], |
|
|
715 |
|
"ui.email" => $ui['confirmed'] > 0 ? $ui['email'] : "", |
716 |
716 |
"ri.name" => $ri['name'], |
"ri.name" => $ri['name'], |
717 |
717 |
"ri.repo_id" => $repo_id); |
"ri.repo_id" => $repo_id); |
718 |
718 |
$r = rg_event_add($db, $event); |
$r = rg_event_add($db, $event); |
|
... |
... |
function rg_repo_delete($db, $repo_id, $ui) |
721 |
721 |
. " (" . rg_event_error() . ")"); |
. " (" . rg_event_error() . ")"); |
722 |
722 |
break; |
break; |
723 |
723 |
} |
} |
|
724 |
|
rg_event_signal_daemon("", 0); |
724 |
725 |
|
|
725 |
726 |
rg_cache_unset("repo_by_id::$repo_id"); |
rg_cache_unset("repo_by_id::$repo_id"); |
726 |
727 |
rg_cache_unset("repo_by_name::" . $ui['uid'] . "::" . $ri['name']); |
rg_cache_unset("repo_by_name::" . $ui['uid'] . "::" . $ri['name']); |
|
... |
... |
function rg_repo_edit($db, $login_ui, &$new) |
936 |
937 |
$event = array("category" => $cat, "prio" => 50, |
$event = array("category" => $cat, "prio" => 50, |
937 |
938 |
"notification" => $notification, |
"notification" => $notification, |
938 |
939 |
"ui.uid" => $login_ui['uid'], |
"ui.uid" => $login_ui['uid'], |
939 |
|
"ui.email" => $login_ui['email'], |
|
|
940 |
|
"ui.email" => $login_ui['confirmed'] > 0 ? $login_ui['email'] : "", |
940 |
941 |
"ri.url" => rg_base_url() . rg_re_repopage($login_ui, $new['name']), |
"ri.url" => rg_base_url() . rg_re_repopage($login_ui, $new['name']), |
941 |
942 |
"history_category" => $hcat, |
"history_category" => $hcat, |
942 |
943 |
"history_message" => $hmess, |
"history_message" => $hmess, |
|
... |
... |
function rg_repo_edit($db, $login_ui, &$new) |
951 |
952 |
. " (" . rg_event_error() . ")"); |
. " (" . rg_event_error() . ")"); |
952 |
953 |
break; |
break; |
953 |
954 |
} |
} |
|
955 |
|
rg_event_signal_daemon("", 0); |
954 |
956 |
|
|
955 |
957 |
$new['ok'] = 1; |
$new['ok'] = 1; |
956 |
958 |
$new['exists'] = 1; |
$new['exists'] = 1; |
|
... |
... |
function rg_repo_admin_delete_rights($db, $rg, $obj_id, &$errmsg) |
1177 |
1179 |
return; |
return; |
1178 |
1180 |
} |
} |
1179 |
1181 |
|
|
1180 |
|
if (!rg_token_valid($db, $rg)) { |
|
|
1182 |
|
if (!rg_token_valid($db, $rg, FALSE)) { |
1181 |
1183 |
$errmsg[] = "invalid token; try again"; |
$errmsg[] = "invalid token; try again"; |
1182 |
1184 |
return; |
return; |
1183 |
1185 |
} |
} |
|
... |
... |
function rg_repo_admin_rights($db, $rg, $type) |
1273 |
1275 |
break; |
break; |
1274 |
1276 |
} |
} |
1275 |
1277 |
|
|
1276 |
|
if (!rg_token_valid($db, $rg)) { |
|
|
1278 |
|
if (!rg_token_valid($db, $rg, FALSE)) { |
1277 |
1279 |
$errmsg[] = "invalid token; try again"; |
$errmsg[] = "invalid token; try again"; |
1278 |
1280 |
break; |
break; |
1279 |
1281 |
} |
} |
|
... |
... |
function rg_repo_admin_delete($db, $rg) |
1374 |
1376 |
break; |
break; |
1375 |
1377 |
} |
} |
1376 |
1378 |
|
|
1377 |
|
if (!rg_token_valid($db, $rg)) { |
|
|
1379 |
|
if (!rg_token_valid($db, $rg, FALSE)) { |
1378 |
1380 |
$errmsg[] = "invalid token; try again"; |
$errmsg[] = "invalid token; try again"; |
1379 |
1381 |
break; |
break; |
1380 |
1382 |
} |
} |
|
... |
... |
function rg_repo_edit_high_level($db, &$rg) |
1414 |
1416 |
$errmsg = array(); |
$errmsg = array(); |
1415 |
1417 |
$load_form = TRUE; |
$load_form = TRUE; |
1416 |
1418 |
while (1) { |
while (1) { |
1417 |
|
if (rg_rights_allow($db, $rg['ri']['repo_id'], "repo", $rg['ri']['uid'], |
|
1418 |
|
$rg['login_ui']['uid'], "E", $rg['ip'], "") !== TRUE) { |
|
|
1419 |
|
if (($rg['ri']['repo_id'] > 0) && (rg_rights_allow($db, $rg['ri']['repo_id'], "repo", $rg['ri']['uid'], |
|
1420 |
|
$rg['login_ui']['uid'], "E", $rg['ip'], "") !== TRUE)) { |
1419 |
1421 |
$ret .= rg_template("user/repo/deny_edit.html", $rg); |
$ret .= rg_template("user/repo/deny_edit.html", $rg); |
1420 |
1422 |
$load_form = FALSE; |
$load_form = FALSE; |
1421 |
1423 |
break; |
break; |
1422 |
1424 |
} |
} |
1423 |
1425 |
|
|
1424 |
1426 |
if ($rg['doit'] != 1) { |
if ($rg['doit'] != 1) { |
1425 |
|
if (!isset($rg['ri'])) { |
|
|
1427 |
|
if ($rg['ri']['repo_id'] == 0) { |
1426 |
1428 |
// Defaults |
// Defaults |
|
1429 |
|
$rg['ri'] = array(); |
1427 |
1430 |
$rg['ri']['repo_id'] = "0"; |
$rg['ri']['repo_id'] = "0"; |
1428 |
1431 |
$rg['ri']['master'] = "0"; |
$rg['ri']['master'] = "0"; |
1429 |
1432 |
$rg['ri']['name'] = ""; |
$rg['ri']['name'] = ""; |
|
... |
... |
function rg_repo_edit_high_level($db, &$rg) |
1439 |
1442 |
break; |
break; |
1440 |
1443 |
} |
} |
1441 |
1444 |
|
|
1442 |
|
if (!rg_token_valid($db, $rg)) { |
|
|
1445 |
|
if (!rg_token_valid($db, $rg, FALSE)) { |
1443 |
1446 |
// TODO: replace all of these with a template |
// TODO: replace all of these with a template |
1444 |
1447 |
$errmsg[] = "invalid token; try again."; |
$errmsg[] = "invalid token; try again."; |
1445 |
1448 |
break; |
break; |
File inc/token.inc.php changed (mode: 100644) (index ecf6f7e..c16461f) |
... |
... |
function rg_token_delete($db, $sid, $token) |
30 |
30 |
$ret = array(); |
$ret = array(); |
31 |
31 |
$ret['ok'] = 0; |
$ret['ok'] = 0; |
32 |
32 |
while (1) { |
while (1) { |
33 |
|
$params = array("sid" => $sid, "token" => $token); |
|
|
33 |
|
$params = array("sid" => $sid); |
34 |
34 |
$add_token = ""; |
$add_token = ""; |
35 |
|
if (!empty($token)) |
|
|
35 |
|
if (!empty($token)) { |
36 |
36 |
$add_token = " AND token = @@token@@"; |
$add_token = " AND token = @@token@@"; |
|
37 |
|
$params['token'] = $token; |
|
38 |
|
} |
37 |
39 |
|
|
38 |
40 |
$sql = "DELETE FROM tokens" |
$sql = "DELETE FROM tokens" |
39 |
41 |
. " WHERE sid = @@sid@@" |
. " WHERE sid = @@sid@@" |
|
... |
... |
function rg_token_get_master($db) |
93 |
95 |
/* |
/* |
94 |
96 |
* Returns TRUE if the token is valid |
* Returns TRUE if the token is valid |
95 |
97 |
*/ |
*/ |
96 |
|
function rg_token_valid($db, $rg) |
|
|
98 |
|
function rg_token_valid($db, $rg, $double_allowed) |
97 |
99 |
{ |
{ |
98 |
100 |
rg_prof_start("token_valid"); |
rg_prof_start("token_valid"); |
99 |
101 |
rg_log_enter("token_valid: sid=" . $rg['sid'] . " token=" . $rg['token'] |
rg_log_enter("token_valid: sid=" . $rg['sid'] . " token=" . $rg['token'] |
|
... |
... |
function rg_token_valid($db, $rg) |
101 |
103 |
|
|
102 |
104 |
$ret = FALSE; |
$ret = FALSE; |
103 |
105 |
while (1) { |
while (1) { |
104 |
|
$ua_hash = substr(sha1($rg['ua']), 0, 8); |
|
|
106 |
|
$ua_hash = substr(sha512($rg['ua']), 0, 8); |
105 |
107 |
|
|
106 |
|
if (strncmp($rg['sid'], "X", 1) == 0) { |
|
107 |
|
// We have a pre-login session. |
|
108 |
|
if (strlen($rg['token']) != 32) { |
|
109 |
|
rg_token_set_error("invalid token"); |
|
110 |
|
break; |
|
111 |
|
} |
|
|
108 |
|
if (strlen($rg['token']) != 32) { |
|
109 |
|
rg_token_set_error("invalid token"); |
|
110 |
|
rg_security_violation_no_exit("invalid token (len)"); |
|
111 |
|
break; |
|
112 |
|
} |
112 |
113 |
|
|
113 |
|
$key = rg_token_get_master($db); |
|
114 |
|
if ($key === FALSE) |
|
115 |
|
break; |
|
|
114 |
|
$key = rg_token_get_master($db); |
|
115 |
|
if ($key === FALSE) |
|
116 |
|
break; |
116 |
117 |
|
|
117 |
|
$rand = substr($rg['token'], 0, 16); |
|
118 |
|
$sign = substr($rg['token'], 16, 16); |
|
|
118 |
|
$rand = substr($rg['token'], 0, 16); |
|
119 |
|
$sign = substr($rg['token'], 16, 16); |
119 |
120 |
|
|
120 |
|
$data = $rand . $rg['sid'] . $ua_hash; |
|
121 |
|
$hash = hash_hmac("sha1", $data, $key); |
|
122 |
|
if ($hash === FALSE) { |
|
123 |
|
rg_token_set_error("cannot compute hmac"); |
|
124 |
|
break; |
|
125 |
|
} |
|
|
121 |
|
$data = $rand . $rg['sid'] . $ua_hash; |
|
122 |
|
$hash = hash_hmac("sha512", $data, $key); |
|
123 |
|
if ($hash === FALSE) { |
|
124 |
|
rg_token_set_error("cannot compute hmac"); |
|
125 |
|
break; |
|
126 |
|
} |
126 |
127 |
|
|
127 |
|
$hash = substr($hash, 0, 16); |
|
128 |
|
if (strcmp($sign, $hash) != 0) { |
|
129 |
|
rg_log("DEBUG: sign=$sign != hash=$hash data=$data"); |
|
130 |
|
rg_token_set_error("token invalid"); |
|
131 |
|
break; |
|
132 |
|
} |
|
|
128 |
|
$hash = substr($hash, 0, 16); |
|
129 |
|
if (strcmp($sign, $hash) != 0) { |
|
130 |
|
rg_log("DEBUG: sign=$sign != hash=$hash data=$data"); |
|
131 |
|
rg_token_set_error("token invalid"); |
|
132 |
|
rg_security_violation_no_exit("invalid token (sign)"); |
|
133 |
|
break; |
|
134 |
|
} |
133 |
135 |
|
|
|
136 |
|
if (strncmp($rg['sid'], "X", 1) == 0) { |
|
137 |
|
// We have a pre-login session: we do not have to mark |
|
138 |
|
// the token as used. |
134 |
139 |
$ret = TRUE; |
$ret = TRUE; |
135 |
140 |
break; |
break; |
136 |
141 |
} |
} |
137 |
142 |
|
|
138 |
|
$rand = substr($rg['token'], 0, 16); |
|
139 |
|
$search = $rand . $ua_hash; |
|
140 |
|
$params = array("sid" => $rg['sid'], "token" => $search); |
|
141 |
|
$sql = "UPDATE tokens SET used = 1" |
|
142 |
|
. " WHERE token = @@token@@" |
|
143 |
|
. " AND sid = @@sid@@" |
|
144 |
|
. " AND used = 0"; |
|
|
143 |
|
if ($double_allowed) { |
|
144 |
|
$ret = TRUE; |
|
145 |
|
break; |
|
146 |
|
} |
|
147 |
|
|
|
148 |
|
$params = array("sid" => $rg['sid'], |
|
149 |
|
"token" => $rg['token'], |
|
150 |
|
"expire" => time() + 24 * 3600); |
|
151 |
|
|
|
152 |
|
// We check to see if token was already used |
|
153 |
|
$sql = "SELECT 1 FROM tokens" |
|
154 |
|
. " WHERE sid = @@sid@@" |
|
155 |
|
. " AND token = @@token@@"; |
145 |
156 |
$res = rg_sql_query_params($db, $sql, $params); |
$res = rg_sql_query_params($db, $sql, $params); |
146 |
157 |
if ($res === FALSE) { |
if ($res === FALSE) { |
147 |
|
rg_token_set_error("cannot get token (" . rg_sql_error() . ")"); |
|
|
158 |
|
rg_token_set_error("cannot check if token is used" |
|
159 |
|
. " (" . rg_sql_error() . ")"); |
148 |
160 |
break; |
break; |
149 |
161 |
} |
} |
150 |
|
|
|
151 |
|
$rows = rg_sql_affected_rows($res); |
|
|
162 |
|
$rows = rg_sql_num_rows($res); |
152 |
163 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
153 |
|
if ($rows == 0) |
|
|
164 |
|
if ($rows == 1) { |
|
165 |
|
rg_token_set_error("token already used"); |
154 |
166 |
break; |
break; |
|
167 |
|
} |
155 |
168 |
|
|
156 |
|
$ret = TRUE; |
|
157 |
|
break; |
|
158 |
|
} |
|
159 |
|
|
|
160 |
|
if ($ret === FALSE) |
|
161 |
|
rg_security_violation_no_exit("invalid token"); |
|
162 |
|
|
|
163 |
|
rg_log_exit(); |
|
164 |
|
rg_prof_end("token_valid"); |
|
165 |
|
return $ret; |
|
166 |
|
} |
|
167 |
|
|
|
168 |
|
/* |
|
169 |
|
* Insert a token |
|
170 |
|
*/ |
|
171 |
|
function rg_token_insert($db, $sid, $token) |
|
172 |
|
{ |
|
173 |
|
rg_prof_start("token_insert"); |
|
174 |
|
rg_log_enter("token_insert: sid=$sid token=$token"); |
|
175 |
|
|
|
176 |
|
$ret = array(); |
|
177 |
|
$ret['ok'] = 0; |
|
178 |
|
while (1) { |
|
179 |
|
$now = time(); |
|
180 |
|
|
|
181 |
|
$params = array("sid" => $sid, |
|
182 |
|
"token" => $token, |
|
183 |
|
"expire" => $now + 24 * 3600); |
|
184 |
169 |
$sql = "INSERT INTO tokens (sid, token, expire)" |
$sql = "INSERT INTO tokens (sid, token, expire)" |
185 |
170 |
. " VALUES (@@sid@@, @@token@@, @@expire@@)"; |
. " VALUES (@@sid@@, @@token@@, @@expire@@)"; |
186 |
171 |
$res = rg_sql_query_params($db, $sql, $params); |
$res = rg_sql_query_params($db, $sql, $params); |
187 |
172 |
if ($res === FALSE) { |
if ($res === FALSE) { |
188 |
|
rg_token_set_error("cannot insert token (" . rg_sql_error() . ")!"); |
|
|
173 |
|
rg_token_set_error("cannot insert token" |
|
174 |
|
. " (" . rg_sql_error() . ")"); |
189 |
175 |
break; |
break; |
190 |
176 |
} |
} |
|
177 |
|
rg_sql_free_result($res); |
191 |
178 |
|
|
192 |
|
$ret['ok'] = 1; |
|
|
179 |
|
$ret = TRUE; |
193 |
180 |
break; |
break; |
194 |
181 |
} |
} |
195 |
182 |
|
|
196 |
183 |
rg_log_exit(); |
rg_log_exit(); |
197 |
|
rg_prof_end("token_insert"); |
|
|
184 |
|
rg_prof_end("token_valid"); |
198 |
185 |
return $ret; |
return $ret; |
199 |
186 |
} |
} |
200 |
187 |
|
|
|
... |
... |
function rg_token_get($db, $rg) |
219 |
206 |
break; |
break; |
220 |
207 |
} |
} |
221 |
208 |
|
|
222 |
|
$rand = rg_id(16); |
|
223 |
|
$ua_hash = substr(sha1($rg['ua']), 0, 8); |
|
|
209 |
|
$key = rg_token_get_master($db); |
|
210 |
|
if ($key === FALSE) |
|
211 |
|
break; |
224 |
212 |
|
|
225 |
|
if (strncmp($rg['sid'], "X", 1) == 0) { |
|
226 |
|
// we have a pre-login session |
|
227 |
|
$key = rg_token_get_master($db); |
|
228 |
|
if ($key === FALSE) |
|
229 |
|
break; |
|
|
213 |
|
$rand = rg_id(16); |
|
214 |
|
$ua_hash = substr(sha512($rg['ua']), 0, 8); |
230 |
215 |
|
|
231 |
|
$data = $rand . $rg['sid'] . $ua_hash; |
|
232 |
|
$sign = hash_hmac("sha1", $data, $key); |
|
233 |
|
if ($sign === FALSE) { |
|
234 |
|
rg_token_set_error("cannot compute hmac"); |
|
235 |
|
break; |
|
236 |
|
} |
|
237 |
|
$sign = substr($sign, 0, 16); |
|
238 |
|
$token = $rand . $sign; |
|
239 |
|
|
|
240 |
|
rg_log("DEBUG: sign=$sign rand=$rand sid=" . $rg['sid'] . " ua_hash=$ua_hash"); |
|
241 |
|
} else { |
|
242 |
|
$token = $rand . $ua_hash; |
|
243 |
|
$r = rg_token_insert($db, $rg['sid'], $token); |
|
244 |
|
if ($r['ok'] != 1) |
|
245 |
|
break; |
|
|
216 |
|
$data = $rand . $rg['sid'] . $ua_hash; |
|
217 |
|
$sign = hash_hmac("sha512", $data, $key); |
|
218 |
|
if ($sign === FALSE) { |
|
219 |
|
rg_token_set_error("cannot compute hmac"); |
|
220 |
|
break; |
246 |
221 |
} |
} |
247 |
|
|
|
248 |
|
$rg_token = $token; |
|
249 |
|
$ret = $token; |
|
|
222 |
|
$sign = substr($sign, 0, 16); |
|
223 |
|
$rg_token = $rand . $sign; |
|
224 |
|
$ret = $rg_token; |
250 |
225 |
break; |
break; |
251 |
226 |
} |
} |
252 |
227 |
|
|
File inc/user.inc.php changed (mode: 100644) (index 04dd2ac..45838ef) |
... |
... |
function rg_user_url($ui) |
184 |
184 |
*/ |
*/ |
185 |
185 |
function rg_user_pass($salt, $pass) |
function rg_user_pass($salt, $pass) |
186 |
186 |
{ |
{ |
187 |
|
return sha1($salt . "===" . $pass); |
|
|
187 |
|
return sha512($salt . "===" . $pass); |
188 |
188 |
} |
} |
189 |
189 |
|
|
190 |
190 |
/* |
/* |
|
... |
... |
function rg_user_rename($db, $ui, $new_name) |
388 |
388 |
. " (" . rg_event_error() . ")"); |
. " (" . rg_event_error() . ")"); |
389 |
389 |
break; |
break; |
390 |
390 |
} |
} |
|
391 |
|
rg_event_signal_daemon("", 0); |
391 |
392 |
|
|
392 |
393 |
$ret = TRUE; |
$ret = TRUE; |
393 |
394 |
break; |
break; |
|
... |
... |
function rg_user_edit($db, $d) |
501 |
502 |
$event = array("category" => 2000, "prio" => 50, |
$event = array("category" => 2000, "prio" => 50, |
502 |
503 |
"ui.uid" => $d['uid'], |
"ui.uid" => $d['uid'], |
503 |
504 |
"ui.username" => $d['username'], |
"ui.username" => $d['username'], |
504 |
|
"ui.email" => $d['email'], |
|
|
505 |
|
"ui.email" => $confirmed > 0 ? $d['email'] : "", |
505 |
506 |
"ui.confirm_token" => $d['confirm_token'], |
"ui.confirm_token" => $d['confirm_token'], |
506 |
507 |
"rg_account_email_confirm" => $rg_account_email_confirm, |
"rg_account_email_confirm" => $rg_account_email_confirm, |
507 |
508 |
"url" => rg_base_url() |
"url" => rg_base_url() |
|
... |
... |
function rg_user_edit($db, $d) |
511 |
512 |
rg_user_set_error("Cannot add event!"); |
rg_user_set_error("Cannot add event!"); |
512 |
513 |
break; |
break; |
513 |
514 |
} |
} |
|
515 |
|
rg_event_signal_daemon("", 0); |
514 |
516 |
} |
} |
515 |
517 |
|
|
516 |
518 |
// 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_info($db, $uid, $user, $email) |
599 |
601 |
$sql = "SELECT * FROM users WHERE username = @@user@@"; |
$sql = "SELECT * FROM users WHERE username = @@user@@"; |
600 |
602 |
} else if (!empty($email)) { |
} else if (!empty($email)) { |
601 |
603 |
$c = rg_cache_get("email_to_uid::" . $email); |
$c = rg_cache_get("email_to_uid::" . $email); |
602 |
|
if ($c != FALSE) { |
|
|
604 |
|
if ($c !== FALSE) { |
603 |
605 |
$uid = $c; |
$uid = $c; |
604 |
606 |
continue; |
continue; |
605 |
607 |
} |
} |
|
... |
... |
function rg_user_info($db, $uid, $user, $email) |
633 |
635 |
rg_cache_set("user::" . $uid, $ret); |
rg_cache_set("user::" . $uid, $ret); |
634 |
636 |
rg_cache_set("username_to_uid::" . $ret['username'], $ret['uid']); |
rg_cache_set("username_to_uid::" . $ret['username'], $ret['uid']); |
635 |
637 |
rg_cache_set("email_to_uid::" . $ret['email'], $ret['uid']); |
rg_cache_set("email_to_uid::" . $ret['email'], $ret['uid']); |
636 |
|
|
|
637 |
638 |
break; |
break; |
638 |
639 |
} |
} |
639 |
640 |
|
|
|
... |
... |
function rg_user_list($db) |
1055 |
1056 |
*/ |
*/ |
1056 |
1057 |
function rg_user_forgot_pass_uid($db, $token) |
function rg_user_forgot_pass_uid($db, $token) |
1057 |
1058 |
{ |
{ |
|
1059 |
|
rg_prof_start("user_forgot_pass_uid"); |
|
1060 |
|
rg_log_enter("user_forgot_pass_uid: token=$token"); |
|
1061 |
|
|
1058 |
1062 |
$ret = array(); |
$ret = array(); |
1059 |
1063 |
$ret['ok'] = 0; |
$ret['ok'] = 0; |
1060 |
1064 |
$ret['uid'] = 0; |
$ret['uid'] = 0; |
1061 |
|
|
|
1062 |
|
rg_log_enter("user_forgot_pass_uid: token=$token"); |
|
1063 |
|
|
|
1064 |
1065 |
while (1) { |
while (1) { |
1065 |
1066 |
$now = time(); |
$now = time(); |
1066 |
1067 |
|
|
|
... |
... |
function rg_user_forgot_pass_uid($db, $token) |
1088 |
1089 |
} |
} |
1089 |
1090 |
|
|
1090 |
1091 |
rg_log_exit(); |
rg_log_exit(); |
|
1092 |
|
rg_prof_end("user_forgot_pass_uid"); |
1091 |
1093 |
return $ret; |
return $ret; |
1092 |
1094 |
} |
} |
1093 |
1095 |
|
|
|
... |
... |
function rg_user_forgot_pass_destroy($db, $uid) |
1218 |
1220 |
*/ |
*/ |
1219 |
1221 |
function rg_user_set_pass($db, $uid, $pass) |
function rg_user_set_pass($db, $uid, $pass) |
1220 |
1222 |
{ |
{ |
1221 |
|
rg_log("user_set_pass: uid=$uid pass=$pass"); |
|
|
1223 |
|
rg_prof_start("user_set_pass"); |
|
1224 |
|
rg_log_enter("user_set_pass: uid=$uid pass=$pass"); |
1222 |
1225 |
|
|
1223 |
1226 |
$ret = FALSE; |
$ret = FALSE; |
1224 |
1227 |
while (1) { |
while (1) { |
|
... |
... |
function rg_user_set_pass($db, $uid, $pass) |
1229 |
1232 |
"pass" => $pass, |
"pass" => $pass, |
1230 |
1233 |
"uid" => $uid); |
"uid" => $uid); |
1231 |
1234 |
$sql = "UPDATE users SET" |
$sql = "UPDATE users SET" |
1232 |
|
." salt = @@salt@@" |
|
|
1235 |
|
. " salt = @@salt@@" |
1233 |
1236 |
. ", pass = @@pass@@" |
. ", pass = @@pass@@" |
1234 |
1237 |
. " WHERE uid = @@uid@@"; |
. " WHERE uid = @@uid@@"; |
1235 |
1238 |
$res = rg_sql_query_params($db, $sql, $params); |
$res = rg_sql_query_params($db, $sql, $params); |
|
... |
... |
function rg_user_set_pass($db, $uid, $pass) |
1239 |
1242 |
} |
} |
1240 |
1243 |
rg_sql_free_result($res); |
rg_sql_free_result($res); |
1241 |
1244 |
|
|
1242 |
|
// Update cache |
|
1243 |
|
$_m = array("salt" => $salt, "pass" => $pass); |
|
1244 |
|
rg_cache_merge("user::$uid", $_m); |
|
|
1245 |
|
// Because we may not have info about the user in cache, |
|
1246 |
|
// we cannot do a merge. |
|
1247 |
|
rg_cache_unset("user::$uid"); |
1245 |
1248 |
|
|
1246 |
1249 |
$ret = TRUE; |
$ret = TRUE; |
1247 |
1250 |
break; |
break; |
1248 |
1251 |
} |
} |
1249 |
1252 |
|
|
1250 |
1253 |
rg_log_exit(); |
rg_log_exit(); |
|
1254 |
|
rg_prof_end("user_set_pass"); |
1251 |
1255 |
return $ret; |
return $ret; |
1252 |
1256 |
} |
} |
1253 |
1257 |
|
|
|
... |
... |
function rg_user_edit_high_level($db, &$rg) |
1427 |
1431 |
break; |
break; |
1428 |
1432 |
} |
} |
1429 |
1433 |
|
|
1430 |
|
if (!rg_token_valid($db, $rg)) { |
|
|
1434 |
|
if (!rg_token_valid($db, $rg, FALSE)) { |
1431 |
1435 |
$errmsg[] = "invalid token; try again"; |
$errmsg[] = "invalid token; try again"; |
1432 |
1436 |
break; |
break; |
1433 |
1437 |
} |
} |
File inc/util.inc.php changed (mode: 100644) (index 595382f..620aa6f) |
... |
... |
function rg_template_func($name, $real_func_name) |
36 |
36 |
$rg_template_functions[$name] = $real_func_name; |
$rg_template_functions[$name] = $real_func_name; |
37 |
37 |
} |
} |
38 |
38 |
|
|
|
39 |
|
function sha512($m) |
|
40 |
|
{ |
|
41 |
|
return hash('sha512', $m); |
|
42 |
|
} |
|
43 |
|
|
39 |
44 |
function rg_1024($v) |
function rg_1024($v) |
40 |
45 |
{ |
{ |
41 |
46 |
if ($v <= 9999) |
if ($v <= 9999) |
|
... |
... |
function rg_id($len) |
70 |
75 |
if ($f !== NULL) { |
if ($f !== NULL) { |
71 |
76 |
$buf = @fread($f, 128); |
$buf = @fread($f, 128); |
72 |
77 |
if ($buf !== NULL) |
if ($buf !== NULL) |
73 |
|
$id = sha1($buf); |
|
|
78 |
|
$id = sha512($buf); |
74 |
79 |
fclose($f); |
fclose($f); |
75 |
80 |
} |
} |
76 |
81 |
|
|
|
... |
... |
function rg_var_str_core($name) |
251 |
256 |
|
|
252 |
257 |
if (isset($_SERVER[$name])) |
if (isset($_SERVER[$name])) |
253 |
258 |
$ret = $_SERVER[$name]; |
$ret = $_SERVER[$name]; |
254 |
|
else if (isset($_COOKIE[$name])) |
|
255 |
|
$ret = $_COOKIE[$name]; |
|
256 |
259 |
else if (isset($_POST[$name])) |
else if (isset($_POST[$name])) |
257 |
260 |
$ret = $_POST[$name]; |
$ret = $_POST[$name]; |
258 |
261 |
else if (isset($_GET[$name])) |
else if (isset($_GET[$name])) |
|
... |
... |
function rg_var_str_core($name) |
261 |
264 |
return $ret; |
return $ret; |
262 |
265 |
} |
} |
263 |
266 |
|
|
|
267 |
|
/* |
|
268 |
|
* Outputs a string to browser, XSS safe |
|
269 |
|
* Thanks OWASP! |
|
270 |
|
*/ |
|
271 |
|
function rg_xss_safe($str) |
|
272 |
|
{ |
|
273 |
|
return htmlspecialchars($str, ENT_QUOTES | ENT_HTML401, 'UTF-8'); |
|
274 |
|
} |
|
275 |
|
|
264 |
276 |
function rg_var_str($name) |
function rg_var_str($name) |
265 |
277 |
{ |
{ |
266 |
278 |
$ret = rg_var_str_core($name); |
$ret = rg_var_str_core($name); |
267 |
279 |
|
|
268 |
280 |
if (is_string($ret)) |
if (is_string($ret)) |
269 |
|
return htmlspecialchars($ret, ENT_QUOTES); |
|
|
281 |
|
return rg_xss_safe($ret); |
270 |
282 |
|
|
271 |
283 |
if (is_array($ret)) { |
if (is_array($ret)) { |
272 |
284 |
$ret2 = array(); |
$ret2 = array(); |
273 |
285 |
foreach ($ret as $k => $v) |
foreach ($ret as $k => $v) |
274 |
|
$ret2[$k] = htmlspecialchars($v, ENT_QUOTES); |
|
|
286 |
|
$ret2[$k] = rg_xss_safe($v); |
275 |
287 |
return $ret; |
return $ret; |
276 |
288 |
} |
} |
277 |
289 |
|
|
|
... |
... |
function rg_var_re($name, $re) |
319 |
331 |
return preg_replace($re, "", $a); |
return preg_replace($re, "", $a); |
320 |
332 |
} |
} |
321 |
333 |
|
|
|
334 |
|
/* |
|
335 |
|
* Extract a cookie from $_COOKIE |
|
336 |
|
*/ |
|
337 |
|
function rg_var_cookie_re($name, $re) |
|
338 |
|
{ |
|
339 |
|
if (!isset($_COOKIE[$name])) |
|
340 |
|
return ""; |
|
341 |
|
|
|
342 |
|
return preg_replace($re, "", $_COOKIE[$name]); |
|
343 |
|
} |
|
344 |
|
|
322 |
345 |
/* |
/* |
323 |
346 |
* Enforce chars in a name. It is used for user and repo. |
* Enforce chars in a name. It is used for user and repo. |
324 |
347 |
*/ |
*/ |
|
... |
... |
function rg_prepare_replace_helper($a, $prefix, &$what, &$values) |
455 |
478 |
$k = substr($k, 5); |
$k = substr($k, 5); |
456 |
479 |
$new_prefix = $prefix . $add . $k; |
$new_prefix = $prefix . $add . $k; |
457 |
480 |
} else { |
} else { |
458 |
|
$v = htmlspecialchars($v); |
|
|
481 |
|
$v = rg_xss_safe($v); |
459 |
482 |
} |
} |
460 |
483 |
|
|
461 |
484 |
$what[$new_prefix] = "/@@" . $new_prefix . "@@/uU"; |
$what[$new_prefix] = "/@@" . $new_prefix . "@@/uU"; |
|
... |
... |
function rg_prepare_replace(&$data, &$what, &$values) |
473 |
496 |
} |
} |
474 |
497 |
|
|
475 |
498 |
$what['DUMP'] = "/@@DUMP@@/uU"; |
$what['DUMP'] = "/@@DUMP@@/uU"; |
476 |
|
$values['DUMP'] = htmlspecialchars(print_r($data, TRUE)); |
|
|
499 |
|
$values['DUMP'] = rg_xss_safe(print_r($data, TRUE)); |
477 |
500 |
|
|
478 |
501 |
// we replace @@unknown@@ with empty |
// we replace @@unknown@@ with empty |
479 |
502 |
//$what['FINAL'] = "/@@.*@@/U"; |
//$what['FINAL'] = "/@@.*@@/U"; |
|
... |
... |
function rg_template($file, &$data) |
722 |
745 |
global $rg_theme_dir; |
global $rg_theme_dir; |
723 |
746 |
global $rg_theme; |
global $rg_theme; |
724 |
747 |
|
|
725 |
|
rg_log("rg_template: $file"); |
|
|
748 |
|
rg_prof_start("rg_template"); |
|
749 |
|
rg_log_enter("rg_template: $file"); |
726 |
750 |
|
|
727 |
|
$xfile = $rg_theme_dir . "/" . $rg_theme . "/" . $file; |
|
728 |
|
if (!is_file($xfile)) |
|
729 |
|
$xfile = $rg_theme_dir . "/default/" . $file; |
|
|
751 |
|
$ret = ""; |
|
752 |
|
while (1) { |
|
753 |
|
$xfile = $rg_theme_dir . "/" . $rg_theme . "/" . $file; |
|
754 |
|
if (!is_file($xfile)) |
|
755 |
|
$xfile = $rg_theme_dir . "/default/" . $file; |
730 |
756 |
|
|
731 |
|
$body = rg_file_get_contents($xfile); |
|
732 |
|
if (empty($body)) { |
|
733 |
|
rg_log("File [$xfile] is empty. Return ''."); |
|
734 |
|
return ""; |
|
735 |
|
} |
|
|
757 |
|
$body = rg_file_get_contents($xfile); |
|
758 |
|
if (empty($body)) { |
|
759 |
|
rg_log("File [$xfile] is empty. Return ''."); |
|
760 |
|
break; |
|
761 |
|
} |
736 |
762 |
|
|
737 |
|
$what = array(); |
|
738 |
|
$values = array(); |
|
|
763 |
|
$what = array(); |
|
764 |
|
$values = array(); |
739 |
765 |
|
|
740 |
|
rg_prepare_replace($data, $what, $values); |
|
741 |
|
rg_prepare_func($body, $what, $values); |
|
|
766 |
|
rg_prepare_replace($data, $what, $values); |
|
767 |
|
rg_prepare_func($body, $what, $values); |
742 |
768 |
|
|
743 |
|
$body = rg_prepare_image($body); |
|
|
769 |
|
$body = rg_prepare_image($body); |
744 |
770 |
|
|
745 |
|
$r = rg_replace_conditionals($body, $data); |
|
746 |
|
// TODO: check error code! |
|
|
771 |
|
$r = rg_replace_conditionals($body, $data); |
|
772 |
|
// TODO: check error code! |
747 |
773 |
|
|
748 |
|
$ret = preg_replace($what, $values, $r); |
|
749 |
|
// TODO: check error code! |
|
|
774 |
|
$ret = preg_replace($what, $values, $r); |
|
775 |
|
// TODO: check error code! |
750 |
776 |
|
|
|
777 |
|
break; |
|
778 |
|
} |
|
779 |
|
|
|
780 |
|
rg_log_exit(); |
|
781 |
|
rg_prof_end("rg_template"); |
751 |
782 |
return $ret; |
return $ret; |
752 |
783 |
} |
} |
753 |
784 |
|
|
|
... |
... |
function rg_template_list($c) |
764 |
795 |
$i = 1; |
$i = 1; |
765 |
796 |
$add = ""; |
$add = ""; |
766 |
797 |
foreach ($a as $line) { |
foreach ($a as $line) { |
767 |
|
$ret .= $add . $i . " " . htmlspecialchars($line); |
|
|
798 |
|
$ret .= $add . $i . " " . rg_xss_safe($line); |
768 |
799 |
$add = "<br />"; |
$add = "<br />"; |
769 |
800 |
$i++; |
$i++; |
770 |
801 |
} |
} |
|
... |
... |
function rg_mail($template, $more) |
1148 |
1179 |
rg_prof_start("mail"); |
rg_prof_start("mail"); |
1149 |
1180 |
rg_log("mail: $template, more=" . rg_array2string($more)); |
rg_log("mail: $template, more=" . rg_array2string($more)); |
1150 |
1181 |
|
|
|
1182 |
|
// Account was not confirmed, so do not send mail |
|
1183 |
|
if (empty($more['ui.email'])) |
|
1184 |
|
return TRUE; |
1151 |
1185 |
|
|
1152 |
1186 |
$more['HTML:rg_admin_email'] = $rg_admin_email; |
$more['HTML:rg_admin_email'] = $rg_admin_email; |
1153 |
1187 |
$more['HTML:utf8_rg_admin_name'] = "=?UTF-8?B?" |
$more['HTML:utf8_rg_admin_name'] = "=?UTF-8?B?" |
File rocketgit.spec.in changed (mode: 100644) (index 222c88e..05bc4d2) |
1 |
1 |
%global selinux_types %(%{__awk} '/^#[[:space:]]*SELINUXTYPE=/,/^[^#]/ { if ($3 == "-") printf "%s ", $2 }' /etc/selinux/config 2>/dev/null) |
%global selinux_types %(%{__awk} '/^#[[:space:]]*SELINUXTYPE=/,/^[^#]/ { if ($3 == "-") printf "%s ", $2 }' /etc/selinux/config 2>/dev/null) |
2 |
2 |
%global selinux_variants %([ -z "%{selinux_types}" ] && echo mls strict targeted || echo %{selinux_types}) |
%global selinux_variants %([ -z "%{selinux_types}" ] && echo mls strict targeted || echo %{selinux_types}) |
3 |
|
%global selinux_policyver %(%{__sed} -e 's,.*selinux-policy-\\([^/]*\\)/.*,\\1,' /usr/share/selinux/devel/policyhelp || echo 0.0.0) |
|
|
3 |
|
|
|
4 |
|
# Seems this is needed for Fedora <= 19 |
|
5 |
|
#%global selinux_policyver %(%{__sed} -e 's,.*selinux-policy-\\([^/]*\\)/.*,\\1,' /usr/share/selinux/devel/policyhelp || echo 0.0.0) |
|
6 |
|
%global selinux_policyver 0.0.0 |
4 |
7 |
|
|
5 |
8 |
Summary: Light and fast Git hosting solution |
Summary: Light and fast Git hosting solution |
6 |
9 |
Name: @PRJ@ |
Name: @PRJ@ |
|
... |
... |
URL: http://kernel.embedromix.ro/us/ |
13 |
16 |
BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot |
BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot |
14 |
17 |
BuildArch: noarch |
BuildArch: noarch |
15 |
18 |
Requires: httpd, php, php-cli, php-pgsql, php-gd, xinetd |
Requires: httpd, php, php-cli, php-pgsql, php-gd, xinetd |
16 |
|
Requires(pre): shadow-utils |
|
17 |
19 |
Requires: git, postgresql-server |
Requires: git, postgresql-server |
18 |
20 |
Requires: util-linux |
Requires: util-linux |
19 |
21 |
# SELinux stuff |
# SELinux stuff |
20 |
22 |
# https://fedoraproject.org/wiki/SELinux_Policy_Modules_Packaging_Draft?rd=PackagingDrafts/SELinux/PolicyModules |
# https://fedoraproject.org/wiki/SELinux_Policy_Modules_Packaging_Draft?rd=PackagingDrafts/SELinux/PolicyModules |
21 |
23 |
BuildRequires: checkpolicy, selinux-policy-devel, hardlink |
BuildRequires: checkpolicy, selinux-policy-devel, hardlink |
22 |
|
BuildRequires: /usr/share/selinux/devel/policyhelp |
|
|
24 |
|
# Needed for Fedora <= 19 |
|
25 |
|
#BuildRequires: /usr/share/selinux/devel/policyhelp |
23 |
26 |
%if "%{selinux_policyver}" != "" |
%if "%{selinux_policyver}" != "" |
24 |
27 |
Requires: selinux-policy >= %{selinux_policyver} |
Requires: selinux-policy >= %{selinux_policyver} |
25 |
28 |
%endif |
%endif |
|
29 |
|
Requires(pre): shadow-utils |
26 |
30 |
Requires(post): /usr/sbin/semodule, /sbin/restorecon, /sbin/fixfiles |
Requires(post): /usr/sbin/semodule, /sbin/restorecon, /sbin/fixfiles |
27 |
31 |
Requires(postun): /usr/sbin/semodule, /sbin/restorecon, /sbin/fixfiles |
Requires(postun): /usr/sbin/semodule, /sbin/restorecon, /sbin/fixfiles |
28 |
32 |
|
|
29 |
33 |
%description |
%description |
30 |
|
Light and fast Git hosting solution, similar with Gitorious/etc. |
|
|
34 |
|
Light and fast Git hosting solution, similar with Gitorious/Gitolite/etc. |
31 |
35 |
|
|
32 |
36 |
%pre |
%pre |
33 |
37 |
getent group rocketgit >/dev/null || groupadd -r rocketgit |
getent group rocketgit >/dev/null || groupadd -r rocketgit |
|
... |
... |
rm -rf ${RPM_BUILD_ROOT} |
93 |
97 |
@USR_SHARE@/selinux/*/@PRJ@.pp |
@USR_SHARE@/selinux/*/@PRJ@.pp |
94 |
98 |
|
|
95 |
99 |
%changelog |
%changelog |
96 |
|
* Wed Oct 17 2012 Catalin(ux) M. BOIE <catab at embedromix dor ro> 0.10 |
|
|
100 |
|
* Wed Oct 17 2012 Catalin(ux) M. BOIE <catab at embedromix dot ro> 0.10 |
97 |
101 |
Alpha1 version released with a lot of fixes and some features. |
Alpha1 version released with a lot of fixes and some features. |
98 |
102 |
|
|
99 |
103 |
* Mon Jun 27 2011 Catalin(ux) M. BOIE <catab at embedromix dot ro> 0.2 |
* Mon Jun 27 2011 Catalin(ux) M. BOIE <catab at embedromix dot ro> 0.2 |
File root/index.php changed (mode: 100644) (index 93f40b8..e051bef) |
1 |
1 |
<?php |
<?php |
2 |
2 |
error_reporting(E_ALL); |
error_reporting(E_ALL); |
3 |
3 |
ini_set("track_errors", "On"); |
ini_set("track_errors", "On"); |
|
4 |
|
set_time_limit(30); |
4 |
5 |
|
|
5 |
6 |
$rg = array(); |
$rg = array(); |
6 |
7 |
|
|
|
... |
... |
rg_log("DEBUG: sparas=$sparas."); |
52 |
53 |
$rg['url'] = "/op"; |
$rg['url'] = "/op"; |
53 |
54 |
$paras = explode("/", trim($sparas, "/")); |
$paras = explode("/", trim($sparas, "/")); |
54 |
55 |
$_t = empty($paras) ? "" : $paras[0]; |
$_t = empty($paras) ? "" : $paras[0]; |
55 |
|
rg_log("DEBUG: paras: " . rg_array2string($paras)); |
|
56 |
56 |
if (strcmp($_t, "op") == 0) { |
if (strcmp($_t, "op") == 0) { |
57 |
57 |
array_shift($paras); |
array_shift($paras); |
58 |
58 |
$_op = empty($paras) ? "" : array_shift($paras); |
$_op = empty($paras) ? "" : array_shift($paras); |
|
... |
... |
if (strcmp($_t, "op") == 0) { |
61 |
61 |
} |
} |
62 |
62 |
|
|
63 |
63 |
$rg['doit'] = rg_var_uint("doit"); |
$rg['doit'] = rg_var_uint("doit"); |
64 |
|
$rg['sid'] = rg_var_re("sid", "/[^A-Za-z0-9]/"); |
|
|
64 |
|
$rg['sid'] = rg_var_cookie_re("sid", "/[^A-Za-z0-9]/"); |
65 |
65 |
$rg['token'] = rg_var_re("token", "/[^A-Za-z0-9]/"); |
$rg['token'] = rg_var_re("token", "/[^A-Za-z0-9]/"); |
66 |
66 |
$user = ""; $repo = ""; $organization = 0; // TODO: those are really used? |
$user = ""; $repo = ""; $organization = 0; // TODO: those are really used? |
67 |
67 |
|
|
|
... |
... |
include($INC . "/dispatch/dispatch.php"); |
119 |
119 |
|
|
120 |
120 |
if ($rg['login_ui']['uid'] > 0) { |
if ($rg['login_ui']['uid'] > 0) { |
121 |
121 |
$rg['login_ui']['homepage'] = rg_re_userpage($rg['login_ui']); |
$rg['login_ui']['homepage'] = rg_re_userpage($rg['login_ui']); |
|
122 |
|
$rg['logout_token'] = rg_token_get($db, $rg); |
122 |
123 |
} else { |
} else { |
123 |
124 |
$rg['login_ui']['username'] = ""; |
$rg['login_ui']['username'] = ""; |
124 |
125 |
$rg['login_ui']['homepage'] = ""; |
$rg['login_ui']['homepage'] = ""; |
|
126 |
|
$rg['logout_token'] = ""; |
125 |
127 |
} |
} |
126 |
128 |
|
|
127 |
129 |
// Some variables from the database |
// Some variables from the database |
|
... |
... |
$rg['HTML:rg_theme_url'] = $THEME_URL; |
139 |
141 |
$rg['HTML:rg_body'] = $body; |
$rg['HTML:rg_body'] = $body; |
140 |
142 |
echo rg_template("index.html", $rg); |
echo rg_template("index.html", $rg); |
141 |
143 |
|
|
142 |
|
rg_prof_log("rg_log"); |
|
|
144 |
|
rg_prof_log(); |
143 |
145 |
rg_log("DONE!"); |
rg_log("DONE!"); |
144 |
146 |
?> |
?> |
File tests/http_csrf.php changed (mode: 100644) (index 7ccd9b5..adf3de7) |
... |
... |
$data = array(); |
33 |
33 |
$headers = array("Cookie: sid=" . $good_sid); |
$headers = array("Cookie: sid=" . $good_sid); |
34 |
34 |
$r = do_req($test_url . "/op/suggestion?t=load_suggestion_form_ua", $data, $headers); |
$r = do_req($test_url . "/op/suggestion?t=load_suggestion_form_ua", $data, $headers); |
35 |
35 |
if (!stristr($r['body'], "action=\"/op/suggestion\"")) { |
if (!stristr($r['body'], "action=\"/op/suggestion\"")) { |
36 |
|
file_put_contents("http_csrf.log", $r); |
|
|
36 |
|
file_put_contents("http_csrf.log", print_r($r, TRUE)); |
37 |
37 |
rg_log_ml("Cannot load form!"); |
rg_log_ml("Cannot load form!"); |
38 |
38 |
exit(1); |
exit(1); |
39 |
39 |
} |
} |
|
... |
... |
$data = array(); |
63 |
63 |
$headers = array("Cookie: sid=" . $good_sid); |
$headers = array("Cookie: sid=" . $good_sid); |
64 |
64 |
$r = do_req($test_url . "/op/suggestion?t=load_suggestion_form_referer", $data, $headers); |
$r = do_req($test_url . "/op/suggestion?t=load_suggestion_form_referer", $data, $headers); |
65 |
65 |
if (!stristr($r['body'], "action=\"/op/suggestion\"")) { |
if (!stristr($r['body'], "action=\"/op/suggestion\"")) { |
66 |
|
file_put_contents("http_csrf.log", $r); |
|
|
66 |
|
file_put_contents("http_csrf.log", print_r($r, TRUE)); |
67 |
67 |
rg_log_ml("Cannot load form!"); |
rg_log_ml("Cannot load form!"); |
68 |
68 |
exit(1); |
exit(1); |
69 |
69 |
} |
} |
70 |
70 |
$good_token = $r['token']; |
$good_token = $r['token']; |
|
71 |
|
$good_logout_token = $r['logout_token']; |
71 |
72 |
|
|
72 |
73 |
rg_log("Try posting with different referer: should not work"); |
rg_log("Try posting with different referer: should not work"); |
73 |
74 |
test_set_ua("user-agent-1"); |
test_set_ua("user-agent-1"); |
|
... |
... |
if (!stristr($r['body'], "invalid referer")) { |
87 |
88 |
} |
} |
88 |
89 |
|
|
89 |
90 |
|
|
|
91 |
|
rg_log("Testing logout CSRF (wrong token)..."); |
|
92 |
|
test_set_ua("user-agent-1"); |
|
93 |
|
test_set_referer($test_url); |
|
94 |
|
$data = array(); |
|
95 |
|
$headers = array("Cookie: sid=" . $good_sid); |
|
96 |
|
$r = do_req($test_url . "/op/logout?t=wrong_token&token=0cb2c9f6e8405eadfef1ccd00c99e3ff", $data, $headers); |
|
97 |
|
if (stristr($r['body'], "You are now logged out")) { |
|
98 |
|
file_put_contents("http_csrf.log", print_r($r, TRUE)); |
|
99 |
|
rg_log_ml("No error on logout with wrong token?!"); |
|
100 |
|
exit(1); |
|
101 |
|
} |
|
102 |
|
|
|
103 |
|
|
|
104 |
|
rg_log("Testing logout CSRF (token passed in cookie)..."); |
|
105 |
|
test_set_ua("user-agent-1"); |
|
106 |
|
test_set_referer($test_url); |
|
107 |
|
$data = array(); |
|
108 |
|
$headers = array("Cookie: sid=" . $good_sid . "; token=" . $good_logout_token); |
|
109 |
|
$r = do_req($test_url . "/op/logout?t=token_passed_by_cookie", $data, $headers); |
|
110 |
|
if (stristr($r['body'], "You are now logged out")) { |
|
111 |
|
file_put_contents("http_csrf.log", print_r($r, TRUE)); |
|
112 |
|
rg_log_ml("No error on logout with token passed by cookie?!"); |
|
113 |
|
exit(1); |
|
114 |
|
} |
|
115 |
|
|
|
116 |
|
|
|
117 |
|
rg_log("Testing logout CSRF (good token)..."); |
|
118 |
|
$url = $test_url . "/op/logout?t=good_token&token=" . $good_logout_token; |
|
119 |
|
$r = do_req($url, $data, $headers); |
|
120 |
|
if (!stristr($r['body'], "You are now logged out")) { |
|
121 |
|
file_put_contents("http_csrf.log", $url . "\n" . print_r($r, TRUE)); |
|
122 |
|
rg_log_ml("Seems I cannot logout with a good token!"); |
|
123 |
|
exit(1); |
|
124 |
|
} |
|
125 |
|
|
90 |
126 |
rg_log("Done!"); |
rg_log("Done!"); |
91 |
127 |
?> |
?> |