svn commit: r204556 - in head: contrib/csup usr.bin/csup

Ulf Lilleengen lulf at FreeBSD.org
Tue Mar 2 07:26:08 UTC 2010


Author: lulf
Date: Tue Mar  2 07:26:07 2010
New Revision: 204556
URL: http://svn.freebsd.org/changeset/base/204556

Log:
  - Move csup away from contrib/ and into usr.bin/. Software is no longer
    contributed, and main development is happening in the FreeBSD repo.
  
  Suggested by:	joel

Added:
  head/usr.bin/csup/README
     - copied unchanged from r204523, head/contrib/csup/README
  head/usr.bin/csup/TODO
     - copied unchanged from r204523, head/contrib/csup/TODO
  head/usr.bin/csup/attrstack.c
     - copied unchanged from r204523, head/contrib/csup/attrstack.c
  head/usr.bin/csup/attrstack.h
     - copied unchanged from r204523, head/contrib/csup/attrstack.h
  head/usr.bin/csup/auth.c
     - copied unchanged from r204523, head/contrib/csup/auth.c
  head/usr.bin/csup/auth.h
     - copied unchanged from r204523, head/contrib/csup/auth.h
  head/usr.bin/csup/config.c
     - copied unchanged from r204523, head/contrib/csup/config.c
  head/usr.bin/csup/config.h
     - copied unchanged from r204523, head/contrib/csup/config.h
  head/usr.bin/csup/cpasswd.1
     - copied unchanged from r204523, head/contrib/csup/cpasswd.1
  head/usr.bin/csup/cpasswd.sh
     - copied unchanged from r204523, head/contrib/csup/cpasswd.sh
  head/usr.bin/csup/csup.1
     - copied unchanged from r204523, head/contrib/csup/csup.1
  head/usr.bin/csup/detailer.c
     - copied unchanged from r204523, head/contrib/csup/detailer.c
  head/usr.bin/csup/detailer.h
     - copied unchanged from r204523, head/contrib/csup/detailer.h
  head/usr.bin/csup/diff.c
     - copied unchanged from r204523, head/contrib/csup/diff.c
  head/usr.bin/csup/diff.h
     - copied unchanged from r204523, head/contrib/csup/diff.h
  head/usr.bin/csup/fattr.c
     - copied unchanged from r204523, head/contrib/csup/fattr.c
  head/usr.bin/csup/fattr.h
     - copied unchanged from r204523, head/contrib/csup/fattr.h
  head/usr.bin/csup/fattr_bsd.h
     - copied unchanged from r204523, head/contrib/csup/fattr_bsd.h
  head/usr.bin/csup/fattr_posix.h
     - copied unchanged from r204523, head/contrib/csup/fattr_posix.h
  head/usr.bin/csup/fixups.c
     - copied unchanged from r204523, head/contrib/csup/fixups.c
  head/usr.bin/csup/fixups.h
     - copied unchanged from r204523, head/contrib/csup/fixups.h
  head/usr.bin/csup/fnmatch.c
     - copied unchanged from r204523, head/contrib/csup/fnmatch.c
  head/usr.bin/csup/fnmatch.h
     - copied unchanged from r204523, head/contrib/csup/fnmatch.h
  head/usr.bin/csup/globtree.c
     - copied unchanged from r204523, head/contrib/csup/globtree.c
  head/usr.bin/csup/globtree.h
     - copied unchanged from r204523, head/contrib/csup/globtree.h
  head/usr.bin/csup/idcache.c
     - copied unchanged from r204523, head/contrib/csup/idcache.c
  head/usr.bin/csup/idcache.h
     - copied unchanged from r204523, head/contrib/csup/idcache.h
  head/usr.bin/csup/keyword.c
     - copied unchanged from r204523, head/contrib/csup/keyword.c
  head/usr.bin/csup/keyword.h
     - copied unchanged from r204523, head/contrib/csup/keyword.h
  head/usr.bin/csup/lex.rcs.c
     - copied unchanged from r204523, head/contrib/csup/lex.rcs.c
  head/usr.bin/csup/lister.c
     - copied unchanged from r204523, head/contrib/csup/lister.c
  head/usr.bin/csup/lister.h
     - copied unchanged from r204523, head/contrib/csup/lister.h
  head/usr.bin/csup/main.c
     - copied unchanged from r204523, head/contrib/csup/main.c
  head/usr.bin/csup/main.h
     - copied unchanged from r204523, head/contrib/csup/main.h
  head/usr.bin/csup/misc.c
     - copied unchanged from r204523, head/contrib/csup/misc.c
  head/usr.bin/csup/misc.h
     - copied unchanged from r204523, head/contrib/csup/misc.h
  head/usr.bin/csup/mux.c
     - copied unchanged from r204523, head/contrib/csup/mux.c
  head/usr.bin/csup/mux.h
     - copied unchanged from r204523, head/contrib/csup/mux.h
  head/usr.bin/csup/parse.y
     - copied unchanged from r204523, head/contrib/csup/parse.y
  head/usr.bin/csup/pathcomp.c
     - copied unchanged from r204523, head/contrib/csup/pathcomp.c
  head/usr.bin/csup/pathcomp.h
     - copied unchanged from r204523, head/contrib/csup/pathcomp.h
  head/usr.bin/csup/proto.c
     - copied unchanged from r204523, head/contrib/csup/proto.c
  head/usr.bin/csup/proto.h
     - copied unchanged from r204523, head/contrib/csup/proto.h
  head/usr.bin/csup/queue.h
     - copied unchanged from r204523, head/contrib/csup/queue.h
  head/usr.bin/csup/rcsfile.c
     - copied unchanged from r204523, head/contrib/csup/rcsfile.c
  head/usr.bin/csup/rcsfile.h
     - copied unchanged from r204523, head/contrib/csup/rcsfile.h
  head/usr.bin/csup/rcsparse.c
     - copied unchanged from r204523, head/contrib/csup/rcsparse.c
  head/usr.bin/csup/rcsparse.h
     - copied unchanged from r204523, head/contrib/csup/rcsparse.h
  head/usr.bin/csup/rcstokenizer.h
     - copied unchanged from r204523, head/contrib/csup/rcstokenizer.h
  head/usr.bin/csup/rcstokenizer.l
     - copied unchanged from r204523, head/contrib/csup/rcstokenizer.l
  head/usr.bin/csup/rsyncfile.c
     - copied unchanged from r204523, head/contrib/csup/rsyncfile.c
  head/usr.bin/csup/rsyncfile.h
     - copied unchanged from r204523, head/contrib/csup/rsyncfile.h
  head/usr.bin/csup/status.c
     - copied unchanged from r204523, head/contrib/csup/status.c
  head/usr.bin/csup/status.h
     - copied unchanged from r204523, head/contrib/csup/status.h
  head/usr.bin/csup/stream.c
     - copied unchanged from r204523, head/contrib/csup/stream.c
  head/usr.bin/csup/stream.h
     - copied unchanged from r204523, head/contrib/csup/stream.h
  head/usr.bin/csup/threads.c
     - copied unchanged from r204523, head/contrib/csup/threads.c
  head/usr.bin/csup/threads.h
     - copied unchanged from r204523, head/contrib/csup/threads.h
  head/usr.bin/csup/token.h
     - copied unchanged from r204523, head/contrib/csup/token.h
  head/usr.bin/csup/token.l
     - copied unchanged from r204523, head/contrib/csup/token.l
  head/usr.bin/csup/updater.c
     - copied unchanged from r204523, head/contrib/csup/updater.c
  head/usr.bin/csup/updater.h
     - copied unchanged from r204523, head/contrib/csup/updater.h
