- Add support for CVSup authentication mechanisms to csup.
- Include a cpasswd script performing the same mechanisms as the cvpasswd utility from CVSup. PR: bin/114129 Submitted by: Petar Zhivkov Petrov <pesho.petrov -at- gmail.com> MFC after: 1 month
This commit is contained in:
parent
7b59c0c5f5
commit
1282a5e283
@ -7,7 +7,7 @@ MANDIR?= ${PREFIX}/man/man
|
|||||||
UNAME!= /usr/bin/uname -s
|
UNAME!= /usr/bin/uname -s
|
||||||
|
|
||||||
PROG= csup
|
PROG= csup
|
||||||
SRCS= attrstack.c config.c detailer.c diff.c fattr.c fixups.c fnmatch.c \
|
SRCS= attrstack.c auth.c config.c detailer.c diff.c fattr.c fixups.c fnmatch.c \
|
||||||
globtree.c idcache.c keyword.c lister.c main.c misc.c mux.c parse.y \
|
globtree.c idcache.c keyword.c lister.c main.c misc.c mux.c parse.y \
|
||||||
pathcomp.c proto.c status.c stream.c threads.c token.l updater.c \
|
pathcomp.c proto.c status.c stream.c threads.c token.l updater.c \
|
||||||
rcsfile.c rcsparse.c lex.rcs.c rsyncfile.c
|
rcsfile.c rcsparse.c lex.rcs.c rsyncfile.c
|
||||||
@ -42,4 +42,7 @@ parse.h: y.tab.h
|
|||||||
DPADD= ${LIBCRYPTO} ${LIBZ}
|
DPADD= ${LIBCRYPTO} ${LIBZ}
|
||||||
LDADD= -lcrypto -lz
|
LDADD= -lcrypto -lz
|
||||||
|
|
||||||
|
SCRIPTS= cpasswd.sh
|
||||||
|
MAN= csup.1 cpasswd.1
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <bsd.prog.mk>
|
||||||
|
@ -17,7 +17,6 @@ BUGS:
|
|||||||
|
|
||||||
MISSING FEATURES:
|
MISSING FEATURES:
|
||||||
|
|
||||||
- Add support for authentication.
|
|
||||||
- Add support for shell commands sent by the server.
|
- Add support for shell commands sent by the server.
|
||||||
- Add missing support for various CVSup options : -D, -a (requires
|
- Add missing support for various CVSup options : -D, -a (requires
|
||||||
authentication support), -e and -E (requires shell commands support)
|
authentication support), -e and -E (requires shell commands support)
|
||||||
|
331
contrib/csup/auth.c
Normal file
331
contrib/csup/auth.c
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2003-2007, Petar Zhivkov Petrov <pesho.petrov@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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
38
contrib/csup/auth.h
Normal file
38
contrib/csup/auth.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2003-2007, Petar Zhivkov Petrov <pesho.petrov@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_ */
|
||||||
|
|
@ -108,6 +108,7 @@ struct config {
|
|||||||
struct chan *chan1;
|
struct chan *chan1;
|
||||||
struct stream *server;
|
struct stream *server;
|
||||||
fattr_support_t fasupport;
|
fattr_support_t fasupport;
|
||||||
|
int reqauth;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct config *config_init(const char *, struct coll *, int);
|
struct config *config_init(const char *, struct coll *, int);
|
||||||
|
120
contrib/csup/cpasswd.1
Normal file
120
contrib/csup/cpasswd.1
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
.\" Copyright 1999-2003 John D. Polstra.
|
||||||
|
.\" 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.
|
||||||
|
.\" 3. All advertising materials mentioning features or use of this software
|
||||||
|
.\" must display the following acknowledgment:
|
||||||
|
.\" This product includes software developed by John D. Polstra.
|
||||||
|
.\" 4. The name of the author may not be used to endorse or promote products
|
||||||
|
.\" derived from this software without specific prior written permission.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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: cvpasswd.1,v 1.4 2003/03/04 18:24:42 jdp Exp $
|
||||||
|
.\" $FreeBSD $
|
||||||
|
.\"
|
||||||
|
.Dd June 27, 2007
|
||||||
|
.Os FreeBSD
|
||||||
|
.Dt CPASSWD 1
|
||||||
|
.Sh NAME
|
||||||
|
.Nm cpasswd
|
||||||
|
.Nd scramble passwords for csup authentication
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Ar clientName
|
||||||
|
.Ar serverName
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility creates scrambled passwords for the
|
||||||
|
.Nm CVSup
|
||||||
|
server's authentication database. It is invoked with a client name
|
||||||
|
and a server name.
|
||||||
|
.Ar ClientName
|
||||||
|
is the name the client uses to gain access to the
|
||||||
|
server. By convention, e-mail addresses are used for all client
|
||||||
|
names, e.g.,
|
||||||
|
.Ql BillyJoe@FreeBSD.ORG .
|
||||||
|
Client names are case-insensitive.
|
||||||
|
.Pp
|
||||||
|
.Ar ServerName
|
||||||
|
is the name of the
|
||||||
|
.Nm CVSup
|
||||||
|
server which the client wishes to access. By convention,
|
||||||
|
it is the canonical fully-qualified domain name of the server, e.g.,
|
||||||
|
.Ql CVSup.FreeBSD.ORG .
|
||||||
|
This must agree with the server's own idea of its name. The name is
|
||||||
|
case-insensitive.
|
||||||
|
.Pp
|
||||||
|
To set up authentication for a given server, one must perform the
|
||||||
|
following steps:
|
||||||
|
.Bl -enum
|
||||||
|
.It
|
||||||
|
Obtain the official
|
||||||
|
.Ar serverName
|
||||||
|
from the administrator of the server or from some other source.
|
||||||
|
.It
|
||||||
|
Choose an appropriate
|
||||||
|
.Ar clientName .
|
||||||
|
It should be in the form of a valid e-mail address, to make it easy
|
||||||
|
for the server administrator to contact the user if necessary.
|
||||||
|
.It
|
||||||
|
Choose an arbitrary secret
|
||||||
|
.Ar password .
|
||||||
|
.It
|
||||||
|
Run
|
||||||
|
.Nm cpasswd ,
|
||||||
|
and type in the
|
||||||
|
.Ar password
|
||||||
|
when prompted for it. The utility will print out a line to send
|
||||||
|
to the server administrator, and instruct you how to modify your
|
||||||
|
.Li $ Ns Ev HOME Ns Pa /.csup/auth
|
||||||
|
file. You should use a secure channel to send the line to the
|
||||||
|
server administrator.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Since
|
||||||
|
.Li $ Ns Ev HOME Ns Pa /.csup/auth
|
||||||
|
contains passwords, you should ensure that it is not readable by
|
||||||
|
anyone except yourself.
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width $HOME/.csup/authxx -compact
|
||||||
|
.It Li $ Ns Ev HOME Ns Pa /.csup/auth
|
||||||
|
Authentication password file.
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr csup 1 ,
|
||||||
|
.Xr cvsup 1 ,
|
||||||
|
.Xr cvsupd 8 .
|
||||||
|
.Pp
|
||||||
|
.Bd -literal
|
||||||
|
http://www.cvsup.org/
|
||||||
|
.Ed
|
||||||
|
.Sh AUTHORS
|
||||||
|
.An -nosplit
|
||||||
|
.An Petar Zhivkov Petrov Aq pesho.petrov@gmail.com
|
||||||
|
is the author of
|
||||||
|
.Nm ,
|
||||||
|
the rewrite of
|
||||||
|
.Nm cvpasswd .
|
||||||
|
.An John Polstra Aq jdp@polstra.com
|
||||||
|
is the author of
|
||||||
|
.Nm CVSup .
|
||||||
|
.Sh LEGALITIES
|
||||||
|
CVSup is a registered trademark of John D. Polstra.
|
135
contrib/csup/cpasswd.sh
Executable file
135
contrib/csup/cpasswd.sh
Executable file
@ -0,0 +1,135 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
#
|
||||||
|
# Copyright 2007. Petar Zhivkov Petrov
|
||||||
|
# pesho.petrov@gmail.com
|
||||||
|
#
|
||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
echo "Usage: $0 clientName serverName"
|
||||||
|
echo " $0 -v"
|
||||||
|
}
|
||||||
|
|
||||||
|
countChars() {
|
||||||
|
_count="`echo "$1" | sed -e "s/[^$2]//g" | tr -d "\n" | wc -c`"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
readPassword() {
|
||||||
|
while [ true ]; do
|
||||||
|
stty -echo
|
||||||
|
read -p "$1" _password
|
||||||
|
stty echo
|
||||||
|
echo ""
|
||||||
|
countChars "$_password" ":"
|
||||||
|
if [ $_count != 0 ]; then
|
||||||
|
echo "Sorry, password must not contain \":\" characters"
|
||||||
|
echo ""
|
||||||
|
else
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
makeSecret() {
|
||||||
|
local clientLower="`echo "$1" | tr "[:upper:]" "[:lower:]"`"
|
||||||
|
local serverLower="`echo "$2" | tr "[:upper:]" "[:lower:]"`"
|
||||||
|
local secret="`md5 -qs "$clientLower:$serverLower:$3"`"
|
||||||
|
_secret="\$md5\$$secret"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $# -eq 1 -a "X$1" = "X-v" ]; then
|
||||||
|
echo "Csup authentication key generator"
|
||||||
|
usage
|
||||||
|
exit
|
||||||
|
elif [ $# -ne 2 ]; then
|
||||||
|
usage
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
clientName=$1
|
||||||
|
serverName=$2
|
||||||
|
|
||||||
|
#
|
||||||
|
# Client name must contain exactly one '@' and at least one '.'.
|
||||||
|
# It must not contain a ':'.
|
||||||
|
#
|
||||||
|
|
||||||
|
countChars "$clientName" "@"
|
||||||
|
aCount=$_count
|
||||||
|
|
||||||
|
countChars "$clientName" "."
|
||||||
|
dotCount=$_count
|
||||||
|
if [ $aCount -ne 1 -o $dotCount -eq 0 ]; then
|
||||||
|
echo "Client name must have the form of an e-mail address,"
|
||||||
|
echo "e.g., \"user@domain.com\""
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
countChars "$clientName" ":"
|
||||||
|
colonCount=$_count
|
||||||
|
if [ $colonCount -gt 0 ]; then
|
||||||
|
echo "Client name must not contain \":\" characters"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# Server name must not contain '@' and must have at least one '.'.
|
||||||
|
# It also must not contain a ':'.
|
||||||
|
#
|
||||||
|
|
||||||
|
countChars "$serverName" "@"
|
||||||
|
aCount=$_count
|
||||||
|
|
||||||
|
countChars "$serverName" "."
|
||||||
|
dotCount=$_count
|
||||||
|
if [ $aCount != 0 -o $dotCount = 0 ]; then
|
||||||
|
echo "Server name must be a fully-qualified domain name."
|
||||||
|
echo "e.g., \"host.domain.com\""
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
countChars "$serverName" ":"
|
||||||
|
colonCount=$_count
|
||||||
|
if [ $colonCount -gt 0 ]; then
|
||||||
|
echo "Server name must not contain \":\" characters"
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
#
|
||||||
|
# Ask for password and generate secret.
|
||||||
|
#
|
||||||
|
|
||||||
|
while [ true ]; do
|
||||||
|
readPassword "Enter password: "
|
||||||
|
makeSecret "$clientName" "$serverName" "$_password"
|
||||||
|
secret=$_secret
|
||||||
|
|
||||||
|
readPassword "Enter same password again: "
|
||||||
|
makeSecret "$clientName" "$serverName" "$_password"
|
||||||
|
secret2=$_secret
|
||||||
|
|
||||||
|
if [ "X$secret" = "X$secret2" ]; then
|
||||||
|
break
|
||||||
|
else
|
||||||
|
echo "Passwords did not match. Try again."
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Send this line to the server administrator at $serverName:"
|
||||||
|
echo "-------------------------------------------------------------------------------"
|
||||||
|
echo "$clientName:$secret::"
|
||||||
|
echo "-------------------------------------------------------------------------------"
|
||||||
|
echo "Be sure to send it using a secure channel!"
|
||||||
|
echo ""
|
||||||
|
echo "Add this line to your file \"$HOME/.csup/auth\", replacing \"XXX\""
|
||||||
|
echo "with the password you typed in:"
|
||||||
|
echo "-------------------------------------------------------------------------------"
|
||||||
|
echo "$serverName:$clientName:XXX:"
|
||||||
|
echo "-------------------------------------------------------------------------------"
|
||||||
|
echo "Make sure the file is readable and writable only by you!"
|
||||||
|
echo ""
|
||||||
|
|
@ -32,7 +32,7 @@
|
|||||||
.Nd network distribution package for CVS repositories
|
.Nd network distribution package for CVS repositories
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl 146ksvzZ
|
.Op Fl 146aksvzZ
|
||||||
.Op Fl A Ar addr
|
.Op Fl A Ar addr
|
||||||
.Op Fl b Ar base
|
.Op Fl b Ar base
|
||||||
.Op Fl c Ar collDir
|
.Op Fl c Ar collDir
|
||||||
@ -106,6 +106,12 @@ to use IPv4 addresses only.
|
|||||||
Forces
|
Forces
|
||||||
.Nm
|
.Nm
|
||||||
to use IPv6 addresses only.
|
to use IPv6 addresses only.
|
||||||
|
.It Fl a
|
||||||
|
Requires the server to authenticate itself (prove its identity) to
|
||||||
|
the client. If authentication of the server fails, the update is
|
||||||
|
canceled. See
|
||||||
|
.Sx AUTHENTICATION ,
|
||||||
|
below.
|
||||||
.It Fl A Ar addr
|
.It Fl A Ar addr
|
||||||
Specifies a local address to bind to when connecting to the server.
|
Specifies a local address to bind to when connecting to the server.
|
||||||
The local address might be a hostname or a numeric host address string
|
The local address might be a hostname or a numeric host address string
|
||||||
@ -793,6 +799,102 @@ as well:
|
|||||||
.It
|
.It
|
||||||
.Pa /bar/stool/src-all/refuse.cvs:RELENG_3
|
.Pa /bar/stool/src-all/refuse.cvs:RELENG_3
|
||||||
.El
|
.El
|
||||||
|
.Sh AUTHENTICATION
|
||||||
|
.Nm
|
||||||
|
implements an optional authentication mechanism which can be used by the
|
||||||
|
client and server to verify each other's identities.
|
||||||
|
Public CVSup servers normally do not enable authentication.
|
||||||
|
.Nm
|
||||||
|
users may ignore this section unless they have been informed
|
||||||
|
that authentication is required by the administrator of their server.
|
||||||
|
.Pp
|
||||||
|
The authentication subsystem uses a
|
||||||
|
challenge-response protocol which is immune to packet sniffing and
|
||||||
|
replay attacks. No passwords are sent over the network in either
|
||||||
|
direction. Both the client and the server can independently verify
|
||||||
|
the identities of each other.
|
||||||
|
.Pp
|
||||||
|
The file
|
||||||
|
.Li $ Ns Ev HOME Ns Pa /.csup/auth
|
||||||
|
holds the information used for authentication. This file contains a
|
||||||
|
record for each server that the client is allowed to access. Each
|
||||||
|
record occupies one line in the file. Lines beginning with
|
||||||
|
.Ql #
|
||||||
|
are ignored, as are lines containing only white space. White space is
|
||||||
|
significant everywhere else in the file. Fields are separated by
|
||||||
|
.Ql \&:
|
||||||
|
characters.
|
||||||
|
.Pp
|
||||||
|
Each record of the file has the following form:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
.Sm off
|
||||||
|
.Xo Ar serverName No : Ar clientName No :
|
||||||
|
.Ar password No : Ar comment
|
||||||
|
.Xc
|
||||||
|
.Sm on
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
All fields must be present even if some of them are empty.
|
||||||
|
.Ar ServerName
|
||||||
|
is the name of the server to which the record applies. By convention,
|
||||||
|
it is the canonical fully-qualified domain name of the server, e.g.,
|
||||||
|
.Ql CVSup177.FreeBSD.ORG .
|
||||||
|
This must agree with the server's own idea of its name. The name is
|
||||||
|
case-insensitive.
|
||||||
|
.Pp
|
||||||
|
.Ar ClientName
|
||||||
|
is the name the client uses to gain access to the server. By
|
||||||
|
convention, e-mail addresses are used for all client names, e.g.,
|
||||||
|
.Ql BillyJoe@FreeBSD.ORG .
|
||||||
|
Client names are case-insensitive.
|
||||||
|
.Pp
|
||||||
|
.Ar Password
|
||||||
|
is a secret string of characters that the client uses to prove its
|
||||||
|
identity. It may not contain any
|
||||||
|
.Ql \&:
|
||||||
|
or newline characters.
|
||||||
|
.Pp
|
||||||
|
.Ar Comment
|
||||||
|
may contain any additional information to identify the record. It
|
||||||
|
is not interpreted by the program.
|
||||||
|
.Pp
|
||||||
|
To set up authentication for a given server, one must perform the
|
||||||
|
following steps:
|
||||||
|
.Bl -enum
|
||||||
|
.It
|
||||||
|
Obtain the official
|
||||||
|
.Ar serverName
|
||||||
|
from the administrator of the server or from some other source.
|
||||||
|
.It
|
||||||
|
Choose an appropriate
|
||||||
|
.Ar clientName .
|
||||||
|
It should be in the form of a valid e-mail address, to make it easy
|
||||||
|
for the server administrator to contact the user if necessary.
|
||||||
|
.It
|
||||||
|
Choose an arbitrary secret
|
||||||
|
.Ar password .
|
||||||
|
.It
|
||||||
|
Run the
|
||||||
|
.Nm cpasswd
|
||||||
|
utility, and type in the
|
||||||
|
.Ar password
|
||||||
|
when prompted for it. The utility will print out a line to send
|
||||||
|
to the server administrator, and instruct you how to modify your
|
||||||
|
.Li $ Ns Ev HOME Ns Pa /.csup/auth
|
||||||
|
file. You should use a secure channel to send the line to the
|
||||||
|
server administrator.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
Since
|
||||||
|
.Li $ Ns Ev HOME Ns Pa /.csup/auth
|
||||||
|
contains passwords, you should ensure that it is not readable by
|
||||||
|
anyone except yourself.
|
||||||
|
.Pp
|
||||||
|
Authentication works independently in both directions. The server
|
||||||
|
administrator controls whether you must prove your identity.
|
||||||
|
You control whether to check the server's identity, by means of the
|
||||||
|
.Fl a
|
||||||
|
command line option.
|
||||||
.Sh csup AND FIREWALLS
|
.Sh csup AND FIREWALLS
|
||||||
In its default mode,
|
In its default mode,
|
||||||
.Nm
|
.Nm
|
||||||
@ -865,6 +967,7 @@ subdirectory.
|
|||||||
List files.
|
List files.
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
|
.Xr cpasswd 1 ,
|
||||||
.Xr cvs 1 ,
|
.Xr cvs 1 ,
|
||||||
.Xr rcsintro 1 ,
|
.Xr rcsintro 1 ,
|
||||||
.Xr ssh 1 .
|
.Xr ssh 1 .
|
||||||
|
@ -60,6 +60,8 @@ usage(char *argv0)
|
|||||||
"(same as \"-r 0\")");
|
"(same as \"-r 0\")");
|
||||||
lprintf(-1, USAGE_OPTFMT, "-4", "Force usage of IPv4 addresses");
|
lprintf(-1, USAGE_OPTFMT, "-4", "Force usage of IPv4 addresses");
|
||||||
lprintf(-1, USAGE_OPTFMT, "-6", "Force usage of IPv6 addresses");
|
lprintf(-1, USAGE_OPTFMT, "-6", "Force usage of IPv6 addresses");
|
||||||
|
lprintf(-1, USAGE_OPTFMT, "-a",
|
||||||
|
"Require server to authenticate itself to us");
|
||||||
lprintf(-1, USAGE_OPTFMT, "-A addr",
|
lprintf(-1, USAGE_OPTFMT, "-A addr",
|
||||||
"Bind local socket to a specific address");
|
"Bind local socket to a specific address");
|
||||||
lprintf(-1, USAGE_OPTFMT, "-b base",
|
lprintf(-1, USAGE_OPTFMT, "-b base",
|
||||||
@ -107,7 +109,7 @@ main(int argc, char *argv[])
|
|||||||
struct stream *lock;
|
struct stream *lock;
|
||||||
char *argv0, *file, *lockfile;
|
char *argv0, *file, *lockfile;
|
||||||
int family, error, lockfd, lflag, overridemask;
|
int family, error, lockfd, lflag, overridemask;
|
||||||
int c, i, deletelim, port, retries, status;
|
int c, i, deletelim, port, retries, status, reqauth;
|
||||||
time_t nexttry;
|
time_t nexttry;
|
||||||
|
|
||||||
error = 0;
|
error = 0;
|
||||||
@ -124,9 +126,10 @@ main(int argc, char *argv[])
|
|||||||
lockfile = NULL;
|
lockfile = NULL;
|
||||||
override = coll_new(NULL);
|
override = coll_new(NULL);
|
||||||
overridemask = 0;
|
overridemask = 0;
|
||||||
|
reqauth = 0;
|
||||||
|
|
||||||
while ((c = getopt(argc, argv,
|
while ((c = getopt(argc, argv,
|
||||||
"146A:b:c:d:gh:i:kl:L:p:P:r:svzZ")) != -1) {
|
"146aA:b:c:d:gh:i:kl:L:p:P:r:svzZ")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '1':
|
case '1':
|
||||||
retries = 0;
|
retries = 0;
|
||||||
@ -137,6 +140,10 @@ main(int argc, char *argv[])
|
|||||||
case '6':
|
case '6':
|
||||||
family = AF_INET6;
|
family = AF_INET6;
|
||||||
break;
|
break;
|
||||||
|
case 'a':
|
||||||
|
/* Require server authentication */
|
||||||
|
reqauth = 1;
|
||||||
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
error = getaddrinfo(optarg, NULL, NULL, &res);
|
error = getaddrinfo(optarg, NULL, NULL, &res);
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -303,6 +310,7 @@ main(int argc, char *argv[])
|
|||||||
config->laddrlen = laddrlen;
|
config->laddrlen = laddrlen;
|
||||||
}
|
}
|
||||||
config->deletelim = deletelim;
|
config->deletelim = deletelim;
|
||||||
|
config->reqauth = reqauth;
|
||||||
lprintf(2, "Connecting to %s\n", config->host);
|
lprintf(2, "Connecting to %s\n", config->host);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -45,6 +45,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "auth.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "detailer.h"
|
#include "detailer.h"
|
||||||
#include "fattr.h"
|
#include "fattr.h"
|
||||||
@ -74,7 +75,6 @@ static void killer_stop(struct killer *);
|
|||||||
static int proto_waitconnect(int);
|
static int proto_waitconnect(int);
|
||||||
static int proto_greet(struct config *);
|
static int proto_greet(struct config *);
|
||||||
static int proto_negproto(struct config *);
|
static int proto_negproto(struct config *);
|
||||||
static int proto_login(struct config *);
|
|
||||||
static int proto_fileattr(struct config *);
|
static int proto_fileattr(struct config *);
|
||||||
static int proto_xchgcoll(struct config *);
|
static int proto_xchgcoll(struct config *);
|
||||||
static struct mux *proto_mux(struct config *);
|
static struct mux *proto_mux(struct config *);
|
||||||
@ -251,56 +251,6 @@ bad:
|
|||||||
return (STATUS_FAILURE);
|
return (STATUS_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
proto_login(struct config *config)
|
|
||||||
{
|
|
||||||
struct stream *s;
|
|
||||||
char hostbuf[MAXHOSTNAMELEN];
|
|
||||||
char *line, *login, *host, *cmd, *realm, *challenge, *msg;
|
|
||||||
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);
|
|
||||||
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)
|
|
||||||
goto bad;
|
|
||||||
if (strcmp(realm, ".") != 0 || strcmp(challenge, ".") != 0) {
|
|
||||||
lprintf(-1, "Authentication required by the server and not "
|
|
||||||
"supported by client\n");
|
|
||||||
return (STATUS_FAILURE);
|
|
||||||
}
|
|
||||||
proto_printf(s, "AUTHMD5 . . .\n");
|
|
||||||
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)
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* File attribute support negotiation.
|
* File attribute support negotiation.
|
||||||
*/
|
*/
|
||||||
@ -601,7 +551,7 @@ proto_run(struct config *config)
|
|||||||
if (status == STATUS_SUCCESS)
|
if (status == STATUS_SUCCESS)
|
||||||
status = proto_negproto(config);
|
status = proto_negproto(config);
|
||||||
if (status == STATUS_SUCCESS)
|
if (status == STATUS_SUCCESS)
|
||||||
status = proto_login(config);
|
status = auth_login(config);
|
||||||
if (status == STATUS_SUCCESS)
|
if (status == STATUS_SUCCESS)
|
||||||
status = proto_fileattr(config);
|
status = proto_fileattr(config);
|
||||||
if (status == STATUS_SUCCESS)
|
if (status == STATUS_SUCCESS)
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
PROG= csup
|
PROG= csup
|
||||||
SRCS= attrstack.c \
|
SRCS= attrstack.c \
|
||||||
|
auth.c \
|
||||||
config.c \
|
config.c \
|
||||||
detailer.c \
|
detailer.c \
|
||||||
diff.c \
|
diff.c \
|
||||||
@ -37,4 +38,7 @@ WARNS?= 1
|
|||||||
DPADD= ${LIBCRYPTO} ${LIBZ} ${LIBPTHREAD}
|
DPADD= ${LIBCRYPTO} ${LIBZ} ${LIBPTHREAD}
|
||||||
LDADD= -lcrypto -lz -lpthread
|
LDADD= -lcrypto -lz -lpthread
|
||||||
|
|
||||||
|
SCRIPTS= cpasswd.sh
|
||||||
|
MAN= csup.1 cpasswd.1
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <bsd.prog.mk>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user