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"