Replaced:
  head/usr.bin/csup/Makefile
     - copied, changed from r204523, head/contrib/csup/Makefile
Deleted:
  head/contrib/csup/

Copied and modified: head/usr.bin/csup/Makefile (from r204523, head/contrib/csup/Makefile)
==============================================================================
--- head/contrib/csup/Makefile	Mon Mar  1 17:20:04 2010	(r204523, copy source)
+++ head/usr.bin/csup/Makefile	Tue Mar  2 07:26:07 2010	(r204556)
@@ -15,30 +15,6 @@ SRCS=	attrstack.c auth.c config.c detail
 CFLAGS+=	-I. -I${.CURDIR} -g -pthread -DHAVE_FFLAGS -DNDEBUG
 WARNS?=		1
 
-# A bit of tweaking is needed to get this Makefile working
-# with the bsd.prog.mk of all the *BSD OSes...
-.if (${UNAME} == "NetBSD")
-LDFLAGS+=	-pthread
-YHEADER=	yes
-
-.elif (${UNAME} == "OpenBSD")
-# I bet there's a better way to do this with the OpenBSD mk
-# framework but well, this works and I got bored.
-LDFLAGS+=	-pthread
-YFLAGS=		-d
-CLEANFILES+=	parse.c parse.h y.tab.h
-
-config.c:	parse.h
-
-token.l:	parse.h
-
-y.tab.h:	parse.c
-
-parse.h:	y.tab.h
-	cp ${.ALLSRC} ${.TARGET}
-
-.endif
-
 DPADD=	${LIBCRYPTO} ${LIBZ}
 LDADD=	-lcrypto -lz
 

