Sorry if it looks a duplicate post. This post is a personal effort and contains also security issues using pserver connections
Three days ago, I had to set up a secure cvs pserver. After spending many hour reading the doc at the excellent site www.cvshome.org, I successfully set it up running it with inetd.
I know that the most secure is to use SSH connection since in pserver authentication passwords are sent in clear, but i tried to focus on the state of art of doing it. Today, I tried to set it up with xinetd but some security issues raised that i didn't solve it yet, but this setting should work very fine if u're not paranoid with security
Here are the steps I used to setup my cvs server :
1) Login as root and create a user/group cvs/cvs. Note: The repository is inside the user's home and not the user's home, this would allow you later to create many repositories as u want in the user's home ( Easier to manage )
Code: Select all
# groupadd cvs
# mkdir -p /var/home/cvs
# useradd -d /var/home/cvs -g cvs -s /bin/bash -p <cvs_passwd> cvs
# chown -R cvs:cvs /var/home/cvs
# su - cvs
/> cvs -d /var/home/cvs/repository init
/> chmod g+rwx /var/home/cvs/repository
/> exit
2) Create users anoncvs and usercvs. anoncvs will be allowed to read repository but cannot write. usercvs will be allowed to read/write in repository
Code: Select all
# useradd -d /var/home/cvs -g cvs -s /bin/false usercvs
# usermod -L usercvs ( Lock user password )
# useradd -d /var/home/cvs -g cvs -s /bin/false anoncvs
# usermod -L anoncvs ( Lock user password )
We have to store users and encrypted passwords in /var/home/cvs/repository/CVSROOT/passwd
Using ur favourite editor, add entries of this form in /var/home/cvs/repository/CVSROOT/passwd:
<cvs_user>:<encrypted_password>:<unix_user>
We encrypt cvs user's password using this well known perl script:
Code: Select all
#!/usr/bin/perl
srand (time());
my $randletter = "(int (rand (26)) + (int (rand (1) + .5) % 2 ? 65 : 97))";
my $salt = sprintf ("%c%c", eval $randletter, eval $randletter);
my $plaintext = shift;
my $crypttext = crypt ($plaintext, $salt);
print "${crypttext}\n";
cryptout <clear_text_password>
it'll produce an encrypted password as the ones stored in /etc/passwd.
Here an example of passwd file:
james:qPd3FRr4r3ln2:usercvs
dreambox:AGJaHG3LxpYoA:usercvs
anoncvs::anoncvs
Typical scenario, users james and dreambox would have read/write access to the repository, and anoncvs would have only read access without having to enter a password.
Note: In practice james and dreambox don't exist in the system as unix users, they are virtual cvs users.
To disable cvs to fallback into system authentication when user doesn't exist we have to modify the file under /var/home/cvs/CVSROOT/config.
To set read/write permissions in repository we have to create 2 files ( readers and writers ) also under /var/home/cvs/CVSROOT. Users in readers file are only allowed to read repository. Users in writers are allowed to read/write in repository.
config, readers, writers have to be versionned, so first we checkout module CVSROOT :
Code: Select all
/> cvs -d /var/home/cvs/repository co CVSROOT
cvs server: Updating CVSROOT
U CVSROOT/checkoutlist
U CVSROOT/commitinfo
U CVSROOT/config
U CVSROOT/cvswrappers
U CVSROOT/editinfo
U CVSROOT/loginfo
U CVSROOT/modules
U CVSROOT/notify
U CVSROOT/rcsinfo
U CVSROOT/taginfo
U CVSROOT/verifymsg
Code: Select all
/> echo james > writers
/> echo dreambox >> writers
/> echo >> writers ( We have to add new line after adding last user )
/> echo anoncvs > readers
/> echo >> readers ( We have to add new line after adding last user )
/> cvs -d /var/home/cvs/repository add readers writers
cvs server: scheduling file `readers' for addition
cvs server: scheduling file `writers' for addition
cvs server: use 'cvs commit' to add these files permanently
/> cvs -d /var/home/cvs/repository ci -m "Updated administration files"
cvs commit: Examining .
Checking in config;
/var/home/cvs/repo/CVSROOT/config,v <-- config
new revision: 1.2; previous revision: 1.1
done
RCS file: /var/home/cvs/repo/CVSROOT/readers,v
done
Checking in readers;
/var/home/cvs/repo/CVSROOT/readers,v <-- readers
initial revision: 1.1
done
RCS file: /var/home/cvs/repo/CVSROOT/writers,v
done
Checking in writers;
/var/home/cvs/repo/CVSROOT/writers,v <-- writers
initial revision: 1.1
done
cvs commit: Rebuilding administrative file database
Edit as root file /etc/xinetd.d/cvspserver. Mine looks like this :
Code: Select all
service cvspserver
{
disable = no
socket_type = stream
wait = no
user = root
log_type = FILE /var/log/cvspserver
protocol = tcp
env = '$HOME=/var/home/cvs'
log_on_failure += USERID
port = 2401
server = /usr/bin/cvs
server_args = -f --allow-root=/var/home/cvs/repository pserver
}
Code: Select all
# rc-update add xinetd boot
Your can start testing security by trying to import a directory as anoncvs for example ( cvs will not allow u ) :
Code: Select all
/> mkdir project
/> cd project
/> touch dreambox
/> cvs -d :pserver:anoncvs@localhost/var/home/cvs/repository login ( Press return when asked a password )
/> cvs -d :pserver:anoncvs@localhost/var/home/cvs/repository import -m "Trying to import" myproject vendor start
Code: Select all
cvs server: cannot open /var/home/cvs/repository/CVSROOT/readers: Permission denied
cvs [server aborted]: "import" requires write access to the repository
The files CVSROOT/*info can be used to execute programs such as sendmail to notify some users of an update, commit,... The thing is that one malicious guy ( such as james or dreambox ) who has write access to repository can checkout CVSROOT and add entries in that files to execute a malicious program and gain access to private ressources in the system !!!
OK, here it is:
We create admincvs group and admincvs user :
Code: Select all
# groupadd admincvs
# useradd -d /var/home/cvs -g cvs -s /bin/false admincvs
# usermod -L admincvs ( Lock user password )
read/write/exec access to that directory to other users
Code: Select all
# cd /var/home/cvs/cvsrepository
# chgrp -R admincvs CVSROOT
# chmod o-rwx CVSROOT
Code: Select all
admincvs:<crypted_passwd>:admincvs
Code: Select all
/> cvs -d :pserver:dreambox@localhost/var/home/cvs/repository login ( Enter password when asked )
/> cvs -d :pserver:dreambox@localhost/var/home/cvs/repository co CVSROOT
Code: Select all
Cannot access /var/home/cvs/repo/CVSROOT
Permission denied
Code: Select all
/> cvs -d :pserver:admincvs@localhost/var/home/cvs/repository login ( Enter password when asked )
/> cvs -d :pserver:admincvs@localhost/var/home/cvs/repository co CVSROOT
Code: Select all
cvs server: Updating CVSROOT
U CVSROOT/checkoutlist
U CVSROOT/commitinfo
U CVSROOT/config
U CVSROOT/cvswrappers
U CVSROOT/editinfo
U CVSROOT/loginfo
U CVSROOT/modules
U CVSROOT/notify
U CVSROOT/rcsinfo
U CVSROOT/readers
U CVSROOT/taginfo
U CVSROOT/verifymsg
U CVSROOT/writers
Code: Select all
/> mkdir test
/> cd test
/> touch test.file
/> cvs -d :pserver:dreambox@localhost/var/home/cvs/repository login ( Enter password when asked )
/> cvs -d :pserver:dreambox@localhost/var/home/cvs/repository import -m "I want to import" test vendor start
Code: Select all
Cannot access /var/home/cvs/repo/CVSROOT
Permission denied
Code: Select all
/> ls -l repository
drwxrwx--- 3 cvs admincvs 1224 May 22 20:21 CVSROOT
Something I don't understand : xinetd is running as root. When xinetd receives a login request it creates a cvs process with usercvs uid, right?
Since usercvs user is the owner of CVSROOT, it should normally have access to that directory!
Thanks for reading all this
I would appreciate any feedback
Regards
dreambox





