diff options
author | pst <pst@FreeBSD.org> | 1994-10-19 00:03:45 +0000 |
---|---|---|
committer | pst <pst@FreeBSD.org> | 1994-10-19 00:03:45 +0000 |
commit | 3bbaa5903cdfa6d903256d9ad37d1d8c20c79437 (patch) | |
tree | 18581614639f8a987cdf2526bd645ecfdd38abd3 /lib/libskey | |
parent | 1552617ffdcabd5ebae23058e72580c06f45e182 (diff) | |
download | FreeBSD-src-3bbaa5903cdfa6d903256d9ad37d1d8c20c79437.zip FreeBSD-src-3bbaa5903cdfa6d903256d9ad37d1d8c20c79437.tar.gz |
Include most of the logdaemon v4.4 S/key changes
Diffstat (limited to 'lib/libskey')
-rw-r--r-- | lib/libskey/Makefile | 8 | ||||
-rw-r--r-- | lib/libskey/mdx.h | 19 | ||||
-rw-r--r-- | lib/libskey/pathnames.h | 5 | ||||
-rw-r--r-- | lib/libskey/put.c | 2 | ||||
-rw-r--r-- | lib/libskey/skey.1 | 59 | ||||
-rw-r--r-- | lib/libskey/skey.access.5 | 47 | ||||
-rw-r--r-- | lib/libskey/skey.h | 9 | ||||
-rw-r--r-- | lib/libskey/skey_crypt.c | 3 | ||||
-rw-r--r-- | lib/libskey/skeyaccess.c | 200 | ||||
-rw-r--r-- | lib/libskey/skeylogin.c | 23 | ||||
-rw-r--r-- | lib/libskey/skeysubr.c | 143 |
11 files changed, 328 insertions, 190 deletions
diff --git a/lib/libskey/Makefile b/lib/libskey/Makefile index f31f725..0630c56 100644 --- a/lib/libskey/Makefile +++ b/lib/libskey/Makefile @@ -1,14 +1,14 @@ # @(#)Makefile 5.4 (Berkeley) 5/7/91 LIB= skey -SRCS= skeyaccess.c md4.c put.c skey_crypt.c skeylogin.c skeysubr.c +SRCS= skeyaccess.c put.c skey_crypt.c skey_getpass.c skeylogin.c skeysubr.c +MAN1= skey.1 MAN5= skey.access.5 -CFLAGS+=-DMPU8086 -DPERMIT_CONSOLE -I${.CURDIR} +CFLAGS+=-DPERMIT_CONSOLE -I${.CURDIR} beforeinstall: - -cd ${.CURDIR}; cmp -s skey.h ${DESTDIR}/usr/include/skey.h > \ - /dev/null 2>&1 || \ + -cd ${.CURDIR}; cmp -s skey.h ${DESTDIR}/usr/include/skey.h || \ install -c -o ${BINOWN} -g ${BINGRP} -m 444 skey.h \ ${DESTDIR}/usr/include diff --git a/lib/libskey/mdx.h b/lib/libskey/mdx.h new file mode 100644 index 0000000..567d541 --- /dev/null +++ b/lib/libskey/mdx.h @@ -0,0 +1,19 @@ +#ifdef MD5 +/* S/Key can use MD5 now, if defined... */ +#include <md5.h> + +#define MDXFinal MD5Final +#define MDXInit MD5Init +#define MDXUpdate MD5Update +#define MDX_CTX MD5_CTX +#else + +/* By default, use MD4 for compatibility */ +#include <md4.h> + +#define MDXFinal MD4Final +#define MDXInit MD4Init +#define MDXUpdate MD4Update +#define MDX_CTX MD4_CTX + +#endif diff --git a/lib/libskey/pathnames.h b/lib/libskey/pathnames.h index 43631f5..87c8a23 100644 --- a/lib/libskey/pathnames.h +++ b/lib/libskey/pathnames.h @@ -1,5 +1,6 @@ -/* $Id$ (FreeBSD) */ +/* $Id: pathnames.h,v 1.1 1994/05/27 07:50:08 pst Exp $ (FreeBSD) */ #include <paths.h> -#define _PATH_SKEYACCESS "/etc/skey.access" +#define _PATH_SKEYACCESS "/etc/skey.access" +#define _PATH_SKEYFILE "/etc/skeykeys" diff --git a/lib/libskey/put.c b/lib/libskey/put.c index 0f62d22..d533714 100644 --- a/lib/libskey/put.c +++ b/lib/libskey/put.c @@ -2,7 +2,7 @@ #include <string.h> #include <assert.h> #include <ctype.h> -#include <skey.h> +#include "skey.h" static unsigned long extract __P((char *s,int start,int length)); static void standard __P((char *word)); diff --git a/lib/libskey/skey.1 b/lib/libskey/skey.1 new file mode 100644 index 0000000..b4e0455 --- /dev/null +++ b/lib/libskey/skey.1 @@ -0,0 +1,59 @@ +.ll 6i +.pl 10.5i +.\" @(#)skey.1 1.1 10/28/93 +.\" +.lt 6.0i +.TH KEY 1 "28 October 1993" +.AT 3 +.SH NAME +S/key \- A procedure to use one time passwords for accessing computer systems. +.SH DESCRIPTION +.I S/key +is a procedure for using one time password to authenticate access to +computer systems. It uses 64 bits of information transformed by the +MD4 algorithm. The user supplies the 64 bits in the form of 6 English +words that are generated by a secure computer. +Example use of the S/key program +.I key +.sp + Usage example: +.sp 0 + >key 99 th91334 +.sp 0 + Enter password: <your secret password is entered here> +.sp 0 + OMEN US HORN OMIT BACK AHOY +.sp 0 + > +.sp +The programs that are part of the S/Key system are keyinit, key, and +keyinfo. Keyinit is used to get your ID set up, key is +used to get the one time password each time, +keyinfo is used to extract information from the S/Key database. +.sp +When you run "keyinit" you inform the system of your +secret password. Running "key" then generates the +one-time passwords, and also requires your secret +password. If however, you misspell your password +while running "key", you will get a list of passwords +that will not work, and no indication about the problem. +.sp +Password sequence numbers count backward from 99. If you +don't know this, the syntax for "key" will be confusing. +.sp +You can enter the passwords using small letters, even +though the "key" program gives them in caps. +.sp +Macintosh and a general purpose PC use +are available. +.sp +Under FreeBSD, you can control, with /etc/skey.access, from which +hosts and/or networks the use of S/Key passwords is obligated. +.LP +.SH SEE ALSO +.BR keyinit(1), +.BR key(1), +.BR keyinfo(1) +.BR skey.access(5) +.SH AUTHOR +Phil Karn, Neil M. Haller, John S. Walden, Scott Chasin diff --git a/lib/libskey/skey.access.5 b/lib/libskey/skey.access.5 index e92b4a6..2e12ad1 100644 --- a/lib/libskey/skey.access.5 +++ b/lib/libskey/skey.access.5 @@ -2,10 +2,9 @@ .SH NAME skey.access \- S/Key password control table .SH DESCRIPTION -The S/Key password control table (default -.IR /etc/skey.access ) -is used by \fIlogin\fR-like programs to determine when UNIX passwords -may be used to access the system. +The S/Key password control table (\fI/etc/skey.access\fR) is used by +\fIlogin\fR-like programs to determine when UNIX passwords may be used +to access the system. .IP \(bu When the table does not exist, there are no password restrictions. The user may enter the UNIX password or the S/Key one. @@ -44,6 +43,7 @@ on it. .SH CONDITIONS .IP "hostname wzv.win.tue.nl" True when the login comes from host wzv.win.tue.nl. +See the WARNINGS section below. .IP "internet 131.155.210.0 255.255.255.0" True when the remote host has an internet address in network 131.155.210. The general form of a net/mask rule is: @@ -58,6 +58,7 @@ and .I mask equals .IR net. +See the WARNINGS section below. .IP "port ttya" True when the login terminal is equal to .IR /dev/ttya . @@ -74,6 +75,44 @@ group. For the sake of backwards compatibility, the .I internet keyword may be omitted from net/mask patterns. +.SH WARNINGS +Several rule types depend on host name or address information obtained +through the network. What follows is a list of conceivable attacks to +force the system to permit UNIX passwords. +.IP "Host address spoofing (source routing)" +An intruder configures a local interface to an address in a trusted +network and connects to the victim using that source address. Given +the wrong client address, the victim draws the wrong conclusion from +rules based on host addresses or from rules based on host names derived +from addresses. +.sp +Remedies: (1) do not permit UNIX passwords with network logins; (2) +use network software that discards source routing information (e.g. +a tcp wrapper). +.PP +Almost every network server must look up the client host name using the +client network address. The next obvious attack therefore is: +.IP "Host name spoofing (bad PTR record)" +An intruder manipulates the name server system so that the client +network address resolves to the name of a trusted host. Given the +wrong host name, the victim draws the wrong conclusion from rules based +on host names, or from rules based on addresses derived from host +names. +.sp +Remedies: (1) do not permit UNIX passwords with network logins; (2) use +network software that verifies that the hostname resolves to the client +network address (e.g. a tcp wrapper). +.PP +Some applications, such as the UNIX login program, must look up the +client network address using the client host name. In addition to the +previous two attacks, this opens up yet another possibility: +.IP "Host address spoofing (extra A record)" +An intruder manipulates the name server system so that the client host +name (also) resolves to a trusted address. +.sp +Remedies: (1) do not permit UNIX passwords with network logins; (2) +the skeyaccess() routines ignore network addresses that appear to +belong to someone else. .SH DIAGNOSTICS Syntax errors are reported to the syslogd. When an error is found the rule is skipped. diff --git a/lib/libskey/skey.h b/lib/libskey/skey.h index e9ee453..039da4e 100644 --- a/lib/libskey/skey.h +++ b/lib/libskey/skey.h @@ -12,8 +12,6 @@ struct skey { char *seed; char *val; long recstart; /*needed so reread of buffer is efficient*/ - - }; /* Client-side structure for scanning data stream for challenge */ @@ -32,6 +30,11 @@ void rip __P((char *buf)); int skeychallenge __P((struct skey *mp,char *name, char *challenge)); int skeylookup __P((struct skey *mp,char *name)); int skeyverify __P((struct skey *mp,char *response)); -int skeyaccess __P((char *user, char *port, char *host)); + +/* Simplified application programming interface. */ +#include <pwd.h> +int skeyaccess __P((char *user, char *port, char *host, char *addr)); +char *skey_getpass __P((char *prompt, struct passwd *pwd, int pwok)); +char *skey_crypt __P((char *pp, char *salt, struct passwd *pwd, int pwok)); #endif /* _SKEY_H_ */ diff --git a/lib/libskey/skey_crypt.c b/lib/libskey/skey_crypt.c index b61bef0..ca1024f 100644 --- a/lib/libskey/skey_crypt.c +++ b/lib/libskey/skey_crypt.c @@ -3,7 +3,8 @@ #include <string.h> #include <stdio.h> #include <pwd.h> -#include <skey.h> + +#include "skey.h" /* skey_crypt - return encrypted UNIX passwd if s/key or regular password ok */ diff --git a/lib/libskey/skeyaccess.c b/lib/libskey/skeyaccess.c index 67ed549..3cd877f 100644 --- a/lib/libskey/skeyaccess.c +++ b/lib/libskey/skeyaccess.c @@ -2,9 +2,14 @@ * Figure out if UNIX passwords are permitted for any combination of user * name, group member, terminal port, host_name or network: * - * Programmatic interface: skeyaccess(char *user, char *port, char *host) + * Programmatic interface: skeyaccess(user, port, host, addr) * - * Specify a null character pointer where information is not available. + * All arguments are null-terminated strings. Specify a null character pointer + * where information is not available. + * + * When no address information is given this code performs the host (internet) + * address lookup itself. It rejects addresses that appear to belong to + * someone else. * * When compiled with -DPERMIT_CONSOLE always permits UNIX passwords with * console logins, no matter what the configuration file says. @@ -12,7 +17,9 @@ * To build a stand-alone test version, compile with -DTEST and run it off an * skey.access file in the current directory: * - * Command-line interface: ./skeyaccess user port [host] + * Command-line interface: ./skeyaccess user port [host_or_ip_addr] + * + * Errors are reported via syslogd. * * Author: Wietse Venema, Eindhoven University of Technology. */ @@ -54,6 +61,8 @@ static int match_internet_addr(); static int match_group(); static int match_token(); static int is_internet_addr(); +static struct in_addr *convert_internet_addr(); +static struct in_addr *lookup_internet_addr(); #define MAX_ADDR 32 #define PERMIT 1 @@ -68,40 +77,53 @@ struct login_info { /* skeyaccess - find out if UNIX passwords are permitted */ -int skeyaccess(user, port, host) +int skeyaccess(user, port, host, addr) char *user; char *port; char *host; +char *addr; { - struct hostent *hp; + FILE *fp; struct login_info login_info; - struct in_addr internet_addr[MAX_ADDR + 1]; - char hostname_buf[MAXHOSTNAMELEN + 1]; - int i; + int result; + /* + * Assume no restriction on the use of UNIX passwords when the s/key + * acces table does not exist. + */ + if ((fp = fopen(_PATH_SKEYACCESS, "r")) == 0) { +#ifdef TEST + fprintf(stderr, "No file %s, thus no access control\n", _PATH_SKEYACCESS); +#endif + return (PERMIT); + } + + /* + * Bundle up the arguments in a structure so we won't have to drag around + * boring long argument lists. + * + * Look up the host address when only the name is given. We try to reject + * addresses that belong to someone else. + */ login_info.user = user; login_info.port = port; - login_info.host_name = 0; - login_info.internet_addr = 0; - - if (host) { - if (is_internet_addr(host)) { /* not DECnet */ - internet_addr[0].s_addr = inet_addr(host); - internet_addr[1].s_addr = 0; - login_info.internet_addr = internet_addr; + + if (host != 0 && !is_internet_addr(host)) { + login_info.host_name = host; + } else { + login_info.host_name = 0; + } + + if (addr != 0 && is_internet_addr(addr)) { + login_info.internet_addr = convert_internet_addr(addr); + } else if (host != 0) { + if (is_internet_addr(host)) { + login_info.internet_addr = convert_internet_addr(host); } else { - if ((hp = gethostbyname(host)) != 0 && hp->h_addrtype == AF_INET) { - for (i = 0; i < MAX_ADDR && hp->h_addr_list[i]; i++) - memcpy((char *) &internet_addr[i], - hp->h_addr_list[i], hp->h_length); - internet_addr[i].s_addr = 0; - login_info.internet_addr = internet_addr; - host = hp->h_name; - } - strncpy(hostname_buf, host, MAXHOSTNAMELEN); - hostname_buf[MAXHOSTNAMELEN] = 0; - login_info.host_name = hostname_buf; + login_info.internet_addr = lookup_internet_addr(host); } + } else { + login_info.internet_addr = 0; } /* @@ -115,20 +137,25 @@ char *host; if (login_info.internet_addr == 0) { printf("none\n"); } else { + int i; + for (i = 0; login_info.internet_addr[i].s_addr; i++) - printf("%s%s", inet_ntoa(login_info.internet_addr[i]), + printf("%s%s", login_info.internet_addr[i].s_addr == -1 ? + "(see error log)" : inet_ntoa(login_info.internet_addr[i]), login_info.internet_addr[i + 1].s_addr ? " " : "\n"); } #endif - return (_skeyaccess(&login_info)); + result = _skeyaccess(fp, &login_info); + fclose(fp); + return (result); } /* _skeyaccess - find out if UNIX passwords are permitted */ -int _skeyaccess(login_info) +int _skeyaccess(fp, login_info) +FILE *fp; struct login_info *login_info; { - FILE *fp; char buf[BUFSIZ]; char *tok; int match; @@ -140,13 +167,6 @@ struct login_info *login_info; #endif /* - * Assume no restriction on the use of UNIX passwords when the s/key - * acces table does not exist. - */ - if ((fp = fopen(_PATH_SKEYACCESS, "r")) == 0) - return (PERMIT); - - /* * Scan the s/key access table until we find an entry that matches. If no * match is found, assume that UNIX passwords are disallowed. */ @@ -187,7 +207,6 @@ struct login_info *login_info; } } } - fclose(fp); return (match ? permission : DENY); } @@ -200,7 +219,6 @@ struct login_info *login_info; long pattern; long mask; struct in_addr *addrp; - struct hostent *hp; if (login_info->internet_addr == 0) return (0); @@ -212,26 +230,13 @@ struct login_info *login_info; mask = inet_addr(tok); /* - * See if any of the addresses matches a pattern in the control file. - * Report and skip the address if it does not belong to the remote host. - * Assume localhost == localhost.domain. + * See if any of the addresses matches a pattern in the control file. We + * have already tried to drop addresses that belong to someone else. */ -#define NEQ(x,y) (strcasecmp((x),(y)) != 0) - - for (addrp = login_info->internet_addr; addrp->s_addr; addrp++) { - if ((addrp->s_addr & mask) == pattern) { - if (login_info->host_name != 0 && - ((hp = gethostbyaddr((char *) addrp, sizeof(*addrp), AF_INET)) == 0 - || (NEQ(login_info->host_name, hp->h_name) - && NEQ(login_info->host_name, "localhost")))) { - syslog(LOG_ERR, "address %s not registered for host %s", - inet_ntoa(*addrp), login_info->host_name); - continue; - } + for (addrp = login_info->internet_addr; addrp->s_addr; addrp++) + if (addrp->s_addr != -1 && (addrp->s_addr & mask) == pattern) return (1); - } - } return (0); } @@ -365,18 +370,97 @@ char *str; return (runs == 4); } +/* lookup_internet_addr - look up internet addresses with extreme prejudice */ + +static struct in_addr *lookup_internet_addr(host) +char *host; +{ + struct hostent *hp; + static struct in_addr list[MAX_ADDR + 1]; + char buf[MAXHOSTNAMELEN + 1]; + int length; + int i; + + if ((hp = gethostbyname(host)) == 0 || hp->h_addrtype != AF_INET) + return (0); + + /* + * Save a copy of the results before gethostbyaddr() clobbers them. + */ + + for (i = 0; i < MAX_ADDR && hp->h_addr_list[i]; i++) + memcpy((char *) &list[i], + hp->h_addr_list[i], hp->h_length); + list[i].s_addr = 0; + + strncpy(buf, hp->h_name, MAXHOSTNAMELEN); + buf[MAXHOSTNAMELEN] = 0; + length = hp->h_length; + + /* + * Wipe addresses that appear to belong to someone else. We will get + * false alarms when when the hostname comes from DNS, while its + * addresses are listed under different names in local databases. + */ +#define NEQ(x,y) (strcasecmp((x),(y)) != 0) +#define NEQ3(x,y,n) (strncasecmp((x),(y), (n)) != 0) + + while (--i >= 0) { + if ((hp = gethostbyaddr((char *) &list[i], length, AF_INET)) == 0) { + syslog(LOG_ERR, "address %s not registered for host %s", + inet_ntoa(list[i]), buf); + list[i].s_addr = -1; + } + if (NEQ(buf, hp->h_name) && NEQ3(buf, "localhost.", 10)) { + syslog(LOG_ERR, "address %s registered for host %s and %s", + inet_ntoa(list[i]), hp->h_name, buf); + list[i].s_addr = -1; + } + } + return (list); +} + +/* convert_internet_addr - convert string to internet address */ + +static struct in_addr *convert_internet_addr(string) +char *string; +{ + static struct in_addr list[2]; + + list[0].s_addr = inet_addr(string); + list[1].s_addr = 0; + return (list); +} + #ifdef TEST main(argc, argv) int argc; char **argv; { + struct hostent *hp; + char host[MAXHOSTNAMELEN + 1]; + int verdict; + char *user; + char *port; + if (argc != 3 && argc != 4) { fprintf(stderr, "usage: %s user port [host_or_ip_address]\n", argv[0]); exit(0); } + if (_PATH_SKEYACCESS[0] != '/') + printf("Warning: this program uses control file: %s\n", KEYACCESS); openlog("login", LOG_PID, LOG_AUTH); - printf("%s\n", skeyaccess(argv[1], argv[2], argv[3]) ? "YES" : "NO"); + + user = argv[1]; + port = argv[2]; + if (argv[3]) { + strncpy(host, (hp = gethostbyname(argv[3])) ? + hp->h_name : argv[3], MAXHOSTNAMELEN); + host[MAXHOSTNAMELEN] = 0; + } + verdict = skeyaccess(user, port, argv[3] ? host : (char *) 0, (char *) 0); + printf("UNIX passwords %spermitted\n", verdict ? "" : "NOT "); return (0); } diff --git a/lib/libskey/skeylogin.c b/lib/libskey/skeylogin.c index f2d4104..e15edb5 100644 --- a/lib/libskey/skeylogin.c +++ b/lib/libskey/skeylogin.c @@ -2,12 +2,10 @@ * of Bellcore. * * Mink is the former name of the S/KEY authentication system. - * Many references for mink may still be found in this program. */ + * Many references for mink may still be found in this program. + */ #include <sys/param.h> -#ifdef QUOTA -#include <sys/quota.h> -#endif #include <sys/stat.h> #include <sys/time.h> #include <sys/resource.h> @@ -19,9 +17,9 @@ #include <sys/stat.h> #include <time.h> #include <errno.h> -#include <skey.h> -#define KEYFILE "/etc/skeykeys" +#include "skey.h" +#include "pathnames.h" char *skipspace(); int skeylookup __P((struct skey *mp,char *name)); @@ -57,7 +55,8 @@ char *prompt; return -1; } return -1; /* Can't happen */ -} +} + /* Return a skey challenge string for user 'name'. If successful, * fill in the caller's skey structure and return 0. If unsuccessful * (e.g., if name is unknown) return -1. @@ -104,13 +103,13 @@ char *name; char *cp; struct stat statbuf; - /* See if the KEYFILE exists, and create it if not */ - if(stat(KEYFILE,&statbuf) == -1 && errno == ENOENT){ - mp->keyfile = fopen(KEYFILE,"w+"); - (void) chmod(KEYFILE, 0644); + /* See if the _PATH_SKEYFILE exists, and create it if not */ + if(stat(_PATH_SKEYFILE,&statbuf) == -1 && errno == ENOENT){ + mp->keyfile = fopen(_PATH_SKEYFILE,"w+"); + (void) chmod(_PATH_SKEYFILE, 0644); } else { /* Otherwise open normally for update */ - mp->keyfile = fopen(KEYFILE,"r+"); + mp->keyfile = fopen(_PATH_SKEYFILE,"r+"); } if(mp->keyfile == NULL) return -1; diff --git a/lib/libskey/skeysubr.c b/lib/libskey/skeysubr.c index b947c01..e144202 100644 --- a/lib/libskey/skeysubr.c +++ b/lib/libskey/skeysubr.c @@ -4,19 +4,14 @@ #ifdef __MSDOS__ #include <dos.h> #endif -#ifdef unix /* Assume POSIX */ +#ifdef unix #include <fcntl.h> #include <termios.h> +#include <signal.h> #endif -#include <skey.h> -#include "md4.h" - -#ifndef LITTLE_ENDIAN -#if (defined(__MSDOS__) || defined(MPU8086) || defined(MPU8080) \ - || defined(vax) || defined (MIPSEL)) -#define LITTLE_ENDIAN /* Low order bytes are first in memory */ -#endif /* Almost all other machines are big-endian */ -#endif + +#include "skey.h" +#include "mdx.h" /* Crunch a key: * concatenate the seed and the password, run through MD4 and @@ -24,17 +19,14 @@ */ int keycrunch(result,seed,passwd) -char *result; /* 8-byte result */ -char *seed; /* Seed, any length */ -char *passwd; /* Password, any length */ +char *result; /* 8-byte result */ +char *seed; /* Seed, any length */ +char *passwd; /* Password, any length */ { char *buf; - MDstruct md; + MDX_CTX md; + u_long results[4]; unsigned int buflen; -#ifndef LITTLE_ENDIAN - int i; - register long tmp; -#endif buflen = strlen(seed) + strlen(passwd); if((buf = malloc(buflen+1)) == NULL) @@ -42,35 +34,17 @@ char *passwd; /* Password, any length */ strcpy(buf,seed); strcat(buf,passwd); - /* Crunch the key through MD4 */ + /* Crunch the key through MD[45] */ sevenbit(buf); - MDbegin(&md); - MDupdate(&md,(unsigned char *)buf,8*buflen); - + MDXInit(&md); + MDXUpdate(&md,(unsigned char *)buf,buflen); + MDXFinal((unsigned char *)results,&md); free(buf); - /* Fold result from 128 to 64 bits */ - md.buffer[0] ^= md.buffer[2]; - md.buffer[1] ^= md.buffer[3]; + results[0] ^= results[2]; + results[1] ^= results[3]; -#ifdef LITTLE_ENDIAN - /* Only works on byte-addressed little-endian machines!! */ - memcpy(result,(char *)md.buffer,8); -#else - /* Default (but slow) code that will convert to - * little-endian byte ordering on any machine - */ - for(i=0;i<2;i++){ - tmp = md.buffer[i]; - *result++ = tmp; - tmp >>= 8; - *result++ = tmp; - tmp >>= 8; - *result++ = tmp; - tmp >>= 8; - *result++ = tmp; - } -#endif + memcpy(result,(char *)results,8); return 0; } @@ -80,44 +54,18 @@ void f(x) char *x; { - MDstruct md; -#ifndef LITTLE_ENDIAN - register long tmp; -#endif - - MDbegin(&md); - MDupdate(&md,(unsigned char *)x,64); + MDX_CTX md; + u_long results[4]; + MDXInit(&md); + MDXUpdate(&md,(unsigned char *)x,8); + MDXFinal((unsigned char *)results,&md); /* Fold 128 to 64 bits */ - md.buffer[0] ^= md.buffer[2]; - md.buffer[1] ^= md.buffer[3]; + results[0] ^= results[2]; + results[1] ^= results[3]; -#ifdef LITTLE_ENDIAN /* Only works on byte-addressed little-endian machines!! */ - memcpy(x,(char *)md.buffer,8); - -#else - /* Default (but slow) code that will convert to - * little-endian byte ordering on any machine - */ - tmp = md.buffer[0]; - *x++ = tmp; - tmp >>= 8; - *x++ = tmp; - tmp >>= 8; - *x++ = tmp; - tmp >>= 8; - *x++ = tmp; - - tmp = md.buffer[1]; - *x++ = tmp; - tmp >>= 8; - *x++ = tmp; - tmp >>= 8; - *x++ = tmp; - tmp >>= 8; - *x = tmp; -#endif + memcpy(x,(char *)results,8); } /* Strip trailing cr/lf from a line of text */ @@ -152,16 +100,26 @@ int n; return buf; } #else +static struct termios saved_ttymode; + +static void interrupt() +{ + tcsetattr(0, TCSANOW, &saved_ttymode); + exit(1); +} + char * readpass(buf,n) char *buf; int n; { - struct termios saved_ttymode; struct termios noecho_ttymode; + void (*oldsig)(); /* Save normal line editing modes */ tcgetattr(0, &saved_ttymode); + if ((oldsig = signal(SIGINT, SIG_IGN)) != SIG_IGN) + signal(SIGINT, interrupt); /* Turn off echoing */ tcgetattr(0, &noecho_ttymode); @@ -172,6 +130,8 @@ int n; /* Restore previous tty modes */ tcsetattr(0, TCSANOW, &saved_ttymode); + if (oldsig != SIG_IGN) + signal(SIGINT, oldsig); /* after the secret key is taken from the keyboard, the line feed is @@ -189,33 +149,6 @@ int n; #endif -/* removebackspaced over charaters from the string*/ -backspace(buf) -char *buf; -{ - char bs = 0x8; - char *cp = buf; - char *out = buf; - - while(*cp){ - if( *cp == bs ) { - if(out == buf){ - cp++; - continue; - } - else { - cp++; - out--; - } - } - else { - *out++ = *cp++; - } - - } - *out = '\0'; - -} sevenbit(s) char *s; { |