Copied: head/usr.bin/csup/README (from r204523, head/contrib/csup/README)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/csup/README	Tue Mar  2 07:26:07 2010	(r204556, copy of r204523, head/contrib/csup/README)
@@ -0,0 +1,39 @@
+$FreeBSD$
+
+Authors
+-------
+
+CVSup was originally written in Modula-3 by
+	John Polstra <jdp at polstra.com>.
+
+Csup is a rewrite of CVSup in C.  It has been mostly written by
+	Maxime Henrion <mux at FreeBSD.org>.
+
+A few contributors have helped him in his task and they are listed here in
+alphabetical order :
+
+	Olivier Houchard <cognet at FreeBSD.org>
+	Ulf Lilleengen <lulf at kerneled.org>
+	Christoph Mathys <cmathys at bluewin.ch>	(Google SoC Project)
+	Etienne Vidal <etienne.vidal at gmail.com>
+
+
+Building & Installing
+---------------------
+
+Csup should build and run fine under any *BSD OS (that includes FreeBSD,
+NetBSD, OpenBSD and DragonFlyBSD), as well as Linux and Darwin.  If you
+have a problem building from source, drop me a mail!
+
+There is one Makefile specifically tailored for *BSD systems named
+Makefile and another one that is gmake-specific for Darwin and Linux
+users named GNUmakefile.  You don't really need to worry about that
+since whatever your "make" command is, it should pick up the correct
+Makefile.
+
+As usual, to build the source code, just run "make".  Once this is done,
+just run "make install" to install the binary and manual page.
+
+Be warned however that if the packaging system of your OS knows about
+csup, it is certainly better to install it from there rather than by
+hand, so that it can then be properly deinstalled.

Copied: head/usr.bin/csup/TODO (from r204523, head/contrib/csup/TODO)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/csup/TODO	Tue Mar  2 07:26:07 2010	(r204556, copy of r204523, head/contrib/csup/TODO)
@@ -0,0 +1,29 @@
+$FreeBSD$
+
+BUGS:
+
+- Fix every XXX in the code :-).
+- The stream API needs some polishing.  It needs proper error numbers
+  and a stream_error() function similar to the ferror() function.
+- The yacc/lex code to parse the configuration file is sub-optimal.  It
+  has global variables because of yacc, but I think it should be possible
+  to do it better by using YYFUNC_PROTOTYPE or something.  I think it
+  should also be possible to completely get rid of the lex file.
+- The $Log$ CVS keyword is not supported.
+- Add missing support for supfile keywords and add sanity checks for
+  some of them.  Also, we're not supposed to choke on unknown keywords
+  to stay in line with CVSup, which just ignores them in order to
+  maintain compatibility with sup configuration files.
+
+MISSING FEATURES:
+
+- Add support for shell commands sent by the server.
+- Add missing support for various CVSup options : -D, -a (requires
+  authentication support), -e and -E (requires shell commands support)
+  and the destDir parameter.
+- For now, this code should build fine on FreeBSD, NetBSD, OpenBSD,
+  Linux and Darwin.  Solaris support would also be nice at some point.
+- Implement some new useful options : the ability to generate CVS
+  checkout files (files in CVS/ subdirectores), a command line override
+  to only update a specific collection and a third verbosity level to
+  display commit log messages.

