info-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

chroot_cvssh.c


From: skyper
Subject: chroot_cvssh.c
Date: Mon, 19 Mar 2001 12:17:47 +0000
User-agent: Mutt/1.2.5i

Hi.

Feel free to check the attached file for errors/(security problems) and
let me know what you think.



/* chrooted cvs-(ssh)-shell                     address@hidden

   [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 address@hidden:/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\;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]