summaryrefslogtreecommitdiffstats
path: root/contrib/opie/libopie
diff options
context:
space:
mode:
authorpst <pst@FreeBSD.org>1997-02-06 17:52:29 +0000
committerpst <pst@FreeBSD.org>1997-02-06 17:52:29 +0000
commit2dfcbf193123fd16b26454eeffa4bbd014e52c53 (patch)
treeec9d150c9da4390c2d223a04ac002523cbfd7f36 /contrib/opie/libopie
downloadFreeBSD-src-2dfcbf193123fd16b26454eeffa4bbd014e52c53.zip
FreeBSD-src-2dfcbf193123fd16b26454eeffa4bbd014e52c53.tar.gz
Initial import of OPIE v2.3 from
ftp://ftp.nrl.navy.mil/pub/security/opie/
Diffstat (limited to 'contrib/opie/libopie')
-rw-r--r--contrib/opie/libopie/Makefile.in28
-rw-r--r--contrib/opie/libopie/accessfile.c165
-rw-r--r--contrib/opie/libopie/atob8.c74
-rw-r--r--contrib/opie/libopie/btoa8.c32
-rw-r--r--contrib/opie/libopie/btoe.c2266
-rw-r--r--contrib/opie/libopie/btoh.c35
-rw-r--r--contrib/opie/libopie/challenge.c74
-rw-r--r--contrib/opie/libopie/generator.c110
-rw-r--r--contrib/opie/libopie/getsequence.c27
-rw-r--r--contrib/opie/libopie/getutmpentry.c72
-rw-r--r--contrib/opie/libopie/hash.c52
-rw-r--r--contrib/opie/libopie/hashlen.c51
-rw-r--r--contrib/opie/libopie/insecure.c146
-rw-r--r--contrib/opie/libopie/keycrunch.c64
-rw-r--r--contrib/opie/libopie/lock.c175
-rw-r--r--contrib/opie/libopie/login.c130
-rw-r--r--contrib/opie/libopie/lookup.c30
-rw-r--r--contrib/opie/libopie/md4c.c267
-rw-r--r--contrib/opie/libopie/md5c.c304
-rw-r--r--contrib/opie/libopie/newseed.c99
-rw-r--r--contrib/opie/libopie/open.c61
-rw-r--r--contrib/opie/libopie/parsechallenge.c70
-rw-r--r--contrib/opie/libopie/passcheck.c50
-rw-r--r--contrib/opie/libopie/passwd.c74
-rw-r--r--contrib/opie/libopie/randomchallenge.c43
-rw-r--r--contrib/opie/libopie/readpass.c304
-rw-r--r--contrib/opie/libopie/readrec.c218
-rw-r--r--contrib/opie/libopie/unlock.c103
-rw-r--r--contrib/opie/libopie/verify.c255
-rw-r--r--contrib/opie/libopie/version.c27
-rw-r--r--contrib/opie/libopie/writerec.c85
31 files changed, 5491 insertions, 0 deletions
diff --git a/contrib/opie/libopie/Makefile.in b/contrib/opie/libopie/Makefile.in
new file mode 100644
index 0000000..99ab4e7
--- /dev/null
+++ b/contrib/opie/libopie/Makefile.in
@@ -0,0 +1,28 @@
+##
+# Makefile.in/Makefile: Directions for building libopie.
+#
+# This software is Copyright 1996 by Craig Metz, All Rights Reserved. The Inner
+# Net Copyright Notice and License Agreement version 2.00 applies to this
+# software.
+#
+# History:
+#
+# Created by cmetz for OPIE 2.3 using old Makefiles as a guide.
+
+OBJS=md4c.o md5c.o atob8.o btoa8.o btoh.o challenge.o getsequence.o hash.o hashlen.o keycrunch.o lock.o lookup.o newseed.o parsechallenge.o passcheck.o passwd.o randomchallenge.o readpass.o unlock.o verify.o version.o btoe.o accessfile.o generator.o insecure.o getutmpentry.o readrec.o writerec.o login.o open.o
+
+CC=@CC@
+CFLAGS=$(CFL) -I..
+TARGET=libopie.a
+
+all: $(TARGET)
+
+$(TARGET): $(OBJS)
+ ar r $(TARGET) $(OBJS)
+ @RANLIB@ $(TARGET)
+
+clean:
+ -rm -f $(OBJS) $(TARGET)
+
+realclean: clean
+ -rm -f *~ core* "\#*\#" *.o *.a Makefile
diff --git a/contrib/opie/libopie/accessfile.c b/contrib/opie/libopie/accessfile.c
new file mode 100644
index 0000000..7b1866e
--- /dev/null
+++ b/contrib/opie/libopie/accessfile.c
@@ -0,0 +1,165 @@
+/* accessfile.c: Handle trusted network access file and per-user
+ overrides.
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+Portions of this software are Copyright 1995 by Randall Atkinson and Dan
+McDonald, All Rights Reserved. All Rights under this copyright are assigned
+to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
+License Agreement applies to this software.
+
+ History:
+
+ Modified by cmetz for OPIE 2.3. Send debug info to syslog.
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
+ Ifdef around some headers. Remove extra semicolon.
+ Modified at NRL for OPIE 2.2. Moved from accessfile.c to
+ libopie/opieaccessfile.c.
+ Modified at NRL for OPIE 2.0.
+ Written at Bellcore for the S/Key Version 1 software distribution
+ (login.c).
+*/
+#include "opie_cfg.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#if HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif /* HAVE_STDLIB_H */
+
+#include "opie.h"
+
+int opieaccessfile FUNCTION((host), char *host)
+{
+#ifdef PATH_ACCESS_FILE
+/* Turn host into an IP address and then look it up in the authorization
+ * database to determine if ordinary password logins are OK
+ */
+ long n;
+ struct hostent *hp;
+ FILE *fp;
+ char buf[128], **lp;
+
+#ifdef DEBUG
+ syslog(LOG_DEBUG, "accessfile: host=%s", host);
+#endif /* DEBUG */
+ if (!host[0])
+ /* Local login, okay */
+ return (1);
+ if (isaddr(host)) {
+ n = inet_addr(host);
+ return rdnets(n);
+ } else {
+ hp = gethostbyname(host);
+ if (!hp) {
+ printf("Unknown host %s\n", host);
+ return 0;
+ }
+ for (lp = hp->h_addr_list; *lp; lp++) {
+ memcpy((char *) &n, *lp, sizeof(n));
+ if (rdnets(n))
+ return (1);
+ }
+ return (0);
+ }
+}
+
+int rdnets FUNCTION((host), long host)
+{
+ FILE *fp;
+ char buf[128], *cp;
+ long pattern, mask;
+ int permit_it;
+
+ if (!(fp = fopen(PATH_ACCESS_FILE, "r")))
+ return 0;
+
+ while (fgets(buf, sizeof(buf), fp), !feof(fp)) {
+ if (buf[0] == '#')
+ continue; /* Comment */
+ if (!(cp = strtok(buf, " \t")))
+ continue;
+ /* two choices permit of deny */
+ if (strncasecmp(cp, "permit", 4) == 0) {
+ permit_it = 1;
+ } else {
+ if (strncasecmp(cp, "deny", 4) == 0) {
+ permit_it = 0;
+ } else {
+ continue; /* ignore; it is not permit/deny */
+ }
+ }
+ if (!(cp = strtok(NULL, " \t")))
+ continue; /* Invalid line */
+ pattern = inet_addr(cp);
+ if (!(cp = strtok(NULL, " \t")))
+ continue; /* Invalid line */
+ mask = inet_addr(cp);
+#ifdef DEBUG
+ syslog(LOG_DEBUG, "accessfile: %08x & %08x == %08x (%s)", host, mask, pattern, ((host & mask) == pattern) ? "true" : "false");
+#endif /* DEBUG */
+ if ((host & mask) == pattern) {
+ fclose(fp);
+ return permit_it;
+ }
+ }
+ fclose(fp);
+ return 0;
+}
+
+
+/* Return TRUE if string appears to be an IP address in dotted decimal;
+ * return FALSE otherwise (i.e., if string is a domain name)
+ */
+int isaddr FUNCTION((s), register char *s)
+{
+ char c;
+
+ if (!s)
+ return 1; /* Can't happen */
+
+ while ((c = *s++) != '\0') {
+ if (c != '[' && c != ']' && !isdigit(c) && c != '.')
+ return 0;
+ }
+ return 1;
+#else /* PATH_ACCESS_FILE */
+ return !host[0];
+#endif /* PATH_ACCESS_FILE */
+}
+
+/* Returns the opposite of what you might expect */
+/* Returns 1 on error (allow)... this might not be what you want */
+int opiealways FUNCTION((homedir), char *homedir)
+{
+ char *opiealwayspath;
+ int i;
+
+ if (!homedir)
+ return 1;
+
+ if (!(opiealwayspath = malloc(strlen(homedir) + sizeof(OPIE_ALWAYS_FILE) + 1)))
+ return 1;
+
+ strcpy(opiealwayspath, homedir);
+ strcat(opiealwayspath, "/");
+ strcat(opiealwayspath, OPIE_ALWAYS_FILE);
+ i = access(opiealwayspath, F_OK);
+ free(opiealwayspath);
+ return (i);
+}
diff --git a/contrib/opie/libopie/atob8.c b/contrib/opie/libopie/atob8.c
new file mode 100644
index 0000000..2c23478
--- /dev/null
+++ b/contrib/opie/libopie/atob8.c
@@ -0,0 +1,74 @@
+/* atob8.c: The opieatob8() library function.
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+Portions of this software are Copyright 1995 by Randall Atkinson and Dan
+McDonald, All Rights Reserved. All Rights under this copyright are assigned
+to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
+License Agreement applies to this software.
+
+ History:
+
+ Modified by cmetz for OPIE 2.3. Return the output variable.
+ Don't check parameters.
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
+ Inlined and obseleted opieskipspace(). Inlined and obseleted
+ opiehtoi().
+ Created at NRL for OPIE 2.2 from opiesubr2.c
+*/
+#include "opie_cfg.h"
+#include <stdio.h>
+#include "opie.h"
+
+/* Convert 8-byte hex-ascii string to binary array
+ */
+char *opieatob8 FUNCTION((out, in), char *out AND char *in)
+{
+ register int i;
+ register int val;
+
+ for (i = 0; i < 8; i++) {
+ while (*in == ' ' || *in == '\t')
+ in++;
+ if (!*in)
+ return NULL;
+
+ if ((*in >= '0') && (*in <= '9'))
+ val = *(in++) - '0';
+ else
+ if ((*in >= 'a') && (*in <= 'f'))
+ val = *(in++) - 'a' + 10;
+ else
+ if ((*in >= 'A') && (*in <= 'F'))
+ val = *(in++) - 'A' + 10;
+ else
+ return NULL;
+
+ *out = val << 4;
+
+ while (*in == ' ' || *in == '\t')
+ in++;
+ if (!*in)
+ return NULL;
+
+ if ((*in >= '0') && (*in <= '9'))
+ val = *(in++) - '0';
+ else
+ if ((*in >= 'a') && (*in <= 'f'))
+ val = *(in++) - 'a' + 10;
+ else
+ if ((*in >= 'A') && (*in <= 'F'))
+ val = *(in++) - 'A' + 10;
+ else
+ return NULL;
+
+ *out++ |= val;
+ }
+
+ return out;
+}
diff --git a/contrib/opie/libopie/btoa8.c b/contrib/opie/libopie/btoa8.c
new file mode 100644
index 0000000..8696a74
--- /dev/null
+++ b/contrib/opie/libopie/btoa8.c
@@ -0,0 +1,32 @@
+/* btoa8.c: The opiebtoa8() library function.
+
+%%% copyright-cmetz
+This software is Copyright 1996 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Created by cmetz for OPIE 2.3 (quick re-write).
+*/
+
+#include "opie_cfg.h"
+#include "opie.h"
+
+static char hextochar[16] =
+{'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+
+char *opiebtoa8 FUNCTION((out, in), char *out AND char *in)
+{
+ int i;
+ char *c = out;
+
+ for (i = 0; i < 8; i++) {
+ *(c++) = hextochar[((*in) >> 4) & 0x0f];
+ *(c++) = hextochar[(*in++) & 0x0f];
+ }
+ *c = 0;
+
+ return out;
+}
diff --git a/contrib/opie/libopie/btoe.c b/contrib/opie/libopie/btoe.c
new file mode 100644
index 0000000..e402e69
--- /dev/null
+++ b/contrib/opie/libopie/btoe.c
@@ -0,0 +1,2266 @@
+/* btoe: The opiebtoe() and opieetob() library functions:
+ Conversion to/from the six-English-word representation of a
+ 64 bit OTP.
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+Portions of this software are Copyright 1995 by Randall Atkinson and Dan
+McDonald, All Rights Reserved. All Rights under this copyright are assigned
+to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
+License Agreement applies to this software.
+
+ History:
+
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
+ Remove unnecessary address futzing with Wp in opiebtoe.
+ Changed unsigned long to UINT4 for Alpha.
+ Modified at NRL for OPIE 2.2. Moved from put.c to libopie/opiebtoe.c.
+ Modified at NRL for OPIE 2.0.
+ Written at Bellcore for the S/Key Version 1 software distribution.
+*/
+#include "opie_cfg.h"
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include "opie.h"
+
+static UINT4 extract __P((char *s, int start, int length));
+static VOIDRET insert __P((char *s, int x, int start, int length));
+static int wsrch __P((char *w, int low, int high));
+
+/* Dictionary for integer-word translations */
+static char Wp[2048][4] =
+{
+ "A",
+ "ABE",
+ "ACE",
+ "ACT",
+ "AD",
+ "ADA",
+ "ADD",
+ "AGO",
+ "AID",
+ "AIM",
+ "AIR",
+ "ALL",
+ "ALP",
+ "AM",
+ "AMY",
+ "AN",
+ "ANA",
+ "AND",
+ "ANN",
+ "ANT",
+ "ANY",
+ "APE",
+ "APS",
+ "APT",
+ "ARC",
+ "ARE",
+ "ARK",
+ "ARM",
+ "ART",
+ "AS",
+ "ASH",
+ "ASK",
+ "AT",
+ "ATE",
+ "AUG",
+ "AUK",
+ "AVE",
+ "AWE",
+ "AWK",
+ "AWL",
+ "AWN",
+ "AX",
+ "AYE",
+ "BAD",
+ "BAG",
+ "BAH",
+ "BAM",
+ "BAN",
+ "BAR",
+ "BAT",
+ "BAY",
+ "BE",
+ "BED",
+ "BEE",
+ "BEG",
+ "BEN",
+ "BET",
+ "BEY",
+ "BIB",
+ "BID",
+ "BIG",
+ "BIN",
+ "BIT",
+ "BOB",
+ "BOG",
+ "BON",
+ "BOO",
+ "BOP",
+ "BOW",
+ "BOY",
+ "BUB",
+ "BUD",
+ "BUG",
+ "BUM",
+ "BUN",
+ "BUS",
+ "BUT",
+ "BUY",
+ "BY",
+ "BYE",
+ "CAB",
+ "CAL",
+ "CAM",
+ "CAN",
+ "CAP",
+ "CAR",
+ "CAT",
+ "CAW",
+ "COD",
+ "COG",
+ "COL",
+ "CON",
+ "COO",
+ "COP",
+ "COT",
+ "COW",
+ "COY",
+ "CRY",
+ "CUB",
+ "CUE",
+ "CUP",
+ "CUR",
+ "CUT",
+ "DAB",
+ "DAD",
+ "DAM",
+ "DAN",
+ "DAR",
+ "DAY",
+ "DEE",
+ "DEL",
+ "DEN",
+ "DES",
+ "DEW",
+ "DID",
+ "DIE",
+ "DIG",
+ "DIN",
+ "DIP",
+ "DO",
+ "DOE",
+ "DOG",
+ "DON",
+ "DOT",
+ "DOW",
+ "DRY",
+ "DUB",
+ "DUD",
+ "DUE",
+ "DUG",
+ "DUN",
+ "EAR",
+ "EAT",
+ "ED",
+ "EEL",
+ "EGG",
+ "EGO",
+ "ELI",
+ "ELK",
+ "ELM",
+ "ELY",
+ "EM",
+ "END",
+ "EST",
+ "ETC",
+ "EVA",
+ "EVE",
+ "EWE",
+ "EYE",
+ "FAD",
+ "FAN",
+ "FAR",
+ "FAT",
+ "FAY",
+ "FED",
+ "FEE",
+ "FEW",
+ "FIB",
+ "FIG",
+ "FIN",
+ "FIR",
+ "FIT",
+ "FLO",
+ "FLY",
+ "FOE",
+ "FOG",
+ "FOR",
+ "FRY",
+ "FUM",
+ "FUN",
+ "FUR",
+ "GAB",
+ "GAD",
+ "GAG",
+ "GAL",
+ "GAM",
+ "GAP",
+ "GAS",
+ "GAY",
+ "GEE",
+ "GEL",
+ "GEM",
+ "GET",
+ "GIG",
+ "GIL",
+ "GIN",
+ "GO",
+ "GOT",
+ "GUM",
+ "GUN",
+ "GUS",
+ "GUT",
+ "GUY",
+ "GYM",
+ "GYP",
+ "HA",
+ "HAD",
+ "HAL",
+ "HAM",
+ "HAN",
+ "HAP",
+ "HAS",
+ "HAT",
+ "HAW",
+ "HAY",
+ "HE",
+ "HEM",
+ "HEN",
+ "HER",
+ "HEW",
+ "HEY",
+ "HI",
+ "HID",
+ "HIM",
+ "HIP",
+ "HIS",
+ "HIT",
+ "HO",
+ "HOB",
+ "HOC",
+ "HOE",
+ "HOG",
+ "HOP",
+ "HOT",
+ "HOW",
+ "HUB",
+ "HUE",
+ "HUG",
+ "HUH",
+ "HUM",
+ "HUT",
+ "I",
+ "ICY",
+ "IDA",
+ "IF",
+ "IKE",
+ "ILL",
+ "INK",
+ "INN",
+ "IO",
+ "ION",
+ "IQ",
+ "IRA",
+ "IRE",
+ "IRK",
+ "IS",
+ "IT",
+ "ITS",
+ "IVY",
+ "JAB",
+ "JAG",
+ "JAM",
+ "JAN",
+ "JAR",
+ "JAW",
+ "JAY",
+ "JET",
+ "JIG",
+ "JIM",
+ "JO",
+ "JOB",
+ "JOE",
+ "JOG",
+ "JOT",
+ "JOY",
+ "JUG",
+ "JUT",
+ "KAY",
+ "KEG",
+ "KEN",
+ "KEY",
+ "KID",
+ "KIM",
+ "KIN",
+ "KIT",
+ "LA",
+ "LAB",
+ "LAC",
+ "LAD",
+ "LAG",
+ "LAM",
+ "LAP",
+ "LAW",
+ "LAY",
+ "LEA",
+ "LED",
+ "LEE",
+ "LEG",
+ "LEN",
+ "LEO",
+ "LET",
+ "LEW",
+ "LID",
+ "LIE",
+ "LIN",
+ "LIP",
+ "LIT",
+ "LO",
+ "LOB",
+ "LOG",
+ "LOP",
+ "LOS",
+ "LOT",
+ "LOU",
+ "LOW",
+ "LOY",
+ "LUG",
+ "LYE",
+ "MA",
+ "MAC",
+ "MAD",
+ "MAE",
+ "MAN",
+ "MAO",
+ "MAP",
+ "MAT",
+ "MAW",
+ "MAY",
+ "ME",
+ "MEG",
+ "MEL",
+ "MEN",
+ "MET",
+ "MEW",
+ "MID",
+ "MIN",
+ "MIT",
+ "MOB",
+ "MOD",
+ "MOE",
+ "MOO",
+ "MOP",
+ "MOS",
+ "MOT",
+ "MOW",
+ "MUD",
+ "MUG",
+ "MUM",
+ "MY",
+ "NAB",
+ "NAG",
+ "NAN",
+ "NAP",
+ "NAT",
+ "NAY",
+ "NE",
+ "NED",
+ "NEE",
+ "NET",
+ "NEW",
+ "NIB",
+ "NIL",
+ "NIP",
+ "NIT",
+ "NO",
+ "NOB",
+ "NOD",
+ "NON",
+ "NOR",
+ "NOT",
+ "NOV",
+ "NOW",
+ "NU",
+ "NUN",
+ "NUT",
+ "O",
+ "OAF",
+ "OAK",
+ "OAR",
+ "OAT",
+ "ODD",
+ "ODE",
+ "OF",
+ "OFF",
+ "OFT",
+ "OH",
+ "OIL",
+ "OK",
+ "OLD",
+ "ON",
+ "ONE",
+ "OR",
+ "ORB",
+ "ORE",
+ "ORR",
+ "OS",
+ "OTT",
+ "OUR",
+ "OUT",
+ "OVA",
+ "OW",
+ "OWE",
+ "OWL",
+ "OWN",
+ "OX",
+ "PA",
+ "PAD",
+ "PAL",
+ "PAM",
+ "PAN",
+ "PAP",
+ "PAR",
+ "PAT",
+ "PAW",
+ "PAY",
+ "PEA",
+ "PEG",
+ "PEN",
+ "PEP",
+ "PER",
+ "PET",
+ "PEW",
+ "PHI",
+ "PI",
+ "PIE",
+ "PIN",
+ "PIT",
+ "PLY",
+ "PO",
+ "POD",
+ "POE",
+ "POP",
+ "POT",
+ "POW",
+ "PRO",
+ "PRY",
+ "PUB",
+ "PUG",
+ "PUN",
+ "PUP",
+ "PUT",
+ "QUO",
+ "RAG",
+ "RAM",
+ "RAN",
+ "RAP",
+ "RAT",
+ "RAW",
+ "RAY",
+ "REB",
+ "RED",
+ "REP",
+ "RET",
+ "RIB",
+ "RID",
+ "RIG",
+ "RIM",
+ "RIO",
+ "RIP",
+ "ROB",
+ "ROD",
+ "ROE",
+ "RON",
+ "ROT",
+ "ROW",
+ "ROY",
+ "RUB",
+ "RUE",
+ "RUG",
+ "RUM",
+ "RUN",
+ "RYE",
+ "SAC",
+ "SAD",
+ "SAG",
+ "SAL",
+ "SAM",
+ "SAN",
+ "SAP",
+ "SAT",
+ "SAW",
+ "SAY",
+ "SEA",
+ "SEC",
+ "SEE",
+ "SEN",
+ "SET",
+ "SEW",
+ "SHE",
+ "SHY",
+ "SIN",
+ "SIP",
+ "SIR",
+ "SIS",
+ "SIT",
+ "SKI",
+ "SKY",
+ "SLY",
+ "SO",
+ "SOB",
+ "SOD",
+ "SON",
+ "SOP",
+ "SOW",
+ "SOY",
+ "SPA",
+ "SPY",
+ "SUB",
+ "SUD",
+ "SUE",
+ "SUM",
+ "SUN",
+ "SUP",
+ "TAB",
+ "TAD",
+ "TAG",
+ "TAN",
+ "TAP",
+ "TAR",
+ "TEA",
+ "TED",
+ "TEE",
+ "TEN",
+ "THE",
+ "THY",
+ "TIC",
+ "TIE",
+ "TIM",
+ "TIN",
+ "TIP",
+ "TO",
+ "TOE",
+ "TOG",
+ "TOM",
+ "TON",
+ "TOO",
+ "TOP",
+ "TOW",
+ "TOY",
+ "TRY",
+ "TUB",
+ "TUG",
+ "TUM",
+ "TUN",
+ "TWO",
+ "UN",
+ "UP",
+ "US",
+ "USE",
+ "VAN",
+ "VAT",
+ "VET",
+ "VIE",
+ "WAD",
+ "WAG",
+ "WAR",
+ "WAS",
+ "WAY",
+ "WE",
+ "WEB",
+ "WED",
+ "WEE",
+ "WET",
+ "WHO",
+ "WHY",
+ "WIN",
+ "WIT",
+ "WOK",
+ "WON",
+ "WOO",
+ "WOW",
+ "WRY",
+ "WU",
+ "YAM",
+ "YAP",
+ "YAW",
+ "YE",
+ "YEA",
+ "YES",
+ "YET",
+ "YOU",
+ "ABED",
+ "ABEL",
+ "ABET",
+ "ABLE",
+ "ABUT",
+ "ACHE",
+ "ACID",
+ "ACME",
+ "ACRE",
+ "ACTA",
+ "ACTS",
+ "ADAM",
+ "ADDS",
+ "ADEN",
+ "AFAR",
+ "AFRO",
+ "AGEE",
+ "AHEM",
+ "AHOY",
+ "AIDA",
+ "AIDE",
+ "AIDS",
+ "AIRY",
+ "AJAR",
+ "AKIN",
+ "ALAN",
+ "ALEC",
+ "ALGA",
+ "ALIA",
+ "ALLY",
+ "ALMA",
+ "ALOE",
+ "ALSO",
+ "ALTO",
+ "ALUM",
+ "ALVA",
+ "AMEN",
+ "AMES",
+ "AMID",
+ "AMMO",
+ "AMOK",
+ "AMOS",
+ "AMRA",
+ "ANDY",
+ "ANEW",
+ "ANNA",
+ "ANNE",
+ "ANTE",
+ "ANTI",
+ "AQUA",
+ "ARAB",
+ "ARCH",
+ "AREA",
+ "ARGO",
+ "ARID",
+ "ARMY",
+ "ARTS",
+ "ARTY",
+ "ASIA",
+ "ASKS",
+ "ATOM",
+ "AUNT",
+ "AURA",
+ "AUTO",
+ "AVER",
+ "AVID",
+ "AVIS",
+ "AVON",
+ "AVOW",
+ "AWAY",
+ "AWRY",
+ "BABE",
+ "BABY",
+ "BACH",
+ "BACK",
+ "BADE",
+ "BAIL",
+ "BAIT",
+ "BAKE",
+ "BALD",
+ "BALE",
+ "BALI",
+ "BALK",
+ "BALL",
+ "BALM",
+ "BAND",
+ "BANE",
+ "BANG",
+ "BANK",
+ "BARB",
+ "BARD",
+ "BARE",
+ "BARK",
+ "BARN",
+ "BARR",
+ "BASE",
+ "BASH",
+ "BASK",
+ "BASS",
+ "BATE",
+ "BATH",
+ "BAWD",
+ "BAWL",
+ "BEAD",
+ "BEAK",
+ "BEAM",
+ "BEAN",
+ "BEAR",
+ "BEAT",
+ "BEAU",
+ "BECK",
+ "BEEF",
+ "BEEN",
+ "BEER",
+ "BEET",
+ "BELA",
+ "BELL",
+ "BELT",
+ "BEND",
+ "BENT",
+ "BERG",
+ "BERN",
+ "BERT",
+ "BESS",
+ "BEST",
+ "BETA",
+ "BETH",
+ "BHOY",
+ "BIAS",
+ "BIDE",
+ "BIEN",
+ "BILE",
+ "BILK",
+ "BILL",
+ "BIND",
+ "BING",
+ "BIRD",
+ "BITE",
+ "BITS",
+ "BLAB",
+ "BLAT",
+ "BLED",
+ "BLEW",
+ "BLOB",
+ "BLOC",
+ "BLOT",
+ "BLOW",
+ "BLUE",
+ "BLUM",
+ "BLUR",
+ "BOAR",
+ "BOAT",
+ "BOCA",
+ "BOCK",
+ "BODE",
+ "BODY",
+ "BOGY",
+ "BOHR",
+ "BOIL",
+ "BOLD",
+ "BOLO",
+ "BOLT",
+ "BOMB",
+ "BONA",
+ "BOND",
+ "BONE",
+ "BONG",
+ "BONN",
+ "BONY",
+ "BOOK",
+ "BOOM",
+ "BOON",
+ "BOOT",
+ "BORE",
+ "BORG",
+ "BORN",
+ "BOSE",
+ "BOSS",
+ "BOTH",
+ "BOUT",
+ "BOWL",
+ "BOYD",
+ "BRAD",
+ "BRAE",
+ "BRAG",
+ "BRAN",
+ "BRAY",
+ "BRED",
+ "BREW",
+ "BRIG",
+ "BRIM",
+ "BROW",
+ "BUCK",
+ "BUDD",
+ "BUFF",
+ "BULB",
+ "BULK",
+ "BULL",
+ "BUNK",
+ "BUNT",
+ "BUOY",
+ "BURG",
+ "BURL",
+ "BURN",
+ "BURR",
+ "BURT",
+ "BURY",
+ "BUSH",
+ "BUSS",
+ "BUST",
+ "BUSY",
+ "BYTE",
+ "CADY",
+ "CAFE",
+ "CAGE",
+ "CAIN",
+ "CAKE",
+ "CALF",
+ "CALL",
+ "CALM",
+ "CAME",
+ "CANE",
+ "CANT",
+ "CARD",
+ "CARE",
+ "CARL",
+ "CARR",
+ "CART",
+ "CASE",
+ "CASH",
+ "CASK",
+ "CAST",
+ "CAVE",
+ "CEIL",
+ "CELL",
+ "CENT",
+ "CERN",
+ "CHAD",
+ "CHAR",
+ "CHAT",
+ "CHAW",
+ "CHEF",
+ "CHEN",
+ "CHEW",
+ "CHIC",
+ "CHIN",
+ "CHOU",
+ "CHOW",
+ "CHUB",
+ "CHUG",
+ "CHUM",
+ "CITE",
+ "CITY",
+ "CLAD",
+ "CLAM",
+ "CLAN",
+ "CLAW",
+ "CLAY",
+ "CLOD",
+ "CLOG",
+ "CLOT",
+ "CLUB",
+ "CLUE",
+ "COAL",
+ "COAT",
+ "COCA",
+ "COCK",
+ "COCO",
+ "CODA",
+ "CODE",
+ "CODY",
+ "COED",
+ "COIL",
+ "COIN",
+ "COKE",
+ "COLA",
+ "COLD",
+ "COLT",
+ "COMA",
+ "COMB",
+ "COME",
+ "COOK",
+ "COOL",
+ "COON",
+ "COOT",
+ "CORD",
+ "CORE",
+ "CORK",
+ "CORN",
+ "COST",
+ "COVE",
+ "COWL",
+ "CRAB",
+ "CRAG",
+ "CRAM",
+ "CRAY",
+ "CREW",
+ "CRIB",
+ "CROW",
+ "CRUD",
+ "CUBA",
+ "CUBE",
+ "CUFF",
+ "CULL",
+ "CULT",
+ "CUNY",
+ "CURB",
+ "CURD",
+ "CURE",
+ "CURL",
+ "CURT",
+ "CUTS",
+ "DADE",
+ "DALE",
+ "DAME",
+ "DANA",
+ "DANE",
+ "DANG",
+ "DANK",
+ "DARE",
+ "DARK",
+ "DARN",
+ "DART",
+ "DASH",
+ "DATA",
+ "DATE",
+ "DAVE",
+ "DAVY",
+ "DAWN",
+ "DAYS",
+ "DEAD",
+ "DEAF",
+ "DEAL",
+ "DEAN",
+ "DEAR",
+ "DEBT",
+ "DECK",
+ "DEED",
+ "DEEM",
+ "DEER",
+ "DEFT",
+ "DEFY",
+ "DELL",
+ "DENT",
+ "DENY",
+ "DESK",
+ "DIAL",
+ "DICE",
+ "DIED",
+ "DIET",
+ "DIME",
+ "DINE",
+ "DING",
+ "DINT",
+ "DIRE",
+ "DIRT",
+ "DISC",
+ "DISH",
+ "DISK",
+ "DIVE",
+ "DOCK",
+ "DOES",
+ "DOLE",
+ "DOLL",
+ "DOLT",
+ "DOME",
+ "DONE",
+ "DOOM",
+ "DOOR",
+ "DORA",
+ "DOSE",
+ "DOTE",
+ "DOUG",
+ "DOUR",
+ "DOVE",
+ "DOWN",
+ "DRAB",
+ "DRAG",
+ "DRAM",
+ "DRAW",
+ "DREW",
+ "DRUB",
+ "DRUG",
+ "DRUM",
+ "DUAL",
+ "DUCK",
+ "DUCT",
+ "DUEL",
+ "DUET",
+ "DUKE",
+ "DULL",
+ "DUMB",
+ "DUNE",
+ "DUNK",
+ "DUSK",
+ "DUST",
+ "DUTY",
+ "EACH",
+ "EARL",
+ "EARN",
+ "EASE",
+ "EAST",
+ "EASY",
+ "EBEN",
+ "ECHO",
+ "EDDY",
+ "EDEN",
+ "EDGE",
+ "EDGY",
+ "EDIT",
+ "EDNA",
+ "EGAN",
+ "ELAN",
+ "ELBA",
+ "ELLA",
+ "ELSE",
+ "EMIL",
+ "EMIT",
+ "EMMA",
+ "ENDS",
+ "ERIC",
+ "EROS",
+ "EVEN",
+ "EVER",
+ "EVIL",
+ "EYED",
+ "FACE",
+ "FACT",
+ "FADE",
+ "FAIL",
+ "FAIN",
+ "FAIR",
+ "FAKE",
+ "FALL",
+ "FAME",
+ "FANG",
+ "FARM",
+ "FAST",
+ "FATE",
+ "FAWN",
+ "FEAR",
+ "FEAT",
+ "FEED",
+ "FEEL",
+ "FEET",
+ "FELL",
+ "FELT",
+ "FEND",
+ "FERN",
+ "FEST",
+ "FEUD",
+ "FIEF",
+ "FIGS",
+ "FILE",
+ "FILL",
+ "FILM",
+ "FIND",
+ "FINE",
+ "FINK",
+ "FIRE",
+ "FIRM",
+ "FISH",
+ "FISK",
+ "FIST",
+ "FITS",
+ "FIVE",
+ "FLAG",
+ "FLAK",
+ "FLAM",
+ "FLAT",
+ "FLAW",
+ "FLEA",
+ "FLED",
+ "FLEW",
+ "FLIT",
+ "FLOC",
+ "FLOG",
+ "FLOW",
+ "FLUB",
+ "FLUE",
+ "FOAL",
+ "FOAM",
+ "FOGY",
+ "FOIL",
+ "FOLD",
+ "FOLK",
+ "FOND",
+ "FONT",
+ "FOOD",
+ "FOOL",
+ "FOOT",
+ "FORD",
+ "FORE",
+ "FORK",
+ "FORM",
+ "FORT",
+ "FOSS",
+ "FOUL",
+ "FOUR",
+ "FOWL",
+ "FRAU",
+ "FRAY",
+ "FRED",
+ "FREE",
+ "FRET",
+ "FREY",
+ "FROG",
+ "FROM",
+ "FUEL",
+ "FULL",
+ "FUME",
+ "FUND",
+ "FUNK",
+ "FURY",
+ "FUSE",
+ "FUSS",
+ "GAFF",
+ "GAGE",
+ "GAIL",
+ "GAIN",
+ "GAIT",
+ "GALA",
+ "GALE",
+ "GALL",
+ "GALT",
+ "GAME",
+ "GANG",
+ "GARB",
+ "GARY",
+ "GASH",
+ "GATE",
+ "GAUL",
+ "GAUR",
+ "GAVE",
+ "GAWK",
+ "GEAR",
+ "GELD",
+ "GENE",
+ "GENT",
+ "GERM",
+ "GETS",
+ "GIBE",
+ "GIFT",
+ "GILD",
+ "GILL",
+ "GILT",
+ "GINA",
+ "GIRD",
+ "GIRL",
+ "GIST",
+ "GIVE",
+ "GLAD",
+ "GLEE",
+ "GLEN",
+ "GLIB",
+ "GLOB",
+ "GLOM",
+ "GLOW",
+ "GLUE",
+ "GLUM",
+ "GLUT",
+ "GOAD",
+ "GOAL",
+ "GOAT",
+ "GOER",
+ "GOES",
+ "GOLD",
+ "GOLF",
+ "GONE",
+ "GONG",
+ "GOOD",
+ "GOOF",
+ "GORE",
+ "GORY",
+ "GOSH",
+ "GOUT",
+ "GOWN",
+ "GRAB",
+ "GRAD",
+ "GRAY",
+ "GREG",
+ "GREW",
+ "GREY",
+ "GRID",
+ "GRIM",
+ "GRIN",
+ "GRIT",
+ "GROW",
+ "GRUB",
+ "GULF",
+ "GULL",
+ "GUNK",
+ "GURU",
+ "GUSH",
+ "GUST",
+ "GWEN",
+ "GWYN",
+ "HAAG",
+ "HAAS",
+ "HACK",
+ "HAIL",
+ "HAIR",
+ "HALE",
+ "HALF",
+ "HALL",
+ "HALO",
+ "HALT",
+ "HAND",
+ "HANG",
+ "HANK",
+ "HANS",
+ "HARD",
+ "HARK",
+ "HARM",
+ "HART",
+ "HASH",
+ "HAST",
+ "HATE",
+ "HATH",
+ "HAUL",
+ "HAVE",
+ "HAWK",
+ "HAYS",
+ "HEAD",
+ "HEAL",
+ "HEAR",
+ "HEAT",
+ "HEBE",
+ "HECK",
+ "HEED",
+ "HEEL",
+ "HEFT",
+ "HELD",
+ "HELL",
+ "HELM",
+ "HERB",
+ "HERD",
+ "HERE",
+ "HERO",
+ "HERS",
+ "HESS",
+ "HEWN",
+ "HICK",
+ "HIDE",
+ "HIGH",
+ "HIKE",
+ "HILL",
+ "HILT",
+ "HIND",
+ "HINT",
+ "HIRE",
+ "HISS",
+ "HIVE",
+ "HOBO",
+ "HOCK",
+ "HOFF",
+ "HOLD",
+ "HOLE",
+ "HOLM",
+ "HOLT",
+ "HOME",
+ "HONE",
+ "HONK",
+ "HOOD",
+ "HOOF",
+ "HOOK",
+ "HOOT",
+ "HORN",
+ "HOSE",
+ "HOST",
+ "HOUR",
+ "HOVE",
+ "HOWE",
+ "HOWL",
+ "HOYT",
+ "HUCK",
+ "HUED",
+ "HUFF",
+ "HUGE",
+ "HUGH",
+ "HUGO",
+ "HULK",
+ "HULL",
+ "HUNK",
+ "HUNT",
+ "HURD",
+ "HURL",
+ "HURT",
+ "HUSH",
+ "HYDE",
+ "HYMN",
+ "IBIS",
+ "ICON",
+ "IDEA",
+ "IDLE",
+ "IFFY",
+ "INCA",
+ "INCH",
+ "INTO",
+ "IONS",
+ "IOTA",
+ "IOWA",
+ "IRIS",
+ "IRMA",
+ "IRON",
+ "ISLE",
+ "ITCH",
+ "ITEM",
+ "IVAN",
+ "JACK",
+ "JADE",
+ "JAIL",
+ "JAKE",
+ "JANE",
+ "JAVA",
+ "JEAN",
+ "JEFF",
+ "JERK",
+ "JESS",
+ "JEST",
+ "JIBE",
+ "JILL",
+ "JILT",
+ "JIVE",
+ "JOAN",
+ "JOBS",
+ "JOCK",
+ "JOEL",
+ "JOEY",
+ "JOHN",
+ "JOIN",
+ "JOKE",
+ "JOLT",
+ "JOVE",
+ "JUDD",
+ "JUDE",
+ "JUDO",
+ "JUDY",
+ "JUJU",
+ "JUKE",
+ "JULY",
+ "JUNE",
+ "JUNK",
+ "JUNO",
+ "JURY",
+ "JUST",
+ "JUTE",
+ "KAHN",
+ "KALE",
+ "KANE",
+ "KANT",
+ "KARL",
+ "KATE",
+ "KEEL",
+ "KEEN",
+ "KENO",
+ "KENT",
+ "KERN",
+ "KERR",
+ "KEYS",
+ "KICK",
+ "KILL",
+ "KIND",
+ "KING",
+ "KIRK",
+ "KISS",
+ "KITE",
+ "KLAN",
+ "KNEE",
+ "KNEW",
+ "KNIT",
+ "KNOB",
+ "KNOT",
+ "KNOW",
+ "KOCH",
+ "KONG",
+ "KUDO",
+ "KURD",
+ "KURT",
+ "KYLE",
+ "LACE",
+ "LACK",
+ "LACY",
+ "LADY",
+ "LAID",
+ "LAIN",
+ "LAIR",
+ "LAKE",
+ "LAMB",
+ "LAME",
+ "LAND",
+ "LANE",
+ "LANG",
+ "LARD",
+ "LARK",
+ "LASS",
+ "LAST",
+ "LATE",
+ "LAUD",
+ "LAVA",
+ "LAWN",
+ "LAWS",
+ "LAYS",
+ "LEAD",
+ "LEAF",
+ "LEAK",
+ "LEAN",
+ "LEAR",
+ "LEEK",
+ "LEER",
+ "LEFT",
+ "LEND",
+ "LENS",
+ "LENT",
+ "LEON",
+ "LESK",
+ "LESS",
+ "LEST",
+ "LETS",
+ "LIAR",
+ "LICE",
+ "LICK",
+ "LIED",
+ "LIEN",
+ "LIES",
+ "LIEU",
+ "LIFE",
+ "LIFT",
+ "LIKE",
+ "LILA",
+ "LILT",
+ "LILY",
+ "LIMA",
+ "LIMB",
+ "LIME",
+ "LIND",
+ "LINE",
+ "LINK",
+ "LINT",
+ "LION",
+ "LISA",
+ "LIST",
+ "LIVE",
+ "LOAD",
+ "LOAF",
+ "LOAM",
+ "LOAN",
+ "LOCK",
+ "LOFT",
+ "LOGE",
+ "LOIS",
+ "LOLA",
+ "LONE",
+ "LONG",
+ "LOOK",
+ "LOON",
+ "LOOT",
+ "LORD",
+ "LORE",
+ "LOSE",
+ "LOSS",
+ "LOST",
+ "LOUD",
+ "LOVE",
+ "LOWE",
+ "LUCK",
+ "LUCY",
+ "LUGE",
+ "LUKE",
+ "LULU",
+ "LUND",
+ "LUNG",
+ "LURA",
+ "LURE",
+ "LURK",
+ "LUSH",
+ "LUST",
+ "LYLE",
+ "LYNN",
+ "LYON",
+ "LYRA",
+ "MACE",
+ "MADE",
+ "MAGI",
+ "MAID",
+ "MAIL",
+ "MAIN",
+ "MAKE",
+ "MALE",
+ "MALI",
+ "MALL",
+ "MALT",
+ "MANA",
+ "MANN",
+ "MANY",
+ "MARC",
+ "MARE",
+ "MARK",
+ "MARS",
+ "MART",
+ "MARY",
+ "MASH",
+ "MASK",
+ "MASS",
+ "MAST",
+ "MATE",
+ "MATH",
+ "MAUL",
+ "MAYO",
+ "MEAD",
+ "MEAL",
+ "MEAN",
+ "MEAT",
+ "MEEK",
+ "MEET",
+ "MELD",
+ "MELT",
+ "MEMO",
+ "MEND",
+ "MENU",
+ "MERT",
+ "MESH",
+ "MESS",
+ "MICE",
+ "MIKE",
+ "MILD",
+ "MILE",
+ "MILK",
+ "MILL",
+ "MILT",
+ "MIMI",
+ "MIND",
+ "MINE",
+ "MINI",
+ "MINK",
+ "MINT",
+ "MIRE",
+ "MISS",
+ "MIST",
+ "MITE",
+ "MITT",
+ "MOAN",
+ "MOAT",
+ "MOCK",
+ "MODE",
+ "MOLD",
+ "MOLE",
+ "MOLL",
+ "MOLT",
+ "MONA",
+ "MONK",
+ "MONT",
+ "MOOD",
+ "MOON",
+ "MOOR",
+ "MOOT",
+ "MORE",
+ "MORN",
+ "MORT",
+ "MOSS",
+ "MOST",
+ "MOTH",
+ "MOVE",
+ "MUCH",
+ "MUCK",
+ "MUDD",
+ "MUFF",
+ "MULE",
+ "MULL",
+ "MURK",
+ "MUSH",
+ "MUST",
+ "MUTE",
+ "MUTT",
+ "MYRA",
+ "MYTH",
+ "NAGY",
+ "NAIL",
+ "NAIR",
+ "NAME",
+ "NARY",
+ "NASH",
+ "NAVE",
+ "NAVY",
+ "NEAL",
+ "NEAR",
+ "NEAT",
+ "NECK",
+ "NEED",
+ "NEIL",
+ "NELL",
+ "NEON",
+ "NERO",
+ "NESS",
+ "NEST",
+ "NEWS",
+ "NEWT",
+ "NIBS",
+ "NICE",
+ "NICK",
+ "NILE",
+ "NINA",
+ "NINE",
+ "NOAH",
+ "NODE",
+ "NOEL",
+ "NOLL",
+ "NONE",
+ "NOOK",
+ "NOON",
+ "NORM",
+ "NOSE",
+ "NOTE",
+ "NOUN",
+ "NOVA",
+ "NUDE",
+ "NULL",
+ "NUMB",
+ "OATH",
+ "OBEY",
+ "OBOE",
+ "ODIN",
+ "OHIO",
+ "OILY",
+ "OINT",
+ "OKAY",
+ "OLAF",
+ "OLDY",
+ "OLGA",
+ "OLIN",
+ "OMAN",
+ "OMEN",
+ "OMIT",
+ "ONCE",
+ "ONES",
+ "ONLY",
+ "ONTO",
+ "ONUS",
+ "ORAL",
+ "ORGY",
+ "OSLO",
+ "OTIS",
+ "OTTO",
+ "OUCH",
+ "OUST",
+ "OUTS",
+ "OVAL",
+ "OVEN",
+ "OVER",
+ "OWLY",
+ "OWNS",
+ "QUAD",
+ "QUIT",
+ "QUOD",
+ "RACE",
+ "RACK",
+ "RACY",
+ "RAFT",
+ "RAGE",
+ "RAID",
+ "RAIL",
+ "RAIN",
+ "RAKE",
+ "RANK",
+ "RANT",
+ "RARE",
+ "RASH",
+ "RATE",
+ "RAVE",
+ "RAYS",
+ "READ",
+ "REAL",
+ "REAM",
+ "REAR",
+ "RECK",
+ "REED",
+ "REEF",
+ "REEK",
+ "REEL",
+ "REID",
+ "REIN",
+ "RENA",
+ "REND",
+ "RENT",
+ "REST",
+ "RICE",
+ "RICH",
+ "RICK",
+ "RIDE",
+ "RIFT",
+ "RILL",
+ "RIME",
+ "RING",
+ "RINK",
+ "RISE",
+ "RISK",
+ "RITE",
+ "ROAD",
+ "ROAM",
+ "ROAR",
+ "ROBE",
+ "ROCK",
+ "RODE",
+ "ROIL",
+ "ROLL",
+ "ROME",
+ "ROOD",
+ "ROOF",
+ "ROOK",
+ "ROOM",
+ "ROOT",
+ "ROSA",
+ "ROSE",
+ "ROSS",
+ "ROSY",
+ "ROTH",
+ "ROUT",
+ "ROVE",
+ "ROWE",
+ "ROWS",
+ "RUBE",
+ "RUBY",
+ "RUDE",
+ "RUDY",
+ "RUIN",
+ "RULE",
+ "RUNG",
+ "RUNS",
+ "RUNT",
+ "RUSE",
+ "RUSH",
+ "RUSK",
+ "RUSS",
+ "RUST",
+ "RUTH",
+ "SACK",
+ "SAFE",
+ "SAGE",
+ "SAID",
+ "SAIL",
+ "SALE",
+ "SALK",
+ "SALT",
+ "SAME",
+ "SAND",
+ "SANE",
+ "SANG",
+ "SANK",
+ "SARA",
+ "SAUL",
+ "SAVE",
+ "SAYS",
+ "SCAN",
+ "SCAR",
+ "SCAT",
+ "SCOT",
+ "SEAL",
+ "SEAM",
+ "SEAR",
+ "SEAT",
+ "SEED",
+ "SEEK",
+ "SEEM",
+ "SEEN",
+ "SEES",
+ "SELF",
+ "SELL",
+ "SEND",
+ "SENT",
+ "SETS",
+ "SEWN",
+ "SHAG",
+ "SHAM",
+ "SHAW",
+ "SHAY",
+ "SHED",
+ "SHIM",
+ "SHIN",
+ "SHOD",
+ "SHOE",
+ "SHOT",
+ "SHOW",
+ "SHUN",
+ "SHUT",
+ "SICK",
+ "SIDE",
+ "SIFT",
+ "SIGH",
+ "SIGN",
+ "SILK",
+ "SILL",
+ "SILO",
+ "SILT",
+ "SINE",
+ "SING",
+ "SINK",
+ "SIRE",
+ "SITE",
+ "SITS",
+ "SITU",
+ "SKAT",
+ "SKEW",
+ "SKID",
+ "SKIM",
+ "SKIN",
+ "SKIT",
+ "SLAB",
+ "SLAM",
+ "SLAT",
+ "SLAY",
+ "SLED",
+ "SLEW",
+ "SLID",
+ "SLIM",
+ "SLIT",
+ "SLOB",
+ "SLOG",
+ "SLOT",
+ "SLOW",
+ "SLUG",
+ "SLUM",
+ "SLUR",
+ "SMOG",
+ "SMUG",
+ "SNAG",
+ "SNOB",
+ "SNOW",
+ "SNUB",
+ "SNUG",
+ "SOAK",
+ "SOAR",
+ "SOCK",
+ "SODA",
+ "SOFA",
+ "SOFT",
+ "SOIL",
+ "SOLD",
+ "SOME",
+ "SONG",
+ "SOON",
+ "SOOT",
+ "SORE",
+ "SORT",
+ "SOUL",
+ "SOUR",
+ "SOWN",
+ "STAB",
+ "STAG",
+ "STAN",
+ "STAR",
+ "STAY",
+ "STEM",
+ "STEW",
+ "STIR",
+ "STOW",
+ "STUB",
+ "STUN",
+ "SUCH",
+ "SUDS",
+ "SUIT",
+ "SULK",
+ "SUMS",
+ "SUNG",
+ "SUNK",
+ "SURE",
+ "SURF",
+ "SWAB",
+ "SWAG",
+ "SWAM",
+ "SWAN",
+ "SWAT",
+ "SWAY",
+ "SWIM",
+ "SWUM",
+ "TACK",
+ "TACT",
+ "TAIL",
+ "TAKE",
+ "TALE",
+ "TALK",
+ "TALL",
+ "TANK",
+ "TASK",
+ "TATE",
+ "TAUT",
+ "TEAL",
+ "TEAM",
+ "TEAR",
+ "TECH",
+ "TEEM",
+ "TEEN",
+ "TEET",
+ "TELL",
+ "TEND",
+ "TENT",
+ "TERM",
+ "TERN",
+ "TESS",
+ "TEST",
+ "THAN",
+ "THAT",
+ "THEE",
+ "THEM",
+ "THEN",
+ "THEY",
+ "THIN",
+ "THIS",
+ "THUD",
+ "THUG",
+ "TICK",
+ "TIDE",
+ "TIDY",
+ "TIED",
+ "TIER",
+ "TILE",
+ "TILL",
+ "TILT",
+ "TIME",
+ "TINA",
+ "TINE",
+ "TINT",
+ "TINY",
+ "TIRE",
+ "TOAD",
+ "TOGO",
+ "TOIL",
+ "TOLD",
+ "TOLL",
+ "TONE",
+ "TONG",
+ "TONY",
+ "TOOK",
+ "TOOL",
+ "TOOT",
+ "TORE",
+ "TORN",
+ "TOTE",
+ "TOUR",
+ "TOUT",
+ "TOWN",
+ "TRAG",
+ "TRAM",
+ "TRAY",
+ "TREE",
+ "TREK",
+ "TRIG",
+ "TRIM",
+ "TRIO",
+ "TROD",
+ "TROT",
+ "TROY",
+ "TRUE",
+ "TUBA",
+ "TUBE",
+ "TUCK",
+ "TUFT",
+ "TUNA",
+ "TUNE",
+ "TUNG",
+ "TURF",
+ "TURN",
+ "TUSK",
+ "TWIG",
+ "TWIN",
+ "TWIT",
+ "ULAN",
+ "UNIT",
+ "URGE",
+ "USED",
+ "USER",
+ "USES",
+ "UTAH",
+ "VAIL",
+ "VAIN",
+ "VALE",
+ "VARY",
+ "VASE",
+ "VAST",
+ "VEAL",
+ "VEDA",
+ "VEIL",
+ "VEIN",
+ "VEND",
+ "VENT",
+ "VERB",
+ "VERY",
+ "VETO",
+ "VICE",
+ "VIEW",
+ "VINE",
+ "VISE",
+ "VOID",
+ "VOLT",
+ "VOTE",
+ "WACK",
+ "WADE",
+ "WAGE",
+ "WAIL",
+ "WAIT",
+ "WAKE",
+ "WALE",
+ "WALK",
+ "WALL",
+ "WALT",
+ "WAND",
+ "WANE",
+ "WANG",
+ "WANT",
+ "WARD",
+ "WARM",
+ "WARN",
+ "WART",
+ "WASH",
+ "WAST",
+ "WATS",
+ "WATT",
+ "WAVE",
+ "WAVY",
+ "WAYS",
+ "WEAK",
+ "WEAL",
+ "WEAN",
+ "WEAR",
+ "WEED",
+ "WEEK",
+ "WEIR",
+ "WELD",
+ "WELL",
+ "WELT",
+ "WENT",
+ "WERE",
+ "WERT",
+ "WEST",
+ "WHAM",
+ "WHAT",
+ "WHEE",
+ "WHEN",
+ "WHET",
+ "WHOA",
+ "WHOM",
+ "WICK",
+ "WIFE",
+ "WILD",
+ "WILL",
+ "WIND",
+ "WINE",
+ "WING",
+ "WINK",
+ "WINO",
+ "WIRE",
+ "WISE",
+ "WISH",
+ "WITH",
+ "WOLF",
+ "WONT",
+ "WOOD",
+ "WOOL",
+ "WORD",
+ "WORE",
+ "WORK",
+ "WORM",
+ "WORN",
+ "WOVE",
+ "WRIT",
+ "WYNN",
+ "YALE",
+ "YANG",
+ "YANK",
+ "YARD",
+ "YARN",
+ "YAWL",
+ "YAWN",
+ "YEAH",
+ "YEAR",
+ "YELL",
+ "YOGA",
+ "YOKE"
+};
+
+/* Encode 8 bytes in 'c' as a string of English words. */
+char *opiebtoe FUNCTION((engout, c), char *engout AND char *c)
+{
+ char cp[9]; /* add in room for the parity 2 bits */
+ int p, i;
+
+ engout[0] = '\0';
+ memcpy(cp, c, 8);
+ /* compute parity */
+ for (p = 0, i = 0; i < 64; i += 2)
+ p += extract(cp, i, 2);
+
+ cp[8] = (char)(p << 6);
+ strncat(engout, Wp[extract(cp, 0, 11)], 4);
+ strcat(engout, " ");
+ strncat(engout, Wp[extract(cp, 11, 11)], 4);
+ strcat(engout, " ");
+ strncat(engout, Wp[extract(cp, 22, 11)], 4);
+ strcat(engout, " ");
+ strncat(engout, Wp[extract(cp, 33, 11)], 4);
+ strcat(engout, " ");
+ strncat(engout, Wp[extract(cp, 44, 11)], 4);
+ strcat(engout, " ");
+ strncat(engout, Wp[extract(cp, 55, 11)], 4);
+ return (engout);
+}
+
+/* convert English to binary
+ * returns 1 OK - all good words and parity is OK
+ * 0 word not in data base
+ * -1 badly formed in put ie > 4 char word
+ * -2 words OK but parity is wrong
+ */
+int opieetob FUNCTION((out, e), char *out AND char *e)
+{
+ char *word, *c, *input, b[9];
+ int i, p, v, l, low, high, rval = -1;
+
+ if (e == NULL)
+ return -1;
+
+ if ((i = strlen(e)) > 64)
+ i = 64;
+
+ if (!(input = malloc(i+1)))
+ return -1;
+
+ strncpy(input, e, i);
+ input[i] = 0;
+ memset(b, 0, sizeof(b));
+ memset(out, 0, 8);
+
+ for (i = 0, p = 0, word = c = input; i < 6; i++, p += 11) {
+ while (*c && !isalpha(*c)) c++;
+ word = c;
+ while (*c) {
+ if (islower(*c))
+ *c = toupper(*c);
+ if (*c == '1')
+ *c = 'L';
+ if (*c == '0')
+ *c = 'O';
+ if (*c == '5')
+ *c = 'S';
+ if (!isalpha(*c))
+ break;
+ c++;
+ }
+ if ((!*c) && (i != 5))
+ goto opiebtoeret;
+ *c = 0;
+ c++;
+ if (c == word)
+ goto opiebtoeret;
+ l = strlen(word);
+ if (l > 4 || l < 1)
+ goto opiebtoeret;
+ if (l < 4) {
+ low = 0;
+ high = 570;
+ } else {
+ low = 571;
+ high = 2047;
+ }
+ if ((v = wsrch(word, low, high)) < 0) {
+ rval = 0;
+ goto opiebtoeret;
+ }
+ insert(b, v, p, 11);
+ }
+
+ /* now check the parity of what we got */
+ for (p = 0, i = 0; i < 64; i += 2)
+ p += extract(b, i, 2);
+
+ if ((p & 3) != extract(b, 64, 2)) {
+ rval = -2;
+ goto opiebtoeret;
+ }
+
+ memcpy(out, b, 8);
+
+ rval = 1;
+
+opiebtoeret:
+ free(input);
+ return rval;
+}
+
+/* Internal subroutines for word encoding/decoding */
+
+/* Dictionary binary search */
+static int wsrch FUNCTION((w, low, high), char *w AND int low AND int high)
+{
+ int i, j;
+
+ for (;;) {
+ i = (low + high) / 2;
+ if ((j = strncmp(w, Wp[i], 4)) == 0)
+ return i; /* Found it */
+ if (high == low + 1) {
+ /* Avoid effects of integer truncation in /2 */
+ if (strncmp(w, Wp[high], 4) == 0)
+ return high;
+ else
+ return -1;
+ }
+ if (low >= high)
+ return -1; /* I don't *think* this can happen... */
+ if (j < 0)
+ high = i; /* Search lower half */
+ else
+ low = i; /* Search upper half */
+ }
+}
+
+static VOIDRET insert FUNCTION((s, x, start, length), char *s AND int x AND int start AND int length)
+{
+ unsigned char cl;
+ unsigned char cc;
+ unsigned char cr;
+ UINT4 y;
+ int shift;
+
+ shift = ((8 - ((start + length) % 8)) % 8);
+ y = (long) x << shift;
+ cl = (y >> 16) & 0xff;
+ cc = (y >> 8) & 0xff;
+ cr = y & 0xff;
+ if (shift + length > 16) {
+ s[start / 8] |= cl;
+ s[start / 8 + 1] |= cc;
+ s[start / 8 + 2] |= cr;
+ } else
+ if (shift + length > 8) {
+ s[start / 8] |= cc;
+ s[start / 8 + 1] |= cr;
+ } else {
+ s[start / 8] |= cr;
+ }
+}
+
+static UINT4 extract FUNCTION((s, start, length), char *s AND int start AND int length)
+{
+ UINT4 x;
+ unsigned char cl;
+ unsigned char cc;
+ unsigned char cr;
+
+ cl = s[start / 8];
+ cc = s[start / 8 + 1];
+ cr = s[start / 8 + 2];
+ x = ((UINT4) (cl << 8 | cc) << 8 | cr);
+ x = x >> (24 - (length + (start % 8)));
+ x = (x & (0xffff >> (16 - length)));
+ return (x);
+}
diff --git a/contrib/opie/libopie/btoh.c b/contrib/opie/libopie/btoh.c
new file mode 100644
index 0000000..68cf75f
--- /dev/null
+++ b/contrib/opie/libopie/btoh.c
@@ -0,0 +1,35 @@
+/* btoh.c: The opiebtoh() library function.
+
+%%% copyright-cmetz
+This software is Copyright 1996 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Created by cmetz for OPIE 2.3.
+*/
+
+#include "opie_cfg.h"
+#include "opie.h"
+
+static char hextochar[16] =
+{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
+
+char *opiebtoh FUNCTION((out, in), char *out AND char *in)
+{
+ int i;
+ char *c = out;
+
+ for (i = 0; i < 4; i++) {
+ *(c++) = hextochar[((*in) >> 4) & 0x0f];
+ *(c++) = hextochar[(*in++) & 0x0f];
+ *(c++) = hextochar[((*in) >> 4) & 0x0f];
+ *(c++) = hextochar[(*in++) & 0x0f];
+ *(c++) = ' ';
+ }
+ *(--c) = 0;
+
+ return out;
+}
diff --git a/contrib/opie/libopie/challenge.c b/contrib/opie/libopie/challenge.c
new file mode 100644
index 0000000..d67d495
--- /dev/null
+++ b/contrib/opie/libopie/challenge.c
@@ -0,0 +1,74 @@
+/* challenge.c: The opiechallenge() library function.
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+Portions of this software are Copyright 1995 by Randall Atkinson and Dan
+McDonald, All Rights Reserved. All Rights under this copyright are assigned
+to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
+License Agreement applies to this software.
+
+ History:
+
+ Modified by cmetz for OPIE 2.3. Use opie_ prefix. Send debug info to
+ syslog. Add sha plumbing.
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
+ Created at NRL for OPIE 2.2 from opiesubr2.c
+*/
+#include "opie_cfg.h"
+#include <stdio.h>
+#include <string.h>
+#if DEBUG
+#include <syslog.h>
+#endif /* DEBUG */
+#include "opie.h"
+
+/* Return an OTP challenge string for user 'name'.
+
+ The return values are:
+
+ 0 = All good
+ -1 = Low-level error (file, memory, I/O, etc.)
+ 1 = High-level error (user not found or locked)
+
+ This function MUST eventually be followed by an opieverify() to release
+ the user lock and file handles.
+
+ This function will give you a blanked-out state block if it returns a
+ nonzero status. Even though it returns a non-zero status and a blank
+ state block, you still MUST call opieverify() to clear the lock and
+ any internal state (the latter condition is not actually used yet).
+*/
+
+static char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" };
+
+int opiechallenge FUNCTION((mp, name, ss), struct opie *mp AND char *name AND char *ss)
+{
+ int rval = -1;
+
+ memset(mp, 0, sizeof(*mp));
+
+ rval = opielookup(mp, name);
+#if DEBUG
+ if (rval) syslog(LOG_DEBUG, "opiechallenge: opielookup(mp, name=%s) returned %d", name, rval);
+#endif /* DEBUG */
+
+ if (!rval) {
+ rval = opielock(name);
+#if DEBUG
+ if (rval) syslog(LOG_DEBUG, "opiechallenge: opielock(name=%s) returned %d", name, rval);
+#endif /* DEBUG */
+ }
+
+ if (rval) {
+ opierandomchallenge(ss);
+ memset(mp, 0, sizeof(*mp));
+ } else
+ sprintf(ss, "otp-%s %d %s", algids[MDX], mp->opie_n - 1, mp->opie_seed);
+
+ return rval;
+}
diff --git a/contrib/opie/libopie/generator.c b/contrib/opie/libopie/generator.c
new file mode 100644
index 0000000..ccd67c7
--- /dev/null
+++ b/contrib/opie/libopie/generator.c
@@ -0,0 +1,110 @@
+/* generator.c: The opiegenerator() library function.
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Modified by cmetz for OPIE 2.3. Use _opieparsechallenge(). ifdef
+ around string.h. Output hex responses by default, output
+ OTP re-init extended responses (same secret) if sequence
+ number falls below 10.
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
+ Bug fixes.
+ Created at NRL for OPIE 2.2.
+*/
+
+#include "opie_cfg.h"
+#if HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#include "opie.h"
+
+static char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" };
+
+int opiegenerator FUNCTION((buffer, secret, response), char *buffer AND char *secret AND char *response)
+{
+ int algorithm;
+ int sequence;
+ char *seed;
+ char key[8];
+ int i;
+
+ if (!(buffer = strstr(buffer, "otp-")))
+ return 1;
+
+ buffer += 4;
+
+ if (_opieparsechallenge(buffer, &algorithm, &sequence, &seed))
+ return 1;
+
+ if ((sequence < 2) || (sequence > 9999))
+ return 1;
+
+ if (opiepasscheck(secret))
+ return -2;
+
+ if (i = opiekeycrunch(algorithm, key, seed, secret))
+ return i;
+
+ if (sequence < 10) {
+ char newseed[OPIE_SEED_MAX + 1];
+ char newkey[8], cko[8], ckn[8], ckxor[8], cv[8];
+ char *c;
+ char buf[OPIE_SEED_MAX + 48 + 1];
+
+ if (opienewseed(strcpy(newseed, seed)) < 0)
+ return -1;
+
+ if (opiekeycrunch(algorithm, newkey, newseed, secret))
+ return -1;
+
+ for (i = 0; i < 499; i++)
+ opiehash(newkey, algorithm);
+
+ if (opiekeycrunch(algorithm | 0x10, cko, seed, secret))
+ return -1;
+
+ if (opiekeycrunch(algorithm | 0x10, ckn, newseed, secret))
+ return -1;
+
+ for (i = 0; i < 8; i++)
+ ckxor[i] = cko[i] ^ ckn[i];
+
+ strcpy(response, "init:");
+ strcat(response, opiebtoh(buf, key));
+ sprintf(buf, ":%s 499 %s:", algids[algorithm], newseed);
+ strcat(response, buf);
+ strcat(response, opiebtoh(buf, newkey));
+ strcat(response, ":");
+ strcat(response, opiebtoh(buf, ckxor));
+ strcat(response, ":");
+
+ c = buf;
+ memcpy(c, ckn, sizeof(ckn)); c += sizeof(ckn);
+ memcpy(c, key, sizeof(key)); c += sizeof(key);
+#ifdef HAVE_ANSISPRINTF
+ c += sprintf(c, "%s 499 %s", algids[algorithm], newseed);
+#else /* HAVE_ANSISPRINTF */
+ sprintf(c, "%s 499 %s", algids[algorithm], newseed);
+ while(*c) c++;
+#endif /* HAVE_ANSISPRINTF */
+ memcpy(c, newkey, sizeof(newkey)); c += sizeof(newkey);
+ memcpy(c, ckxor, sizeof(ckxor)); c += sizeof(ckxor);
+ memcpy(c, ckn, sizeof(ckn)); c += sizeof(ckn);
+ opiehashlen(algorithm, buf, cv, (unsigned int)c - (unsigned int)buf);
+
+ strcat(response, opiebtoh(buf, cv));
+ } else {
+ while (sequence-- != 0)
+ opiehash(key, algorithm);
+
+ opiebtoh(response, key);
+ }
+
+ return 0;
+}
diff --git a/contrib/opie/libopie/getsequence.c b/contrib/opie/libopie/getsequence.c
new file mode 100644
index 0000000..f0a6e78
--- /dev/null
+++ b/contrib/opie/libopie/getsequence.c
@@ -0,0 +1,27 @@
+/* getsequence.c: The opiegetsequence() library function.
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+Portions of this software are Copyright 1995 by Randall Atkinson and Dan
+McDonald, All Rights Reserved. All Rights under this copyright are assigned
+to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
+License Agreement applies to this software.
+
+ History:
+
+ Modified by cmetz for OPIE 2.3. Use opie_ prefix.
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
+ Created at NRL for OPIE 2.2 from opiesubr2.c
+*/
+#include "opie_cfg.h"
+#include "opie.h"
+
+int opiegetsequence FUNCTION((stateblock), struct opie *stateblock)
+{
+ return stateblock->opie_n;
+}
diff --git a/contrib/opie/libopie/getutmpentry.c b/contrib/opie/libopie/getutmpentry.c
new file mode 100644
index 0000000..8013f87
--- /dev/null
+++ b/contrib/opie/libopie/getutmpentry.c
@@ -0,0 +1,72 @@
+/* getutmpentry.c: The __opiegetutmpentry() library function.
+
+%%% copyright-cmetz
+This software is Copyright 1996 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Created by cmetz for OPIE 2.3 (re-write).
+*/
+
+#include "opie_cfg.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <utmp.h>
+
+#if DOUTMPX
+#include <utmpx.h>
+#define getutline(x) getutxline(x)
+#define utmp utmpx
+#endif /* DOUTMPX */
+
+#if HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+
+#if DEBUG
+#include <syslog.h>
+#endif /* DEBUG */
+#include "opie.h"
+
+#if !HAVE_GETUTLINE
+struct utmp *getutline __P((struct utmp *));
+#endif /* HAVE_GETUTLINE */
+
+int __opiegetutmpentry FUNCTION((line, utmp), char *line AND struct utmp *utmp)
+{
+ struct utmp u, *pu;
+
+ memset(&u, 0, sizeof(u));
+
+ if (!strncmp(line, "/dev/", 5)) {
+ strncpy(u.ut_line, line + 5, sizeof(u.ut_line));
+ if ((pu = getutline(&u)))
+ goto gotit;
+
+#ifdef hpux
+ strcpy(u.ut_line, "pty/");
+ strncpy(u.ut_line + 4, line + 5, sizeof(u.ut_line) - 4);
+ if ((pu = getutline(&u)))
+ goto gotit;
+#endif /* hpux */
+ }
+
+ strncpy(u.ut_line, line, sizeof(u.ut_line));
+ if ((pu = getutline(&u)))
+ goto gotit;
+
+#if DEBUG
+ syslog(LOG_DEBUG, "__opiegetutmpentry: failed to find entry for line %s", line);
+#endif /* DEBUG */
+ return -1;
+
+gotit:
+#if DEBUG
+ syslog(LOG_DEBUG, "__opiegetutmpentry: succeeded with line %s", pu->ut_line);
+#endif /* DEBUG */
+ memcpy(utmp, pu, sizeof(struct utmp));
+ return 0;
+}
diff --git a/contrib/opie/libopie/hash.c b/contrib/opie/libopie/hash.c
new file mode 100644
index 0000000..4029fa9
--- /dev/null
+++ b/contrib/opie/libopie/hash.c
@@ -0,0 +1,52 @@
+/* hash.c: The opiehash() library function.
+
+%%% copyright-cmetz
+This software is Copyright 1996 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Created by cmetz for OPIE 2.3 using the old hash.c as a guide.
+*/
+
+#include "opie_cfg.h"
+#include "opie.h"
+
+static struct opiemdx_ctx mdx;
+static UINT4 mdx_tmp[4];
+#if 0
+static SHA_INFO sha;
+#endif /* 0 */
+
+VOIDRET opiehash FUNCTION((x, algorithm), VOIDPTR x AND unsigned algorithm)
+{
+ UINT4 *results = (UINT4 *)x;
+
+ switch(algorithm) {
+#if 0
+ case 3:
+ sha_init(&sha);
+ sha_update(&sha, (BYTE *)x, 8);
+ sha_final(&sha);
+ results[0] = sha.digest[0] ^ sha.digest[2] ^ sha.digest[4];
+ results[1] = sha.digest[1] ^ sha.digest[3] ^ sha.digest[5];
+ break;
+#endif /* 0 */
+ case 4:
+ opiemd4init(&mdx);
+ opiemd4update(&mdx, (unsigned char *)x, 8);
+ opiemd4final((unsigned char *)mdx_tmp, &mdx);
+ results[0] = mdx_tmp[0] ^ mdx_tmp[2];
+ results[1] = mdx_tmp[1] ^ mdx_tmp[3];
+ break;
+ case 5:
+ opiemd5init(&mdx);
+ opiemd5update(&mdx, (unsigned char *)x, 8);
+ opiemd5final((unsigned char *)mdx_tmp, &mdx);
+ results[0] = mdx_tmp[0] ^ mdx_tmp[2];
+ results[1] = mdx_tmp[1] ^ mdx_tmp[3];
+ break;
+ }
+}
diff --git a/contrib/opie/libopie/hashlen.c b/contrib/opie/libopie/hashlen.c
new file mode 100644
index 0000000..110eef4
--- /dev/null
+++ b/contrib/opie/libopie/hashlen.c
@@ -0,0 +1,51 @@
+/* hashlen.c: The opiehashlen() library function.
+
+%%% copyright-cmetz
+This software is Copyright 1996 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Created by cmetz for OPIE 2.3.
+*/
+
+#include "opie_cfg.h"
+#include "opie.h"
+
+VOIDRET opiehashlen FUNCTION((algorithm, in, out, n), int algorithm AND VOIDPTR in AND VOIDPTR out AND int n)
+{
+ UINT4 *results = (UINT4 *)out;
+ struct opiemdx_ctx mdx;
+ UINT4 mdx_tmp[4];
+#if 0
+ SHA_INFO sha;
+#endif /* 0 */
+
+ switch(algorithm) {
+#if 0
+ case 3:
+ sha_init(&sha);
+ sha_update(&sha, (BYTE *)in, n);
+ sha_final(&sha);
+ results[0] = sha.digest[0] ^ sha.digest[2] ^ sha.digest[4];
+ results[1] = sha.digest[1] ^ sha.digest[3] ^ sha.digest[5];
+ break;
+#endif /* 0 */
+ case 4:
+ opiemd4init(&mdx);
+ opiemd4update(&mdx, (unsigned char *)in, n);
+ opiemd4final((unsigned char *)mdx_tmp, &mdx);
+ results[0] = mdx_tmp[0] ^ mdx_tmp[2];
+ results[1] = mdx_tmp[1] ^ mdx_tmp[3];
+ break;
+ case 5:
+ opiemd5init(&mdx);
+ opiemd5update(&mdx, (unsigned char *)in, n);
+ opiemd5final((unsigned char *)mdx_tmp, &mdx);
+ results[0] = mdx_tmp[0] ^ mdx_tmp[2];
+ results[1] = mdx_tmp[1] ^ mdx_tmp[3];
+ break;
+ }
+}
diff --git a/contrib/opie/libopie/insecure.c b/contrib/opie/libopie/insecure.c
new file mode 100644
index 0000000..afab006
--- /dev/null
+++ b/contrib/opie/libopie/insecure.c
@@ -0,0 +1,146 @@
+/* insecure.c: The opieinsecure() library function.
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+Portions of this software are Copyright 1995 by Randall Atkinson and Dan
+McDonald, All Rights Reserved. All Rights under this copyright are assigned
+to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
+License Agreement applies to this software.
+
+ History:
+
+ Modified by cmetz for OPIE 2.3. Added result caching. Use
+ __opiegetutmpentry(). Ifdef around ut_host check. Eliminate
+ unused variable.
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
+ Allow IP loopback. DISPLAY and ut_host must match exactly,
+ not just the part before the colon. Added work-around for
+ Sun CDE dtterm bug. Leave the environment as it was
+ found. Use uname().
+ Created at NRL for OPIE 2.2 from opiesubr.c. Fixed pointer
+ assignment that should have been a comparison.
+*/
+#include "opie_cfg.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h> /* ANSI C standard library */
+#include <sys/param.h>
+#include <unistd.h>
+
+#include <utmp.h>
+#if DOUTMPX
+#include <utmpx.h>
+#define utmp utmpx
+#endif /* DOUTMPX */
+
+#if HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif /* HAVE_SYS_UTSNAME_H */
+
+#include "opie.h"
+
+int opieinsecure FUNCTION_NOARGS
+{
+#ifndef NO_INSECURE_CHECK
+ char *display_name;
+ char *s;
+ char *term_name;
+ int insecure = 0;
+#if HAVE_UT_HOST
+ struct utmp utmp;
+#endif /* HAVE_UT_HOST */
+ static int result = -1;
+
+ if (result != -1)
+ return result;
+
+ display_name = (char *) getenv("DISPLAY");
+ term_name = (char *) getenv("TERM");
+
+ if (display_name) {
+ insecure = 1;
+ if (s = strchr(display_name, ':')) {
+ int n = s - display_name;
+ if (!n)
+ insecure = 0;
+ else {
+ if (!strncmp("unix", display_name, n))
+ insecure = 0;
+ else if (!strncmp("localhost", display_name, n))
+ insecure = 0;
+ else if (!strncmp("loopback", display_name, n))
+ insecure = 0;
+ else if (!strncmp("127.0.0.1", display_name, n))
+ insecure = 0;
+ else {
+ struct utsname utsname;
+
+ if (!uname(&utsname)) {
+ if (!strncmp(utsname.nodename, display_name, n))
+ insecure = 0;
+ else {
+ if (s = strchr(display_name, '.')) {
+ int n2 = s - display_name;
+ if (n < n2)
+ n2 = n;
+ if (!strncmp(utsname.nodename, display_name, n))
+ insecure = 0;
+ } /* endif display_name is '.' */
+ } /* endif hostname != display_name */
+ } /* endif was able to get hostname */
+ } /* endif display_name == UNIX */
+ }
+ }
+ } /* endif display_name == ":" */
+ if (insecure)
+ return (result = 1);
+
+ /* If no DISPLAY variable exists and TERM=xterm,
+ then we probably have an xterm executing on a remote system
+ with an rlogin or telnet to our system. If it were a local
+ xterm, then the DISPLAY environment variable would
+ have to exist. rja */
+ if (!display_name && !term_name && !strcmp("xterm", term_name))
+ return (result = 1);
+
+#if HAVE_UT_HOST
+ memset(&utmp, 0, sizeof(struct utmp));
+ if (!__opiegetutmpentry(ttyname(0), &utmp) && utmp.ut_host[0]) {
+ insecure = 1;
+
+ if (s = strchr(utmp.ut_host, ':')) {
+ int n = s - utmp.ut_host;
+ if (!n)
+ insecure = 0;
+ else
+ if (display_name) {
+ if (!strncmp(utmp.ut_host, display_name, n))
+ insecure = 0;
+#ifdef SOLARIS
+ else
+ if (s = strchr(utmp.ut_host, ' ')) {
+ *s = ':';
+ if (s = strchr(s + 1, ' '))
+ *s = '.';
+ if (!strncmp(utmp.ut_host, display_name, n))
+ insecure = 0;
+ }
+#endif /* SOLARIS */
+ }
+ }
+ }
+#endif /* HAVE_UT_HOST */
+ if (insecure)
+ return (result = 1);
+
+ return (result = 0);
+#else /* NO_INSECURE_CHECK */
+ return 0;
+#endif /* NO_INSECURE_CHECK */
+}
diff --git a/contrib/opie/libopie/keycrunch.c b/contrib/opie/libopie/keycrunch.c
new file mode 100644
index 0000000..7df86d9
--- /dev/null
+++ b/contrib/opie/libopie/keycrunch.c
@@ -0,0 +1,64 @@
+/* keycrunch.c: The opiekeycrunch() library function.
+
+%%% copyright-cmetz
+This software is Copyright 1996 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Created by cmetz for OPIE 2.3 using the old keycrunch.c as a guide.
+*/
+
+#include "opie_cfg.h"
+
+#if HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif /* HAVE_STDLIB_H */
+#include <ctype.h>
+
+#include "opie.h"
+
+int opiekeycrunch FUNCTION((algorithm, result, seed, secret), int algorithm AND char *result AND char *seed AND char *secret)
+{
+ int i, rval = -1;
+ char *c;
+
+ if (!result || !seed || !secret)
+ return 1;
+
+ i = strlen(seed) + strlen(secret);
+ if (!(c = malloc(i + 1)))
+ return -1;
+
+ {
+ char *c2 = c;
+
+ if (algorithm & 0x10)
+ while(*c2 = *(secret++)) c2++;
+
+ while(*seed)
+ if (isspace(*(c2++) = tolower(*(seed++))))
+ goto kcret;
+
+ if (!(algorithm & 0x10))
+ strcpy(c2, secret);
+ }
+
+ opiehashlen(algorithm & 0x0f, c, result, i);
+ rval = 0;
+
+kcret:
+ {
+ char *c2 = c;
+ while(*c2)
+ *(c2++) = 0;
+ }
+
+ free(c);
+ return rval;
+}
diff --git a/contrib/opie/libopie/lock.c b/contrib/opie/libopie/lock.c
new file mode 100644
index 0000000..d6ea56e
--- /dev/null
+++ b/contrib/opie/libopie/lock.c
@@ -0,0 +1,175 @@
+/* lock.c: The opielock() library function.
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+Portions of this software are Copyright 1995 by Randall Atkinson and Dan
+McDonald, All Rights Reserved. All Rights under this copyright are assigned
+to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
+License Agreement applies to this software.
+
+ History:
+
+ Modified by cmetz for OPIE 2.3. Do refcounts whether or not we
+ actually lock. Fixed USER_LOCKING=0 case.
+ Modified by cmetz for OPIE 2.22. Added reference count for locks.
+ Changed lock filename/refcount symbol names to better indicate
+ that they're not user serviceable.
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
+ Use "principal" instead of "name" to make it clearer.
+ Ifdef around some headers, be more careful about allowed
+ error return values. Check open() return value properly.
+ Avoid NULL.
+ Created at NRL for OPIE 2.2 from opiesubr2.c
+*/
+#include "opie_cfg.h"
+#if HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <fcntl.h>
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif /* HAVE_STDLIB_H */
+#include "opie.h"
+
+int __opie_lockrefcount = 0;
+
+#if USER_LOCKING
+char *__opie_lockfilename = (char *)0;
+
+/* atexit() handler for opielock() */
+static VOIDRET opieunlockaeh FUNCTION_NOARGS
+{
+ if (__opie_lockfilename) {
+ __opie_lockrefcount = 0;
+ opieunlock();
+ }
+}
+#endif /* USER_LOCKING */
+
+/*
+ Serialize (we hope) authentication of user to prevent race conditions.
+ Creates a lock file with a name of OPIE_LOCK_PREFIX with the user name
+ appended. This file contains the pid of the lock's owner and a time()
+ stamp. We use the former to check for dead owners and the latter to
+ provide an upper bound on the lock duration. If there are any problems,
+ we assume the lock is bogus.
+
+ The value of this locking and its security implications are still not
+ completely clear and require further study.
+
+ One could conceivably hack this facility to provide locking of user
+ accounts after several authentication failures.
+
+ Return -1 on low-level error, 0 if ok, 1 on locking failure.
+*/
+int opielock FUNCTION((principal), char *principal)
+{
+#if USER_LOCKING
+ int fh, waits = 0, rval = -1, pid, t, i;
+ char buffer[128], buffer2[128], *c, *c2;
+
+ if (__opie_lockfilename) {
+ __opie_lockrefcount++;
+ return 0;
+ }
+
+ if (!(__opie_lockfilename = (char *)malloc(sizeof(OPIE_LOCK_PREFIX) + strlen(principal))))
+ return -1;
+
+ strcpy(__opie_lockfilename, OPIE_LOCK_PREFIX);
+ strcat(__opie_lockfilename, principal);
+
+ fh = 0;
+ while (!fh)
+ if ((fh = open(__opie_lockfilename, O_WRONLY | O_CREAT | O_EXCL, 0600)) < 0) {
+ if ((fh = open(__opie_lockfilename, O_RDWR, 0600)) < 0)
+ goto lockret;
+ if ((i = read(fh, buffer, sizeof(buffer))) <= 0)
+ goto lockret;
+
+ buffer[sizeof(buffer) - 1] = 0;
+ buffer[i - 1] = 0;
+
+ if (!(c = strchr(buffer, '\n')))
+ break;
+
+ *(c++) = 0;
+
+ if (!(c2 = strchr(c, '\n')))
+ break;
+
+ *(c2++) = 0;
+
+ if (!(pid = atoi(buffer)))
+ break;
+
+ if (!(t = atoi(c)))
+ break;
+
+ if ((time(0) + OPIE_LOCK_TIMEOUT) < t)
+ break;
+
+ if (kill(pid, 0))
+ break;
+
+ close(fh);
+ fh = 0;
+ sleep(1);
+ if (waits++ > 3) {
+ rval = 1;
+ goto lockret;
+ };
+ };
+
+ sprintf(buffer, "%d\n%d\n", getpid(), time(0));
+ i = strlen(buffer) + 1;
+ if (lseek(fh, 0, SEEK_SET)) {
+ close(fh);
+ unlink(__opie_lockfilename);
+ fh = 0;
+ goto lockret;
+ };
+ if (write(fh, buffer, i) != i) {
+ close(fh);
+ unlink(__opie_lockfilename);
+ fh = 0;
+ goto lockret;
+ };
+ close(fh);
+ if ((fh = open(__opie_lockfilename, O_RDWR, 0600)) < 0) {
+ unlink(__opie_lockfilename);
+ goto lockret;
+ };
+ if (read(fh, buffer2, i) != i) {
+ close(fh);
+ unlink(__opie_lockfilename);
+ fh = 0;
+ goto lockret;
+ };
+ close(fh);
+ if (memcmp(buffer, buffer2, i)) {
+ unlink(__opie_lockfilename);
+ goto lockret;
+ };
+
+ __opie_lockrefcount++;
+ rval = 0;
+ atexit(opieunlockaeh);
+
+lockret:
+ if (fh)
+ close(fh);
+ return rval;
+#else /* USER_LOCKING */
+ __opie_lockrefcount++;
+ return 0;
+#endif /* USER_LOCKING */
+}
diff --git a/contrib/opie/libopie/login.c b/contrib/opie/libopie/login.c
new file mode 100644
index 0000000..d70280f
--- /dev/null
+++ b/contrib/opie/libopie/login.c
@@ -0,0 +1,130 @@
+/* login.c: The opielogin() library function.
+
+%%% copyright-cmetz
+This software is Copyright 1996 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Created by cmetz for OPIE 2.3.
+*/
+
+#include "opie_cfg.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <utmp.h>
+
+#if DOUTMPX
+#include <utmpx.h>
+#define pututline(x) pututxline(x)
+#define utmp utmpx
+#endif /* DOUTMPX */
+
+#if HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#include <sys/stat.h>
+#if DEBUG
+#include <syslog.h>
+#include <errno.h>
+#endif /* DEBUG */
+#include "opie.h"
+
+int opielogin FUNCTION((line, name, host), char *line AND char *name AND char *host)
+{
+ struct utmp u;
+ int rval = 0;
+
+ if (__opiegetutmpentry(line, &u)) {
+#if DEBUG
+ syslog(LOG_DEBUG, "opielogin: __opiegetutmpentry(line=%s, &u) failed", line);
+#endif /* DEBUG */
+ memset(&u, 0, sizeof(struct utmp));
+ if (!strncmp(line, "/dev/", 5))
+ strncpy(u.ut_line, line + 5, sizeof(u.ut_line));
+ else
+ strncpy(u.ut_line, line, sizeof(u.ut_line));
+#if DEBUG
+ syslog(LOG_DEBUG, "opielogin: continuing with ut_line=%s", u.ut_line);
+#endif /* DEBUG */
+ }
+
+#if HAVE_UT_TYPE && defined(USER_PROCESS)
+ u.ut_type = USER_PROCESS;
+#endif /* HAVE_UT_TYPE && defined(USER_PROCESS) */
+#if HAVE_UT_PID
+ u.ut_pid = getpid();
+#endif /* HAVE_UT_PID */
+
+#if HAVE_UT_NAME
+ strncpy(u.ut_name, name, sizeof(u.ut_name));
+ u.ut_name[sizeof(u.ut_name)] = 0;
+#else /* HAVE_UT_NAME */
+#error No ut_name field in struct utmp? (Please send in a bug report)
+#endif /* HAVE_UT_NAME */
+
+#if HAVE_UT_HOST
+ strncpy(u.ut_host, host, sizeof(u.ut_host));
+ u.ut_host[sizeof(u.ut_host)] = 0;
+#endif /* HAVE_UT_HOST */
+
+#if DOUTMPX
+#ifdef HAVE_ONE_ARG_GETTIMEOFDAY
+ gettimeofday(&u->ut_tv);
+#else /* HAVE_ONE_ARG_GETTIMEOFDAY */
+ gettimeofday(&u->ut_tv, NULL);
+#endif /* HAVE_ONE_ARG_GETTIMEOFDAY */
+#else /* DOUTMPX */
+ time(&u.ut_time);
+#endif /* DOUTMPX */
+
+ pututline(&u);
+ endutent();
+
+#if DEBUG
+ syslog(LOG_DEBUG, "opielogin: utmp suceeded");
+#endif /* DEBUG */
+
+dowtmp:
+ {
+ FILE *f;
+
+#if DOUTMPX
+ updutmpx(_PATH_WTMPX, &u);
+#else /* DOUTMPX */
+ if (!(f = __opieopen(_PATH_WTMP, 2, 0664))) {
+ rval = -1;
+#if DEBUG
+ syslog(LOG_DEBUG, "opielogin: wtmp open failed: %s (%d)", strerror(errno), errno);
+#endif /* DEBUG */
+ goto dosetlogin;
+ }
+
+ if (fwrite(&u, sizeof(struct utmp), 1, f) != sizeof(struct utmp)) {
+#if DEBUG
+ syslog(LOG_DEBUG, "opielogin: wtmp write failed: %s (%d)", strerror(errno), errno);
+#endif /* DEBUG */
+ rval = -1;
+ }
+
+ fclose(f);
+#endif /* DOUTMPX */
+ }
+
+#if DEBUG
+ syslog(LOG_DEBUG, "opielogin: wtmp suceeded");
+#endif /* DEBUG */
+
+dosetlogin:
+#if HAVE_SETLOGIN
+ setlogin(name);
+#endif /* HAVE_SETLOGIN */
+
+#if DEBUG
+ syslog(LOG_DEBUG, "opielogin: rval=%d", rval);
+#endif /* DEBUG */
+
+ return rval;
+}
diff --git a/contrib/opie/libopie/lookup.c b/contrib/opie/libopie/lookup.c
new file mode 100644
index 0000000..e3df681
--- /dev/null
+++ b/contrib/opie/libopie/lookup.c
@@ -0,0 +1,30 @@
+/* lookup.c: The opielookup() library function.
+
+%%% copyright-cmetz
+This software is Copyright 1996 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Created by cmetz for OPIE 2.3 (re-write).
+*/
+
+#include "opie_cfg.h"
+#include <stdio.h>
+#include "opie.h"
+
+int opielookup FUNCTION((opie, principal), struct opie *opie AND char *principal)
+{
+ int i;
+
+ memset(opie, 0, sizeof(struct opie));
+ opie->opie_principal = principal;
+
+ if (i = __opiereadrec(opie))
+ return i;
+
+ return (opie->opie_flags & __OPIE_FLAGS_RW) ? 0 : 2;
+}
+
diff --git a/contrib/opie/libopie/md4c.c b/contrib/opie/libopie/md4c.c
new file mode 100644
index 0000000..fd46857
--- /dev/null
+++ b/contrib/opie/libopie/md4c.c
@@ -0,0 +1,267 @@
+/* md4c.c: "RSA Data Security, Inc. MD4 Message-Digest Algorithm"
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+Portions of this software are Copyright 1995 by Randall Atkinson and Dan
+McDonald, All Rights Reserved. All Rights under this copyright are assigned
+to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
+License Agreement applies to this software.
+
+ History:
+
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
+ Use the real memcpy() and memset(). Use unified context
+ structure.
+ Modified at NRL for OPIE 2.0.
+ Originally from RSADSI reference code.
+*/
+/* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
+
+ License to copy and use this software is granted provided that it
+ is identified as the "RSA Data Security, Inc. MD4 Message-Digest
+ Algorithm" in all material mentioning or referencing this software
+ or this function.
+
+ License is also granted to make and use derivative works provided
+ that such works are identified as "derived from the RSA Data
+ Security, Inc. MD4 Message-Digest Algorithm" in all material
+ mentioning or referencing the derived work.
+
+ RSA Data Security, Inc. makes no representations concerning either
+ the merchantability of this software or the suitability of this
+ software for any particular purpose. It is provided "as is"
+ without express or implied warranty of any kind.
+
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
+ */
+
+#include "opie_cfg.h"
+#include "opie.h"
+
+/* Constants for MD4Transform routine.
+ */
+#define S11 3
+#define S12 7
+#define S13 11
+#define S14 19
+#define S21 3
+#define S22 5
+#define S23 9
+#define S24 13
+#define S31 3
+#define S32 9
+#define S33 11
+#define S34 15
+
+static VOIDRET MD4Transform __P((UINT4[4], unsigned char[64]));
+static VOIDRET Encode __P((unsigned char *, UINT4 *, unsigned int));
+static VOIDRET Decode __P((UINT4 *, unsigned char *, unsigned int));
+
+static unsigned char PADDING[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G and H are basic MD4 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
+/* Rotation is separate from addition to prevent recomputation */
+
+#define FF(a, b, c, d, x, s) { \
+ (a) += F ((b), (c), (d)) + (x); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ }
+#define GG(a, b, c, d, x, s) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ }
+#define HH(a, b, c, d, x, s) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ }
+
+/* MD4 initialization. Begins an MD4 operation, writing a new context.
+ */
+VOIDRET opiemd4init FUNCTION((context), struct opiemdx_ctx *context)
+{
+ context->count[0] = context->count[1] = 0;
+
+ /* Load magic initialization constants. */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/* MD4 block update operation. Continues an MD4 message-digest
+ operation, processing another message block, and updating the
+ context.
+ */
+VOIDRET opiemd4update FUNCTION((context, input, inputLen), struct opiemdx_ctx *context AND unsigned char *input AND unsigned int inputLen)
+{
+ unsigned int i, index, partLen;
+
+ /* Compute number of bytes mod 64 */
+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
+ /* Update number of bits */
+ if ((context->count[0] += ((UINT4) inputLen << 3))
+ < ((UINT4) inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((UINT4) inputLen >> 29);
+
+ partLen = 64 - index;
+
+ /* Transform as many times as possible. */
+ if (inputLen >= partLen) {
+ memcpy((POINTER) & context->buffer[index], (POINTER) input, partLen);
+ MD4Transform(context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ MD4Transform(context->state, &input[i]);
+
+ index = 0;
+ } else
+ i = 0;
+
+ /* Buffer remaining input */
+ memcpy((POINTER) & context->buffer[index], (POINTER) & input[i], inputLen - i);
+}
+
+/* MD4 finalization. Ends an MD4 message-digest operation, writing the
+ the message digest and zeroizing the context.
+ */
+VOIDRET opiemd4final FUNCTION((digest, context), unsigned char *digest AND struct opiemdx_ctx *context)
+{
+ unsigned char bits[8];
+ unsigned int index, padLen;
+
+ /* Save number of bits */
+ Encode(bits, context->count, 8);
+
+ /* Pad out to 56 mod 64. */
+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ opiemd4update(context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ opiemd4update(context, bits, 8);
+ /* Store state in digest */
+ Encode(digest, context->state, 16);
+
+ /* Zeroize sensitive information. */
+ memset((POINTER) context, 0, sizeof(*context));
+}
+
+/* MD4 basic transformation. Transforms state based on block.
+ */
+static VOIDRET MD4Transform FUNCTION((state, block), UINT4 state[4] AND unsigned char block[64])
+{
+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ Decode(x, block, 64);
+
+ /* Round 1 */
+ FF(a, b, c, d, x[0], S11); /* 1 */
+ FF(d, a, b, c, x[1], S12); /* 2 */
+ FF(c, d, a, b, x[2], S13); /* 3 */
+ FF(b, c, d, a, x[3], S14); /* 4 */
+ FF(a, b, c, d, x[4], S11); /* 5 */
+ FF(d, a, b, c, x[5], S12); /* 6 */
+ FF(c, d, a, b, x[6], S13); /* 7 */
+ FF(b, c, d, a, x[7], S14); /* 8 */
+ FF(a, b, c, d, x[8], S11); /* 9 */
+ FF(d, a, b, c, x[9], S12); /* 10 */
+ FF(c, d, a, b, x[10], S13); /* 11 */
+ FF(b, c, d, a, x[11], S14); /* 12 */
+ FF(a, b, c, d, x[12], S11); /* 13 */
+ FF(d, a, b, c, x[13], S12); /* 14 */
+ FF(c, d, a, b, x[14], S13); /* 15 */
+ FF(b, c, d, a, x[15], S14); /* 16 */
+
+ /* Round 2 */
+ GG(a, b, c, d, x[0], S21); /* 17 */
+ GG(d, a, b, c, x[4], S22); /* 18 */
+ GG(c, d, a, b, x[8], S23); /* 19 */
+ GG(b, c, d, a, x[12], S24); /* 20 */
+ GG(a, b, c, d, x[1], S21); /* 21 */
+ GG(d, a, b, c, x[5], S22); /* 22 */
+ GG(c, d, a, b, x[9], S23); /* 23 */
+ GG(b, c, d, a, x[13], S24); /* 24 */
+ GG(a, b, c, d, x[2], S21); /* 25 */
+ GG(d, a, b, c, x[6], S22); /* 26 */
+ GG(c, d, a, b, x[10], S23); /* 27 */
+ GG(b, c, d, a, x[14], S24); /* 28 */
+ GG(a, b, c, d, x[3], S21); /* 29 */
+ GG(d, a, b, c, x[7], S22); /* 30 */
+ GG(c, d, a, b, x[11], S23); /* 31 */
+ GG(b, c, d, a, x[15], S24); /* 32 */
+
+ /* Round 3 */
+ HH(a, b, c, d, x[0], S31); /* 33 */
+ HH(d, a, b, c, x[8], S32); /* 34 */
+ HH(c, d, a, b, x[4], S33); /* 35 */
+ HH(b, c, d, a, x[12], S34); /* 36 */
+ HH(a, b, c, d, x[2], S31); /* 37 */
+ HH(d, a, b, c, x[10], S32); /* 38 */
+ HH(c, d, a, b, x[6], S33); /* 39 */
+ HH(b, c, d, a, x[14], S34); /* 40 */
+ HH(a, b, c, d, x[1], S31); /* 41 */
+ HH(d, a, b, c, x[9], S32); /* 42 */
+ HH(c, d, a, b, x[5], S33); /* 43 */
+ HH(b, c, d, a, x[13], S34); /* 44 */
+ HH(a, b, c, d, x[3], S31); /* 45 */
+ HH(d, a, b, c, x[11], S32); /* 46 */
+ HH(c, d, a, b, x[7], S33); /* 47 */
+ HH(b, c, d, a, x[15], S34); /* 48 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information. */
+ memset((POINTER) x, 0, sizeof(x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+ a multiple of 4.
+ */
+static VOIDRET Encode FUNCTION((output, input, len), unsigned char *output AND UINT4 *input AND unsigned int len)
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char) (input[i] & 0xff);
+ output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
+ output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
+ output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
+ }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+ a multiple of 4.
+ */
+static VOIDRET Decode FUNCTION((output, input, len), UINT4 *output AND unsigned char *input AND unsigned int len)
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4) input[j]) | (((UINT4) input[j + 1]) << 8) |
+ (((UINT4) input[j + 2]) << 16) | (((UINT4) input[j + 3]) << 24);
+}
diff --git a/contrib/opie/libopie/md5c.c b/contrib/opie/libopie/md5c.c
new file mode 100644
index 0000000..6b20508
--- /dev/null
+++ b/contrib/opie/libopie/md5c.c
@@ -0,0 +1,304 @@
+/* md5c.c: "RSA Data Security, Inc. MD5 Message-Digest Algorithm"
+ "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm"
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+Portions of this software are Copyright 1995 by Randall Atkinson and Dan
+McDonald, All Rights Reserved. All Rights under this copyright are assigned
+to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
+License Agreement applies to this software.
+
+ History:
+
+ Modified by cmetz for OPIE 2.3. Changed PTR to VOIDPTR.
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
+ Don't play macro games with memset/memcpy. Renamed exported
+ functions to avoid conflicts. Use unified context structure.
+ Modified at NRL for OPIE 2.1. Minor autoconf mods.
+ Modified at NRL for OPIE 2.0.
+ Originally from RSADSI reference code.
+*/
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+ rights reserved.
+
+ License to copy and use this software is granted provided that it
+ is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+ Algorithm" in all material mentioning or referencing this software
+ or this function.
+
+ License is also granted to make and use derivative works provided
+ that such works are identified as "derived from the RSA Data
+ Security, Inc. MD5 Message-Digest Algorithm" in all material
+ mentioning or referencing the derived work.
+
+ RSA Data Security, Inc. makes no representations concerning either
+ the merchantability of this software or the suitability of this
+ software for any particular purpose. It is provided "as is"
+ without express or implied warranty of any kind.
+
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
+ */
+
+#include "opie_cfg.h"
+#include "opie.h"
+
+/* Constants for MD5Transform routine.
+ */
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static VOIDRET MD5Transform __P((UINT4[4], unsigned char[64]));
+
+static unsigned char PADDING[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * Encodes input (UINT4) into output (unsigned char).
+ * Assumes len is a multiple of 4.
+ */
+static VOIDRET EEncode FUNCTION((output, input, len), unsigned char *output AND UINT4 *input AND unsigned int len)
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char) (input[i] & 0xff);
+ output[j + 1] = (unsigned char) ((input[i] >> 8) & 0xff);
+ output[j + 2] = (unsigned char) ((input[i] >> 16) & 0xff);
+ output[j + 3] = (unsigned char) ((input[i] >> 24) & 0xff);
+ }
+}
+
+/*
+ * Decodes input (unsigned char) into output (UINT4).
+ * Assumes len is a multiple of 4.
+ */
+static VOIDRET EDecode FUNCTION((output, input, len), UINT4 *output AND unsigned char *input AND unsigned int len)
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4) input[j]) | (((UINT4) input[j + 1]) << 8) |
+ (((UINT4) input[j + 2]) << 16) | (((UINT4) input[j + 3]) << 24);
+}
+
+/* F, G, H and I are basic MD5 functions. */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits. */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+ Rotation is separate from addition to prevent recomputation. */
+
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context. */
+VOIDRET opiemd5init FUNCTION((context), struct opiemdx_ctx *context)
+{
+ context->count[0] = context->count[1] = 0;
+ /* Load magic initialization constants. */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/*
+ * MD5 block update operation. Continues an MD5 message-digest
+ * operation, processing another message block, and updating the
+ * context.
+ */
+VOIDRET opiemd5update FUNCTION((context, input, inputLen), struct opiemdx_ctx *context AND unsigned char *input AND unsigned int inputLen)
+{
+ unsigned int i, index, partLen;
+
+ /* Compute number of bytes mod 64 */
+ index = (unsigned int) ((context->count[0] >> 3) & 0x3F);
+
+ /* Update number of bits */
+ if ((context->count[0] += ((UINT4) inputLen << 3)) < ((UINT4) inputLen << 3))
+ context->count[1]++;
+
+ context->count[1] += ((UINT4) inputLen >> 29);
+ partLen = 64 - index;
+
+ /* Transform as many times as possible. */
+ if (inputLen >= partLen) {
+ memcpy((VOIDPTR)&context->buffer[index], (VOIDPTR)input, partLen);
+ MD5Transform(context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ MD5Transform(context->state, &input[i]);
+
+ index = 0;
+ } else
+ i = 0;
+
+ /* Buffer remaining input */
+ memcpy((VOIDPTR) & context->buffer[index],
+ (VOIDPTR) & input[i],
+ inputLen - i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+ the message digest and zeroizing the context.
+ */
+VOIDRET opiemd5final FUNCTION((digest, context), unsigned char *digest AND struct opiemdx_ctx *context)
+{
+ unsigned char bits[8];
+ unsigned int index, padLen;
+
+ /* Save number of bits */
+ EEncode(bits, context->count, 8);
+
+ /* Pad out to 56 mod 64. */
+ index = (unsigned int) ((context->count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ opiemd5update(context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ opiemd5update(context, bits, 8);
+
+ /* Store state in digest */
+ EEncode(digest, context->state, 16);
+
+ /* Zeroize sensitive information. */
+ memset((VOIDPTR) context, 0, sizeof(*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block. */
+static VOIDRET MD5Transform FUNCTION((state, block), UINT4 state[4] AND unsigned char block[64])
+{
+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ EDecode(x, block, 64);
+
+ /* Round 1 */
+ FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
+ FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
+ FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
+ FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
+ FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
+ FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
+ FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
+ FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
+ FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
+ FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
+ FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
+ GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
+ GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
+ GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
+ GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
+ GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
+ GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
+ GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
+ GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
+ GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
+ GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
+ HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
+ HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
+ HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
+ HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
+ HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
+ HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
+ HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
+ HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
+ HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
+ II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
+ II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
+ II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
+ II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
+ II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
+ II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
+ II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
+ II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
+ II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information. */
+ memset((VOIDPTR)x, 0, sizeof(x));
+}
diff --git a/contrib/opie/libopie/newseed.c b/contrib/opie/libopie/newseed.c
new file mode 100644
index 0000000..af4cac7
--- /dev/null
+++ b/contrib/opie/libopie/newseed.c
@@ -0,0 +1,99 @@
+/* newseed.c: The opienewseed() library function.
+
+%%% copyright-cmetz
+This software is Copyright 1996 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Created by cmetz for OPIE 2.22.
+*/
+
+#include "opie_cfg.h"
+#if HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#include <ctype.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#if HAVE_SYS_UTSNAME_H
+#include <sys/utsname.h>
+#endif /* HAVE_SYS_UTSNAME_H */
+#include <errno.h>
+#include "opie.h"
+
+int opienewseed FUNCTION((seed), char *seed)
+{
+ if (!seed)
+ return -1;
+
+ if (seed[0]) {
+ int i;
+
+ if ((i = strlen(seed)) >= OPIE_SEED_MIN) {
+ long j;
+ char *c;
+
+ if (i > OPIE_SEED_MAX)
+ i = OPIE_SEED_MAX;
+
+ c = seed + i - 1;
+
+ while(c != seed) {
+ if (!isdigit(*c))
+ break;
+ c--;
+ }
+
+ c++;
+
+ if (j = strtol(c, (char **)0, 10)) {
+ char buf[OPIE_SEED_MAX];
+
+ *c = 0;
+ strcpy(buf, seed);
+
+ if (errno == ERANGE) {
+ j = 1;
+ } else {
+ int k = 1, l = OPIE_SEED_MAX - strlen(buf);
+ while(l--) k *= 10;
+
+ if (++j >= k)
+ j = 1;
+ }
+
+ sprintf(seed, "%s%04d", buf, j);
+ return 0;
+ }
+ }
+ }
+
+ {
+ {
+ time_t now;
+ time(&now);
+ srand(now);
+ }
+
+ {
+ struct utsname utsname;
+
+ if (uname(&utsname) < 0) {
+#if 0
+ perror("uname");
+#endif /* 0 */
+ utsname.nodename[0] = 'k';
+ utsname.nodename[1] = 'e';
+ }
+ utsname.nodename[2] = 0;
+
+ sprintf(seed, "%s%04d", utsname.nodename, (rand() % 9999) + 1);
+ return 0;
+ }
+ }
+}
+
diff --git a/contrib/opie/libopie/open.c b/contrib/opie/libopie/open.c
new file mode 100644
index 0000000..0082c34
--- /dev/null
+++ b/contrib/opie/libopie/open.c
@@ -0,0 +1,61 @@
+/* open.c: The __opieopen() library function.
+
+%%% copyright-cmetz
+This software is Copyright 1996 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Created by cmetz for OPIE 2.3.
+*/
+#include "opie_cfg.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <sys/stat.h>
+#include <errno.h>
+
+#include "opie.h"
+
+#if !HAVE_LSTAT
+#define lstat(x, y) stat(x, y)
+#endif /* !HAVE_LSTAT */
+
+FILE *__opieopen FUNCTION((file, rw, mode), char *file AND int rw AND int mode)
+{
+ FILE *f;
+ struct stat st;
+
+ if (lstat(file, &st)) {
+ if (errno != ENOENT)
+ return NULL;
+
+ if (!(f = fopen(file, "w")))
+ return NULL;
+
+ fclose(f);
+
+ if (chmod(file, mode))
+ return NULL;
+
+ if (lstat(file, &st))
+ return NULL;
+ }
+
+ if (!S_ISREG(st.st_mode))
+ return NULL;
+
+ {
+ char *fmodes[] = { "r", "r+", "a" };
+
+ if (!(f = fopen(file, fmodes[rw])))
+ return NULL;
+ }
+
+ return f;
+}
diff --git a/contrib/opie/libopie/parsechallenge.c b/contrib/opie/libopie/parsechallenge.c
new file mode 100644
index 0000000..9dca1e6
--- /dev/null
+++ b/contrib/opie/libopie/parsechallenge.c
@@ -0,0 +1,70 @@
+/* parsechallenge.c: The _opieparsechallenge() library function.
+
+%%% copyright-cmetz
+This software is Copyright 1996 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Created by cmetz for OPIE 2.3 using generator.c as a guide.
+*/
+
+#include "opie_cfg.h"
+#if HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#include "opie.h"
+
+struct algorithm {
+ char *name;
+ int num;
+};
+
+static struct algorithm algorithms[] = {
+ { "md5", 5 },
+ { "md4", 4 },
+ { "sha1", 3 },
+ { NULL, 0 },
+};
+
+int _opieparsechallenge FUNCTION((buffer, algorithm, sequence, seed), char *buffer AND int *algorithm AND int *sequence AND char **seed)
+{
+ char *c;
+
+ if (!(c = strchr(buffer, ' ')))
+ return 1;
+
+ {
+ struct algorithm *a;
+
+ for (a = algorithms; a->name && strncmp(buffer, a->name, (int)(c - buffer)); a++);
+ if (!a->name)
+ return -1;
+
+ *algorithm = a->num;
+ }
+
+ if ((*sequence = strtoul(++c, &c, 10)) > 9999)
+ return -1;
+
+ while(*c && isspace(*c)) c++;
+ if (!*c)
+ return -1;
+
+ buffer = c;
+ while(*c && !isspace(*c)) c++;
+
+ {
+ int i = (int)(c - buffer);
+
+ if ((i > OPIE_SEED_MAX) || (i < OPIE_SEED_MIN))
+ return -1;
+ }
+
+ *seed = buffer;
+ *c = 0;
+
+ return 0;
+}
diff --git a/contrib/opie/libopie/passcheck.c b/contrib/opie/libopie/passcheck.c
new file mode 100644
index 0000000..3b30d70
--- /dev/null
+++ b/contrib/opie/libopie/passcheck.c
@@ -0,0 +1,50 @@
+/* passcheck.c: The opiepasscheck() library function.
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+Portions of this software are Copyright 1995 by Randall Atkinson and Dan
+McDonald, All Rights Reserved. All Rights under this copyright are assigned
+to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
+License Agreement applies to this software.
+
+ History:
+
+ Modified by cmetz for OPIE 2.3. OPIE_PASS_{MIN,MAX} changed to
+ OPIE_SECRET_{MIN,MAX}.
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
+ Created at NRL for OPIE 2.2 from opiesubr.c.
+*/
+#include "opie_cfg.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "opie.h"
+
+/*
+ Applies "good password" rules to the secret pass phrase.
+
+ We currently implement the following:
+
+ Passwords must be at least OPIE_SECRET_MIN (10) characters long.
+ Passwords must be at most OPIE_SECRET_MAX (127) characters long.
+
+ N.B.: Passing NULL pointers to this function is a bad idea.
+*/
+int opiepasscheck FUNCTION((secret), char *secret)
+{
+ int len = strlen(secret);
+
+ if (len < OPIE_SECRET_MIN)
+ return 1;
+
+ if (len > OPIE_SECRET_MAX)
+ return 1;
+
+ return 0;
+}
diff --git a/contrib/opie/libopie/passwd.c b/contrib/opie/libopie/passwd.c
new file mode 100644
index 0000000..e50bf17
--- /dev/null
+++ b/contrib/opie/libopie/passwd.c
@@ -0,0 +1,74 @@
+/* passwd.c: The opiepasswd() library function.
+
+%%% copyright-cmetz
+This software is Copyright 1996 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Modified by cmetz for OPIE 2.3. Split most of the function off
+ and turned this into a front-end for the new __opiewriterec().
+ Added code to compute the key from the secret. Use the opie_
+ prefix. Use new opieatob8() and opiebtoa8() return values.
+ Created by cmetz for OPIE 2.22.
+*/
+
+#include "opie_cfg.h"
+#include "opie.h"
+
+int opiepasswd FUNCTION((old, mode, principal, n, seed, ks), struct opie *old AND int mode AND char *principal AND int n AND char *seed AND char *ks)
+{
+ int i;
+ struct opie opie;
+
+ if ((mode & 1) && opieinsecure())
+ return -1;
+
+ memset(&opie, 0, sizeof(struct opie));
+
+ if (old) {
+ opie.opie_flags = old->opie_flags;
+ opie.opie_recstart = old->opie_recstart;
+ opie.opie_extrecstart = old->opie_extrecstart;
+ }
+
+ opie.opie_principal = principal;
+ opie.opie_n = n;
+ opie.opie_seed = seed;
+
+ if (ks) {
+ char key[8];
+
+ if (mode & 1) {
+ if (opiekeycrunch(MDX, key, seed, ks))
+ return -1;
+ for (i = n; i; i--)
+ opiehash(key, MDX);
+ if (!(opie.opie_val = opiebtoa8(opie.opie_buf, key)))
+ return -1;
+
+ if (opiekeycrunch(MDX | 0x10, key, seed, ks))
+ return -1;
+
+ if (!(opie.opie_reinitkey = opiebtoa8(opie.opie_extbuf, key)))
+ return -1;
+ } else {
+ if ((opieetob(key, ks) != 1) && !opieatob8(key, ks))
+ return 1;
+ if (!(opie.opie_val = opiebtoa8(opie.opie_buf, key)))
+ return 1;
+ }
+ }
+
+ if (opielock(principal))
+ return -1;
+
+ i = __opiewriterec(&opie);
+
+ if (opieunlock())
+ return -1;
+
+ return i;
+}
diff --git a/contrib/opie/libopie/randomchallenge.c b/contrib/opie/libopie/randomchallenge.c
new file mode 100644
index 0000000..6e0d5b7
--- /dev/null
+++ b/contrib/opie/libopie/randomchallenge.c
@@ -0,0 +1,43 @@
+/* randomchallenge.c: The opierandomchallenge() library function.
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+Portions of this software are Copyright 1995 by Randall Atkinson and Dan
+McDonald, All Rights Reserved. All Rights under this copyright are assigned
+to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
+License Agreement applies to this software.
+
+ History:
+
+ Modified by cmetz for OPIE 2.3. Add sha support.
+ Modified by cmetz for OPIE 2.22. Don't include stdio.h.
+ Use opienewseed(). Don't include unneeded headers.
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
+ Changed use of gethostname() to uname(). Ifdefed around some
+ headers.
+ Created at NRL for OPIE 2.2 from opiesubr2.c
+*/
+
+#include "opie_cfg.h"
+#include "opie.h"
+
+static char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" };
+
+/* Generate a random challenge */
+/* This could grow into quite a monster, really. Random is good enough for
+ most situations; it is certainly better than a fixed string */
+VOIDRET opierandomchallenge FUNCTION((prompt), char *prompt)
+{
+ char buf[OPIE_SEED_MAX + 1];
+
+ buf[0] = 0;
+ if (opienewseed(buf))
+ strcpy(buf, "ke4452");
+
+ sprintf(prompt, "otp-%s %d %s", algids[MDX], (rand() % 499) + 1, buf);
+}
diff --git a/contrib/opie/libopie/readpass.c b/contrib/opie/libopie/readpass.c
new file mode 100644
index 0000000..4dc22e2
--- /dev/null
+++ b/contrib/opie/libopie/readpass.c
@@ -0,0 +1,304 @@
+/* readpass.c: The opiereadpass() library function.
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+Portions of this software are Copyright 1995 by Randall Atkinson and Dan
+McDonald, All Rights Reserved. All Rights under this copyright are assigned
+to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
+License Agreement applies to this software.
+
+ History:
+
+ Modified by cmetz for OPIE 2.3. Use TCSAFLUSH always.
+ Modified by cmetz for OPIE 2.22. Replaced echo w/ flags.
+ Really use FUNCTION.
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
+ Flush extraneous characters up to eol. Handle gobs of possible
+ erase and kill keys if on a terminal. To do so, use RAW
+ terminal I/O and handle echo ourselves. (should also help
+ DOS et al portability). Fixed include order. Re-did MSDOS
+ and OS/2 includes. Set up VMIN and VTIME. Added some non-UNIX
+ portability cruft. Limit backspacing and killing. In terminal
+ mode, eat random other control characters. Added eof handling.
+ Created at NRL for OPIE 2.2 from opiesubr.c. Change opiestrip_crlf to
+ opiestripcrlf. Don't strip to seven bits.
+*/
+#include "opie_cfg.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h> /* ANSI C standard library */
+
+#ifdef unix
+#include <fcntl.h> /* POSIX file control function headers */
+#include <termios.h> /* POSIX Terminal I/O functions */
+#if HAVE_UNISTD_H
+#include <unistd.h> /* POSIX standard definitions */
+#endif /* HAVE_UNISTD_H */
+#include <signal.h>
+#include <setjmp.h>
+#endif /* unix */
+
+#ifdef __MSDOS__
+#include <dos.h>
+#endif /* __MSDOS__ */
+
+#ifdef __OS2__
+#define INCL_KBD
+#include <os2.h>
+#include <io.h>
+#endif /* __OS2__ */
+
+#include "opie.h"
+
+#define CONTROL(x) (x - 64)
+
+char *bsseq = "\b \b";
+
+#ifdef unix
+static jmp_buf jmpbuf;
+
+static VOIDRET catch FUNCTION((i), int i)
+{
+ longjmp(jmpbuf, 1);
+}
+#endif /* unix */
+
+char *opiereadpass FUNCTION((buf, len, flags), char *buf AND int len AND int flags)
+{
+#ifdef unix
+ struct termios attr, orig_attr;
+#endif /* unix */
+ char erase[5];
+ char kill[4];
+ char eof[4];
+
+ memset(erase, 0, sizeof(erase));
+ memset(kill, 0, sizeof(kill));
+ memset(eof, 0, sizeof(eof));
+
+ /* This section was heavily rewritten by rja following the model of code
+ samples circa page 151 of the POSIX Programmer's Guide by Donald Lewine,
+ ISBN 0-937175-73-0. That book is Copyright 1991 by O'Reilly &
+ Associates, Inc. All Rights Reserved. I recommend the book to anyone
+ trying to write portable software. rja */
+
+#ifdef unix
+ if (setjmp(jmpbuf))
+ goto error;
+
+ signal(SIGINT, catch);
+#endif /* unix */
+
+ /* Flush any pending output */
+ fflush(stderr);
+ fflush(stdout);
+
+#ifdef unix
+ /* Get original terminal attributes */
+ if (isatty(0)) {
+ if (tcgetattr(0, &orig_attr))
+ return NULL;
+
+ /* copy terminal settings into attr */
+ memcpy(&attr, &orig_attr, sizeof(struct termios));
+
+ attr.c_lflag &= ~(ECHO | ICANON);
+ attr.c_lflag |= ISIG;
+
+ attr.c_cc[VMIN] = 1;
+ attr.c_cc[VTIME] = 0;
+
+ erase[0] = CONTROL('H');
+ erase[1] = 127;
+
+#ifdef CERASE
+ {
+ char *e = erase;
+
+ while(*e)
+ if (*(e++) == CERASE)
+ break;
+
+ if (!*e)
+ *e = CERASE;
+ }
+#endif /* CERASE */
+#ifdef VERASE
+ {
+ char *e = erase;
+
+ while(*e)
+ if (*(e++) == attr.c_cc[VERASE])
+ break;
+
+ if (!*e)
+ *e = attr.c_cc[VERASE];
+ }
+#endif /* VERASE */
+
+ kill[0] = CONTROL('U');
+#ifdef CKILL
+ {
+ char *e = kill;
+
+ while(*e)
+ if (*(e++) == CKILL)
+ break;
+
+ if (!*e)
+ *e = CKILL;
+ }
+#endif /* CKILL */
+#ifdef VKILL
+ {
+ char *e = kill;
+
+ while(*e)
+ if (*(e++) == attr.c_cc[VKILL])
+ break;
+
+ if (!*e)
+ *e = attr.c_cc[VKILL];
+ }
+#endif /* VKILL */
+
+ eof[0] = CONTROL('D');
+#ifdef CEOF
+ {
+ char *e = eof;
+
+ while(*e)
+ if (*(e++) == CEOF)
+ break;
+
+ if (!*e)
+ *e = CEOF;
+ }
+#endif /* CEOF */
+#ifdef VEOF
+ {
+ char *e = eof;
+
+ while(*e)
+ if (*(e++) == attr.c_cc[VEOF])
+ break;
+
+ if (!*e)
+ *e = VEOF;
+ }
+#endif /* VEOF */
+
+ if (tcsetattr(0, TCSAFLUSH, &attr))
+ goto error;
+ }
+#else /* unix */
+ erase[0] = CONTROL('H');
+ erase[1] = 127;
+ kill[0] = CONTROL('U');
+ eof[0] = CONTROL('D');
+ eof[1] = CONTROL('Z');
+#endif /* unix */
+
+ {
+ char *c = buf, *end = buf + len, *e;
+#ifdef __OS2__
+ KBDKEYINFO keyInfo;
+#endif /* __OS2__ */
+
+loop:
+#ifdef unix
+ if (read(0, c, 1) != 1)
+ goto error;
+#endif /* unix */
+#ifdef MSDOS
+ *c = bdos(7, 0, 0);
+#endif /* MSDOS */
+#ifdef __OS2__
+ KbdCharIn(&keyInfo, 0, 0);
+ *c = keyInfo.chChar;
+#endif /* __OS2__ */
+
+ if ((*c == '\r') || (*c == '\n')) {
+ *c = 0;
+ goto restore;
+ }
+
+ e = eof;
+ while(*e)
+ if (*(e++) == *c)
+ goto error;
+
+ e = erase;
+ while(*e)
+ if (*(e++) == *c) {
+ if (c <= buf)
+ goto beep;
+
+ if (flags & 1)
+ write(1, bsseq, sizeof(bsseq) - 1);
+ c--;
+ goto loop;
+ }
+
+ e = kill;
+ while(*e)
+ if (*(e++) == *c) {
+ if (c <= buf)
+ goto beep;
+
+ if (flags & 1)
+ while(c-- > buf)
+ write(1, bsseq, sizeof(bsseq) - 1);
+
+ c = buf;
+ goto loop;
+ }
+
+ if (c < end) {
+ if (*c < 32)
+ goto beep;
+ if (flags & 1)
+ write(1, c, 1);
+ c++;
+ } else {
+ beep:
+ *c = CONTROL('G');
+ write(1, c, 1);
+ }
+
+ goto loop;
+ }
+
+restore:
+#ifdef unix
+ /* Restore previous tty modes */
+ if (isatty(0))
+ if (tcsetattr(0, TCSAFLUSH, &orig_attr))
+ return NULL;
+
+ signal(SIGINT, SIG_DFL);
+#endif /* unix */
+
+ /* After the secret key is taken from the keyboard, the line feed is
+ written to standard error instead of standard output. That means that
+ anyone using the program from a terminal won't notice, but capturing
+ standard output will get the key words without a newline in front of
+ them. */
+ if (!(flags & 4)) {
+ fprintf(stderr, "\n");
+ fflush(stderr);
+ }
+
+ return buf;
+
+error:
+ *buf = 0;
+ buf = NULL;
+ goto restore;
+}
diff --git a/contrib/opie/libopie/readrec.c b/contrib/opie/libopie/readrec.c
new file mode 100644
index 0000000..c98daaa
--- /dev/null
+++ b/contrib/opie/libopie/readrec.c
@@ -0,0 +1,218 @@
+/* readrec.c: The __opiereadrec() library function.
+
+%%% copyright-cmetz
+This software is Copyright 1996 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Created by cmetz for OPIE 2.3.
+*/
+#include "opie_cfg.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#if HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif /* HAVE_STDLIB_H */
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#endif /* HAVE_FCNTL_H */
+#include <ctype.h>
+#include <errno.h>
+#if DEBUG
+#include <syslog.h>
+#endif /* DEBUG */
+#include "opie.h"
+
+static int parserec FUNCTION((opie), struct opie *opie)
+{
+ char *c, *c2;
+
+ if (!(c2 = strchr(opie->opie_principal = opie->opie_buf, ' ')))
+ return -1;
+
+ while(*c2 == ' ') c2++;
+ *(c2 - 1) = 0;
+
+ if (!(c2 = strchr(c = c2, ' ')))
+ return -1;
+
+ *(c2++) = 0;
+
+ if (!(opie->opie_n = atoi(c)))
+ return -1;
+
+ if (!(c2 = strchr(opie->opie_seed = c2, ' ')))
+ return -1;
+
+ *(c2++) = 0;
+
+ while(*c2 == ' ') c2++;
+
+ if (!(c2 = strchr(opie->opie_val = c2, ' ')))
+ return -1;
+
+ *(c2++) = 0;
+
+ return 0;
+}
+
+static int parseextrec FUNCTION((opie), struct opie *opie)
+{
+ char *c;
+
+ if (!(c = strchr(opie->opie_extbuf, ' ')))
+ return -1;
+
+ *(c++) = 0;
+ while(*c == ' ') c++;
+
+ if (!(c = strchr(opie->opie_reinitkey = c, ' ')))
+ return -1;
+
+ *(c++) = 0;
+
+ return 0;
+}
+
+int __opiereadrec FUNCTION((opie), struct opie *opie)
+{
+ FILE *f = NULL, *f2 = NULL;
+ int rval = -1;
+
+ if (!(f = __opieopen(STD_KEY_FILE, 0, 0644))) {
+#if DEBUG
+ syslog(LOG_DEBUG, "__opiereadrec: __opieopen(STD_KEY_FILE..) failed!");
+#endif /* DEBUG */
+ goto ret;
+ }
+
+ if (!(f2 = __opieopen(EXT_KEY_FILE, 0, 0600))) {
+#if DEBUG
+ syslog(LOG_DEBUG, "__opiereadrec: __opieopen(EXT_KEY_FILE..) failed!");
+#endif /* DEBUG */
+ }
+
+ {
+ int i;
+
+ if ((i = open(STD_KEY_FILE, O_RDWR)) < 0) {
+ opie->opie_flags &= ~__OPIE_FLAGS_RW;
+#if DEBUG
+ syslog(LOG_DEBUG, "__opiereadrec: open(STD_KEY_FILE, O_RDWR) failed: %s", strerror(errno));
+#endif /* DEBUG */
+ } else {
+ close(i);
+ if ((i = open(EXT_KEY_FILE, O_RDWR)) < 0) {
+ opie->opie_flags &= ~__OPIE_FLAGS_RW;
+#if DEBUG
+ syslog(LOG_DEBUG, "__opiereadrec: open(STD_KEY_FILE, O_RDWR) failed: %s", strerror(errno));
+#endif /* DEBUG */
+ } else {
+ close(i);
+ opie->opie_flags |= __OPIE_FLAGS_RW;
+ }
+ }
+ }
+
+ if (opie->opie_buf[0]) {
+ if (fseek(f, opie->opie_recstart, SEEK_SET))
+ goto ret;
+
+ if (fgets(opie->opie_buf, sizeof(opie->opie_buf), f))
+ goto ret;
+
+ if (parserec(opie))
+ goto ret;
+
+ if (opie->opie_extbuf[0]) {
+ if (!f2) {
+#if DEBUG
+ syslog(LOG_DEBUG, "__opiereadrec: can't read ext file, but could before?");
+#endif /* DEBUG */
+ goto ret;
+ }
+
+ if (fseek(f2, opie->opie_extrecstart, SEEK_SET))
+ goto ret;
+
+ if (fgets(opie->opie_extbuf, sizeof(opie->opie_extbuf), f2))
+ goto ret;
+
+ if (parseextrec(opie))
+ goto ret;
+ }
+
+ rval = 0;
+ goto ret;
+ }
+
+ if (!opie->opie_principal)
+ return -1;
+
+ {
+ char *c, principal[OPIE_PRINCIPAL_MAX];
+ int i;
+
+ if (c = strchr(opie->opie_principal, ':'))
+ *c = 0;
+ if (strlen(opie->opie_principal) > OPIE_PRINCIPAL_MAX)
+ (opie->opie_principal)[OPIE_PRINCIPAL_MAX] = 0;
+
+ strcpy(principal, opie->opie_principal);
+
+ do {
+ if ((opie->opie_recstart = ftell(f)) < 0)
+ goto ret;
+
+ if (!fgets(opie->opie_buf, sizeof(opie->opie_buf), f)) {
+ rval = 1;
+ goto ret;
+ }
+
+ if (parserec(opie))
+ goto ret;
+ } while (strcmp(principal, opie->opie_principal));
+
+ if (!f2) {
+ opie->opie_extbuf[0] = rval = 0;
+ goto ret;
+ }
+
+ do {
+ if ((opie->opie_extrecstart = ftell(f2)) < 0)
+ goto ret;
+
+ if (!fgets(opie->opie_extbuf, sizeof(opie->opie_extbuf), f2)) {
+ if (feof(f2)) {
+ opie->opie_reinitkey = NULL;
+ rval = 0;
+ } else
+ rval = 1;
+ goto ret;
+ }
+
+ if (parseextrec(opie))
+ goto ret;
+ } while (strcmp(principal, opie->opie_extbuf));
+
+ rval = 0;
+ }
+
+ret:
+ if (f)
+ fclose(f);
+ if (f2)
+ fclose(f2);
+ return rval;
+}
+
diff --git a/contrib/opie/libopie/unlock.c b/contrib/opie/libopie/unlock.c
new file mode 100644
index 0000000..35c266d
--- /dev/null
+++ b/contrib/opie/libopie/unlock.c
@@ -0,0 +1,103 @@
+/* unlock.c: The opieunlock() library function.
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+Portions of this software are Copyright 1995 by Randall Atkinson and Dan
+McDonald, All Rights Reserved. All Rights under this copyright are assigned
+to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
+License Agreement applies to this software.
+
+ History:
+
+ Modified by cmetz for OPIE 2.3. Do refcounts whether or not
+ we actually lock. Fixed USER_LOCKING=0 case.
+ Modified by cmetz for OPIE 2.22. Added reference count support.
+ Changed lock filename/refcount symbol names to better indicate
+ that they're not user serviceable.
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration.
+ Check for read() == -1. ifdef around unistd.h.
+ Created at NRL for OPIE 2.2 from opiesubr2.c
+*/
+#include "opie_cfg.h"
+#include <string.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <fcntl.h>
+#include "opie.h"
+
+extern int __opie_lockrefcount;
+#if USER_LOCKING
+extern char *__opie_lockfilename;
+#endif /* USER_LOCKING */
+
+/*
+ Just remove the lock, right?
+ Well, not exactly -- we need to make sure it's ours.
+*/
+int opieunlock FUNCTION_NOARGS
+{
+#if USER_LOCKING
+ int fh, rval = -1, pid, t, i;
+ char buffer[128], *c, *c2;
+
+ if (--__opie_lockrefcount > 0)
+ return 0;
+
+ if (!__opie_lockfilename)
+ return -1;
+
+ if (!(fh = open(__opie_lockfilename, O_RDWR, 0600)))
+ goto unlockret;
+
+ if ((i = read(fh, buffer, sizeof(buffer))) < 0)
+ goto unlockret;
+
+ buffer[sizeof(buffer) - 1] = 0;
+ buffer[i - 1] = 0;
+
+ if (!(c = strchr(buffer, '\n')))
+ goto unlockret;
+
+ *(c++) = 0;
+
+ if (!(c2 = strchr(c, '\n')))
+ goto unlockret;
+
+ *(c2++) = 0;
+
+ if (!(pid = atoi(buffer)))
+ goto unlockret;
+
+ if (!(t = atoi(c)))
+ goto unlockret;
+
+ if ((pid != getpid()) && (time(NULL) + OPIE_LOCK_TIMEOUT <= t) &&
+ (!kill(pid, 0))) {
+ rval = 1;
+ goto unlockret1;
+ }
+
+ rval = 0;
+
+unlockret:
+ unlink(__opie_lockfilename);
+
+unlockret1:
+ if (fh)
+ close(fh);
+ free(__opie_lockfilename);
+ __opie_lockfilename = NULL;
+ return rval;
+#else /* USER_LOCKING */
+ if (__opie_lockrefcount-- > 0)
+ return 0;
+
+ return -1;
+#endif /* USER_LOCKING */
+}
diff --git a/contrib/opie/libopie/verify.c b/contrib/opie/libopie/verify.c
new file mode 100644
index 0000000..7388a8a
--- /dev/null
+++ b/contrib/opie/libopie/verify.c
@@ -0,0 +1,255 @@
+/* verify.c: The opieverify() library function.
+
+%%% copyright-cmetz
+This software is Copyright 1996 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Created by cmetz for OPIE 2.3 using the old verify.c as a guide.
+*/
+
+#include "opie_cfg.h"
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#include "opie.h"
+
+#define RESPONSE_STANDARD 0
+#define RESPONSE_WORD 1
+#define RESPONSE_HEX 2
+#define RESPONSE_INIT 3
+#define RESPONSE_INIT_WORD 4
+#define RESPONSE_UNKNOWN 5
+
+struct _rtrans {
+ int type;
+ char *name;
+};
+
+static struct _rtrans rtrans[] = {
+ { RESPONSE_WORD, "word" },
+ { RESPONSE_HEX, "hex" },
+ { RESPONSE_INIT, "init" },
+ { RESPONSE_INIT_WORD, "init-word" },
+ { RESPONSE_STANDARD, "" },
+ { RESPONSE_UNKNOWN, NULL }
+};
+
+static char *algids[] = { NULL, NULL, NULL, "sha1", "md4", "md5" };
+
+static int changed FUNCTION((opie), struct opie *opie)
+{
+ struct opie opie2;
+
+ memset(&opie2, 0, sizeof(struct opie));
+ opie2.opie_principal = opie->opie_principal;
+ if (__opiereadrec(&opie2))
+ return 1;
+
+ if ((opie2.opie_n != opie->opie_n) || strcmp(opie2.opie_val, opie->opie_val) || strcmp(opie2.opie_seed, opie->opie_seed))
+ return 1;
+
+ memset(&opie2, 0, sizeof(struct opie));
+ return 0;
+}
+
+int opieverify FUNCTION((opie, response), struct opie *opie AND char *response)
+{
+ int i, rval = -1;
+ char *c;
+ char key[8], fkey[8], lastkey[8];
+ struct opie nopie;
+
+ if (!opie || !response)
+ goto verret;
+
+ if (!opie->opie_principal)
+#if DEBUG
+ abort();
+#else /* DEBUG */
+ goto verret;
+#endif /* DEBUG */
+
+ if (!opieatob8(lastkey, opie->opie_val))
+ goto verret;
+
+ if (c = strchr(response, ':')) {
+ *(c++) = 0;
+ {
+ struct _rtrans *r;
+ for (r = rtrans; r->name && strcmp(r->name, response); r++);
+ i = r->type;
+ }
+ } else
+ i = RESPONSE_STANDARD;
+
+ switch(i) {
+ case RESPONSE_STANDARD:
+ i = 1;
+
+ if (opieetob(key, response) == 1) {
+ memcpy(fkey, key, sizeof(key));
+ opiehash(fkey, MDX);
+ i = memcmp(fkey, lastkey, sizeof(key));
+ }
+ if (i && opieatob8(key, response)) {
+ memcpy(fkey, key, sizeof(key));
+ opiehash(fkey, MDX);
+ i = memcmp(fkey, lastkey, sizeof(key));
+ }
+ break;
+ case RESPONSE_WORD:
+ i = 1;
+
+ if (opieetob(key, c) == 1) {
+ memcpy(fkey, key, sizeof(key));
+ opiehash(fkey, MDX);
+ i = memcmp(fkey, lastkey, sizeof(key));
+ }
+ break;
+ case RESPONSE_HEX:
+ i = 1;
+
+ if (opieatob8(key, c)) {
+ memcpy(fkey, key, sizeof(key));
+ opiehash(fkey, MDX);
+ i = memcmp(fkey, lastkey, sizeof(key));
+ }
+ break;
+ case RESPONSE_INIT:
+ case RESPONSE_INIT_WORD:
+ {
+ char *c2;
+ char newkey[8], ckxor[8], ck[8], cv[8], cvc[8];
+ char buf[OPIE_SEED_MAX + 48 + 1];
+
+ if (!(c2 = strchr(c, ':')))
+ goto verret;
+
+ *(c2++) = 0;
+
+ if (i == RESPONSE_INIT) {
+ if (!opieatob8(key, c))
+ goto verret;
+ } else {
+ if (opieetob(key, c) != 1)
+ goto verret;
+ }
+
+ memcpy(fkey, key, sizeof(key));
+ opiehash(fkey, MDX);
+
+ if (memcmp(fkey, lastkey, sizeof(key)))
+ goto verret;
+
+ if (changed(opie))
+ goto verret;
+
+ opie->opie_n--;
+
+ if (!opiebtoa8(opie->opie_val, key))
+ goto verret;
+
+ if (__opiewriterec(opie))
+ goto verret;
+
+ if (!(c2 = strchr(c = c2, ':')))
+ goto verret;
+
+ *(c2++) = 0;
+
+ {
+ int j;
+
+ if (_opieparsechallenge(c, &j, &(opie->opie_n), &(opie->opie_seed)) || (j != MDX))
+ goto verret;
+ }
+
+ if (!(c2 = strchr(c = c2, ':')))
+ goto verret;
+
+ *(c2++) = 0;
+
+ if (i == RESPONSE_INIT) {
+ if (!opieatob8(newkey, c))
+ goto verret;
+ } else {
+ if (opieetob(newkey, c) != 1)
+ goto verret;
+ }
+
+ if (!opie->opie_reinitkey || (opie->opie_reinitkey[0] == '*'))
+ goto verwrt;
+
+ if (!(c2 = strchr(c = c2, ':')))
+ goto verret;
+
+ *(c2++) = 0;
+
+ if (i == RESPONSE_INIT) {
+ if (!opieatob8(ckxor, c))
+ goto verret;
+ if (!opieatob8(cv, c2))
+ goto verret;
+ } else {
+ if (opieetob(ckxor, c) != 1)
+ goto verret;
+ if (opieetob(cv, c2) != 1)
+ goto verret;
+ }
+
+ if (!opieatob8(ck, opie->opie_reinitkey))
+ goto verret;
+
+ c = buf;
+ memcpy(c, ck, sizeof(ck)); c += sizeof(ck);
+ memcpy(c, key, sizeof(key)); c += sizeof(key);
+ c += sprintf(c, "%s 499 %s", algids[MDX], opie->opie_seed);
+ memcpy(c, newkey, sizeof(newkey)); c += sizeof(newkey);
+ memcpy(c, ckxor, sizeof(ckxor)); c += sizeof(ckxor);
+ memcpy(c, ck, sizeof(ck)); c += sizeof(ck);
+ opiehashlen(MDX, buf, cvc, (unsigned int)c - (unsigned int)buf);
+
+ if (memcmp(cv, cvc, sizeof(cv)))
+ goto verret;
+
+ for (i = 0; i < 8; i++)
+ ck[i] ^= ckxor[i];
+
+ if (!opiebtoa8(opie->opie_reinitkey, ck))
+ goto verret;
+
+ memcpy(key, newkey, sizeof(key));
+ }
+ goto verwrt;
+ case RESPONSE_UNKNOWN:
+ rval = 1;
+ goto verret;
+ default:
+ rval = -1;
+ goto verret;
+ }
+
+ if (i) {
+ rval = 1;
+ goto verret;
+ }
+
+ if (changed(opie))
+ goto verret;
+
+ opie->opie_n--;
+
+verwrt:
+ if (!opiebtoa8(opie->opie_val, key))
+ goto verret;
+ rval = __opiewriterec(opie);
+
+verret:
+ opieunlock();
+ memset(opie, 0, sizeof(struct opie));
+ return rval;
+}
diff --git a/contrib/opie/libopie/version.c b/contrib/opie/libopie/version.c
new file mode 100644
index 0000000..48b1dc5
--- /dev/null
+++ b/contrib/opie/libopie/version.c
@@ -0,0 +1,27 @@
+/* version.c: The opieversion() library function.
+
+%%% portions-copyright-cmetz
+Portions of this software are Copyright 1996 by Craig Metz, All Rights
+Reserved. The Inner Net License Version 2 applies to these portions of
+the software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+Portions of this software are Copyright 1995 by Randall Atkinson and Dan
+McDonald, All Rights Reserved. All Rights under this copyright are assigned
+to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
+License Agreement applies to this software.
+
+ History:
+
+ Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
+ Created at NRL for OPIE 2.2 from opiesubr.c.
+*/
+#include "opie_cfg.h"
+#include "opie.h"
+
+VOIDRET opieversion FUNCTION_NOARGS
+{
+ printf("\nOPIE %s (%s)\n\n", VERSION, DATE);
+ exit(0);
+}
diff --git a/contrib/opie/libopie/writerec.c b/contrib/opie/libopie/writerec.c
new file mode 100644
index 0000000..6978669
--- /dev/null
+++ b/contrib/opie/libopie/writerec.c
@@ -0,0 +1,85 @@
+/* writerec.c: The __opiewriterec() library function.
+
+%%% copyright-cmetz
+This software is Copyright 1996 by Craig Metz, All Rights Reserved.
+The Inner Net License Version 2 applies to this software.
+You should have received a copy of the license with this software. If
+you didn't get a copy, you may request one from <license@inner.net>.
+
+ History:
+
+ Created by cmetz for OPIE 2.3 from passwd.c.
+*/
+#include "opie_cfg.h"
+
+#include <stdio.h>
+#if TM_IN_SYS_TIME
+#include <sys/time.h>
+#else /* TM_IN_SYS_TIME */
+#include <time.h>
+#endif /* TM_IN_SYS_TIME */
+#include <sys/types.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#if HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif /* HAVE_STDLIB_H */
+#include "opie.h"
+
+char *__opienone = "****************";
+
+int __opiewriterec FUNCTION((opie), struct opie *opie)
+{
+ char buf[17], buf2[64];
+ time_t now;
+ FILE *f, *f2 = NULL;
+ int i = 0;
+
+ time(&now);
+ if (strftime(buf2, sizeof(buf2), " %b %d,%Y %T", localtime(&now)) < 1)
+ return -1;
+
+ if (!(opie->opie_flags & __OPIE_FLAGS_READ)) {
+ struct opie opie2;
+ i = opielookup(&opie2, opie->opie_principal);
+ }
+
+ switch(i) {
+ case 0:
+ if (!(f = __opieopen(STD_KEY_FILE, 1, 0644)))
+ return -1;
+ if (!(f2 = __opieopen(EXT_KEY_FILE, 1, 0600)))
+ return -1;
+ if (fseek(f, opie->opie_recstart, SEEK_SET))
+ return -1;
+ if (fseek(f2, opie->opie_extrecstart, SEEK_SET))
+ return -1;
+ break;
+ case 1:
+ if (!(f = __opieopen(STD_KEY_FILE, 2, 0644)))
+ return -1;
+ if (!(f2 = __opieopen(EXT_KEY_FILE, 2, 0600)))
+ return -1;
+ break;
+ default:
+ return -1;
+ }
+
+ if (fprintf(f, "%s %04d %-16s %s %-21s\n", opie->opie_principal, opie->opie_n, opie->opie_seed, opie->opie_val ? opie->opie_val : __opienone, buf2) < 1)
+ return -1;
+
+ fclose(f);
+
+ if (f2) {
+ if (fprintf(f2, "%-32s %-16s %-77s\n", opie->opie_principal, opie->opie_reinitkey ? opie->opie_reinitkey : __opienone, "") < 1)
+ return -1;
+
+ fclose(f2);
+ }
+
+ return 0;
+}
OpenPOWER on IntegriCloud