diff -ruN ssh/ChangeLog.linux openssh/ChangeLog.linux --- ssh/ChangeLog.linux Thu Jan 1 10:00:00 1970 +++ openssh/ChangeLog.linux Wed Oct 27 12:00:52 1999 @@ -0,0 +1,20 @@ +19991027 + - Adapted PAM patch. + - Released 1.0pre2 + + - Excised my buggy replacements for strlcpy and mkdtemp + - Imported correct OpenBSD strlcpy and mkdtemp routines. + - Reduced arc4random_stir entropy read to 32 bytes (256 bits) + - Picked up correct version number from OpenBSD + - Added sshd.pam PAM configuration file + - Added sshd.init Redhat init script + - Added openssh.spec RPM spec file + - Released 1.2pre3 + +19991026 + - Fixed include paths of OpenSSL functions + - Use OpenSSL MD5 routines + - Imported RC4 code from nanocrypt + - Wrote replacements for OpenBSD arc4random* functions + - Wrote replacements for strlcpy and mkdtemp + - Released 1.0pre1 diff -ruN ssh/Makefile.GNU openssh/Makefile.GNU --- ssh/Makefile.GNU Thu Jan 1 10:00:00 1970 +++ openssh/Makefile.GNU Wed Oct 27 12:24:24 1999 @@ -0,0 +1,50 @@ +OPT_FLAGS=-g +CFLAGS=$(OPT_FLAGS) -Wall -DETCDIR=\"/etc/ssh\" -DHAVE_PAM +TARGETS=bin/libssh.a bin/ssh bin/sshd bin/ssh-add bin/ssh-keygen bin/ssh-agent bin/scp +LFLAGS=-L./bin +LIBS=-lssh -lcrypto -lz -lutil -lpam -ldl +AR=ar +RANLIB=ranlib + +OBJS= authfd.o authfile.o auth-passwd.o auth-rhosts.o auth-rh-rsa.o \ + auth-rsa.o bufaux.o buffer.o canohost.o channels.o cipher.o \ + clientloop.o compress.o crc32.o deattack.o hostfile.o \ + log-client.o login.o log-server.o match.o mpaux.o packet.o pty.o \ + readconf.o readpass.o rsa.o servconf.o serverloop.o \ + sshconnect.o tildexpand.o ttymodes.o uidswap.o xmalloc.o \ + helper.o mktemp.o strlcpy.o rc4.o + +all: $(OBJS) $(TARGETS) + +bin/libssh.a: authfd.o authfile.o bufaux.o buffer.o canohost.o channels.o cipher.o compat.o compress.o crc32.o deattack.o hostfile.o match.o mpaux.o nchan.o packet.o readpass.o rsa.o tildexpand.o ttymodes.o uidswap.o xmalloc.o helper.o rc4.o mktemp.o strlcpy.o + [ -d bin ] || mkdir bin + $(AR) rv $@ $^ + $(RANLIB) $@ + +bin/ssh: ssh.o sshconnect.o log-client.o readconf.o clientloop.o + [ -d bin ] || mkdir bin + $(CC) -o $@ $^ $(LFLAGS) $(LIBS) + +bin/sshd: sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o pty.o log-server.o login.o servconf.o serverloop.o + [ -d bin ] || mkdir bin + $(CC) -o $@ $^ $(LFLAGS) $(LIBS) + +bin/scp: scp.o + [ -d bin ] || mkdir bin + $(CC) -o $@ $^ $(LFLAGS) $(LIBS) + +bin/ssh-add: ssh-add.o log-client.o + [ -d bin ] || mkdir bin + $(CC) -o $@ $^ $(LFLAGS) $(LIBS) + +bin/ssh-agent: ssh-agent.o log-client.o + [ -d bin ] || mkdir bin + $(CC) -o $@ $^ $(LFLAGS) $(LIBS) + +bin/ssh-keygen: ssh-keygen.o log-client.o + [ -d bin ] || mkdir bin + $(CC) -o $@ $^ $(LFLAGS) $(LIBS) + +clean: + rm -f *.o core bin/* + diff -ruN ssh/README.openssh openssh/README.openssh --- ssh/README.openssh Thu Jan 1 10:00:00 1970 +++ openssh/README.openssh Wed Oct 27 12:44:44 1999 @@ -0,0 +1,44 @@ +This is a Linux port of OpenBSD's excellent OpenSSH. + +OpenSSH is based on the last free version of Tatu Ylonen's SSH with all +patent-encumbered algorithms removed, all known security bugs fixed, new +features reintroduced and many other clean-ups. + +This Linux port basically consists of a few fixes to deal with the way that +OpenSSL is usually installed on Linux systems, a few replacements for +OpenBSD library functions and the introduction of partial PAM support. + +The PAM support is less than optimal - it is only used when password +authentication is requested, so things like pam_limits will not apply if a +use authenticates with a RSA key. OTOH this is exactly the level of support +that the popular Linux SSH packages have. Perhaps a PAM hacker can rectify +this? + +All new code is released under a XFree style license, which is very liberal. +This code is released with no warranties of any kind, neither I nor my +employer (Internet Business Solutions) will take any responsibility for +any loss, damage or liability arising from the use or abuse of this software. + +OpenSSH depends on Zlib, OpenSSL and PAM. Use the Makefile.GNU to build it. + +Damien Miller +Internet Business Solutions + + +Credits - + +The OpenBSD team +'jonchen' - the original author of PAM support of SSH + +Miscellania - + +This version of SSH is based upon code retrieved from the OpenBSD CVS +repository on 1999-10-26, which in turn was based on the last free +version of SSH released by Tatu Ylonen. + +Code in helper.[ch] is Copyright 1999 Internet Business Solutions and +is released under a X11-style license (see source file for details). + +(A)RC4 code in rc4.[ch] is Copyright 1999 Damien Miller. It too is +under a X11-style license (see source file for details). + diff -ruN ssh/auth-passwd.c openssh/auth-passwd.c --- ssh/auth-passwd.c Wed Oct 20 01:56:41 1999 +++ openssh/auth-passwd.c Wed Oct 27 10:04:48 1999 @@ -26,6 +26,14 @@ extern char *ticket; #endif /* KRB4 */ +#ifdef HAVE_PAM +#include +extern pam_handle_t *pamh; +extern int retval; +extern char* pampasswd; +extern int origretval; +#endif /* HAVE_PAM */ + /* Tries to authenticate the user using password. Returns true if authentication succeeds. */ @@ -50,6 +58,26 @@ if (pw == NULL) return 0; +#ifdef HAVE_PAM + retval = origretval; + + pampasswd = xstrdup(password); + + if (retval == PAM_SUCCESS) + retval = pam_authenticate ((pam_handle_t *)pamh, 0); + + if (retval == PAM_SUCCESS) + retval = pam_acct_mgmt ((pam_handle_t *)pamh, 0); + + xfree(pampasswd); + + if (retval == PAM_SUCCESS) + retval = pam_open_session ((pam_handle_t *)pamh, 0); + + return (retval == PAM_SUCCESS); + +#else /* HAVE_PAM */ + #ifdef SKEY if (options.skey_authentication == 1) { if (strncasecmp(password, "s/key", 5) == 0) { @@ -177,4 +205,5 @@ /* Authentication is accepted if the encrypted passwords are identical. */ return (strcmp(encrypted_password, pw->pw_passwd) == 0); +#endif /* HAVE_PAM */ } diff -ruN ssh/auth-rsa.c openssh/auth-rsa.c --- ssh/auth-rsa.c Mon Oct 18 11:54:18 1999 +++ openssh/auth-rsa.c Tue Oct 26 17:01:21 1999 @@ -25,8 +25,8 @@ #include "mpaux.h" #include "uidswap.h" -#include -#include +#include +#include /* Flags that may be set in authorized_keys options. */ extern int no_port_forwarding_flag; @@ -94,10 +94,10 @@ assert(len <= 32 && len); memset(buf, 0, 32); BN_bn2bin(challenge, buf + 32 - len); - MD5Init(&md); - MD5Update(&md, buf, 32); - MD5Update(&md, session_id, 16); - MD5Final(mdbuf, &md); + MD5_Init(&md); + MD5_Update(&md, buf, 32); + MD5_Update(&md, session_id, 16); + MD5_Final(mdbuf, &md); /* We will no longer need these. */ BN_clear_free(encrypted_challenge); diff -ruN ssh/authfd.c openssh/authfd.c --- ssh/authfd.c Fri Oct 15 04:17:41 1999 +++ openssh/authfd.c Tue Oct 26 17:01:18 1999 @@ -24,7 +24,7 @@ #include "xmalloc.h" #include "getput.h" -#include +#include /* Returns the number of the authentication fd, or -1 if there is none. */ diff -ruN ssh/authfile.c openssh/authfile.c --- ssh/authfile.c Tue Oct 12 06:00:35 1999 +++ openssh/authfile.c Tue Oct 26 17:01:16 1999 @@ -17,7 +17,7 @@ #include "includes.h" RCSID("$Id: authfile.c,v 1.7 1999/10/11 20:00:35 markus Exp $"); -#include +#include #include "xmalloc.h" #include "buffer.h" #include "bufaux.h" diff -ruN ssh/bufaux.c openssh/bufaux.c --- ssh/bufaux.c Tue Sep 28 14:45:36 1999 +++ openssh/bufaux.c Tue Oct 26 17:01:13 1999 @@ -18,7 +18,7 @@ RCSID("$Id: bufaux.c,v 1.2 1999/09/28 04:45:36 provos Exp $"); #include "ssh.h" -#include +#include #include "bufaux.h" #include "xmalloc.h" #include "getput.h" diff -ruN ssh/cipher.c openssh/cipher.c --- ssh/cipher.c Fri Oct 1 08:12:16 1999 +++ openssh/cipher.c Tue Oct 26 16:59:28 1999 @@ -17,7 +17,7 @@ #include "ssh.h" #include "cipher.h" -#include +#include /* * What kind of tripple DES are these 2 routines? @@ -178,9 +178,9 @@ MD5_CTX md; unsigned char digest[16]; - MD5Init(&md); - MD5Update(&md, (const unsigned char *)passphrase, strlen(passphrase)); - MD5Final(digest, &md); + MD5_Init(&md); + MD5_Update(&md, (const unsigned char *)passphrase, strlen(passphrase)); + MD5_Final(digest, &md); cipher_set_key(context, cipher, digest, 16, for_encryption); diff -ruN ssh/cipher.h openssh/cipher.h --- ssh/cipher.h Sun Oct 3 05:14:54 1999 +++ openssh/cipher.h Tue Oct 26 17:01:09 1999 @@ -16,8 +16,8 @@ #ifndef CIPHER_H #define CIPHER_H -#include -#include +#include +#include /* Cipher types. New types can be added, but old types should not be removed for compatibility. The maximum allowed value is 31. */ diff -ruN ssh/helper.c openssh/helper.c --- ssh/helper.c Thu Jan 1 10:00:00 1970 +++ openssh/helper.c Wed Oct 27 11:48:10 1999 @@ -0,0 +1,108 @@ +/* +** +** OpenBSD emulation routines +** +** Damien Miller +** +** Copyright 1999 Internet Business Solutions +** +** Permission is hereby granted, free of charge, to any person +** obtaining a copy of this software and associated documentation +** files (the "Software"), to deal in the Software without +** restriction, including without limitation the rights to use, copy, +** modify, merge, publish, distribute, sublicense, and/or sell copies +** of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +** KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +** WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE +** AND NONINFRINGEMENT. IN NO EVENT SHALL DAMIEN MILLER OR INTERNET +** BUSINESS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +** OR OTHER DEALINGS IN THE SOFTWARE. +** +** Except as contained in this notice, the name of Internet Business +** Solutions shall not be used in advertising or otherwise to promote +** the sale, use or other dealings in this Software without prior +** written authorization from Internet Business Solutions. +** +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "rc4.h" +#include "xmalloc.h" + +#include "helper.h" + +void get_random_bytes(unsigned char *buf, int len); + +static rc4_t *rc4 = NULL; + +void setproctitle(const char *fmt, ...) +{ + /* FIXME */ +} + +unsigned char arc4random(void) +{ + unsigned char r; + + if (rc4 == NULL) + arc4random_stir(); + + rc4_getbytes(rc4, &r, 1); + + return(r); +} + +void arc4random_stir(void) +{ + unsigned char rand_buf[32]; + + if (rc4 == NULL) + rc4 = xmalloc(sizeof(*rc4)); + + get_random_bytes(rand_buf, sizeof(rand_buf)); + rc4_key(rc4, rand_buf, sizeof(rand_buf)); +} + +void get_random_bytes(unsigned char *buf, int len) +{ + int urandom; + int c; + + urandom = open("/dev/urandom", O_RDONLY); + if (urandom == -1) + { + fprintf(stderr, "Couldn't open /dev/urandom: %s", strerror(errno)); + exit(1); + } + + c = read(urandom, buf, len); + if (c == -1) + { + fprintf(stderr, "Couldn't read from /dev/urandom: %s", strerror(errno)); + exit(1); + } + + if (c != len) + { + fprintf(stderr, "Short read from /dev/urandom"); + exit(1); + } +} + diff -ruN ssh/helper.h openssh/helper.h --- ssh/helper.h Thu Jan 1 10:00:00 1970 +++ openssh/helper.h Wed Oct 27 11:30:33 1999 @@ -0,0 +1,43 @@ +/* +** +** OpenBSD emulation routines +** +** Damien Miller +** +** Copyright 1999 Internet Business Solutions +** +** Permission is hereby granted, free of charge, to any person +** obtaining a copy of this software and associated documentation +** files (the "Software"), to deal in the Software without +** restriction, including without limitation the rights to use, copy, +** modify, merge, publish, distribute, sublicense, and/or sell copies +** of the Software, and to permit persons to whom the Software is +** furnished to do so, subject to the following conditions: +** +** The above copyright notice and this permission notice shall be +** included in all copies or substantial portions of the Software. +** +** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +** KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +** WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE +** AND NONINFRINGEMENT. IN NO EVENT SHALL DAMIEN MILLER OR INTERNET +** BUSINESS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE +** OR OTHER DEALINGS IN THE SOFTWARE. +** +** Except as contained in this notice, the name of Internet Business +** Solutions shall not be used in advertising or otherwise to promote +** the sale, use or other dealings in this Software without prior +** written authorization from Internet Business Solutions. +** +*/ + +#ifndef _HELPER_H +#define _HELPER_H + +unsigned char arc4random(void); +void arc4random_stir(void); +void setproctitle(const char *fmt, ...); + +#endif /* _HELPER_H */ diff -ruN ssh/includes.h openssh/includes.h --- ssh/includes.h Thu Sep 30 18:34:25 1999 +++ openssh/includes.h Wed Oct 27 11:34:19 1999 @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -38,7 +37,7 @@ #include #include -#include +#include #include #include #include @@ -58,8 +57,19 @@ #include "version.h" +#include "helper.h" +#include "mktemp.h" +#include "strlcpy.h" + /* Define this to be the path of the xauth program. */ +#ifndef XAUTH_PATH #define XAUTH_PATH "/usr/X11R6/bin/xauth" +#endif /* XAUTH_PATH */ + +/* Define this to be the path of the rsh program. */ +#ifndef _PATH_RSH +#define _PATH_RSH "/usr/bin/rsh" +#endif /* _PATH_RSH */ /* Define this to use pipes instead of socketpairs for communicating with the client program. Socketpairs do not seem to work on all systems. */ diff -ruN ssh/login.c openssh/login.c --- ssh/login.c Fri Oct 1 02:55:06 1999 +++ openssh/login.c Tue Oct 26 17:04:13 1999 @@ -20,7 +20,6 @@ #include "includes.h" RCSID("$Id: login.c,v 1.7 1999/09/30 16:55:06 deraadt Exp $"); -#include #include #include "ssh.h" diff -ruN ssh/mktemp.c openssh/mktemp.c --- ssh/mktemp.c Thu Jan 1 10:00:00 1970 +++ openssh/mktemp.c Wed Oct 27 11:39:30 1999 @@ -0,0 +1,181 @@ +/* THIS FILE HAS BEEN MODIFIED FROM THE ORIGINAL OPENBSD SOURCE */ +/* Changes: Removed mktemp */ + +/* + * 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)); + +int +mkstemps(path, slen) + char *path; + int slen; +{ + int fd; + + return (_gettemp(path, &fd, 0, slen) ? fd : -1); +} + +int +mkstemp(path) + char *path; +{ + int fd; + + return (_gettemp(path, &fd, 0, 0) ? fd : -1); +} + +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 -ruN ssh/mktemp.h openssh/mktemp.h --- ssh/mktemp.h Thu Jan 1 10:00:00 1970 +++ openssh/mktemp.h Wed Oct 27 11:34:28 1999 @@ -0,0 +1,7 @@ +#ifndef _MKTEMP_H +#define _MKTEMP_H +int mkstemps(char *path, int slen); +int mkstemp(char *path); +char *mkdtemp(char *path); + +#endif /* _MKTEMP_H */ diff -ruN ssh/mpaux.c openssh/mpaux.c --- ssh/mpaux.c Fri Oct 1 03:08:52 1999 +++ openssh/mpaux.c Tue Oct 26 17:01:07 1999 @@ -17,11 +17,11 @@ #include "includes.h" RCSID("$Id: mpaux.c,v 1.3 1999/09/30 17:08:52 deraadt Exp $"); -#include +#include #include "getput.h" #include "xmalloc.h" -#include +#include void compute_session_id(unsigned char session_id[16], @@ -39,8 +39,8 @@ BN_bn2bin(session_key_n, buf + (host_key_bits + 7 ) / 8); memcpy(buf + (host_key_bits + 7) / 8 + (session_key_bits + 7) / 8, cookie, 8); - MD5Init(&md); - MD5Update(&md, buf, bytes); - MD5Final(session_id, &md); + MD5_Init(&md); + MD5_Update(&md, buf, bytes); + MD5_Final(session_id, &md); xfree(buf); } diff -ruN ssh/openssh.spec openssh/openssh.spec --- ssh/openssh.spec Thu Jan 1 10:00:00 1970 +++ openssh/openssh.spec Wed Oct 27 12:50:29 1999 @@ -0,0 +1,105 @@ +Summary: OpenSSH free Secure Shell (SSH) implementation +Name: openssh +Version: 1.2pre3 +Release: 1 +Packager: Damien Miller +Source0: openssh-%{version}-linux.tar.gz +Copyright: BSD +Group: Applications/Internet +BuildRoot: /tmp/openssh-%{version}-buildroot + +%description +Ssh (Secure Shell) a program for logging into a remote machine and for +executing commands in a remote machine. It is intended to replace +rlogin and rsh, and provide secure encrypted communications between +two untrusted hosts over an insecure network. X11 connections and +arbitrary TCP/IP ports can also be forwarded over the secure channel. + +OpenSSH is OpenBSD's rework of the last free version of SSH, bringing it +up to date in terms of security and features, as well as removing all +patented algorithms to seperate libraries (OpenSSL). + +%changelog +* Wed Oct 27 1999 Damien Miller +- Initial RPMification, based on Jan "Yenya" Kasprzak's spec. + +%prep + +%setup -n openssh + +%build + +make -f Makefile.GNU OPT_FLAGS="$RPM_OPT_FLAGS" + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/usr/bin +mkdir -p $RPM_BUILD_ROOT/usr/sbin +mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d +mkdir -p $RPM_BUILD_ROOT/etc/pam.d +mkdir -p $RPM_BUILD_ROOT/etc/ssh +mkdir -p $RPM_BUILD_ROOT/usr/man/man1 +mkdir -p $RPM_BUILD_ROOT/usr/man/man8 + +install -m644 ssh.pam $RPM_BUILD_ROOT/etc/pam.d/ssh +install -m755 sshd.init $RPM_BUILD_ROOT/etc/rc.d/init.d/sshd +install -m600 ssh_config $RPM_BUILD_ROOT/etc/ssh/ssh_config +install -m600 sshd_config $RPM_BUILD_ROOT/etc/ssh/sshd_config + +install -s -m755 bin/sshd $RPM_BUILD_ROOT/usr/sbin +install -s -m755 bin/ssh $RPM_BUILD_ROOT/usr/bin +install -s -m755 bin/scp $RPM_BUILD_ROOT/usr/bin +install -s -m755 bin/ssh-agent $RPM_BUILD_ROOT/usr/bin +install -s -m755 bin/ssh-add $RPM_BUILD_ROOT/usr/bin +install -s -m755 bin/ssh-keygen $RPM_BUILD_ROOT/usr/bin + +install -m644 sshd.8 $RPM_BUILD_ROOT/usr/man/man8 +install -m644 ssh.1 $RPM_BUILD_ROOT/usr/man/man1 +install -m644 scp.1 $RPM_BUILD_ROOT/usr/man/man1 +install -m644 ssh-agent.1 $RPM_BUILD_ROOT/usr/man/man1 +install -m644 ssh-add.1 $RPM_BUILD_ROOT/usr/man/man1 +install -m644 ssh-keygen.1 $RPM_BUILD_ROOT/usr/man/man1 + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +/sbin/chkconfig --add sshd +if [ ! -f /etc/ssh/ssh_host_key -o ! -s /etc/ssh/ssh_host_key ]; then + /usr/bin/ssh-keygen -b 1024 -f /etc/ssh/ssh_host_key -N '' >&2 +fi +if test -r /var/run/sshd.pid +then + /etc/rc.d/init.d/sshd restart >&2 +fi + +%preun +if [ "$1" = 0 ] +then + /etc/rc.d/init.d/sshd stop >&2 + /sbin/chkconfig --del sshd +fi + +%files +%defattr(-,root,root) +%doc COPYING.Ylonen ChangeLog ChangeLog.linux OVERVIEW +%doc README README.openssh +%attr(0755,root,root) /usr/sbin/sshd +%attr(0755,root,root) /usr/bin/ssh +%attr(0755,root,root) /usr/bin/ssh-agent +%attr(0755,root,root) /usr/bin/ssh-keygen +%attr(0755,root,root) /usr/bin/ssh-add +%attr(0755,root,root) /usr/bin/scp + +%attr(0755,root,root) /usr/man/man8/sshd.8 +%attr(0755,root,root) /usr/man/man1/ssh.1 +%attr(0755,root,root) /usr/man/man1/ssh-agent.1 +%attr(0755,root,root) /usr/man/man1/ssh-keygen.1 +%attr(0755,root,root) /usr/man/man1/ssh-add.1 +%attr(0755,root,root) /usr/man/man1/scp.1 + +%attr(0600,root,root) %config /etc/ssh/sshd_config +%attr(0600,root,root) %config /etc/pam.d/ssh +%attr(0755,root,root) %config /etc/rc.d/init.d/sshd +%attr(0644,root,root) %config /etc/ssh/ssh_config + diff -ruN ssh/packet.h openssh/packet.h --- ssh/packet.h Tue Sep 28 14:45:36 1999 +++ openssh/packet.h Tue Oct 26 17:01:04 1999 @@ -18,7 +18,7 @@ #ifndef PACKET_H #define PACKET_H -#include +#include /* Sets the socket used for communication. Disables encryption until packet_set_encryption_key is called. It is permissible that fd_in diff -ruN ssh/rc4.c openssh/rc4.c --- ssh/rc4.c Thu Jan 1 10:00:00 1970 +++ openssh/rc4.c Tue Oct 26 17:22:37 1999 @@ -0,0 +1,105 @@ +/*! \file rc4.c + \brief Source file for RC4 stream cipher routines + \author Damien Miller + \version 0.0.0 + \date 1999 + + A simple implementation of the RC4 stream cipher, based on the + description given in _Bruce Schneier's_ "Applied Cryptography" + 2nd edition. + + Copyright 1999 Damien Miller + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + AND NONINFRINGEMENT. IN NO EVENT SHALL DAMIEN MILLER BE LIABLE + FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + \warning None of these functions clears its memory after use. It + \warning is the responsability of the calling routines to ensure + \warning that any sensitive data (keystream, key or plaintext) is + \warning properly erased after use. + + \warning The name "RC4" is trademarked in the United States, + \warning you may need to use "RC4 compatible" or "ARC4" + \warning (Alleged RC4). +*/ + +/* $Id: rc4.c,v 1.1.1.1 1999/10/26 05:48:13 damien Exp $ */ + +#include "rc4.h" + + +void rc4_key(rc4_t *r, unsigned char *key, int len) +{ + int t; + + for(r->i = 0; r->i < 256; r->i++) + r->s[r->i] = r->i; + + r->j = 0; + for(r->i = 0; r->i < 256; r->i++) + { + r->j = (r->j + r->s[r->i] + key[r->i % len]) % 256; + t = r->s[r->i]; + r->s[r->i] = r->s[r->j]; + r->s[r->j] = t; + } + r->i = r->j = 0; +} + +void rc4_crypt(rc4_t *r, unsigned char *plaintext, int len) +{ + int t; + int c; + + c = 0; + while(c < len) + { + r->i = (r->i + 1) % 256; + r->j = (r->j + r->s[r->i]) % 256; + t = r->s[r->i]; + r->s[r->i] = r->s[r->j]; + r->s[r->j] = t; + + t = (r->s[r->i] + r->s[r->j]) % 256; + + plaintext[c] ^= r->s[t]; + c++; + } +} + +void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len) +{ + int t; + int c; + + c = 0; + while(c < len) + { + r->i = (r->i + 1) % 256; + r->j = (r->j + r->s[r->i]) % 256; + t = r->s[r->i]; + r->s[r->i] = r->s[r->j]; + r->s[r->j] = t; + + t = (r->s[r->i] + r->s[r->j]) % 256; + + buffer[c] = r->s[t]; + c++; + } +} diff -ruN ssh/rc4.h openssh/rc4.h --- ssh/rc4.h Thu Jan 1 10:00:00 1970 +++ openssh/rc4.h Tue Oct 26 17:22:25 1999 @@ -0,0 +1,110 @@ +/*! \file rc4.h + \brief Header file for RC4 stream cipher routines + \author Damien Miller + \version 0.0.0 + \date 1999 + + A simple implementation of the RC4 stream cipher, based on the + description given in _Bruce Schneier's_ "Applied Cryptography" + 2nd edition. + + Copyright 1999 Damien Miller + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY + KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + AND NONINFRINGEMENT. IN NO EVENT SHALL DAMIEN MILLER BE LIABLE + FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + \warning None of these functions clears its memory after use. It + \warning is the responsability of the calling routines to ensure + \warning that any sensitive data (keystream, key or plaintext) is + \warning properly erased after use. + + \warning The name "RC4" is trademarked in the United States, + \warning you may need to use "RC4 compatible" or "ARC4" + \warning (Alleged RC4). +*/ + +/* $Id: rc4.h,v 1.1.1.1 1999/10/26 05:48:13 damien Exp $ */ + +#ifndef _RC4_H +#define _RC4_H + +/*! \struct rc4_t + \brief RC4 stream cipher state object + \var s State array + \var i Monotonic index + \var j Randomised index + + \warning This structure should not be accessed directly. To + \warning initialise a rc4_t object, you should use the rc4_key() + \warning function + + This structure holds the current state of the RC4 algorithm. +*/ +typedef struct +{ + unsigned int s[256]; + int i; + int j; +} rc4_t; + +/*! \fn void rc4_key(rc4_t *r, unsigned char *key, int len); + \brief Set up key structure of RC4 stream cipher + \param r pointer to RC4 structure to be seeded + \param key pointer to buffer containing raw key + \param len length of key + + This function set the internal state of the RC4 data structure + pointed to by \a r using the specified \a key of length \a len. + + This function can use up to 256 bytes of key, any more are ignored. + + \warning Stream ciphers (such as RC4) can be insecure if the same + \warning key is used repeatedly. Ensure that any key specified has + \warning an reasonably sized Initialisation Vector component. +*/ +void rc4_key(rc4_t *r, unsigned char *key, int len); + +/*! \fn rc4_crypt(rc4_t *r, unsigned char *plaintext, int len); + \brief Crypt bytes using RC4 algorithm + \param r pointer to RC4 structure to be used + \param plaintext Pointer to bytes to encrypt + \param len number of bytes to crypt + + This function encrypts one or more bytes (pointed to by \a plaintext) + using the RC4 algorithm. \a r is a state structure that must be + initialiased using the rc4_key() function prior to use. + + Since RC4 XORs each byte of plaintext with a byte of keystream, + this function can be used for both encryption and decryption. +*/ +void rc4_crypt(rc4_t *r, unsigned char *plaintext, int len); + +/*! \fn rc4_getbytes(rc4_t *r, unsigned char *buffer, int len); + \brief Generate key stream using the RC4 stream cipher + \param r pointer to RC4 structure to be used + \param buffer pointer to buffer in which to deposit keystream + \param len number of bytes to deposit + + This function gives access to the raw RC4 key stream. In this + consiguration RC4 can be used as a fast, strong pseudo-random + number generator with a very long period. +*/ +void rc4_getbytes(rc4_t *r, unsigned char *buffer, int len); + +#endif /* _RC4_H */ diff -ruN ssh/rsa.h openssh/rsa.h --- ssh/rsa.h Wed Sep 29 16:15:00 1999 +++ openssh/rsa.h Tue Oct 26 17:01:01 1999 @@ -18,8 +18,8 @@ #ifndef RSA_H #define RSA_H -#include -#include +#include +#include /* Calls SSL RSA_generate_key, only copies to prv and pub */ void rsa_generate_key(RSA *prv, RSA *pub, unsigned int bits); diff -ruN ssh/ssh-agent.c openssh/ssh-agent.c --- ssh/ssh-agent.c Fri Oct 15 04:17:42 1999 +++ openssh/ssh-agent.c Tue Oct 26 16:59:09 1999 @@ -26,7 +26,7 @@ #include "getput.h" #include "mpaux.h" -#include +#include typedef struct { @@ -132,10 +132,10 @@ assert(len <= 32 && len); memset(buf, 0, 32); BN_bn2bin(challenge, buf + 32 - len); - MD5Init(&md); - MD5Update(&md, buf, 32); - MD5Update(&md, session_id, 16); - MD5Final(mdbuf, &md); + MD5_Init(&md); + MD5_Update(&md, buf, 32); + MD5_Update(&md, session_id, 16); + MD5_Final(mdbuf, &md); break; default: diff -ruN ssh/ssh.h openssh/ssh.h --- ssh/ssh.h Tue Oct 26 06:41:55 1999 +++ openssh/ssh.h Tue Oct 26 17:58:35 1999 @@ -51,7 +51,10 @@ port if present. */ #define SSH_SERVICE_NAME "ssh" +#ifndef ETCDIR #define ETCDIR "/etc" +#endif /* ETCDIR */ + #define PIDDIR "/var/run" /* System-wide file containing host keys of known hosts. This file should be @@ -64,9 +67,9 @@ are all defined in Makefile.in. Of these, ssh_host_key should be readable only by root, whereas ssh_config should be world-readable. */ -#define HOST_KEY_FILE "/etc/ssh_host_key" -#define SERVER_CONFIG_FILE "/etc/sshd_config" -#define HOST_CONFIG_FILE "/etc/ssh_config" +#define HOST_KEY_FILE ETCDIR "/ssh_host_key" +#define SERVER_CONFIG_FILE ETCDIR "/sshd_config" +#define HOST_CONFIG_FILE ETCDIR "/ssh_config" #define SSH_PROGRAM "/usr/bin/ssh" diff -ruN ssh/ssh.pam openssh/ssh.pam --- ssh/ssh.pam Thu Jan 1 10:00:00 1970 +++ openssh/ssh.pam Wed Oct 27 11:49:48 1999 @@ -0,0 +1,7 @@ +#%PAM-1.0 +auth required /lib/security/pam_pwdb.so shadow +auth required /lib/security/pam_nologin.so +account required /lib/security/pam_pwdb.so +password required /lib/security/pam_cracklib.so +password required /lib/security/pam_pwdb.so shadow nullok use_authtok +session required /lib/security/pam_pwdb.so diff -ruN ssh/ssh_config openssh/ssh_config --- ssh/ssh_config Mon Oct 4 08:10:11 1999 +++ openssh/ssh_config Wed Oct 27 11:55:32 1999 @@ -26,5 +26,5 @@ # StrictHostKeyChecking no # IdentityFile ~/.ssh/identity # Port 22 -# Cipher idea +# Cipher blowfish # EscapeChar ~ diff -ruN ssh/sshconnect.c openssh/sshconnect.c --- ssh/sshconnect.c Tue Oct 26 06:34:30 1999 +++ openssh/sshconnect.c Tue Oct 26 17:00:58 1999 @@ -17,7 +17,7 @@ #include "includes.h" RCSID("$Id: sshconnect.c,v 1.23 1999/10/25 20:34:30 markus Exp $"); -#include +#include #include "xmalloc.h" #include "rsa.h" #include "ssh.h" @@ -28,7 +28,7 @@ #include "uidswap.h" #include "compat.h" -#include +#include /* Session id for the current session. */ unsigned char session_id[16]; @@ -452,10 +452,10 @@ assert(len <= sizeof(buf) && len); memset(buf, 0, sizeof(buf)); BN_bn2bin(challenge, buf + sizeof(buf) - len); - MD5Init(&md); - MD5Update(&md, buf, 32); - MD5Update(&md, session_id, 16); - MD5Final(response, &md); + MD5_Init(&md); + MD5_Update(&md, buf, 32); + MD5_Update(&md, session_id, 16); + MD5_Final(response, &md); debug("Sending response to host key RSA challenge."); diff -ruN ssh/sshd.c openssh/sshd.c --- ssh/sshd.c Tue Oct 26 06:38:49 1999 +++ openssh/sshd.c Wed Oct 27 10:25:43 1999 @@ -47,6 +47,14 @@ char *ticket = NULL; #endif /* KRB4 */ +#ifdef HAVE_PAM +#include +struct pam_handle_t *pamh=NULL; +char *pampasswd=NULL; +int retval; +int origretval; +#endif /* HAVE_PAM */ + /* Local Xauthority file. */ char *xauthfile = NULL; @@ -128,6 +136,74 @@ 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); +#ifdef HAVE_PAM +static int pamconv(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr); + +static struct pam_conv conv = { + pamconv, + NULL +}; + +static int pamconv(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) +{ + int count = 0; + int replies = 0; + struct pam_response *reply = NULL; + int size = sizeof(struct pam_response); + + for(count = 0; count < num_msg; count++) + { + switch (msg[count]->msg_style) + { + case PAM_PROMPT_ECHO_ON: + case PAM_PROMPT_ECHO_OFF: + if (reply == NULL) + reply = xmalloc(size); + else + reply = realloc(reply, size); + + if (reply == NULL) + return PAM_CONV_ERR; + + size += sizeof(struct pam_response); + + reply[replies].resp_retcode = PAM_SUCCESS; + + reply[replies++].resp = xstrdup(pampasswd); + /* PAM frees resp */ + break; + + case PAM_TEXT_INFO: + /* ignore it... */ + break; + + case PAM_ERROR_MSG: + default: + /* Must be an error of some sort... */ + if (reply != NULL) + free(reply); + + return PAM_CONV_ERR; + } + } + + if (reply != NULL) + *resp = reply; + + return PAM_SUCCESS; +} + +void pam_cleanup_proc(void *context) +{ + if (retval == PAM_SUCCESS) + retval = pam_close_session((pam_handle_t *)pamh, 0); + + if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS) + log("Cannot release PAM authentication."); +} +#endif /* HAVE_PAM */ /* Signal handler for SIGHUP. Sshd execs itself when it receives SIGHUP; the effect is to reread the configuration file (and to regenerate @@ -710,7 +786,19 @@ /* The connection has been terminated. */ log("Closing connection to %.100s", inet_ntoa(sin.sin_addr)); + +#ifdef HAVE_PAM + if (retval == PAM_SUCCESS) + retval = pam_close_session((pam_handle_t *)pamh, 0); + + if (pam_end((pam_handle_t *)pamh, retval) != PAM_SUCCESS) + log("Cannot release PAM authentication."); + + fatal_remove_cleanup(&pam_cleanup_proc, NULL); +#endif /* HAVE_PAM */ + packet_close(); + exit(0); } @@ -995,6 +1083,9 @@ char *client_user; unsigned int client_host_key_bits; BIGNUM *client_host_key_e, *client_host_key_n; +#ifdef HAVE_PAM + int pam_auth_ok; +#endif /* HAVE_PAM */ #ifdef AFS /* If machine has AFS, set process authentication group. */ @@ -1006,7 +1097,21 @@ /* Verify that the user is a valid user. */ pw = getpwnam(user); +#ifdef HAVE_PAM + if ((pw != NULL) && allowed_user(pw)) + { + /* Initialise PAM */ + retval = pam_start("ssh", pw->pw_name, &conv, (pam_handle_t **)&pamh); + fatal_add_cleanup(&pam_cleanup_proc, NULL); + origretval = retval; + if (retval == PAM_SUCCESS) + pam_auth_ok = 1; + } + + if (pam_auth_ok == 0) +#else /* HAVE_PAM */ if (!pw || !allowed_user(pw)) +#endif /* HAVE_PAM */ { /* The user does not exist or access is denied, but fake indication that authentication is needed. */ diff -ruN ssh/sshd.init openssh/sshd.init --- ssh/sshd.init Thu Jan 1 10:00:00 1970 +++ openssh/sshd.init Wed Oct 27 11:53:23 1999 @@ -0,0 +1,49 @@ +#!/bin/bash + +# Init file for OpenSSH sshd +# +# chkconfig: 234 55 25 +# description: OpenSSH server daemon +# +# processname: sshd +# config: /etc/ssh/ssh_host_key +# config: /etc/ssh/ssh_host_key.pub +# config: /etc/ssh/ssh_random_seed +# config: /etc/ssh/sshd_config +# pidfile: /var/run/sshd.pid + +# source function library +. /etc/rc.d/init.d/functions + +RETVAL=0 + +case "$1" in + start) + echo -n "Starting sshd: " + daemon /usr/sbin/sshd + RETVAL=$? + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/sshd + echo + ;; + stop) + echo -n "Shutting down sshd: " + killproc sshd + RETVAL=$? + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/sshd + echo + ;; + restart) + $0 stop + $0 start + RETVAL=$? + ;; + status) + status sshd + RETVAL=$? + ;; + *) + echo "Usage: sshd {start|stop|restart|status}" + exit 1 +esac + +exit $RETVAL diff -ruN ssh/sshd_config openssh/sshd_config --- ssh/sshd_config Mon Oct 18 06:48:08 1999 +++ openssh/sshd_config Wed Oct 27 12:11:16 1999 @@ -2,7 +2,7 @@ Port 22 ListenAddress 0.0.0.0 -HostKey /etc/ssh_host_key +HostKey /etc/ssh/ssh_host_key ServerKeyBits 768 LoginGraceTime 600 KeyRegenerationInterval 3600 @@ -20,7 +20,7 @@ SyslogFacility AUTH RhostsAuthentication no # -# For this to work you will also need host keys in /etc/ssh_known_hosts +# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts RhostsRSAAuthentication no # RSAAuthentication yes diff -ruN ssh/strlcpy.c openssh/strlcpy.c --- ssh/strlcpy.c Thu Jan 1 10:00:00 1970 +++ openssh/strlcpy.c Wed Oct 27 11:26:15 1999 @@ -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 -ruN ssh/strlcpy.h openssh/strlcpy.h --- ssh/strlcpy.h Thu Jan 1 10:00:00 1970 +++ openssh/strlcpy.h Wed Oct 27 11:30:22 1999 @@ -0,0 +1,4 @@ +#ifndef _STRLCPY_H +#define _STRLCPY_H +size_t strlcpy(char *dst, const char *src, size_t siz); +#endif /* _STRLCPY_H */