Hi. Feel free to check the attached file for errors/(security problems) and let me know what you think. /* chrooted cvs-(ssh)-shell [EMAIL PROTECTED] [0x00] what is it It's a (secure?) "shell" to use cvs with ssh without the need to give cvs-users an interactive shell. I hacked this together yesterday afternoon. First i used a stunnel + cvs solution. This cvssh solution is smaller, faster, crypted, chrooted and doesn't depend on cvspserv. User management and auth. is pretty easy. We use /etc/passwd and and the present unix file permissions. We just give the user who wants to use cvs but we dont want to have on our system (interactive shell) the "chroot_cvssh" as a shell. chroot_cvssh can only execute "/bin/cvs server" and nothing else. [0x01] How to compile gcc -Wall -O2 -o chroot_cvssh chroot_cvssh.c [0x02] How to install cp chroot_cvssh /bin/chroot_cvssh chmod 4710 /bin/chroot_cvssh chgrp chrootuser /bin/chroot_cvssh mkdir /home/chrooted/sshcvs/cvs mkdir /home/chrooted/sshcvs/bin .... (some other directories needed for chrooted env. see list) [0x03] How to configure create a user "cvs (800)" with home directory /home/chrooted/sshcvs. Create a group "cvs (800)". Make the user "cvs" member of the group "cvs": cvs:x:800:800:cvs,,,:/home/chrooted/sshcvs:/bin/chroot_cvssh Create users who should have access to the cvs-tree (+rw!): plasmoidcvs:x:801:800:plasmoidcvs,,,:/home/chrooted/sshcvs:/bin/chroot_cvssh skypercvs:x:802:800:skypercvs,,,:/home/chrooted/sshcvs:/bin/chroot_cvssh ... (hint hint: they are all members of group "cvs") Create your repositories in /home/chrooted/sshcvs/cvs [0x04] How to use The user can access the cvs via ssh + cvs: $ export CVSROOT=username@server:/cvs $ export CVS_RSH=ssh $ cvs checkout test Thats it. [0x05] How to secure # chown -R root.root CVSROOT # chattr +i CVSROOT # this is optional...but I'm paranoid! mount /cvs via loopback-device with noexec flag: [or if you are as lame as I am creata a fs in a file and mount the file via loopback] dd if=/dev/zero of=/home/chrooted/cvs.fs bs=1k count=500000 mke2fs /home/chrooted/cvs.fs mount /home/chrooted/cvs.fs -o loop=/dev/loop6,noexec,nodev \ /home/chrooted/sshcvs/cvs Here is a listing of files you may need in your chrooted environement: Use the permission flags exactly as shown in this list: drwx--x--x 2 root root 4096 Mar 15 17:06 bin lrwxrwxrwx 1 root root 1 Mar 15 18:28 chrooted -> . drwxrwsr-x 6 cvs cvs 4096 Mar 16 00:16 cvs drwx--x--x 2 root root 4096 Mar 15 17:30 dev drwxr-xr-x 2 root root 4096 Mar 15 22:42 etc lrwxrwxrwx 1 root root 1 Mar 15 18:28 home -> . drwx--x--x 2 root root 4096 Mar 15 17:24 lib lrwxrwxrwx 1 root root 1 Mar 15 17:22 local -> . lrwxrwxrwx 1 root root 1 Mar 15 18:28 cvs -> . drwxrws--- 2 root cvs 4096 Mar 16 01:33 tmp lrwxrwxrwx 1 root root 1 Mar 15 17:22 usr -> . ./bin: -rwx--x--x 1 root root 1511918 Mar 15 23:29 cvs ./cvs: drwxrwsr-x 3 root root 4096 Mar 14 18:03 CVSROOT drwxrwsr-x 3 skypercvs cvs 4096 Mar 16 01:33 test ./cvs/CVSROOT: drwxrwsr-x 3 root root 4096 Mar 14 18:03 . -rw-rw-r-- 1 root root 493 Nov 26 23:45 .#checkoutlist -rw-rw-r-- 1 root root 760 Nov 26 23:45 .#commitinfo -rw-rw-r-- 1 root root 527 Nov 26 23:45 .#config -rw-rw-r-- 1 root root 753 Nov 26 23:45 .#cvswrappers -rw-rw-r-- 1 root root 1025 Nov 26 23:45 .#editinfo -rw-rw-r-- 1 root root 1141 Nov 26 23:45 .#loginfo -rw-rw-r-- 1 root root 1151 Nov 26 23:45 .#modules -rw-rw-r-- 1 root root 564 Nov 26 23:45 .#notify -rw-rw-r-- 1 root root 649 Nov 26 23:45 .#rcsinfo -rw-rw-r-- 1 root root 879 Nov 26 23:45 .#taginfo -rw-rw-r-- 1 root root 1026 Nov 26 23:45 .#verifymsg drwxrwsr-x 6 root root 4096 Mar 16 00:16 .. drwxrwsr-x 2 root root 4096 Nov 26 23:45 Emptydir -r--r--r-- 1 root root 493 Nov 26 23:45 checkoutlist -r--r--r-- 1 root root 697 Nov 26 23:45 checkoutlist,v -r--r--r-- 1 root root 760 Nov 26 23:45 commitinfo -r--r--r-- 1 root root 964 Nov 26 23:45 commitinfo,v -r--r--r-- 1 root root 527 Nov 26 23:45 config -r--r--r-- 1 root root 731 Nov 26 23:45 config,v -r--r--r-- 1 root root 753 Nov 26 23:45 cvswrappers -r--r--r-- 1 root root 957 Nov 26 23:45 cvswrappers,v -r--r--r-- 1 root root 1025 Nov 26 23:45 editinfo -r--r--r-- 1 root root 1229 Nov 26 23:45 editinfo,v -rw-rw-rw- 1 root root 42661 Mar 16 01:31 history -r--r--r-- 1 root root 1141 Nov 26 23:45 loginfo -r--r--r-- 1 root root 1345 Nov 26 23:45 loginfo,v -r--r--r-- 1 root root 1151 Nov 26 23:45 modules -r--r--r-- 1 root root 1355 Nov 26 23:45 modules,v -r--r--r-- 1 root root 564 Nov 26 23:45 notify -r--r--r-- 1 root root 768 Nov 26 23:45 notify,v -r--r--r-- 1 root root 649 Nov 26 23:45 rcsinfo -r--r--r-- 1 root root 853 Nov 26 23:45 rcsinfo,v -r--r--r-- 1 root root 879 Nov 26 23:45 taginfo -r--r--r-- 1 root root 1083 Nov 26 23:45 taginfo,v -rw-rw-r-- 1 root root 0 Nov 26 23:45 val-tags -r--r--r-- 1 root root 1026 Nov 26 23:45 verifymsg -r--r--r-- 1 root root 1230 Nov 26 23:45 verifymsg,v ./cvs/CVSROOT/Emptydir: drwxrwsr-x 2 root root 4096 Nov 26 23:45 . drwxrwsr-x 3 root root 4096 Mar 14 18:03 .. ./cvs/test: -r--r--r-- 1 skypercv cvs 1134 Mar 16 01:31 README,v -r--r--r-- 1 skypercv cvs 247 Mar 16 00:28 README2,v drwxrwsr-x 2 skypercv cvs 4096 Mar 16 00:51 testdir ./dev: drwx--x--x 2 root root 4096 Mar 15 17:30 . crw-rw-rw- 1 root root 1, 3 Mar 15 17:30 null ./etc: drwxr-xr-x 2 root root 4096 Mar 15 22:42 . -rw-r--r-- 1 root root 100 Mar 15 23:06 group -rw-r--r-- 1 root root 459 Mar 16 00:17 passwd ./lib: drwx--x--x 2 root root 4096 Mar 15 17:24 . -rwxr-xr-x 4 root root 361928 Sep 16 2000 ld-2.1.3.so lrwxrwxrwx 1 root root 11 Mar 15 17:10 ld-linux.so.2 -> ld-2.1.3.so -rwxr-xr-x 4 root root 4061241 Sep 16 2000 libc-2.1.3.so lrwxrwxrwx 1 root root 13 Mar 15 17:09 libc.so.6 -> libc-2.1.3.so -rwxr-xr-x 4 root root 60985 Sep 20 16:08 libcrypt-2.1.3.so lrwxrwxrwx 1 root root 17 Mar 15 17:09 libcrypt.so.1 -> libcrypt-2.1.3.so */ #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <pwd.h> #include <sys/types.h> #include <string.h> void die(char *str, int code) { if (str != NULL) fprintf(stderr, "%s", str); exit(code); } int main(int argc, char *argv[]) { struct passwd *pwdata; char *myenv[3]; char *cache; char buf[128]; int c; memset(buf, 0, sizeof(buf)); if ( (pwdata = getpwuid(getuid())) == NULL) die("who are you?\n", -1); if (getuid() == 0) die("bad uid. this is too risky.\n", -1); if (chroot(pwdata->pw_dir) != 0) die("cant chroot\n", -1); if (chdir("/") != 0) die("cant chdir after chroot.\n", -1); if (setuid(getuid()) != 0) die("bastard. setuid failed!\n", -1); /* read new <chrooted>/etc/passwd infos */ if ( (pwdata = getpwuid(getuid())) != NULL) chdir(pwdata->pw_dir); /* dont care if this fails...*/ /* hmm. we should close all open fd's/[0,1,2] (if any) here */ if (argc < 3) die("not enough arguements\n", -1); if (strcmp(argv[1],"-c") != 0) die("cvssh is a non interactive command shell....\n", -1); if (strncmp(argv[2], "cvs", 3) != 0) die("you are not my cvs!\n", -1); c = 0; if ( (cache = getenv("USER")) != NULL) if (strlen(cache) < 20) { snprintf(buf, sizeof(buf)-2, "USER=%s", cache); myenv[c++] = strdup(buf); } if ( (cache = getenv("LOGNAME")) != NULL) if (strlen(cache) < 20) { snprintf(buf, sizeof(buf)-1, "LOGNAME=%s", cache); myenv[c++] = strdup(cache); } myenv[c++] = NULL; if (execle("/bin/cvs", "cvs", "server", NULL, myenv) == -1) { printf("unable to execle\n"); exit(0); } return(0); } skyper -- PGP: dig @segfault.net skyper axfr|grep TX|cut -f2 -d\"|sort|cut -f2 -d\; _______________________________________________ Info-cvs mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/info-cvs