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 <j...@polstra.com>.
+
+Csup is a rewrite of CVSup in C.  It has been mostly written by
+       Maxime Henrion <m...@freebsd.org>.
+
+A few contributors have helped him in his task and they are listed here in
+alphabetical order :
+
+       Olivier Houchard <cog...@freebsd.org>
+       Ulf Lilleengen <l...@kerneled.org>
+       Christoph Mathys <cmat...@bluewin.ch>   (Google SoC Project)
+       Etienne Vidal <etienne.vi...@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 <m...@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 <m...@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.pet...@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.pet...@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 <m...@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 ***
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to