Copied: head/usr.bin/csup/attrstack.c (from r204523, head/contrib/csup/attrstack.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/csup/attrstack.c	Tue Mar  2 07:26:07 2010	(r204556, copy of r204523, head/contrib/csup/attrstack.c)
@@ -0,0 +1,90 @@
+/*-
+ * Copyright (c) 2006, Maxime Henrion <mux at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "attrstack.h"
+#include "fattr.h"
+#include "misc.h"
+
+#define	ATTRSTACK_DEFSIZE	16	/* Initial size of the stack. */
+
+struct attrstack {
+	struct fattr **stack;
+	size_t cur;
+	size_t size;
+};
+
+struct attrstack *
+attrstack_new(void)
+{
+	struct attrstack *as;
+
+	as = xmalloc(sizeof(struct attrstack));
+	as->stack = xmalloc(sizeof(struct fattr *) * ATTRSTACK_DEFSIZE);
+	as->size = ATTRSTACK_DEFSIZE;
+	as->cur = 0;
+	return (as);
+}
+
+struct fattr *
+attrstack_pop(struct attrstack *as)
+{
+
+	assert(as->cur > 0);
+	return (as->stack[--as->cur]);
+}
+
+void
+attrstack_push(struct attrstack *as, struct fattr *fa)
+{
+
+	if (as->cur >= as->size) {
+		as->size *= 2;
+		as->stack = xrealloc(as->stack,
+		    sizeof(struct fattr *) * as->size);
+	}
+	as->stack[as->cur++] = fa;
+}
+
+size_t
+attrstack_size(struct attrstack *as)
+{
+
+	return (as->cur);
+}
+
+void
+attrstack_free(struct attrstack *as)
+{
+
+	assert(as->cur == 0);
+	free(as->stack);
+	free(as);
+}

Copied: head/usr.bin/csup/attrstack.h (from r204523, head/contrib/csup/attrstack.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/csup/attrstack.h	Tue Mar  2 07:26:07 2010	(r204556, copy of r204523, head/contrib/csup/attrstack.h)
@@ -0,0 +1,40 @@
+/*-
+ * Copyright (c) 2006, Maxime Henrion <mux at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+#ifndef _ATTRSTACK_H_
+#define _ATTRSTACK_H_
+
+struct fattr;
+struct attrstack;
+
+struct attrstack	*attrstack_new(void);
+void			 attrstack_push(struct attrstack *, struct fattr *);
+struct fattr		*attrstack_pop(struct attrstack *);
+size_t			 attrstack_size(struct attrstack *);
+void			 attrstack_free(struct attrstack *);
+
+#endif /* !_ATTRSTACK_H_ */

Copied: head/usr.bin/csup/auth.c (from r204523, head/contrib/csup/auth.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/csup/auth.c	Tue Mar  2 07:26:07 2010	(r204556, copy of r204523, head/contrib/csup/auth.c)
@@ -0,0 +1,331 @@
+/*-
+ * Copyright (c) 2003-2007, Petar Zhivkov Petrov <pesho.petrov at gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#include <ctype.h>
+#include <openssl/md5.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "auth.h"
+#include "config.h"
+#include "misc.h"
+#include "proto.h"
+#include "stream.h"
+
+#define MD5_BYTES			16
+
+/* This should be at least 2 * MD5_BYTES + 6 (length of "$md5$" + 1) */
+#define MD5_CHARS_MAX		(2*(MD5_BYTES)+6)
+
+struct srvrecord {
+	char server[MAXHOSTNAMELEN];
+	char client[256];
+	char password[256];
+};
+
+static int		auth_domd5auth(struct config *);
+static int		auth_lookuprecord(char *, struct srvrecord *);
+static int		auth_parsetoken(char **, char *, int);
+static void		auth_makesecret(struct srvrecord *, char *);
+static void		auth_makeresponse(char *, char *, char *);
+static void		auth_readablesum(unsigned char *, char *);
+static void		auth_makechallenge(struct config *, char *);
+static int		auth_checkresponse(char *, char *, char *);
+
+int auth_login(struct config *config)
+{
+	struct stream *s;
+	char hostbuf[MAXHOSTNAMELEN];
+	char *login, *host;
+	int error;
+
+	s = config->server;
+	error = gethostname(hostbuf, sizeof(hostbuf));
+	hostbuf[sizeof(hostbuf) - 1] = '\0';
+	if (error)
+		host = NULL;
+	else
+		host = hostbuf;
+	login = getlogin();
+	proto_printf(s, "USER %s %s\n", login != NULL ? login : "?",
+	    host != NULL ? host : "?");
+	stream_flush(s);
+	error = auth_domd5auth(config);
+	return (error);
+}
+
+static int
+auth_domd5auth(struct config *config)
+{
+	struct stream *s;
+	char *line, *cmd, *challenge, *realm, *client, *srvresponse, *msg;
+	char shrdsecret[MD5_CHARS_MAX], response[MD5_CHARS_MAX];
+	char clichallenge[MD5_CHARS_MAX];
+	struct srvrecord auth;
+	int error;
+
+	lprintf(2, "MD5 authentication started\n");
+	s = config->server;
+	line = stream_getln(s, NULL);
+	cmd = proto_get_ascii(&line);
+	realm = proto_get_ascii(&line);
+	challenge = proto_get_ascii(&line);
+	if (challenge == NULL ||
+	    line != NULL ||
+	    (strcmp(cmd, "AUTHMD5") != 0)) {
+		lprintf(-1, "Invalid server reply to USER\n");
+		return (STATUS_FAILURE);
+	}
+
+	client = NULL;
+	response[0] = clichallenge[0] = '.';
+	response[1] = clichallenge[1] = 0;
+	if (config->reqauth || (strcmp(challenge, ".") != 0)) {
+		if (strcmp(realm, ".") == 0) {
+			lprintf(-1, "Authentication required, but not enabled on server\n");
+			return (STATUS_FAILURE);
+		}
+		error = auth_lookuprecord(realm, &auth);
+		if (error != STATUS_SUCCESS)
+			return (error);
+		client = auth.client;
+		auth_makesecret(&auth, shrdsecret);
+	}
+
+	if (strcmp(challenge, ".") != 0)
+		auth_makeresponse(challenge, shrdsecret, response);
+	if (config->reqauth)
+		auth_makechallenge(config, clichallenge);
+	proto_printf(s, "AUTHMD5 %s %s %s\n",
+		client == NULL ? "." : client, response, clichallenge);
+	stream_flush(s);
+	line = stream_getln(s, NULL);
+	cmd = proto_get_ascii(&line);
+	if (cmd == NULL || line == NULL)
+		goto bad;
+	if (strcmp(cmd, "OK") == 0) {
+		srvresponse = proto_get_ascii(&line);
+		if (srvresponse == NULL)
+			goto bad;
+		if (config->reqauth &&
+		    !auth_checkresponse(srvresponse, clichallenge, shrdsecret)) {
+			lprintf(-1, "Server failed to authenticate itself to client\n");
+			return (STATUS_FAILURE);
+		}
+		lprintf(2, "MD5 authentication successfull\n");
+		return (STATUS_SUCCESS);
+	}
+	if (strcmp(cmd, "!") == 0) {
+		msg = proto_get_rest(&line);
+		if (msg == NULL)
+			goto bad;
+		lprintf(-1, "Server error: %s\n", msg);
+		return (STATUS_FAILURE);
+	}
+bad:
+	lprintf(-1, "Invalid server reply to AUTHMD5\n");
+	return (STATUS_FAILURE);
+}
+
+static int
+auth_lookuprecord(char *server, struct srvrecord *auth)
+{
+	char *home, *line, authfile[FILENAME_MAX];
+	struct stream *s;
+	int linenum = 0, error;
+
+	home = getenv("HOME");
+	if (home == NULL) {
+		lprintf(-1, "Environment variable \"HOME\" is not set\n");
+		return (STATUS_FAILURE);
+	}
+	snprintf(authfile, sizeof(authfile), "%s/%s", home, AUTHFILE);
+	s = stream_open_file(authfile, O_RDONLY);
+	if (s == NULL) {
+		lprintf(-1, "Could not open file %s\n", authfile);
+		return (STATUS_FAILURE);
+	}
+
+	while ((line = stream_getln(s, NULL)) != NULL) {
+		linenum++;
+		if (line[0] == '#' || line[0] == '\0')
+			continue;
+		error = auth_parsetoken(&line, auth->server,
+		    sizeof(auth->server));
+		if (error != STATUS_SUCCESS) {
+			lprintf(-1, "%s:%d Missng client name\n", authfile, linenum);
+			goto close;
+		}
+		/* Skip the rest of this line, it isn't what we are looking for. */
+		if (strcmp(auth->server, server) != 0)
+			continue;
+		error = auth_parsetoken(&line, auth->client,
+		    sizeof(auth->client));
+		if (error != STATUS_SUCCESS) {
+			lprintf(-1, "%s:%d Missng password\n", authfile, linenum);
+			goto close;
+		}
+		error = auth_parsetoken(&line, auth->password,
+		    sizeof(auth->password));
+		if (error != STATUS_SUCCESS) {
+			lprintf(-1, "%s:%d Missng comment\n", authfile, linenum);
+			goto close;
+		}
+		stream_close(s);
+		lprintf(2, "Found authentication record for server \"%s\"\n",
+		    server);
+		return (STATUS_SUCCESS);
+	}
+	lprintf(-1, "Unknown server \"%s\". Fix your %s\n", server , authfile);
+	memset(auth->password, 0, sizeof(auth->password));
+close:
+	stream_close(s);
+	return (STATUS_FAILURE);
+}
+
+static int
+auth_parsetoken(char **line, char *buf, int len)
+{
+	char *colon;
+
+	colon = strchr(*line, ':');
+	if (colon == NULL)
+		return (STATUS_FAILURE);
+	*colon = 0;
+	buf[len - 1] = 0;
+	strncpy(buf, *line, len - 1);
+	*line = colon + 1;
+	return (STATUS_SUCCESS);
+}
+
+static void
+auth_makesecret(struct srvrecord *auth, char *secret)
+{
+	char *s, ch;
+	const char *md5salt = "$md5$";
+	unsigned char md5sum[MD5_BYTES];
+	MD5_CTX md5;
+
+	MD5_Init(&md5);
+	for (s = auth->client; *s != 0; ++s) {
+		ch = tolower(*s);
+		MD5_Update(&md5, &ch, 1);
+	}
+	MD5_Update(&md5, ":", 1);
+	for (s = auth->server; *s != 0; ++s) {
+		ch = tolower(*s);
+		MD5_Update(&md5, &ch, 1);
+	}
+	MD5_Update(&md5, ":", 1);
+	MD5_Update(&md5, auth->password, strlen(auth->password));
+	MD5_Final(md5sum, &md5);
+	memset(secret, 0, sizeof(secret));
+	strcpy(secret, md5salt);
+	auth_readablesum(md5sum, secret + strlen(md5salt));
+}
+
+static void
+auth_makeresponse(char *challenge, char *sharedsecret, char *response)
+{
+	MD5_CTX md5;
+	unsigned char md5sum[MD5_BYTES];
+
+	MD5_Init(&md5);
+	MD5_Update(&md5, sharedsecret, strlen(sharedsecret));
+	MD5_Update(&md5, ":", 1);
+	MD5_Update(&md5, challenge, strlen(challenge));
+	MD5_Final(md5sum, &md5);
+	auth_readablesum(md5sum, response);
+}
+
+/*
+ * Generates a challenge string which is an MD5 sum
+ * of a fairly random string. The purpose is to decrease
+ * the possibility of generating the same challenge
+ * string (even by different clients) more then once
+ * for the same server.
+ */
+static void
+auth_makechallenge(struct config *config, char *challenge)
+{
+	MD5_CTX md5;
+	unsigned char md5sum[MD5_BYTES];
+	char buf[128];
+	struct timeval tv;
+	struct sockaddr_in laddr;
+	pid_t pid, ppid;
+	int error, addrlen;
+
+	gettimeofday(&tv, NULL);
+	pid = getpid();
+	ppid = getppid();
+	srand(tv.tv_usec ^ tv.tv_sec ^ pid);
+	addrlen = sizeof(laddr);
+	error = getsockname(config->socket, (struct sockaddr *)&laddr, &addrlen);
+	if (error < 0) {
+		memset(&laddr, 0, sizeof(laddr));
+	}
+	gettimeofday(&tv, NULL);
+	MD5_Init(&md5);
+	snprintf(buf, sizeof(buf), "%s:%ld:%ld:%ld:%d:%d",
+	    inet_ntoa(laddr.sin_addr), tv.tv_sec, tv.tv_usec, random(), pid, ppid);
+	MD5_Update(&md5, buf, strlen(buf));
+	MD5_Final(md5sum, &md5);
+	auth_readablesum(md5sum, challenge);
+}
+
+static int
+auth_checkresponse(char *response, char *challenge, char *secret)
+{
+	char correctresponse[MD5_CHARS_MAX];
+
+	auth_makeresponse(challenge, secret, correctresponse);
+	return (strcmp(response, correctresponse) == 0);
+}
+
+static void
+auth_readablesum(unsigned char *md5sum, char *readable)
+{
+	unsigned int i;
+	char *s = readable;
+
+	for (i = 0; i < MD5_BYTES; ++i, s+=2) {
+		sprintf(s, "%.2x", md5sum[i]);
+	}
+}
+

Copied: head/usr.bin/csup/auth.h (from r204523, head/contrib/csup/auth.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/csup/auth.h	Tue Mar  2 07:26:07 2010	(r204556, copy of r204523, head/contrib/csup/auth.h)
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2003-2007, Petar Zhivkov Petrov <pesho.petrov at gmail.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifndef _AUTH_H_
+#define _AUTH_H_
+
+#define	AUTHFILE	".csup/auth" /* user home relative */
+
+struct config;
+
+int auth_login(struct config *);
+
+#endif /* !_AUTH_H_ */
+

Copied: head/usr.bin/csup/config.c (from r204523, head/contrib/csup/config.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.bin/csup/config.c	Tue Mar  2 07:26:07 2010	(r204556, copy of r204523, head/contrib/csup/config.c)
@@ -0,0 +1,579 @@
+/*-
+ * Copyright (c) 2003-2006, Maxime Henrion <mux at FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "config.h"
+#include "globtree.h"
+#include "keyword.h"
+#include "misc.h"
+#include "parse.h"
+#include "stream.h"
+#include "token.h"
+
+static int		 config_parse_refusefiles(struct coll *);
+static int		 config_parse_refusefile(struct coll *, char *);
+
+extern FILE *yyin;
+
+/* These are globals because I can't think of a better way with yacc. */
+static STAILQ_HEAD(, coll) colls;
+static struct coll *cur_coll;
+static struct coll *defaults;
+static struct coll *ovcoll;
+static int ovmask;
+static const char *cfgfile;
+
+/*
+ * Extract all the configuration information from the config
+ * file and some command line parameters.
+ */
+struct config *
+config_init(const char *file, struct coll *override, int overridemask)
+{
+	struct config *config;
+	struct coll *coll;
+	size_t slen;
+	char *prefix;
+	int error;
+	mode_t mask;
+
+	config = xmalloc(sizeof(struct config));
+	memset(config, 0, sizeof(struct config));
+	STAILQ_INIT(&colls);
+
+	defaults = coll_new(NULL);
+	/* Set the default umask. */
+	mask = umask(0);
+	umask(mask);
+	defaults->co_umask = mask;
+	ovcoll = override;
+	ovmask = overridemask;
+
+	/* Extract a list of collections from the configuration file. */
+	cur_coll = coll_new(defaults);
+	yyin = fopen(file, "r");
+	if (yyin == NULL) {
+		lprintf(-1, "Cannot open \"%s\": %s\n", file, strerror(errno));
+		goto bad;
+	}
+	cfgfile = file;
+	error = yyparse();
+	fclose(yyin);
+	if (error)
+		goto bad;
+
+	memcpy(&config->colls, &colls, sizeof(colls));
+	if (STAILQ_EMPTY(&config->colls)) {
+		lprintf(-1, "Empty supfile\n");
+		goto bad;
+	}
+
+	/* Fixup the list of collections. */
+	STAILQ_FOREACH(coll, &config->colls, co_next) {
+ 		if (coll->co_base == NULL)
+			coll->co_base = xstrdup("/usr/local/etc/cvsup");
+		if (coll->co_colldir == NULL)
+			coll->co_colldir = "sup";
+		if (coll->co_prefix == NULL) {
+			coll->co_prefix = xstrdup(coll->co_base);
+		/*
+		 * If prefix is not an absolute pathname, it is
+		 * interpreted relative to base.
+		 */
+		} else if (coll->co_prefix[0] != '/') {
+			slen = strlen(coll->co_base);
+			if (slen > 0 && coll->co_base[slen - 1] != '/')
+				xasprintf(&prefix, "%s/%s", coll->co_base,
+				    coll->co_prefix);
+			else
+				xasprintf(&prefix, "%s%s", coll->co_base,
+				    coll->co_prefix);
+			free(coll->co_prefix);
+			coll->co_prefix = prefix;
+		}
+		coll->co_prefixlen = strlen(coll->co_prefix);
+		/* Determine whether to checksum RCS files or not. */
+		if (coll->co_options & CO_EXACTRCS)
+			coll->co_options |= CO_CHECKRCS;
+		else
+			coll->co_options &= ~CO_CHECKRCS;
+		/* In recent versions, we always try to set the file modes. */
+		coll->co_options |= CO_SETMODE;
+		coll->co_options |= CO_NORSYNC;
+		error = config_parse_refusefiles(coll);
+		if (error)
+			goto bad;
+	}
+
+	coll_free(cur_coll);
+	coll_free(defaults);
+	config->host = STAILQ_FIRST(&config->colls)->co_host;
+	return (config);
+bad:
+	coll_free(cur_coll);
+	coll_free(defaults);
+	config_free(config);
+	return (NULL);
+}
+
+int
+config_checkcolls(struct config *config)
+{
+	char linkname[4];
+	struct stat sb;
+	struct coll *coll;
+	int error, numvalid, ret;
+
+	numvalid = 0;
+	STAILQ_FOREACH(coll, &config->colls, co_next) {
+		error = stat(coll->co_prefix, &sb);
+		if (error || !S_ISDIR(sb.st_mode)) {
+			/* Skip this collection, and warn about it unless its
+			   prefix is a symbolic link pointing to "SKIP". */
+			coll->co_options |= CO_SKIP;
+			ret = readlink(coll->co_prefix, linkname,
+			    sizeof(linkname));
+			if (ret != 4 || memcmp(linkname, "SKIP", 4) != 0) {
+				lprintf(-1,"Nonexistent prefix \"%s\" for "
+				    "%s/%s\n", coll->co_prefix, coll->co_name,
+				    coll->co_release);
+			}
+			continue;
+		}
+		numvalid++;
+	}
+	return (numvalid);
+}
+
+static int
+config_parse_refusefiles(struct coll *coll)
+{
+	char *collstem, *suffix, *supdir, *path;
+	int error;
+
+	if (coll->co_colldir[0] == '/')
+		supdir = xstrdup(coll->co_colldir);
+	else
+		xasprintf(&supdir, "%s/%s", coll->co_base, coll->co_colldir);
+
+	/* First, the global refuse file that applies to all collections. */
+	xasprintf(&path, "%s/refuse", supdir);
+	error = config_parse_refusefile(coll, path);
+	free(path);
+	if (error) {
+		free(supdir);
+		return (error);
+	}
+
+	/* Next the per-collection refuse files that applies to all release/tag
+	   combinations. */
+	xasprintf(&collstem, "%s/%s/refuse", supdir, coll->co_name);
+	free(supdir);
+	error = config_parse_refusefile(coll, collstem);
+	if (error) {
+		free(collstem);
+		return (error);
+	}
+
+	/* Finally, the per-release and per-tag refuse file. */
+	suffix = coll_statussuffix(coll);
+	if (suffix != NULL) {
+		xasprintf(&path, "%s%s", collstem, suffix);
+		free(suffix);
+		error = config_parse_refusefile(coll, path);
+		free(path);
+	}
+	free(collstem);
+	return (error);
+}
+
+/*
+ * Parses a "refuse" file, and records the relevant information in
+ * coll->co_refusals.  If the file does not exist, it is silently
+ * ignored.
+ */
+static int
+config_parse_refusefile(struct coll *coll, char *path)
+{
+	struct stream *rd;
+	char *cp, *line, *pat;
+
+	rd = stream_open_file(path, O_RDONLY);
+	if (rd == NULL)
+		return (0);
+	while ((line = stream_getln(rd, NULL)) != NULL) {
+		pat = line;
+		for (;;) {
+			/* Trim leading whitespace. */
+			pat += strspn(pat, " \t");
+			if (pat[0] == '\0')
+				break;
+			cp = strpbrk(pat, " \t");
+			if (cp != NULL)
+				*cp = '\0';
+			pattlist_add(coll->co_refusals, pat);
+			if (cp == NULL)
+				break;
+			pat = cp + 1;
+		}
+	}
+	if (!stream_eof(rd)) {
+		stream_close(rd);
+		lprintf(-1, "Read failure from \"%s\": %s\n", path,
+		    strerror(errno));
+		return (-1);
+	}
+	stream_close(rd);
+	return (0);
+}
+
+void
+config_free(struct config *config)
+{
+	struct coll *coll;
+
+	while (!STAILQ_EMPTY(&config->colls)) {
+		coll = STAILQ_FIRST(&config->colls);
+		STAILQ_REMOVE_HEAD(&config->colls, co_next);
+		coll_free(coll);
+	}
+	if (config->server != NULL)
+		stream_close(config->server);
+	if (config->laddr != NULL)
+		free(config->laddr);
+	free(config);
+}
+
+/* Create a new collection, inheriting options from the default collection. */
+struct coll *
+coll_new(struct coll *def)
+{
+	struct coll *new;
+
+	new = xmalloc(sizeof(struct coll));
+	memset(new, 0, sizeof(struct coll));
+	if (def != NULL) {
+		new->co_options = def->co_options;
+		new->co_umask = def->co_umask;
+		if (def->co_host != NULL)
+			new->co_host = xstrdup(def->co_host);
+		if (def->co_base != NULL)
+			new->co_base = xstrdup(def->co_base);
+		if (def->co_date != NULL)
+			new->co_date = xstrdup(def->co_date);
+		if (def->co_prefix != NULL)
+			new->co_prefix = xstrdup(def->co_prefix);
+		if (def->co_release != NULL)
+			new->co_release = xstrdup(def->co_release);
+		if (def->co_tag != NULL)
+			new->co_tag = xstrdup(def->co_tag);
+		if (def->co_listsuffix != NULL)
+			new->co_listsuffix = xstrdup(def->co_listsuffix);
+	} else {
+		new->co_tag = xstrdup(".");
+		new->co_date = xstrdup(".");
+	}
+	new->co_keyword = keyword_new();
+	new->co_accepts = pattlist_new();
+	new->co_refusals = pattlist_new();
+	new->co_attrignore = FA_DEV | FA_INODE;
+	return (new);
+}
+
+void
+coll_override(struct coll *coll, struct coll *from, int mask)
+{
+	size_t i;
+	int newoptions, oldoptions;
+
+	newoptions = from->co_options & mask;
+	oldoptions = coll->co_options & (CO_MASK & ~mask);
+
+	if (from->co_release != NULL) {
+		if (coll->co_release != NULL)
+			free(coll->co_release);
+		coll->co_release = xstrdup(from->co_release);
+	}
+	if (from->co_host != NULL) {
+		if (coll->co_host != NULL)
+			free(coll->co_host);
+		coll->co_host = xstrdup(from->co_host);
+	}
+	if (from->co_base != NULL) {
+		if (coll->co_base != NULL)
+			free(coll->co_base);
+		coll->co_base = xstrdup(from->co_base);
+	}
+	if (from->co_colldir != NULL)
+		coll->co_colldir = from->co_colldir;
+	if (from->co_prefix != NULL) {
+		if (coll->co_prefix != NULL)
+			free(coll->co_prefix);
+		coll->co_prefix = xstrdup(from->co_prefix);
+	}
+	if (newoptions & CO_CHECKOUTMODE) {
+		if (from->co_tag != NULL) {
+			if (coll->co_tag != NULL)
+				free(coll->co_tag);
+			coll->co_tag = xstrdup(from->co_tag);
+		}
+		if (from->co_date != NULL) {
+			if (coll->co_date != NULL)
+				free(coll->co_date);
+			coll->co_date = xstrdup(from->co_date);
+		}
+	}
+	if (from->co_listsuffix != NULL) {
+		if (coll->co_listsuffix != NULL)
+			free(coll->co_listsuffix);
+		coll->co_listsuffix = xstrdup(from->co_listsuffix);
+	}
+	for (i = 0; i < pattlist_size(from->co_accepts); i++) {
+		pattlist_add(coll->co_accepts,
+		    pattlist_get(from->co_accepts, i));
+	}
+	for (i = 0; i < pattlist_size(from->co_refusals); i++) {
+		pattlist_add(coll->co_refusals,
+		    pattlist_get(from->co_refusals, i));
+	}
+	coll->co_options = oldoptions | newoptions;
+}
+
+char *
+coll_statussuffix(struct coll *coll)
+{
+	const char *tag;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list