diff -uNr ../../OpenBSD/openssh-2.1.0/Makefile ./Makefile --- ../../OpenBSD/openssh-2.1.0/Makefile Mon Oct 25 22:27:26 1999 +++ ./Makefile Mon May 15 03:48:55 2000 @@ -1,13 +1,11 @@ # $OpenBSD: Makefile,v 1.5 1999/10/25 20:27:26 markus Exp $ -.include - SUBDIR= lib ssh sshd ssh-add ssh-keygen ssh-agent scp distribution: - install -C -o root -g wheel -m 0644 ${.CURDIR}/ssh_config \ + install -c -o root -g wheel -m 0644 ${.CURDIR}/ssh_config \ ${DESTDIR}/etc/ssh_config - install -C -o root -g wheel -m 0644 ${.CURDIR}/sshd_config \ + install -c -o root -g wheel -m 0644 ${.CURDIR}/sshd_config \ ${DESTDIR}/etc/sshd_config .include diff -uNr ../../OpenBSD/openssh-2.1.0/Makefile.inc ./Makefile.inc --- ../../OpenBSD/openssh-2.1.0/Makefile.inc Mon Oct 25 22:27:26 1999 +++ ./Makefile.inc Thu May 11 03:08:06 2000 @@ -1,11 +1,5 @@ -CFLAGS+= -I${.CURDIR}/.. - -.include - -.if exists(${.CURDIR}/../lib/${__objdir}) -LDADD+= -L${.CURDIR}/../lib/${__objdir} -lssh -DPADD+= ${.CURDIR}/../lib/${__objdir}/libssh.a -.else -LDADD+= -L${.CURDIR}/../lib -lssh -DPADD+= ${.CURDIR}/../lib/libssh.a -.endif +BINDIR?= /usr/local/bin +MANDIR= /usr/local/man/cat +CFLAGS+= -I${.CURDIR}/.. -I/usr/local/include +LDFLAGS+= -L${.OBJDIR}/../lib -L/usr/local/lib +DPADD+= ${.OBJDIR}/../lib/libssh.a diff -uNr ../../OpenBSD/openssh-2.1.0/README.BSDI ./README.BSDI --- ../../OpenBSD/openssh-2.1.0/README.BSDI Thu Jan 1 02:00:00 1970 +++ ./README.BSDI Mon May 15 04:20:37 2000 @@ -0,0 +1,80 @@ +Copyright (c) 1999, 2000 + Vadim Vygonets . All rights reserved. + +This is a port of OpenSSH 2.1.0 to BSD/OS 3.x and 4.0. + +This port owes a great deal to Brian Fundakowski Feldman + and his port of OpenSSH from the FreeBSD +ports collection. Most notably, ConnectionsPerPeriod was +incorporated from there. + +This port also incorporates my patches to auth-passwd.c of ssh +1.2.26 (BSD authentication). I also tried to incorporate login +capabilities handling throughout sshd. The code was partly based +on Brian's code and partly on my older code. I tried to make the +code still compatible with FreeBSD, but, having no FreeBSD +machine, I cannot guarrantee anything. + +================================================================= += Changes from previous versions = +================================================================= + +2.1.0: + The way login_cap_t is handled is different now. It's no + longer passed all way from do_authentication() down to + do_child(), but generated and destroyed in authentication + routines, and then generated in do_exec_{no_,}pty() and + destroyed in do_child. Passing it all way down became + cumbersome due to the way SSH2 authentication routines + are organized. And FreeBSD doesn't use login_cap_t in + OpenSSH authentication routines. + + There are now two different BSD/OS-related CPP macros, + LOGIN_CAP and BSD_AUTH. This is to prepare ground for + merging of this port with the FreeBSD port of OpenSSH. + +1.2.2/1.2.3: + Important note: sshd is now installed in /usr/local/sbin. + I strongly advise that you remove /usr/local/bin/sshd to + avoid confusion. + +================================================================= += INSTALLATION = +================================================================= + +IF YOU DON'T LIVE IN A FREE COUNTRY, DON'T BLAME ME IF YOU GET +ARRESTED FOR USING THESE INSTRUCTIONS. I don't care, alright? +Please also note that I can get arrested, too. + +You need OpenSSL 0.9.4. You can get it from: + http://www.openssl.org/ +I had problems with OpenSSL 0.9.5a (RSA appears to be dead). + +Note that if you live in the USA and/or are a USA citizen +(consult your lawyer for details) you will have to use the RSAREF +library from RSA Security Inc. (http://www.rsa.com/). See the +file INSTALL in the OpenSSL distribution for some details. The +rest of this instruction e-sheet[tm] assumes that you don't have +to use RSAREF. + +If you intend to use OpenSSL on an 80386 machine (as opposed to +i486 or higher), consult the file INSTALL in the OpenSSL +distribution. The rest of this file assumes that you are rich. + +Compile and install OpenSSL with the following commands: + $ ./config --prefix=/usr/local --openssldir=/usr/local/lib/openssl + $ make + $ make test + $ su + # make install + +OpenSSH expects to find OpenSSL header files in subdirectory ssl. +Calm it by doing: + # cd /usr/local/include + # ln -s openssl ssl + +Compile OpenSSH by doing: + $ make + +Install OpenSSH: + # make install diff -uNr ../../OpenBSD/openssh-2.1.0/auth-passwd.c ./auth-passwd.c --- ../../OpenBSD/openssh-2.1.0/auth-passwd.c Fri Apr 14 13:30:29 2000 +++ ./auth-passwd.c Mon May 15 03:27:13 2000 @@ -19,6 +19,22 @@ * Tries to authenticate the user using password. Returns true if * authentication succeeds. */ +#ifdef BSD_AUTH /* BSDI and FreeBSD <=3? */ +int +auth_password(struct passwd *pw, const char *password, + login_cap_t *lc, char *style) +{ + char *challenge; + int status; + + /* style is already definitive */ + auth_setopt("auth_type", "auth-ssh"); + challenge = auth_value("challenge"); + status = auth_response(pw->pw_name, lc->lc_class, style, "response", + NULL, challenge ? challenge : "", (char *)password); + return (status > 0) && (status & AUTH_OKAY); +} +#else /* BSD_AUTH */ int auth_password(struct passwd * pw, const char *password) { @@ -60,3 +76,4 @@ /* Authentication is accepted if the encrypted passwords are identical. */ return (strcmp(encrypted_password, pw->pw_passwd) == 0); } +#endif /* BSD_AUTH */ diff -uNr ../../OpenBSD/openssh-2.1.0/auth.c ./auth.c --- ../../OpenBSD/openssh-2.1.0/auth.c Thu Apr 27 00:28:31 2000 +++ ./auth.c Mon May 15 03:50:12 2000 @@ -26,7 +26,6 @@ #include "session.h" #include "dispatch.h" - /* import */ extern ServerOptions options; extern char *forced_command; @@ -106,6 +105,16 @@ return 0; } } +#if defined(__FreeBSD__) || defined(__bsdi__) + /* Fail if the account's expiration time has passed. */ + if (pw->pw_expire != 0) { + struct timeval tv; + + (void)gettimeofday(&tv, NULL); + if (tv.tv_sec >= pw->pw_expire) + return 0; + } +#endif /* __FreeBSD__ || __bsdi__ */ /* We found no reason not to let this user try to log on... */ return 1; } diff -uNr ../../OpenBSD/openssh-2.1.0/auth1.c ./auth1.c --- ../../OpenBSD/openssh-2.1.0/auth1.c Sat Apr 29 21:11:52 2000 +++ ./auth1.c Mon May 15 03:29:46 2000 @@ -122,7 +122,11 @@ * return if authentication is successfull */ void +#ifdef BSD_AUTH +do_authloop(struct passwd * pw, login_cap_t *lc, char *style) +#else /* BSD_AUTH */ do_authloop(struct passwd * pw) +#endif /* BSD_AUTH */ { int attempt = 0; unsigned int bits; @@ -293,7 +297,11 @@ packet_integrity_check(plen, 4 + dlen, type); /* Try authentication with the password. */ +#ifdef BSD_AUTH + authenticated = auth_password(pw, password, lc, style); +#else /* BSD_AUTH */ authenticated = auth_password(pw, password); +#endif /* BSD_AUTH */ memset(password, 0, strlen(password)); xfree(password); @@ -399,6 +407,10 @@ int plen; unsigned int ulen; char *user; +#ifdef BSD_AUTH + login_cap_t *lc; + char *style; +#endif /* BSD_AUTH */ /* Get the name of the user that we wish to log in as. */ packet_read_expect(&plen, SSH_CMSG_USER); @@ -417,9 +429,24 @@ } #endif /* AFS */ +#ifdef BSD_AUTH + if ((style = strchr(user, ':')) != NULL) + *style++ = '\0'; +#endif /* BSD_AUTH */ + /* Verify that the user is a valid user. */ pw = getpwnam(user); + +#ifdef BSD_AUTH + lc = login_getpwclass(pw); + if (lc == NULL) + lc = login_getclassbyname(NULL, pw); + auth_setopt("auth_type", "auth-ssh"); + style = login_getstyle(lc, style, "auth-ssh"); + if (!pw || !lc || !style || !allowed_user(pw)) +#else /* BSD_AUTH */ if (!pw || !allowed_user(pw)) +#endif /* BSD_AUTH */ do_fake_authloop1(user); xfree(user); @@ -431,6 +458,11 @@ pwcopy.pw_gid = pw->pw_gid; pwcopy.pw_dir = xstrdup(pw->pw_dir); pwcopy.pw_shell = xstrdup(pw->pw_shell); +#ifdef LOGIN_CAP + pwcopy.pw_class = xstrdup(pw->pw_class); + pwcopy.pw_expire = pw->pw_expire; + pwcopy.pw_change = pw->pw_change; +#endif /* LOGIN_CAP */ pw = &pwcopy; /* @@ -447,7 +479,11 @@ #ifdef KRB4 (!options.kerberos_authentication || options.kerberos_or_local_passwd) && #endif /* KRB4 */ +#ifdef BSD_AUTH + auth_password(pw, "", lc, style)) { +#else /* BSD_AUTH */ auth_password(pw, "")) { +#endif /* BSD_AUTH */ /* Authentication with empty password succeeded. */ log("Login for user %s from %.100s, accepted without authentication.", pw->pw_name, get_remote_ipaddr()); @@ -455,7 +491,11 @@ /* Loop until the user has been authenticated or the connection is closed, do_authloop() returns only if authentication is successfull */ +#ifdef BSD_AUTH + do_authloop(pw, lc, style); +#else /* BSD_AUTH */ do_authloop(pw); +#endif /* BSD_AUTH */ } /* The user has been authenticated and accepted. */ @@ -464,5 +504,8 @@ packet_write_wait(); /* Perform session preparation. */ +#ifdef BSD_AUTH + login_close(lc); +#endif /* BSD_AUTH */ do_authenticated(pw); } diff -uNr ../../OpenBSD/openssh-2.1.0/auth2.c ./auth2.c --- ../../OpenBSD/openssh-2.1.0/auth2.c Mon May 8 20:42:24 2000 +++ ./auth2.c Mon May 15 03:31:02 2000 @@ -67,8 +67,13 @@ void protocol_error(int type, int plen); /* auth */ +#ifdef BSD_AUTH +int ssh2_auth_none(struct passwd *pw, login_cap_t *lc, char *style); +int ssh2_auth_password(struct passwd *pw, login_cap_t *lc, char *style); +#else /* BSD_AUTH */ int ssh2_auth_none(struct passwd *pw); int ssh2_auth_password(struct passwd *pw); +#endif /* BSD_AUTH */ int ssh2_auth_pubkey(struct passwd *pw, unsigned char *raw, unsigned int rlen); /* helper */ @@ -154,6 +159,10 @@ int authenticated = 0; char *raw, *user, *service, *method, *authmsg = NULL; struct passwd *pw; +#ifdef BSD_AUTH + login_cap_t *lc; + char *style; +#endif /* BSD_AUTH */ if (++attempt == AUTH_FAIL_MAX) packet_disconnect("too many failed userauth_requests"); @@ -165,18 +174,40 @@ service = packet_get_string(&len); method = packet_get_string(&len); debug("userauth-request for user %s service %s method %s", user, service, method); +#ifdef BSD_AUTH + if ((style = strchr(user, ':')) != NULL) + *style++ = '\0'; +#endif /* BSD_AUTH */ /* XXX we only allow the ssh-connection service */ pw = auth_set_user(user, service); +#ifdef BSD_AUTH + lc = login_getpwclass(pw); + if (lc == NULL) + lc = login_getclassbyname(NULL, pw); + auth_setopt("auth_type", "auth-ssh"); + style = login_getstyle(lc, style, "auth-ssh"); +#endif /* BSD_AUTH */ if (pw && strcmp(service, "ssh-connection")==0) { if (strcmp(method, "none") == 0) { +#ifdef BSD_AUTH + authenticated = ssh2_auth_none(pw, lc, style); +#else /* BSD_AUTH */ authenticated = ssh2_auth_none(pw); +#endif /* BSD_AUTH */ } else if (strcmp(method, "password") == 0) { +#ifdef BSD_AUTH + authenticated = ssh2_auth_password(pw, lc, style); +#else /* BSD_AUTH */ authenticated = ssh2_auth_password(pw); +#endif /* BSD_AUTH */ } else if (strcmp(method, "publickey") == 0) { authenticated = ssh2_auth_pubkey(pw, raw, rlen); } } +#ifdef BSD_AUTH + login_close(lc); +#endif /* BSD_AUTH */ if (authenticated && pw && pw->pw_uid == 0 && !options.permit_root_login) { authenticated = 0; log("ROOT LOGIN REFUSED FROM %.200s", @@ -227,13 +258,26 @@ } int +#ifdef BSD_AUTH +ssh2_auth_none(struct passwd *pw, login_cap_t *lc, char *style) +#else /* BSD_AUTH */ ssh2_auth_none(struct passwd *pw) +#endif /* BSD_AUTH */ { packet_done(); +#ifdef BSD_AUTH + return auth_password(pw, "", lc, style); +#else /* BSD_AUTH */ return auth_password(pw, ""); +#endif /* BSD_AUTH */ } + int +#ifdef BSD_AUTH +ssh2_auth_password(struct passwd *pw, login_cap_t *lc, char *style) +#else /* BSD_AUTH */ ssh2_auth_password(struct passwd *pw) +#endif /* BSD_AUTH */ { char *password; int authenticated = 0; @@ -245,7 +289,11 @@ password = packet_get_string(&len); packet_done(); if (options.password_authentication && +#ifdef BSD_AUTH + auth_password(pw, password, lc, style) == 1) +#else /* BSD_AUTH */ auth_password(pw, password) == 1) +#endif /* BSD_AUTH */ authenticated = 1; memset(password, 0, len); xfree(password); diff -uNr ../../OpenBSD/openssh-2.1.0/channels.c ./channels.c --- ../../OpenBSD/openssh-2.1.0/channels.c Mon May 8 20:42:24 2000 +++ ./channels.c Sat May 13 23:45:47 2000 @@ -34,6 +34,10 @@ #include "ssh2.h" +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK (u_int32_t)0x7f000001 /* 127.0.0.1 */ +#endif + /* Maximum number of fake X11 displays to try. */ #define MAX_DISPLAYS 1000 diff -uNr ../../OpenBSD/openssh-2.1.0/includes.h ./includes.h --- ../../OpenBSD/openssh-2.1.0/includes.h Fri Apr 14 13:30:31 2000 +++ ./includes.h Mon May 15 04:54:39 2000 @@ -24,12 +24,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include @@ -38,7 +38,6 @@ #include #include -#include #include #include #include @@ -65,5 +64,32 @@ * client program. Socketpairs do not seem to work on all systems. */ #define USE_PIPES 1 + +#if defined(__FreeBSD__) && __FreeBSD__ <= 3 || defined(__bsdi__) +/* + * Data types. + */ +#ifndef __bsdi__ +typedef u_char sa_family_t; +typedef int socklen_t; +#endif /* !__bsdi__ */ + +/* + * bsd-api-new-02a: protocol-independent placeholder for socket addresses + */ +#define _SS_MAXSIZE 128 +#define _SS_ALIGNSIZE (sizeof(int64_t)) +#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) * 2) +#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) * 2 - \ + _SS_PAD1SIZE - _SS_ALIGNSIZE) + +struct sockaddr_storage { + u_char ss_len; /* address length */ + sa_family_t ss_family; /* address family */ + char __ss_pad1[_SS_PAD1SIZE]; + int64_t __ss_align; /* force desired structure storage alignment */ + char __ss_pad2[_SS_PAD2SIZE]; +}; +#endif #endif /* INCLUDES_H */ diff -uNr ../../OpenBSD/openssh-2.1.0/lib/Makefile ./lib/Makefile --- ../../OpenBSD/openssh-2.1.0/lib/Makefile Wed Apr 26 23:56:30 2000 +++ ./lib/Makefile Sat May 13 16:45:50 2000 @@ -5,22 +5,13 @@ cipher.c compat.c compress.c crc32.c deattack.c fingerprint.c \ hostfile.c log.c match.c mpaux.c nchan.c packet.c readpass.c \ rsa.c tildexpand.c ttymodes.c uidswap.c xmalloc.c atomicio.c \ - key.c dispatch.c dsa.c kex.c hmac.c uuencode.c + key.c dispatch.c dsa.c kex.c hmac.c uuencode.c \ + strlcat.c strlcpy.c arc4random.c mkdtemp.c timersub.c NOPROFILE= yes NOPIC= yes install: @echo -n - -.include - -.if (${KERBEROS} == "yes") -CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV -.if (${AFS} == "yes") -CFLAGS+= -DAFS -SRCS+= radix.c -.endif # AFS -.endif # KERBEROS .include diff -uNr ../../OpenBSD/openssh-2.1.0/lib/arc4random.c ./lib/arc4random.c --- ../../OpenBSD/openssh-2.1.0/lib/arc4random.c Thu Jan 1 02:00:00 1970 +++ ./lib/arc4random.c Thu Apr 20 02:30:52 2000 @@ -0,0 +1,196 @@ +/* $OpenBSD: arc4random.c,v 1.5 1999/09/28 01:24:48 deraadt Exp $ */ + +/* + * Arc4 random number generator for OpenBSD. + * Copyright 1996 David Mazieres . + * + * Modification and redistribution in source and binary forms is + * permitted provided that due credit is given to the author and the + * OpenBSD project (for instance by leaving this copyright notice + * intact). + */ + +/* + * This code is derived from section 17.1 of Applied Cryptography, + * second edition, which describes a stream cipher allegedly + * compatible with RSA Labs "RC4" cipher (the actual description of + * which is a trade secret). The same algorithm is used as a stream + * cipher called "arcfour" in Tatu Ylonen's ssh package. + * + * Here the stream cipher has been modified always to include the time + * when initializing the state. That makes it impossible to + * regenerate the same random sequence twice, so this can't be used + * for encryption, but will generate good random numbers. + * + * RC4 is a registered trademark of RSA Laboratories. + */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +#define inline __inline +#else /* !__GNUC__ */ +#define inline +#endif /* !__GNUC__ */ + +struct arc4_stream { + u_int8_t i; + u_int8_t j; + u_int8_t s[256]; +}; + +int rs_initialized; +static struct arc4_stream rs; + +static inline void +arc4_init(as) + struct arc4_stream *as; +{ + int n; + + for (n = 0; n < 256; n++) + as->s[n] = n; + as->i = 0; + as->j = 0; +} + +static inline void +arc4_addrandom(as, dat, datlen) + struct arc4_stream *as; + u_char *dat; + int datlen; +{ + int n; + u_int8_t si; + + as->i--; + for (n = 0; n < 256; n++) { + as->i = (as->i + 1); + si = as->s[as->i]; + as->j = (as->j + si + dat[n % datlen]); + as->s[as->i] = as->s[as->j]; + as->s[as->j] = si; + } + as->j = as->i; +} + +static void +arc4_stir(as) + struct arc4_stream *as; +{ + int fd; + struct { + struct timeval tv; + u_int rnd[(128 - sizeof(struct timeval)) / sizeof(u_int)]; + } rdat; + + gettimeofday(&rdat.tv, NULL); +#if 0 + fd = open("/dev/arandom", O_RDONLY); + if (fd != -1) { + read(fd, rdat.rnd, sizeof(rdat.rnd)); + close(fd); + } else { + int i, mib[2]; + size_t len; + + /* Device could not be opened, we might be chrooted, take + * randomness from sysctl. */ + + mib[0] = CTL_KERN; + mib[1] = KERN_ARND; + + for (i = 0; i < sizeof(rdat.rnd) / sizeof(u_int); i ++) { + len = sizeof(u_int); + if (sysctl(mib, 2, &rdat.rnd[i], &len, NULL, 0) == -1) + break; + } + } +#endif + /* fd < 0 or failed sysctl ? Ah, what the heck. We'll just take + * whatever was on the stack... */ + + arc4_addrandom(as, (void *) &rdat, sizeof(rdat)); +} + +static inline u_int8_t +arc4_getbyte(as) + struct arc4_stream *as; +{ + u_int8_t si, sj; + + as->i = (as->i + 1); + si = as->s[as->i]; + as->j = (as->j + si); + sj = as->s[as->j]; + as->s[as->i] = sj; + as->s[as->j] = si; + return (as->s[(si + sj) & 0xff]); +} + +static inline u_int32_t +arc4_getword(as) + struct arc4_stream *as; +{ + u_int32_t val; + val = arc4_getbyte(as) << 24; + val |= arc4_getbyte(as) << 16; + val |= arc4_getbyte(as) << 8; + val |= arc4_getbyte(as); + return val; +} + +void +arc4random_stir() +{ + if (!rs_initialized) { + arc4_init(&rs); + rs_initialized = 1; + } + arc4_stir(&rs); +} + +void +arc4random_addrandom(dat, datlen) + u_char *dat; + int datlen; +{ + if (!rs_initialized) + arc4random_stir(); + arc4_addrandom(&rs, dat, datlen); +} + +u_int32_t +arc4random() +{ + if (!rs_initialized) + arc4random_stir(); + return arc4_getword(&rs); +} + +#if 0 +/*-------- Test code for i386 --------*/ +#include +#include +int +main(int argc, char **argv) +{ + const int iter = 1000000; + int i; + pctrval v; + + v = rdtsc(); + for (i = 0; i < iter; i++) + arc4random(); + v = rdtsc() - v; + v /= iter; + + printf("%qd cycles\n", v); +} +#endif diff -uNr ../../OpenBSD/openssh-2.1.0/lib/mkdtemp.c ./lib/mkdtemp.c --- ../../OpenBSD/openssh-2.1.0/lib/mkdtemp.c Thu Jan 1 02:00:00 1970 +++ ./lib/mkdtemp.c Thu Apr 20 02:30:52 2000 @@ -0,0 +1,159 @@ +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. 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 acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char rcsid[] = "$OpenBSD: mktemp.c,v 1.13 1998/06/30 23:03:13 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static int _gettemp __P((char *, int *, int, int)); + +char * +mkdtemp(path) + char *path; +{ + return(_gettemp(path, (int *)NULL, 1, 0) ? path : (char *)NULL); +} + +static int +_gettemp(path, doopen, domkdir, slen) + char *path; + register int *doopen; + int domkdir; + int slen; +{ + register char *start, *trv, *suffp; + struct stat sbuf; + int pid, rval; + + if (doopen && domkdir) { + errno = EINVAL; + return(0); + } + + for (trv = path; *trv; ++trv) + ; + trv -= slen; + suffp = trv; + --trv; + if (trv < path) { + errno = EINVAL; + return (0); + } + pid = getpid(); + while (*trv == 'X' && pid != 0) { + *trv-- = (pid % 10) + '0'; + pid /= 10; + } + while (*trv == 'X') { + char c; + + pid = (arc4random() & 0xffff) % (26+26); + if (pid < 26) + c = pid + 'A'; + else + c = (pid - 26) + 'a'; + *trv-- = c; + } + start = trv + 1; + + /* + * check the target directory; if you have six X's and it + * doesn't exist this runs for a *very* long time. + */ + if (doopen || domkdir) { + for (;; --trv) { + if (trv <= path) + break; + if (*trv == '/') { + *trv = '\0'; + rval = stat(path, &sbuf); + *trv = '/'; + if (rval != 0) + return(0); + if (!S_ISDIR(sbuf.st_mode)) { + errno = ENOTDIR; + return(0); + } + break; + } + } + } + + for (;;) { + if (doopen) { + if ((*doopen = + open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) + return(1); + if (errno != EEXIST) + return(0); + } else if (domkdir) { + if (mkdir(path, 0700) == 0) + return(1); + if (errno != EEXIST) + return(0); + } else if (lstat(path, &sbuf)) + return(errno == ENOENT ? 1 : 0); + + /* tricky little algorithm for backward compatibility */ + for (trv = start;;) { + if (!*trv) + return (0); + if (*trv == 'Z') { + if (trv == suffp) + return (0); + *trv++ = 'a'; + } else { + if (isdigit(*trv)) + *trv = 'a'; + else if (*trv == 'z') /* inc from z to A */ + *trv = 'A'; + else { + if (trv == suffp) + return (0); + ++*trv; + } + break; + } + } + } + /*NOTREACHED*/ +} diff -uNr ../../OpenBSD/openssh-2.1.0/lib/strlcat.c ./lib/strlcat.c --- ../../OpenBSD/openssh-2.1.0/lib/strlcat.c Thu Jan 1 02:00:00 1970 +++ ./lib/strlcat.c Thu Apr 20 02:30:52 2000 @@ -0,0 +1,71 @@ +/* $OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * 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. 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 ``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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t strlcat(dst, src, siz) + char *dst; + const char *src; + size_t siz; +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (*d != '\0' && n-- != 0) + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} diff -uNr ../../OpenBSD/openssh-2.1.0/lib/strlcpy.c ./lib/strlcpy.c --- ../../OpenBSD/openssh-2.1.0/lib/strlcpy.c Thu Jan 1 02:00:00 1970 +++ ./lib/strlcpy.c Thu Apr 20 02:30:52 2000 @@ -0,0 +1,68 @@ +/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * 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. 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 ``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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t strlcpy(dst, src, siz) + char *dst; + const char *src; + size_t siz; +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} diff -uNr ../../OpenBSD/openssh-2.1.0/lib/timersub.c ./lib/timersub.c --- ../../OpenBSD/openssh-2.1.0/lib/timersub.c Thu Jan 1 02:00:00 1970 +++ ./lib/timersub.c Thu Apr 20 02:30:52 2000 @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1999 + * Vadim Vygonets . 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. Neither the name of Vadim Vygonets nor the names of his contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY VADIM VYGONETS 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 VADIM VYGONETS 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. + */ + +/* If you want it in public domain, contact me. */ + +/* + * void + * timersub(const struct timeval *a, const struct timeval *b, + * struct timeval *result); + * + * Does result = a - b with timeval. + * Originally written for OpenSSH (it was easier than to find the source). + * I really really hope this function must be void. + */ + +#include + +void +timersub(const struct timeval *a, const struct timeval *b, + struct timeval *result) +{ + result->tv_sec = a->tv_sec - b->tv_sec; + result->tv_usec = a->tv_usec - b->tv_usec; + if (result->tv_usec < 0) { + result->tv_usec += 1000000; + result->tv_sec--; + } +} diff -uNr ../../OpenBSD/openssh-2.1.0/login.c ./login.c --- ../../OpenBSD/openssh-2.1.0/login.c Wed Apr 19 10:05:49 2000 +++ ./login.c Sat May 13 16:53:29 2000 @@ -20,7 +20,13 @@ #include "includes.h" RCSID("$Id: login.c,v 1.13 2000/04/19 07:05:49 deraadt Exp $"); +#ifndef __bsdi__ +#ifdef __FreeBSD__ +#include +#else /* __FreeBSD__ */ #include +#endif /* __FreeBSD__ */ +#endif /* __bsdi__ */ #include #include "ssh.h" diff -uNr ../../OpenBSD/openssh-2.1.0/pty.c ./pty.c --- ../../OpenBSD/openssh-2.1.0/pty.c Fri Apr 14 13:30:32 2000 +++ ./pty.c Sat May 13 16:52:26 2000 @@ -16,7 +16,13 @@ #include "includes.h" RCSID("$Id: pty.c,v 1.13 2000/04/14 10:30:32 markus Exp $"); +#ifndef __bsdi__ +#ifdef __FreeBSD__ +#include +#else /* __FreeBSD__ */ #include +#endif /* __FreeBSD__ */ +#endif /* __bsdi__ */ #include "pty.h" #include "ssh.h" diff -uNr ../../OpenBSD/openssh-2.1.0/scp/Makefile ./scp/Makefile --- ../../OpenBSD/openssh-2.1.0/scp/Makefile Mon Dec 6 23:47:11 1999 +++ ./scp/Makefile Sat May 13 14:44:24 2000 @@ -3,16 +3,11 @@ PROG= scp BINOWN= root -.if (${MACHINE_ARCH} == "alpha" || ${MACHINE_ARCH} == "powerpc" || \ - ${MACHINE_ARCH} == "hppa") -BINMODE=0000 -.else BINMODE?=555 -.endif -BINDIR= /usr/bin MAN= scp.1 SRCS= scp.c +LDADD+= -lssh .include diff -uNr ../../OpenBSD/openssh-2.1.0/servconf.c ./servconf.c --- ../../OpenBSD/openssh-2.1.0/servconf.c Mon May 8 20:12:15 2000 +++ ./servconf.c Sat May 13 23:29:53 2000 @@ -74,6 +74,8 @@ options->ciphers = NULL; options->protocol = SSH_PROTO_UNKNOWN; options->gateway_ports = -1; + options->connections_per_period = 0; + options->connections_period = 0; } void @@ -172,7 +174,7 @@ #ifdef SKEY sSkeyAuthentication, #endif - sPasswordAuthentication, sListenAddress, + sPasswordAuthentication, sListenAddress, sConnectionsPerPeriod, sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset, sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail, sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups, @@ -231,6 +233,7 @@ { "ciphers", sCiphers }, { "protocol", sProtocol }, { "gatewayports", sGatewayPorts }, + { "connectionsperperiod", sConnectionsPerPeriod }, { NULL, 0 } }; @@ -340,7 +343,11 @@ filename, linenum); exit(1); } - value = atoi(cp); + if (sscanf(cp, " %d ", &value) != 1) { + fprintf(stderr, "%s line %d: invalid integer value.\n", + filename, linenum); + exit(1); + } if (*intptr == -1) *intptr = value; break; @@ -584,6 +591,21 @@ filename, linenum); options->deny_groups[options->num_deny_groups++] = xstrdup(cp); } + break; + + case sConnectionsPerPeriod: + cp = strtok(NULL, WHITESPACE); + if (cp == NULL) + fatal("%.200s line %d: missing (>= 0) number argument.\n", + filename, linenum); + if (sscanf(cp, " %u/%u ", &options->connections_per_period, + &options->connections_period) != 2) + fatal("%.200s line %d: invalid numerical argument(s).\n", + filename, linenum); + if (options->connections_per_period != 0 && + options->connections_period == 0) + fatal("%.200s line %d: invalid connections period.\n", + filename, linenum); break; case sCiphers: diff -uNr ../../OpenBSD/openssh-2.1.0/servconf.h ./servconf.h --- ../../OpenBSD/openssh-2.1.0/servconf.h Sat May 6 20:45:37 2000 +++ ./servconf.h Sat May 13 23:30:07 2000 @@ -93,6 +93,12 @@ char *allow_groups[MAX_ALLOW_GROUPS]; unsigned int num_deny_groups; char *deny_groups[MAX_DENY_GROUPS]; + unsigned int connections_per_period; /* + * If not 0, number of sshd + * connections accepted per + * connections_period. + */ + unsigned int connections_period; } ServerOptions; /* * Initializes the server options to special values that indicate that they diff -uNr ../../OpenBSD/openssh-2.1.0/session.c ./session.c --- ../../OpenBSD/openssh-2.1.0/session.c Wed May 3 21:03:07 2000 +++ ./session.c Mon May 15 04:47:40 2000 @@ -27,6 +27,15 @@ #include "ssh2.h" #include "auth.h" +#ifdef LOGIN_CAP +#ifdef __FreeBSD__ +#include +#include +#endif /* __FreeBSD__ */ +#include +#include +#endif /* LOGIN_CAP */ + /* types */ #define TTYSZ 64 @@ -61,10 +70,17 @@ void do_exec_pty(Session *s, const char *command, struct passwd * pw); void do_exec_no_pty(Session *s, const char *command, struct passwd * pw); +#ifdef LOGIN_CAP +void +do_child(const char *command, struct passwd * pw, const char *term, + const char *display, const char *auth_proto, + const char *auth_data, const char *ttyname, login_cap_t *lc); +#else /* LOGIN_CAP */ void do_child(const char *command, struct passwd * pw, const char *term, const char *display, const char *auth_proto, const char *auth_data, const char *ttyname); +#endif /* LOGIN_CAP */ /* import */ extern ServerOptions options; @@ -377,6 +393,9 @@ do_exec_no_pty(Session *s, const char *command, struct passwd * pw) { int pid; +#ifdef LOGIN_CAP + login_cap_t *lc; +#endif /* LOGIN_CAP */ #ifdef USE_PIPES int pin[2], pout[2], perr[2]; @@ -403,6 +422,13 @@ log_init(__progname, options.log_level, options.log_facility, log_stderr); /* + * Using login and executing a specific "command" are mutually + * exclusive, so turn off use_login if there's a command. + */ + if (command != NULL) + options.use_login = 0; + + /* * Create a new session and process group since the 4.4BSD * setlogin() affects the entire process group. */ @@ -447,7 +473,14 @@ #endif /* USE_PIPES */ /* Do processing for the child (exec command etc). */ +#ifdef LOGIN_CAP + lc = login_getpwclass(pw); + if (lc == NULL) + lc = login_getclassbyname(NULL, pw); + do_child(command, pw, NULL, s->display, s->auth_proto, s->auth_data, NULL, lc); +#else /* LOGIN_CAP */ do_child(command, pw, NULL, s->display, s->auth_proto, s->auth_data, NULL); +#endif /* LOGIN_CAP */ /* NOTREACHED */ } if (pid < 0) @@ -504,6 +537,10 @@ struct sockaddr_storage from; struct stat st; time_t last_login_time; +#ifdef LOGIN_CAP + login_cap_t *lc; + char *fname; +#endif /* LOGIN_CAP */ if (s == NULL) fatal("do_exec_pty: no session"); @@ -513,15 +550,6 @@ /* Get remote host name. */ hostname = get_canonical_hostname(); - /* - * Get the time when the user last logged in. Buf will be set to - * contain the hostname the last login was from. - */ - if (!options.use_login) { - last_login_time = get_last_login_time(pw->pw_uid, pw->pw_name, - buf, sizeof(buf)); - } - /* Fork the child. */ if ((pid = fork()) == 0) { pid = getpid(); @@ -530,6 +558,22 @@ changed. */ log_init(__progname, options.log_level, options.log_facility, log_stderr); + /* + * Using login and executing a specific "command" are mutually + * exclusive, so turn off use_login if there's a command. + */ + if (command != NULL) + options.use_login = 0; + + /* + * Get the time when the user last logged in. Buf will be set + * to contain the hostname the last login was from. + */ + if (!options.use_login) { + last_login_time = get_last_login_time(pw->pw_uid, + pw->pw_name, buf, sizeof(buf)); + } + /* Close the master side of the pseudo tty. */ close(ptyfd); @@ -573,6 +617,12 @@ /* Check if .hushlogin exists. */ snprintf(line, sizeof line, "%.200s/.hushlogin", pw->pw_dir); quiet_login = stat(line, &st) >= 0; +#ifdef LOGIN_CAP + lc = login_getpwclass(pw); + if (lc == NULL) + lc = login_getclassbyname(NULL, pw); + quiet_login = login_getcapbool(lc, "hushlogin", quiet_login); +#endif /* LOGIN_CAP */ /* * If the user has logged in before, display the time of last @@ -596,6 +646,34 @@ else printf("Last login: %s from %s\r\n", time_string, buf); } +#ifdef LOGIN_CAP + if (command == NULL && !quiet_login && !options.use_login) { +#ifdef __bsdi__ + (void)printf( + "Copyright 1992, 1993, 1994, 1995, 1996, 1997 " + "Berkeley Software Design, Inc.\n"); + (void)printf("%s\n\t%s %s\n\n", + "Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994", + "The Regents of the University of California. ", + "All rights reserved."); + if ((fname = + login_getcapstr(lc, "copyright", NULL, NULL)) + != NULL) + auth_cat(fname); +#else /* __bsdi__ */ + fname = login_getcapstr(lc, "copyright", NULL, NULL); + if (fname != NULL && (f = fopen(fname, "r")) != NULL) { + while (fgets(line, sizeof(line), f) != NULL) + fputs(line, stdout); + fclose(f); + } else + (void)printf("%s\n\t%s %s\n", + "Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994", + "The Regents of the University of California. ", + "All rights reserved."); +#endif /* __bsdi__ */ + } +#endif /* LOGIN_CAP */ /* * Print /etc/motd unless a command was specified or printing * it was disabled in server options or login(1) will be @@ -605,7 +683,17 @@ if (command == NULL && options.print_motd && !quiet_login && !options.use_login) { /* Print /etc/motd if it exists. */ +#ifdef LOGIN_CAP + fname = login_getcapstr(lc, "welcome", NULL, NULL); + if (fname != NULL) { + f = fopen(fname, "r"); + if (f == NULL) + f = fopen("/etc/motd", "r"); + } else + f = fopen("/etc/motd", "r"); +#else /* LOGIN_CAP */ f = fopen("/etc/motd", "r"); +#endif /* LOGIN_CAP */ if (f) { while (fgets(line, sizeof(line), f)) fputs(line, stdout); @@ -613,7 +701,11 @@ } } /* Do common processing for the child, such as execing the command. */ +#ifdef LOGIN_CAP + do_child(command, pw, s->term, s->display, s->auth_proto, s->auth_data, s->tty, lc); +#else /* LOGIN_CAP */ do_child(command, pw, s->term, s->display, s->auth_proto, s->auth_data, s->tty); +#endif /* LOGIN_CAP */ /* NOTREACHED */ } if (pid < 0) @@ -730,10 +822,18 @@ * environment, closing extra file descriptors, setting the user and group * ids, and executing the command or shell. */ + +#ifdef LOGIN_CAP +void +do_child(const char *command, struct passwd * pw, const char *term, + const char *display, const char *auth_proto, + const char *auth_data, const char *ttyname, login_cap_t *lc) +#else /* LOGIN_CAP */ void do_child(const char *command, struct passwd * pw, const char *term, const char *display, const char *auth_proto, const char *auth_data, const char *ttyname) +#endif /* LOGIN_CAP */ { const char *shell, *cp = NULL; char buf[256]; @@ -744,8 +844,21 @@ struct stat st; char *argv[10]; +#ifdef __bsdi__ + /* On BSDI, let nologin be handled by libc. */ + auth_checknologin(lc); +#else /* __bsdi__ */ f = fopen("/etc/nologin", "r"); +#ifdef __FreeBSD__ + if (f == NULL) + f = fopen("/var/run/nologin", "r"); +#endif /* __FreeBSD__ */ +#ifdef LOGIN_CAP + /* on FreeBSD, etc., allow overriding nologin via login.conf. */ + if (f != NULL && !login_getcapbool(lc, "ignorenologin", 0)) { +#else /* LOGIN_CAP */ if (f) { +#endif /* LOGIN_CAP */ /* /etc/nologin exists. Print its contents and exit. */ while (fgets(buf, sizeof(buf), f)) fputs(buf, stderr); @@ -753,6 +866,7 @@ if (pw->pw_uid != 0) exit(254); } +#endif /* __bsdi__ */ /* Set login name in the kernel. */ if (setlogin(pw->pw_name) < 0) error("setlogin failed: %s", strerror(errno)); @@ -761,6 +875,18 @@ /* Login(1) does this as well, and it needs uid 0 for the "-h" switch, so we let login(1) to this for us. */ if (!options.use_login) { +#ifdef __bsdi__ + /* Use setusercontext() instead of doing manual magic. */ + if (setusercontext(lc, pw, pw->pw_uid, LOGIN_SETALL) == -1) + err(1, "setusercontext"); +#else /* __bsdi__ */ +#ifdef LOGIN_CAP + if (setclasscontext(pw->pw_class, LOGIN_SETPRIORITY | + LOGIN_SETRESOURCES | LOGIN_SETUMASK) == -1) { + perror("setclasscontext"); + exit(1); + } +#endif /* LOGIN_CAP */ if (getuid() == 0 || geteuid() == 0) { if (setgid(pw->pw_gid) < 0) { perror("setgid"); @@ -778,12 +904,20 @@ } if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid) fatal("Failed to set uids to %d.", (int) pw->pw_uid); +#endif /* __bsdi__ */ } /* * Get the shell from the password data. An empty shell field is * legal, and means /bin/sh. */ +#ifdef LOGIN_CAP + shell = pw->pw_shell; + shell = login_getcapstr(lc, "shell", (char *)shell, (char *)shell); + if (shell[0] == '\0') + shell = _PATH_BSHELL; +#else /* LOGIN_CAP */ shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; +#endif /* LOGIN_CAP */ #ifdef AFS /* Try to get AFS tokens for the local cell. */ @@ -807,7 +941,21 @@ child_set_env(&env, &envsize, "USER", pw->pw_name); child_set_env(&env, &envsize, "LOGNAME", pw->pw_name); child_set_env(&env, &envsize, "HOME", pw->pw_dir); +#ifdef LOGIN_CAP +#ifdef __bsdi__ + /* + * In BSD/OS, PATH is already in the environment after + * setusercontext(). We trust libc. Just copy PATH + * into the child's environment. + */ + child_set_env(&env, &envsize, "PATH", getenv("PATH")); +#else /* __bsdi__ */ + child_set_env(&env, &envsize, "PATH", + login_getpath(lc, "path", _PATH_STDPATH)); +#endif /* __bsdi__ */ +#else /* LOGIN_CAP */ child_set_env(&env, &envsize, "PATH", _PATH_STDPATH); +#endif /* LOGIN_CAP */ snprintf(buf, sizeof buf, "%.200s/%.50s", _PATH_MAILDIR, pw->pw_name); @@ -896,6 +1044,9 @@ * descriptors left by system functions. They will be closed later. */ endpwent(); +#ifdef LOGIN_CAP + login_close(lc); +#endif /* LOGIN_CAP */ /* * Close any extra open file descriptors so that we don\'t have them @@ -903,7 +1054,7 @@ * initgroups, because at least on Solaris 2.3 it leaves file * descriptors open. */ - for (i = 3; i < 64; i++) + for (i = 3; i < getdtablesize(); i++) close(i); /* Change current directory to the user\'s home directory. */ @@ -922,7 +1073,27 @@ * in this order). */ if (!options.use_login) { - if (stat(SSH_USER_RC, &st) >= 0) { +#if defined(__FreeBSD__) || defined(__bsdi__) + /* + * If the password change time is set and has passed, give the + * user a password expiry notice and chance to change it. + */ + if (pw->pw_change != 0) { + struct timeval tv; + + (void)gettimeofday(&tv, NULL); + if (tv.tv_sec >= pw->pw_change) { + (void)printf( + "Sorry -- your password has expired.\n"); + syslog(LOG_INFO, + "%s Password expired - forcing change", + pw->pw_name); + if (system("/usr/bin/passwd") != 0) + perror("/usr/bin/passwd"); + } + } +#endif /* __FreeBSD__ || __bsdi__ */ + if (stat(SSH_USER_RC, &st) >= 0) { if (debug_flag) fprintf(stderr, "Running /bin/sh %s\n", SSH_USER_RC); @@ -1028,7 +1199,21 @@ */ argv[0] = (char *) cp; argv[1] = "-c"; - argv[2] = (char *) command; +#ifdef __bsdi__ + /* + * Dirty hack. scp is installed in /usr/local/bin, so it's not + * in $PATH by default. To make scp work, canonicalize command + * if it starts with "scp\s". What makes it worse is that + * everything is hardcoded. Oh well. I'm lazy. + */ + if (strncmp(command, "scp", 3) == 0 && + isspace(command[3])) { + argv[2] = xmalloc(strlen(command) + sizeof("/usr/local/bin/")); + strcpy(argv[2], "/usr/local/bin/"); + strcat(argv[2], command); + } else +#endif /* __bsdi__ */ + argv[2] = (char *) command; argv[3] = NULL; execve(shell, argv, env); perror(shell); diff -uNr ../../OpenBSD/openssh-2.1.0/ssh/Makefile ./ssh/Makefile --- ../../OpenBSD/openssh-2.1.0/ssh/Makefile Thu Apr 27 00:31:58 2000 +++ ./ssh/Makefile Sat May 13 14:42:26 2000 @@ -3,14 +3,8 @@ PROG= ssh BINOWN= root -.if (${MACHINE_ARCH} == "alpha" || ${MACHINE_ARCH} == "powerpc" || \ - ${MACHINE_ARCH} == "hppa") -BINMODE=0000 -.else BINMODE?=4555 -.endif -BINDIR= /usr/bin MAN= ssh.1 LINKS= ${BINDIR}/ssh ${BINDIR}/slogin MLINKS= ssh.1 slogin.1 @@ -18,20 +12,7 @@ SRCS= ssh.c log-client.c readconf.c clientloop.c \ sshconnect.c sshconnect1.c sshconnect2.c -.include # for AFS - -.if (${KERBEROS} == "yes") -CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV -LDADD+= -lkrb -DPADD+= ${LIBKRB} -.if (${AFS} == "yes") -CFLAGS+= -DAFS -LDADD+= -lkafs -DPADD+= ${LIBKRBAFS} -.endif # AFS -.endif # KERBEROS - .include -LDADD+= -lutil -lz -lcrypto +LDADD+= -lssh -lutil -lz -lcrypto DPADD+= ${LIBCRYPTO} ${LIBUTIL} ${LIBZ} diff -uNr ../../OpenBSD/openssh-2.1.0/ssh-add/Makefile ./ssh-add/Makefile --- ../../OpenBSD/openssh-2.1.0/ssh-add/Makefile Mon Dec 6 23:47:11 1999 +++ ./ssh-add/Makefile Sat May 13 14:42:09 2000 @@ -3,19 +3,13 @@ PROG= ssh-add BINOWN= root -.if (${MACHINE_ARCH} == "alpha" || ${MACHINE_ARCH} == "powerpc" || \ - ${MACHINE_ARCH} == "hppa") -BINMODE=0000 -.else BINMODE?=555 -.endif -BINDIR= /usr/bin MAN= ssh-add.1 SRCS= ssh-add.c log-client.c .include -LDADD+= -lcrypto -lutil -lz +LDADD+= -lssh -lcrypto -lutil -lz DPADD+= ${LIBCRYPTO} ${LIBDES} ${LIBUTIL} ${LIBZ} diff -uNr ../../OpenBSD/openssh-2.1.0/ssh-agent/Makefile ./ssh-agent/Makefile --- ../../OpenBSD/openssh-2.1.0/ssh-agent/Makefile Wed Oct 27 18:54:49 1999 +++ ./ssh-agent/Makefile Sat May 13 14:43:47 2000 @@ -3,19 +3,13 @@ PROG= ssh-agent BINOWN= root -.if (${MACHINE_ARCH} == "alpha" || ${MACHINE_ARCH} == "powerpc" || \ - ${MACHINE_ARCH} == "hppa") -BINMODE=0000 -.else BINMODE?=555 -.endif -BINDIR= /usr/bin MAN= ssh-agent.1 SRCS= ssh-agent.c log-client.c .include -LDADD+= -lcrypto -lutil -lz +LDADD+= -lssh -lcrypto -lutil -lz DPADD+= ${LIBCRYPTO} ${LIBDES} ${LIBUTIL} ${LIBZ} diff -uNr ../../OpenBSD/openssh-2.1.0/ssh-keygen/Makefile ./ssh-keygen/Makefile --- ../../OpenBSD/openssh-2.1.0/ssh-keygen/Makefile Wed Oct 27 18:54:49 1999 +++ ./ssh-keygen/Makefile Sat May 13 14:43:13 2000 @@ -3,19 +3,13 @@ PROG= ssh-keygen BINOWN= root -.if (${MACHINE_ARCH} == "alpha" || ${MACHINE_ARCH} == "powerpc" || \ - ${MACHINE_ARCH} == "hppa") -BINMODE=0000 -.else BINMODE?=555 -.endif -BINDIR= /usr/bin MAN= ssh-keygen.1 SRCS= ssh-keygen.c log-client.c .include -LDADD+= -lcrypto -lutil -lz +LDADD+= -lssh -lcrypto -lutil -lz DPADD+= ${LIBCRYPTO} ${LIBDES} ${LIBUTIL} ${LIBZ} diff -uNr ../../OpenBSD/openssh-2.1.0/ssh-keygen.c ./ssh-keygen.c --- ../../OpenBSD/openssh-2.1.0/ssh-keygen.c Mon May 8 21:23:07 2000 +++ ./ssh-keygen.c Sat May 13 16:55:13 2000 @@ -516,7 +516,11 @@ extern int optind; extern char *optarg; +#ifdef __bsdi__ + SSLeay_add_all_algorithms(); +#else OpenSSL_add_all_algorithms(); +#endif /* we need this for the home * directory. */ pw = getpwuid(getuid()); diff -uNr ../../OpenBSD/openssh-2.1.0/ssh.c ./ssh.c --- ../../OpenBSD/openssh-2.1.0/ssh.c Mon May 8 20:12:15 2000 +++ ./ssh.c Mon May 15 04:41:58 2000 @@ -154,6 +154,9 @@ log("Using rsh. WARNING: Connection will not be encrypted."); /* Build argument list for rsh. */ i = 0; +#ifndef _PATH_RSH +#define _PATH_RSH "/usr/bin/rsh" +#endif args[i++] = _PATH_RSH; /* host may have to come after user on some systems */ args[i++] = host; @@ -422,7 +425,11 @@ if (!host) usage(); +#ifdef __bsdi__ + SSLeay_add_all_algorithms(); +#else OpenSSL_add_all_algorithms(); +#endif /* Initialize the command to execute on remote host. */ buffer_init(&command); @@ -477,6 +484,11 @@ pwcopy.pw_gid = pw->pw_gid; pwcopy.pw_dir = xstrdup(pw->pw_dir); pwcopy.pw_shell = xstrdup(pw->pw_shell); +#ifdef LOGIN_CAP + pwcopy.pw_class = xstrdup(pw->pw_class); + pwcopy.pw_expire = pw->pw_expire; + pwcopy.pw_change = pw->pw_change; +#endif /* LOGIN_CAP */ pw = &pwcopy; /* Initialize "log" output. Since we are the client all output diff -uNr ../../OpenBSD/openssh-2.1.0/ssh.h ./ssh.h --- ../../OpenBSD/openssh-2.1.0/ssh.h Mon May 8 20:12:16 2000 +++ ./ssh.h Mon May 15 03:41:11 2000 @@ -21,6 +21,16 @@ #include "rsa.h" #include "cipher.h" +#if defined(__FreeBSD__) || defined(__bsdi__) +#include +#define LOGIN_CAP +#ifdef __bsdi__ +#define BSD_AUTH +#define login_getpwclass(pw) login_getclass((pw)->pw_class) +#define login_getclassbyname(foo, bar) NULL /* No idea what it does. */ +#endif /* __bsdi__ */ +#endif /* __FreeBSD__ || __bsdi__ */ + /* * XXX * The default cipher used if IDEA is not supported by the remote host. It is @@ -83,7 +93,11 @@ #define HOST_CONFIG_FILE ETCDIR "/ssh_config" #define HOST_DSA_KEY_FILE ETCDIR "/ssh_host_dsa_key" +#ifdef __bsdi__ +#define SSH_PROGRAM "/usr/local/bin/ssh" +#else #define SSH_PROGRAM "/usr/bin/ssh" +#endif /* * The process id of the daemon listening for connections is saved here to @@ -327,7 +341,13 @@ * Tries to authenticate the user using password. Returns true if * authentication succeeds. */ + +#ifdef BSD_AUTH +int auth_password(struct passwd * pw, const char *password, + login_cap_t *lc, char *style); +#else /* BSD_AUTH */ int auth_password(struct passwd * pw, const char *password); +#endif /* BSD_AUTH */ /* * Performs the RSA authentication dialog with the client. This returns 0 if diff -uNr ../../OpenBSD/openssh-2.1.0/sshconnect.c ./sshconnect.c --- ../../OpenBSD/openssh-2.1.0/sshconnect.c Thu May 4 12:50:22 2000 +++ ./sshconnect.c Sat May 13 23:57:36 2000 @@ -146,7 +146,11 @@ */ if (privileged) { int p = IPPORT_RESERVED - 1; +#ifdef __bsdi__ + sock = rresvport(&p); +#else /* __bsdi__ */ sock = rresvport_af(&p, family); +#endif /* __bsdi__ */ if (sock < 0) error("rresvport: af=%d %.100s", family, strerror(errno)); else @@ -482,9 +486,11 @@ case AF_INET: local = (ntohl(((struct sockaddr_in *)hostaddr)->sin_addr.s_addr) >> 24) == IN_LOOPBACKNET; break; +#ifdef INET6 case AF_INET6: local = IN6_IS_ADDR_LOOPBACK(&(((struct sockaddr_in6 *)hostaddr)->sin6_addr)); break; +#endif /* INET6 */ default: local = 0; break; diff -uNr ../../OpenBSD/openssh-2.1.0/sshd/Makefile ./sshd/Makefile --- ../../OpenBSD/openssh-2.1.0/sshd/Makefile Thu Apr 27 00:31:57 2000 +++ ./sshd/Makefile Sat May 13 14:42:34 2000 @@ -3,44 +3,14 @@ PROG= sshd BINOWN= root BINMODE=555 -BINDIR= /usr/sbin +BINDIR= /usr/local/sbin MAN= sshd.8 SRCS= sshd.c auth-rhosts.c auth-passwd.c auth-rsa.c auth-rh-rsa.c \ pty.c log-server.c login.c servconf.c serverloop.c \ auth.c auth1.c auth2.c session.c -.include # for KERBEROS and AFS - -.if (${KERBEROS} == "yes") -.if (${AFS} == "yes") -CFLAGS+= -DAFS -LDADD+= -lkafs -DPADD+= ${LIBKRBAFS} -.endif # AFS -CFLAGS+= -DKRB4 -I${DESTDIR}/usr/include/kerberosIV -SRCS+= auth-krb4.c -LDADD+= -lkrb -DPADD+= ${LIBKRB} -.endif # KERBEROS - -.if (${SKEY} == "yes") -SRCS+= auth-skey.c -.endif - .include -LDADD+= -lcrypto -lutil -lz +LDADD+= -lssh -lcrypto -lutil -lz DPADD+= ${LIBCRYPTO} ${LIBUTIL} ${LIBZ} - -.if (${TCP_WRAPPERS} == "yes") -CFLAGS+= -DLIBWRAP -LDADD+= -lwrap -DPADD+= ${LIBWRAP} -.endif - -.if (${SKEY} == "yes") -CFLAGS+= -DSKEY -LDADD+= -lskey -DPADD+= ${SKEY} -.endif diff -uNr ../../OpenBSD/openssh-2.1.0/sshd.8 ./sshd.8 --- ../../OpenBSD/openssh-2.1.0/sshd.8 Mon May 8 20:42:31 2000 +++ ./sshd.8 Sat May 13 23:32:53 2000 @@ -284,6 +284,31 @@ should check for new mail for interactive logins. The default is .Dq no . +.It Cm ConnectionsPerPeriod +This keyword allows for rate-limiting of connections, and +is followed by two numbers in the format +.Dq n/s , +where +.Ar n +is the number of connections from a certain address group +accepted per period of +.Ar s +seconds. Any connection after the number +.Ar n +connection in the period of +.Ar s +seconds will be dropped, and an informational message will be logged. +A connection will belong to a certain group, of which there are 13 +by default, according to its IP address. +The default for this keyword is +.Dq 0/0 , +and rate-limiting can be explicitly turned off by using an +.Ar n +parameter of +.Ql 0 +and any +.Ar s +parameter. .It Cm DenyGroups This keyword can be followed by a number of group names, separated by spaces. @@ -589,7 +614,7 @@ .It Checks .Pa /etc/nologin ; -if it exists, prints contents and quits +if it exists, prints the contents and quits (unless root). .It Changes to run with normal user privileges. diff -uNr ../../OpenBSD/openssh-2.1.0/sshd.c ./sshd.c --- ../../OpenBSD/openssh-2.1.0/sshd.c Wed May 3 13:21:49 2000 +++ ./sshd.c Sun May 14 02:18:49 2000 @@ -49,6 +49,15 @@ int deny_severity = LOG_WARNING; #endif /* LIBWRAP */ +#ifdef LOGIN_CAP +#ifdef __FreeBSD__ +#include +#include +#endif /* __FreeBSD__ */ +#include +#include +#endif /* LOGIN_CAP */ + #ifndef O_NOCTTY #define O_NOCTTY 0 #endif @@ -134,6 +143,20 @@ unsigned char *session_id2 = NULL; int session_id2_len = 0; +/* These are used to implement connections_per_period. */ +struct magic_connection { + struct timeval connections_begin; + unsigned int connections_this_period; +} *magic_connections; +/* Magic number, too! TODO: this doesn't have to be static. */ +const size_t MAGIC_CONNECTIONS_SIZE = 1; + +static __inline int +magic_hash(struct sockaddr_storage *sa) { + + return 0; +} + /* Prototypes for various functions defined later in this file. */ void do_ssh1_kex(); void do_ssh2_kex(); @@ -418,6 +441,7 @@ int opt, sock_in = 0, sock_out = 0, newsock, i, fdsetsz, on = 1; pid_t pid; socklen_t fromlen; + int connections_per_period_exceeded = 0; int silent = 0; fd_set *fdset; struct sockaddr_storage from; @@ -763,6 +787,12 @@ fdsetsz = howmany(maxfd, NFDBITS) * sizeof(fd_mask); fdset = (fd_set *)xmalloc(fdsetsz); + /* Initialize the magic_connections table. It's magical! */ + magic_connections = calloc(MAGIC_CONNECTIONS_SIZE, + sizeof(struct magic_connection)); + if (magic_connections == NULL) + fatal("calloc: %s", strerror(errno)); + /* * Stay listening for connections until the system crashes or * the daemon is killed with a signal. @@ -794,9 +824,31 @@ error("newsock del O_NONBLOCK: %s", strerror(errno)); continue; } + if (options.connections_per_period != 0) { + struct timeval diff, connections_end; + struct magic_connection *mc; + + (void)gettimeofday(&connections_end, NULL); + mc = &magic_connections[magic_hash(&from)]; + timersub(&connections_end, &mc->connections_begin, &diff); + if (diff.tv_sec >= options.connections_period) { + /* + * Slide the window forward only after completely + * leaving it. + */ + mc->connections_begin = connections_end; + mc->connections_this_period = 1; + } else { + if (++mc->connections_this_period > + options.connections_per_period) + connections_per_period_exceeded = 1; + } + } + /* - * Got connection. Fork a child to handle it, unless - * we are in debugging mode. + * Got connection. Fork a child to handle it unless + * we are in debugging mode or the maximum number of + * connections per period has been exceeded. */ if (debug_flag) { /* @@ -810,6 +862,12 @@ sock_out = newsock; pid = getpid(); break; + } else if (connections_per_period_exceeded) { + log("Connection rate limit of %u/%us has been exceeded; " + "dropping connection from %s.", + options.connections_per_period, options.connections_period, + ntop); + connections_per_period_exceeded = 0; } else { /* * Normal production daemon. Fork, and have diff -uNr ../../OpenBSD/openssh-2.1.0/sshd_config ./sshd_config --- ../../OpenBSD/openssh-2.1.0/sshd_config Mon Apr 17 16:46:53 2000 +++ ./sshd_config Sat May 13 23:29:50 2000 @@ -8,8 +8,9 @@ ServerKeyBits 768 LoginGraceTime 600 KeyRegenerationInterval 3600 -PermitRootLogin yes -# +PermitRootLogin no +# Rate-limit sshd connections to 5 connections per 10 seconds +ConnectionsPerPeriod 5/10 # Don't read ~/.rhosts and ~/.shosts files IgnoreRhosts yes # Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication