Subject: Re: OT: recommendation for vm tuning for anoncvs mirror?
To: None <riz@tastylime.net>
From: Thor Lancelot Simon <tls@rek.tjls.com>
List: netbsd-users
Date: 02/26/2005 20:55:23
--W/nzBZO5zC0uMSeA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Sat, Feb 26, 2005 at 08:48:58PM -0500, Thor Lancelot Simon wrote:
> 
> You may find the attached program useful.

It is now actually attached. :-)

Thor

--W/nzBZO5zC0uMSeA
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="anoncvssh.c"

/*
 * $NetBSD: anoncvssh.c,v 1.7 2004/05/24 21:26:28 tls Exp $
 *
 * From an early version of OpenBSD "anoncvssh.c", heavily modified for
 * the rather different NetBSD AnonCVS environment.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <paths.h>
#include <pwd.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>
#include <syslog.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>

/*
 * Location of CVS tree, relative to the anonymous CVS user's
 * home directory
 */
#ifndef LOCALROOT
#define	LOCALROOT	"/cvsroot"
#endif

/*
 * Account and host name to be used when accessing the
 * CVS repository remotely
 */
#ifndef HOSTNAME
#define	HOSTNAME	"anoncvs@anoncvs.netbsd.org"
#endif

/*
 * $CVSROOT is created based on HOSTNAME and LOCALROOT above
 */
#ifndef CVSROOT
#define	CVSROOT		HOSTNAME ":" LOCALROOT
#endif

#ifndef _PATH_CVS
#define _PATH_CVS	"/usr/bin/cvs"
#endif

/* Syslog facility and priority */
#define LOG_FACILITY LOG_DAEMON
#define LOG_PRIO LOG_INFO

/* 
 * CHECKOUT_USER is the user to switch to upon invocation.
 * This lets us run the sshd as an unprivileged user, but run CVS
 * as a *different* unprivileged user, by making this program
 * setuid.  That, in turn, prevents holes in the cvs program from
 * allowing the anoncvs environment's SSH private key to be read.
 *
 */
#define CHECKOUT_USER "checkout"

char * const env[] = {
	"PATH=" _PATH_DEFPATH,
	"SHELL=" _PATH_BSHELL,
	"CVSROOT=" LOCALROOT,
	"HOME=/",
	NULL
};

int main(int argc, char *argv[])
{
	struct passwd *pw;
#ifdef DEBUG
	int i;
#endif /* DEBUG */

	pw = getpwnam(CHECKOUT_USER);
	if (pw == NULL) {
		errx(EX_NOUSER, "User %s does not exist!", CHECKOUT_USER);
	}
	if (pw->pw_dir == NULL) {
		errx(EX_OSFILE, "User %s has no home directory!",
		    CHECKOUT_USER);
	}

	if (geteuid() != pw->pw_uid) {
		errx(EX_NOPERM, "Wrong user: %s = %d, euid = %d",
		    CHECKOUT_USER, pw->pw_uid, geteuid());
	}

	/*
	 * program now "safe"
	 */

	openlog("anoncvssh", LOG_PID | LOG_NDELAY, LOG_FACILITY);
	
	if ((argc == 2) && (strcmp("pserver", argv[1]) == 0)) {
 	        int slen;
		struct sockaddr_in my_sa, peer_sa;
		char *us, *them;
		
		slen = sizeof(my_sa);
		if (getsockname(0, (struct sockaddr *) &my_sa, &slen)
		    != 0) {
		  perror("getsockname");
		  exit(1);
		}
		us = strdup(inet_ntoa(my_sa.sin_addr));
		if (us == NULL) {
		  fprintf(stderr, "malloc failed\n");
		  exit(1);
		}
		slen = sizeof(peer_sa);
		if (getpeername(0, (struct sockaddr *) &peer_sa, &slen)
		    != 0) {
		  perror("getpeername");
		  exit(1);
		}
		them=strdup(inet_ntoa(peer_sa.sin_addr));
		if (them == NULL) {
		  fprintf(stderr, "malloc failed\n");
		  exit(1);
		}
	        syslog(LOG_PRIO, 
		       "pserver connection from %s:%d to %s:%d\n",
		       them, ntohs(peer_sa.sin_port),
		       us, ntohs(my_sa.sin_port));
		execle(_PATH_CVS, "cvs", "-u",
		    "--allow-root=" LOCALROOT, "pserver", NULL, env);
		perror("execle: cvs");
		fprintf(stderr, "unable to exec CVS pserver!\n");
		exit(1);
		/* NOTREACHED */
	}

	if (argc != 3 || 
		strcmp("anoncvssh",  argv[0]) != 0 ||
		strcmp("-c",         argv[1]) != 0 ||
		(strcmp("cvs server", argv[2]) != 0 &&
		 strcmp("cvs -d " LOCALROOT " server", argv[2]) != 0)) {
		fprintf(stderr, "\nTo use anonymous CVS install the latest ");
		fprintf(stderr,"version of CVS on your local machine.\n");
		fprintf(stderr,"Then set your CVSROOT environment variable ");
		fprintf(stderr,"to the following value:\n");
		fprintf(stderr,"\t%s\n\n", CVSROOT);
#ifdef DEBUG
		fprintf(stderr, "argc = %d\n", argc);
		for (i = 0 ; i < argc ; i++)
			fprintf(stderr, "argv[%d] = \"%s\"\n", i, argv[i]);
#endif /* DEBUG */
		sleep(10);
		exit(0);
	}
	execle(_PATH_CVS, "cvs", "-u", "server", NULL, env);
	perror("execle: cvs");
	fprintf(stderr, "unable to exec CVS server!\n");
	exit(1);
	/* NOTREACHED */
}

--W/nzBZO5zC0uMSeA--