summaryrefslogtreecommitdiff
path: root/libexec/login_token
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2000-12-20 01:41:54 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2000-12-20 01:41:54 +0000
commitcffcf376225c41635be9c952a0a26c0c0f12d4e7 (patch)
treed56292c95b8b6140045f29baf9e41f0c6d177b51 /libexec/login_token
parent005d89db1e301780453d7ba2b1ba4f9c0c7ae81a (diff)
Provides ActivCard, CRYPTOCard and SNK-004 authentication from BSDi
Will be used when BSD authentication is enabled
Diffstat (limited to 'libexec/login_token')
-rw-r--r--libexec/login_token/Makefile27
-rw-r--r--libexec/login_token/init.c126
-rw-r--r--libexec/login_token/login_token.8102
-rw-r--r--libexec/login_token/login_token.c174
-rw-r--r--libexec/login_token/token.c411
-rw-r--r--libexec/login_token/token.h84
-rw-r--r--libexec/login_token/tokendb.c343
-rw-r--r--libexec/login_token/tokendb.h80
8 files changed, 1347 insertions, 0 deletions
diff --git a/libexec/login_token/Makefile b/libexec/login_token/Makefile
new file mode 100644
index 00000000000..840383dddd7
--- /dev/null
+++ b/libexec/login_token/Makefile
@@ -0,0 +1,27 @@
+# $OpenBSD: Makefile,v 1.1 2000/12/20 01:41:52 millert Exp $
+
+PROG= login_token
+SRCS= login_token.c init.c token.c tokendb.c
+MAN= login_token.8
+DPADD= ${LIBDES}
+LDADD= -ldes
+
+TOKENS= activ crypto snk
+
+MLINKS= login_token.8 login_activ.8
+MLINKS+=login_token.8 login_crypto.8
+MLINKS+=login_token.8 login_snk.8
+
+afterinstall:
+ for i in ${TOKENS} ; do \
+ cd ${DESTDIR}/${BINDIR} && \
+ rm -f login_$$i && \
+ ln ${PROG} login_$$i ; \
+ done
+
+BINOWN= root
+BINGRP= auth
+BINMODE=4555
+BINDIR= /usr/libexec/auth
+
+.include <bsd.prog.mk>
diff --git a/libexec/login_token/init.c b/libexec/login_token/init.c
new file mode 100644
index 00000000000..eaeadefda34
--- /dev/null
+++ b/libexec/login_token/init.c
@@ -0,0 +1,126 @@
+/* $OpenBSD: init.c,v 1.1 2000/12/20 01:41:53 millert Exp $ */
+
+/*-
+ * Copyright (c) 1996 Berkeley Software Design, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Berkeley Software Design,
+ * Inc.
+ * 4. The name of Berkeley Software Design, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * BSDI $From: init.c,v 1.2 1996/09/05 23:17:06 prb Exp $
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "token.h"
+#include "tokendb.h"
+
+static struct token_types types[] = {
+ { "activ", "ActivCard", "/etc/activ.db", "012345",
+ TOKEN_HEXINIT,
+ TOKEN_DECMODE | TOKEN_HEXMODE, /* avail */
+ TOKEN_HEXMODE }, /* default */
+ { "crypto", "CRYPTOCard", "/etc/crypto.db", "012345",
+ TOKEN_HEXINIT | TOKEN_PHONE,
+ TOKEN_DECMODE | TOKEN_HEXMODE | TOKEN_PHONEMODE | TOKEN_RIM,
+ TOKEN_HEXMODE }, /* default */
+ { "snk", "SNK 004", "/etc/snk.db", "222333",
+ 0,
+ TOKEN_DECMODE | TOKEN_HEXMODE, /* avail */
+ TOKEN_DECMODE }, /* default */
+ { "token", "X9.9 Token", "/etc/x99token.db", "012345",
+ TOKEN_HEXINIT,
+ TOKEN_DECMODE | TOKEN_HEXMODE | TOKEN_RIM, /* avail */
+ TOKEN_HEXMODE }, /* default */
+};
+
+static struct {
+ char *name;
+ u_int value;
+} modes[] = {
+ { "hexadecimal", TOKEN_HEXMODE },
+ { "hex", TOKEN_HEXMODE },
+ { "decimal", TOKEN_DECMODE },
+ { "dec", TOKEN_DECMODE },
+ { "phonebook", TOKEN_PHONEMODE },
+ { "phone", TOKEN_PHONEMODE },
+ { "reduced-input", TOKEN_RIM },
+ { "rim", TOKEN_RIM }
+};
+
+int
+token_init(char *path)
+{
+ char *p;
+ int i;
+
+ if ((p = strrchr(path, '/')) && p[1] != '\0')
+ path = p + 1;
+
+ for (i = 0; i < sizeof(types)/sizeof(types[0]); ++i)
+ if (strstr(path, types[i].name) != NULL) {
+ tt = &types[i];
+ return (0);
+ }
+ if ((p = strstr(path, "token")) != NULL) {
+ fprintf(stderr, "Please invoke as one of:");
+ for (i = 0; i < sizeof(types)/sizeof(types[0]); ++i)
+ fprintf(stderr, " %.*s%s%s",
+ p - path, path, types[i].name, p + 5);
+ fprintf(stderr, "\n");
+ exit(1);
+
+ }
+ return (-1);
+}
+
+u_int
+token_mode(char *mode)
+{
+ int i;
+
+ for (i = 0; i < sizeof(modes)/sizeof(modes[0]); ++i)
+ if (strstr(mode, modes[i].name) != NULL)
+ return (tt->modes & modes[i].value);
+ return (0);
+ return (0);
+}
+
+char *
+token_getmode(u_int mode)
+{
+ int i;
+ static char buf[32];
+
+ for (i = 0; i < sizeof(modes)/sizeof(modes[0]); ++i)
+ if (mode == modes[i].value)
+ return(modes[i].name);
+ snprintf(buf, sizeof(buf), "0x%x", mode);
+ return(buf);
+}
diff --git a/libexec/login_token/login_token.8 b/libexec/login_token/login_token.8
new file mode 100644
index 00000000000..404137656cb
--- /dev/null
+++ b/libexec/login_token/login_token.8
@@ -0,0 +1,102 @@
+.\" $OpenBSD: login_token.8,v 1.1 2000/12/20 01:41:53 millert Exp $
+.\"
+.\" Copyright (c) 1995 Berkeley Software Design, Inc. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Berkeley Software Design,
+.\" Inc.
+.\" 4. The name of Berkeley Software Design, Inc. may not be used to endorse
+.\" or promote products derived from this software without specific prior
+.\" written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN, INC. ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN, INC. BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Dd September 26, 1995
+.Dt LOGIN_TOKEN 8
+.Os
+.Sh NAME
+.Nm login_activ , login_crypto , login_snk
+.Nd provide ActivCard, CRYPTOCard and SNK-004 authentication
+.Sh SYNOPSIS
+.Nm login_token
+.Op Fl s Ar service
+.Op Fl v Ar name=value
+.Ar user
+.Op Ar class
+.Sh DESCRIPTION
+.Pp
+The
+.Nm login_token
+program implements a X9.9 token card challenge response authentication
+mechanism (see
+.Xr login.conf 5 ) .
+It must be invoked by one of the names:
+.Nm login_activ , login_crypto ,
+or
+.Nm login_snk .
+.Pp
+Available options are:
+.Bl -tag -width indent
+.It Fl s
+Specify the service. Currently only
+.Li challenge ,
+.Li login ,
+and
+.Li response
+are supported.
+.It Fl v
+This option and its value are ignored.
+.El
+.Pp
+.Nm login_token
+will look up
+.Ar user
+in the the appropriate database file, depending on what name it was called as:
+.Pa /etc/activ.db ,
+.Pa /etc/crypto.db ,
+or
+.Pa /etc/snk.db .
+It will then will issue a challenge, and if the user
+is able to correctly respond (by using the appropriate token)
+the user will be authenticated.
+The
+.Ar class
+argument is unused.
+.Sh DIAGNOSTICS
+Diagnostic messages are logged via syslog(3) with the LOG_AUTH facility.
+.Sh FILES
+.Bl -tag -width xetcxcrypto.db
+.It Pa /etc/activ.db
+data base of information for the ActivCard tokens.
+.It Pa /etc/crypto.db
+data base of information for the CRYPTOCard tokens.
+.It Pa /etc/snk.db
+data base of information for the SNK-004 tokens.
+.El
+.Sh SEE ALSO
+.Xr syslog 3 ,
+.Xr login.conf 5 ,
+.Xr tokenadm 8 ,
+.Xr tokenctl 8 ,
+.Xr tokeninit 8
+.Sh AUTHOR
+Jack Flory <jpf@mig.com>
diff --git a/libexec/login_token/login_token.c b/libexec/login_token/login_token.c
new file mode 100644
index 00000000000..1e6461460d4
--- /dev/null
+++ b/libexec/login_token/login_token.c
@@ -0,0 +1,174 @@
+/* $OpenBSD: login_token.c,v 1.1 2000/12/20 01:41:53 millert Exp $ */
+
+/*-
+ * Copyright (c) 1995, 1996 Berkeley Software Design, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Berkeley Software Design,
+ * Inc.
+ * 4. The name of Berkeley Software Design, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * BSDI $From: login_token.c,v 1.2 1996/09/04 05:33:05 prb Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <err.h>
+#include <readpassphrase.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <login_cap.h>
+#include <bsd_auth.h>
+
+#include "token.h"
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ FILE *back = NULL;
+ char *class = 0;
+ char *username = 0;
+ char *instance;
+ char challenge[1024];
+ char response[1024];
+ char *pp;
+ int c;
+ int mode = 0;
+ struct rlimit cds;
+
+ (void)signal(SIGQUIT, SIG_IGN);
+ (void)signal(SIGINT, SIG_IGN);
+ (void)setpriority(PRIO_PROCESS, 0, 0);
+
+ openlog(NULL, LOG_ODELAY, LOG_AUTH);
+
+ cds.rlim_cur = 0;
+ cds.rlim_max = 0;
+ if (setrlimit(RLIMIT_CORE, &cds) < 0)
+ syslog(LOG_ERR, "couldn't set core dump size to 0: %m");
+
+ if (token_init(argv[0]) < 0) {
+ syslog(LOG_ERR, "unknown token type");
+ errx(1, "unknown token type");
+ }
+
+ while ((c = getopt(argc, argv, "ds:v:")) != EOF)
+ switch(c) {
+ case 'd': /* to remain undocumented */
+ back = stdout;
+ break;
+ case 'v':
+ break;
+ case 's': /* service */
+ if (strcmp(optarg, "login") == 0)
+ mode = 0;
+ else if (strcmp(optarg, "challenge") == 0)
+ mode = 1;
+ else if (strcmp(optarg, "response") == 0)
+ mode = 2;
+ else {
+ syslog(LOG_ERR, "%s: invalid service", optarg);
+ exit(1);
+ }
+ break;
+ default:
+ syslog(LOG_ERR, "usage error");
+ exit(1);
+ }
+
+ switch(argc - optind) {
+ case 2:
+ class = argv[optind + 1];
+ case 1:
+ username = argv[optind];
+ break;
+ default:
+ syslog(LOG_ERR, "usage error");
+ exit(1);
+ }
+
+
+ if (back == NULL && (back = fdopen(3, "r+")) == NULL) {
+ syslog(LOG_ERR, "reopening back channel");
+ exit(1);
+ }
+ if (mode == 2) {
+ mode = 0;
+ c = -1;
+ while (++c < sizeof(challenge) &&
+ read(3, &challenge[c], 1) == 1) {
+ if (challenge[c] == '\0' && ++mode == 2)
+ break;
+ if (challenge[c] == '\0' && mode == 1)
+ pp = challenge + c + 1;
+ }
+ if (mode < 2) {
+ syslog(LOG_ERR, "protocol error on back channel");
+ exit(1);
+ }
+ } else {
+ tokenchallenge(username, challenge, sizeof(challenge),
+ tt->proper);
+ if (mode == 1) {
+ fprintf(back, BI_VALUE " challenge %s\n",
+ auth_mkvalue(challenge));
+ fprintf(back, BI_CHALLENGE "\n");
+ exit(0);
+ }
+
+ pp = readpassphrase(challenge, response, sizeof(response), 0);
+ if (!pp || *pp == '\0') {
+ char buf[64];
+ snprintf(buf, sizeof(buf), "%s Response [echo on]: ",
+ tt->proper);
+ pp = readpassphrase(buf, response, sizeof(response),
+ RPP_ECHO_ON);
+ }
+ }
+
+ if (tokenverify(username, challenge, pp) == 0) {
+ fprintf(back, BI_AUTH "\n");
+
+ if ((instance = strchr(username, '.'))) {
+ *instance++ = 0;
+ if (strcmp(instance, "root") == 0)
+ fprintf(back, BI_ROOTOKAY "\n");
+ }
+ fprintf(back, BI_SECURE "\n");
+ exit(0);
+ }
+
+ fprintf(back, BI_REJECT "\n");
+ exit(1);
+}
diff --git a/libexec/login_token/token.c b/libexec/login_token/token.c
new file mode 100644
index 00000000000..5ac24a926e7
--- /dev/null
+++ b/libexec/login_token/token.c
@@ -0,0 +1,411 @@
+/* $OpenBSD: token.c,v 1.1 2000/12/20 01:41:53 millert Exp $ */
+
+/*-
+ * Copyright (c) 1995 Berkeley Software Design, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Berkeley Software Design,
+ * Inc.
+ * 4. The name of Berkeley Software Design, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * BSDI $From: token.c,v 1.2 1996/08/28 22:07:55 prb Exp $
+ */
+
+/*
+ * DES functions for one-way encrypting Authentication Tokens.
+ * All knowledge of DES is confined to this file.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <ctype.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <des.h>
+
+#include "token.h"
+#include "tokendb.h"
+
+/*
+ * Define a union of various types of arguments to DES functions.
+ * All native DES types are modulo 8 bytes in length. Cipher text
+ * needs a trailing null byte.
+ */
+
+typedef union {
+ des_cblock cb;
+ char ct[9];
+ unsigned long ul[2];
+} TOKEN_CBlock;
+
+/*
+ * Static definition of random number challenge for token.
+ * Challenge length is 8 bytes, left-justified with trailing null byte.
+ */
+
+static TOKEN_CBlock tokennumber;
+
+/*
+ * Static function prototypes
+ */
+
+static long tokenrandomnumber(void);
+static void tokenseed(des_cblock);
+static void lcase(char *);
+static void h2d(char *);
+static void h2cb(char *, TOKEN_CBlock *);
+static void cb2h(TOKEN_CBlock, char *);
+
+/*
+ * Generate random DES cipherblock seed. Feedback key into
+ * new_random_key to strengthen.
+ */
+
+static void
+tokenseed(des_cblock cb)
+{
+ static int first_time = 1;
+
+ if (first_time) {
+ first_time = 0;
+ des_random_key(cb);
+ des_init_random_number_generator(cb);
+ }
+ des_new_random_key(cb);
+}
+
+/*
+ * Generate a random key of eight decimal digits. Actually,
+ * with the CRYPTOCard, this could be up to 64 digits.
+ * This string must be zero filled
+ * and padded to a 64-bit boundary with a trailing null byte.
+ * It could also be hex, but decimal is easier for the user
+ * to enter into the token.
+ */
+
+static long
+tokenrandomnumber(void)
+{
+ TOKEN_CBlock seed;
+
+ tokenseed(seed.cb);
+ return (((seed.ul[0] ^ seed.ul[1]) % 99999999));
+}
+
+/*
+ * Send a random challenge string to the token. The challenge
+ * is always base 10 as there are no alpha keys on the keyboard.
+ */
+
+void
+tokenchallenge(char *user, char *challenge, int size, char *card_type)
+{
+ TOKENDB_Rec tr;
+ TOKEN_CBlock cb;
+ des_key_schedule ks;
+ int r, c;
+
+ r = 1; /* no reduced input mode by default! */
+
+ if ((tt->modes & TOKEN_RIM) &&
+ tokendb_getrec(user, &tr) == 0 &&
+ (tr.mode & TOKEN_RIM)) {
+ c = 0;
+ while ((r = tokendb_lockrec(user, &tr, TOKEN_LOCKED)) == 1) {
+ if (c++ >= 60)
+ break;
+ sleep(1);
+ }
+ tr.flags &= ~TOKEN_LOCKED;
+ if (r == 0 && tr.rim[0]) {
+ h2cb(tr.secret, &cb);
+ des_fixup_key_parity(&cb.cb);
+ des_key_sched(&cb.cb, ks);
+ des_ecb_encrypt(&tr.rim, &cb.cb, ks, DES_ENCRYPT);
+ memcpy(tr.rim, cb.cb, 8);
+ for (r = 0; r < 8; ++r) {
+ if ((tr.rim[r] &= 0xf) > 9)
+ tr.rim[r] -= 10;
+ tr.rim[r] |= 0x30;
+ }
+ r = 0; /* reset it back */
+ memcpy(tokennumber.ct, tr.rim, 8);
+ tokennumber.ct[8] = 0;
+ tokendb_putrec(user, &tr);
+ }
+ }
+ if (r != 0 || tr.rim[0] == '\0') {
+ memset(tokennumber.ct, 0, sizeof(tokennumber));
+ snprintf(tokennumber.ct, sizeof(tokennumber.ct), "%08.8lu",
+ tokenrandomnumber());
+ if (r == 0) {
+ memcpy(tr.rim, tokennumber.ct, 8);
+ tokendb_putrec(user, &tr);
+ }
+ }
+
+ snprintf(challenge, size, "%s Challenge \"%s\"\r\n%s Response: ",
+ card_type, tokennumber.ct, card_type);
+}
+
+/*
+ * Verify response from user against token's predicted cipher
+ * of the random number challenge.
+ */
+
+int
+tokenverify(char *username, char *challenge, char *response)
+{
+ char *state;
+ TOKENDB_Rec tokenrec;
+ TOKEN_CBlock tmp;
+ TOKEN_CBlock cmp_text;
+ TOKEN_CBlock user_seed;
+ TOKEN_CBlock cipher_text;
+ des_key_schedule key_schedule;
+
+
+ memset(cmp_text.ct, 0, sizeof(cmp_text));
+ memset(user_seed.ct, 0, sizeof(user_seed));
+ memset(cipher_text.ct, 0, sizeof(cipher_text));
+ memset(tokennumber.ct, 0, sizeof(tokennumber));
+
+ state = strtok(challenge, "\"");
+ state = strtok(NULL, "\"");
+ tmp.ul[0] = strtoul(state, NULL, 10);
+ snprintf(tokennumber.ct, sizeof(tokennumber.ct), "%08.8lu",tmp.ul[0]);
+
+ /*
+ * Retrieve the db record for the user. Nuke it as soon as
+ * we have translated out the user's shared secret just in
+ * case we (somehow) get core dumped...
+ */
+
+ if (tokendb_getrec(username, &tokenrec))
+ return (-1);
+
+ h2cb(tokenrec.secret, &user_seed);
+ memset((char*)&tokenrec.secret, 0, sizeof(tokenrec.secret));
+
+ if (!(tokenrec.flags & TOKEN_ENABLED))
+ return (-1);
+
+ /*
+ * Compute the anticipated response in hex. Nuke the user's
+ * shared secret asap.
+ */
+
+ des_fixup_key_parity(&user_seed.cb);
+ des_key_sched(&user_seed.cb, key_schedule);
+ memset(user_seed.ct, 0, sizeof(user_seed.ct));
+ des_ecb_encrypt(&tokennumber.cb, &cipher_text.cb, key_schedule,
+ DES_ENCRYPT);
+
+ /*
+ * The token thinks it's descended from VAXen. Deal with i386
+ * endian-ness of binary cipher prior to generating ascii from first
+ * 32 bits.
+ */
+
+ HTONL(cipher_text.ul[0]);
+ snprintf(cmp_text.ct, sizeof(cmp_text.ct), "%08.8lx", cipher_text.ul[0]);
+
+ if (tokenrec.mode & TOKEN_PHONEMODE) {
+ /*
+ * If we are a CRYPTOCard, we need to see if we are in
+ * "telephone number mode". If so, transmogrify the fourth
+ * digit of the cipher. Lower case response just in case
+ * it's * hex. Compare hex cipher with anticipated response
+ * from token.
+ */
+
+ lcase(response);
+
+ if (response[3] == '-')
+ cmp_text.ct[3] = '-';
+ }
+
+ if ((tokenrec.mode & TOKEN_HEXMODE) && !strcmp(response, cmp_text.ct))
+ return (0);
+
+ /*
+ * No match against the computed hex cipher. The token could be
+ * in decimal mode. Pervert the string to magic decimal equivalent.
+ */
+
+ h2d(cmp_text.ct);
+
+ if ((tokenrec.mode & TOKEN_DECMODE) && !strcmp(response, cmp_text.ct))
+ return (0);
+
+ return (-1);
+}
+
+/*
+ * Initialize a new user record in the token database.
+ */
+
+int
+tokenuserinit(int flags, char *username, unsigned char *usecret, unsigned mode)
+{
+ TOKENDB_Rec tokenrec;
+ TOKEN_CBlock secret;
+ TOKEN_CBlock nulls;
+ TOKEN_CBlock checksum;
+ TOKEN_CBlock checktxt;
+ des_key_schedule key_schedule;
+
+ /*
+ * If no user secret passed in, create one
+ */
+
+ if ( (flags & TOKEN_GENSECRET) )
+ tokenseed(secret.cb);
+ else {
+ memset(&secret, 0, sizeof(secret));
+ memcpy(&secret, usecret, sizeof(des_cblock));
+ des_fixup_key_parity(&secret.cb);
+ }
+
+ /*
+ * Check if the db record already exists. If no
+ * force-init flag and it exists, go away. Else,
+ * create the user's db record and put to the db.
+ */
+
+
+ if (!(flags & TOKEN_FORCEINIT) &&
+ tokendb_getrec(username, &tokenrec) == 0)
+ return (1);
+
+ memset(&tokenrec, 0, sizeof(tokenrec));
+ strncpy(tokenrec.uname, username, sizeof(tokenrec.uname));
+ cb2h(secret, tokenrec.secret);
+ tokenrec.mode = 0;
+ tokenrec.flags = TOKEN_ENABLED | TOKEN_USEMODES;
+ tokenrec.mode = mode;
+ memset(tokenrec.reserved_char1, '0', sizeof(tokenrec.reserved_char1));
+ memset(tokenrec.reserved_char2, '0', sizeof(tokenrec.reserved_char2));
+
+ if (tokendb_putrec(username, &tokenrec))
+ return (-1);
+
+ /*
+ * Check if the shared secret was generated here. If so, we
+ * need to inform the user about it in order that it can be
+ * programmed into the token. See tokenverify() (above) for
+ * discussion of cipher generation.
+ */
+
+ if (!(flags & TOKEN_GENSECRET))
+ return (0);
+
+ printf("Shared secret for %s\'s token: "
+ "%03o %03o %03o %03o %03o %03o %03o %03o\n",
+ username, secret.cb[0], secret.cb[1], secret.cb[2], secret.cb[3],
+ secret.cb[4], secret.cb[5], secret.cb[6], secret.cb[7]);
+
+
+ des_key_sched(&secret.cb, key_schedule);
+ memset(&nulls, 0, sizeof(nulls));
+ des_ecb_encrypt(&nulls.cb, &checksum.cb, key_schedule, DES_ENCRYPT);
+ HTONL(checksum.ul[0]);
+ snprintf(checktxt.ct, sizeof(checktxt.ct), "%08.8lx", checksum.ul[0]);
+ printf("Hex Checksum: \"%s\"", checktxt.ct);
+
+ h2d(checktxt.ct);
+ printf("\tDecimal Checksum: \"%s\"\n", checktxt.ct);
+
+ return (0);
+}
+
+/*
+ * Magically transform a hex character string into a decimal character
+ * string as defined by the token card vendor. The string should have
+ * been lowercased by now.
+ */
+
+static void
+h2d(char *cp)
+{
+ int i;
+
+ for (i=0; i<sizeof(des_cblock); i++, cp++) {
+ if (*cp >= 'a' && *cp <= 'f')
+ *cp = tt->map[*cp - 'a'];
+ }
+}
+
+/*
+ * Translate an hex 16 byte ascii representation of an unsigned
+ * integer to a des_cblock.
+ */
+
+static void
+h2cb(char *hp, TOKEN_CBlock *cb)
+{
+ char scratch[9];
+
+ strlcpy(scratch, hp, sizeof(scratch));
+ cb->ul[0] = strtoul(scratch, NULL, 16);
+
+ strlcpy(scratch, hp + 8, sizeof(scratch));
+ cb->ul[1] = strtoul(scratch, NULL, 16);
+}
+
+/*
+ * Translate a des_cblock to an 16 byte ascii hex representation.
+ */
+
+static void
+cb2h(TOKEN_CBlock cb, char* hp)
+{
+ char scratch[17];
+
+ snprintf(scratch, 9, "%08.8lx", cb.ul[0]);
+ snprintf(scratch+8, 9, "%08.8lx", cb.ul[1]);
+ memcpy(hp, scratch, 16);
+}
+
+/*
+ * Lowercase possible hex response
+ */
+
+static void
+lcase(char *cp)
+{
+ while (*cp) {
+ if (isupper(*cp))
+ *cp = tolower(*cp);
+ cp++;
+ }
+}
diff --git a/libexec/login_token/token.h b/libexec/login_token/token.h
new file mode 100644
index 00000000000..e1d5baf54b6
--- /dev/null
+++ b/libexec/login_token/token.h
@@ -0,0 +1,84 @@
+/* $OpenBSD: token.h,v 1.1 2000/12/20 01:41:53 millert Exp $ */
+
+/*-
+ * Copyright (c) 1995 Berkeley Software Design, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Berkeley Software Design,
+ * Inc.
+ * 4. The name of Berkeley Software Design, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * BSDI $From: token.h,v 1.1 1996/08/26 20:13:10 prb Exp $
+ */
+
+/*
+ * Operations accepted by the token admin commands
+ */
+
+#define TOKEN_DISABLE 0x1 /* disable user account */
+#define TOKEN_ENABLE 0x2 /* enable user account */
+#define TOKEN_INITUSER 0x4 /* add/init user account */
+#define TOKEN_RMUSER 0x8 /* remove user account */
+#define TOKEN_UNLOCK 0x10 /* force unlock db record */
+
+/*
+ * Flags for options to modify TOKEN_INITUSER
+ */
+
+#define TOKEN_FORCEINIT 0x100 /* reinit existing account */
+#define TOKEN_GENSECRET 0x200 /* gen shared secret for token */
+
+/*
+ * Structure describing different token cards
+ */
+struct token_types {
+ char *name; /* name of card */
+ char *proper; /* proper name of card */
+ char *db; /* path to database */
+ char map[6]; /* how A-F map to decimal */
+ int options; /* varios available options */
+ u_int modes; /* available modes */
+ u_int defmode; /* default mode (if none specified) */
+};
+
+struct token_types *tt; /* what type we are running as now */
+
+/*
+ * Options
+ */
+#define TOKEN_PHONE 0x0001 /* Allow phone number representation */
+#define TOKEN_HEXINIT 0x0002 /* Allow initialization in hex (and octal) */
+
+/*
+ * Function prototypes for commands involving intimate DES knowledge
+ */
+
+extern void tokenchallenge(char *, char *, int, char *);
+extern int tokenverify(char *, char *, char *);
+extern int tokenuserinit(int, char *, u_char *, u_int);
+extern int token_init(char *);
+extern u_int token_mode(char *);
+extern char * token_getmode(u_int);
diff --git a/libexec/login_token/tokendb.c b/libexec/login_token/tokendb.c
new file mode 100644
index 00000000000..bfc021ac4aa
--- /dev/null
+++ b/libexec/login_token/tokendb.c
@@ -0,0 +1,343 @@
+/* $OpenBSD: tokendb.c,v 1.1 2000/12/20 01:41:53 millert Exp $ */
+
+/*-
+ * Copyright (c) 1995 Berkeley Software Design, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Berkeley Software Design,
+ * Inc.
+ * 4. The name of Berkeley Software Design, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * BSDI $From: tokendb.c,v 1.1 1996/08/26 20:13:10 prb Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <ctype.h>
+#include <db.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "token.h"
+#include "tokendb.h"
+
+static DB *tokendb;
+
+/*
+ * Static function prototypes
+ */
+
+static int tokendb_open(void);
+static void tokendb_close(void);
+
+/*
+ * Retrieve a user record from the token database file
+ */
+
+int
+tokendb_getrec(char *username, TOKENDB_Rec *tokenrec)
+{
+ DBT key;
+ DBT data;
+ int status = 0;
+
+ key.data = username;
+ key.size = strlen(username) + 1;
+ memset(&data, 0, sizeof(data));
+
+ if (tokendb_open())
+ return(-1);
+
+ status = (tokendb->get)(tokendb, &key, &data, 0);
+ tokendb_close();
+
+ switch (status) {
+ case 1:
+ return(ENOENT);
+ case -1:
+ return(-1);
+ }
+ memcpy(tokenrec, data.data, sizeof(TOKENDB_Rec));
+ if ((tokenrec->flags & TOKEN_USEMODES) == 0)
+ tokenrec->mode = tt->modes & ~TOKEN_RIM;
+ return (0);
+}
+
+/*
+ * Put a user record to the token database file.
+ */
+
+int
+tokendb_putrec(char *username, TOKENDB_Rec *tokenrec)
+{
+ DBT key;
+ DBT data;
+ int status = 0;
+
+ key.data = username;
+ key.size = strlen(username) + 1;
+
+ if (tokenrec->mode)
+ tokenrec->flags |= TOKEN_USEMODES;
+ data.data = tokenrec;
+ data.size = sizeof(TOKENDB_Rec);
+
+ if (!tokendb_open()) {
+ if (flock((tokendb->fd)(tokendb), LOCK_EX)) {
+ tokendb_close();
+ return (-1);
+ }
+ status = (tokendb->put)(tokendb, &key, &data, 0);
+ }
+ tokendb_close();
+ return (status);
+}
+
+/*
+ * Remove a user record from the token database file.
+ */
+
+int
+tokendb_delrec(char *username)
+{
+ DBT key;
+ DBT data;
+ int status = 0;
+
+ key.data = username;
+ key.size = strlen(username) + 1;
+ memset(&data, 0, sizeof(data));
+
+ if (!tokendb_open()) {
+ if (flock((tokendb->fd)(tokendb), LOCK_EX)) {
+ tokendb_close();
+ return (-1);
+ }
+ status = (tokendb->del)(tokendb, &key, 0);
+ }
+ tokendb_close();
+ return (status);
+}
+
+/*
+ * Open the token database. In order to expedite access in
+ * heavily loaded conditions, we employ a N1 lock method.
+ * Updates should be brief, so all locks wait infinitely.
+ * Wait for a read (shared) lock as all updates read first.
+ */
+
+static int
+tokendb_open(void)
+{
+ int must_set_perms = 0;
+ struct stat statb;
+
+ if (stat(tt->db, &statb) < 0) {
+ if (errno != ENOENT)
+ return (-1);
+ must_set_perms++;
+ } else {
+ if (statb.st_uid != 0 || statb.st_gid != 0) {
+#ifdef PARANOID
+ printf("Authentication disabled\n");
+ fflush(stdout);
+ syslog(LOG_ALERT,
+ "POTENTIAL COMPROMISE of %s. Owner was %d, "
+ "Group was %d", tt->db, statb.st_uid, statb.st_gid);
+ return (-1);
+#else
+ must_set_perms++;
+#endif
+ }
+ if ((statb.st_mode & 0777) != 0600) {
+#ifdef PARANOID
+ printf("Authentication disabled\n");
+ fflush(stdout);
+ syslog(LOG_ALERT,
+ "POTENTIAL COMPROMISE of %s. Mode was %o",
+ tt->db, statb.st_mode);
+ return (-1);
+#else
+ must_set_perms++;
+#endif
+ }
+ }
+ if (!(tokendb =
+ dbopen(tt->db, O_CREAT | O_RDWR, 0600, DB_BTREE, 0)) )
+ return (-1);
+
+ if (flock((tokendb->fd)(tokendb), LOCK_SH)) {
+ (tokendb->close)(tokendb);
+ return (-1);
+ }
+ if (must_set_perms && chown(tt->db, 0, 0))
+ syslog(LOG_INFO,
+ "Can't set owner/group of %s errno=%m", tt->db);
+
+ return (0);
+}
+
+/*
+ * Close the token database. We are holding an unknown lock.
+ * Release it, then close the db. Since little can be done
+ * about errors, we ignore them.
+ */
+
+static void
+tokendb_close(void)
+{
+ (void)flock((tokendb->fd)(tokendb), LOCK_UN);
+ (tokendb->close)(tokendb);
+}
+
+/*
+ * Retrieve the first user record from the database, leaving the
+ * database open for the next retrieval. If the march thru the
+ * the database is aborted before end-of-file, the caller should
+ * call tokendb_close to release the read lock.
+ */
+
+int
+tokendb_firstrec(int reverse_flag, TOKENDB_Rec *tokenrec)
+{
+ DBT key;
+ DBT data;
+ int status = 0;
+
+ memset(&data, 0, sizeof(data));
+
+ if (!tokendb_open()) {
+ status = (tokendb->seq)(tokendb, &key, &data,
+ reverse_flag ? R_LAST : R_FIRST);
+ }
+ if (status) {
+ tokendb_close();
+ return (status);
+ }
+ if (!data.data) {
+ tokendb_close();
+ return (ENOENT);
+ }
+ memcpy(tokenrec, data.data, sizeof(TOKENDB_Rec));
+ if ((tokenrec->flags & TOKEN_USEMODES) == 0)
+ tokenrec->mode = tt->modes & ~TOKEN_RIM;
+ return (0);
+}
+
+/*
+ * Retrieve the next sequential user record from the database. Close
+ * the database only on end-of-file or error.
+ */
+
+
+int
+tokendb_nextrec(int reverse_flag, TOKENDB_Rec *tokenrec)
+{
+ DBT key;
+ DBT data;
+ int status;
+
+ memset(&data, 0, sizeof(data));
+
+ status = (tokendb->seq)(tokendb, &key, &data,
+ reverse_flag ? R_PREV : R_NEXT);
+
+ if (status) {
+ tokendb_close();
+ return (status);
+ }
+ if (!data.data) {
+ tokendb_close();
+ return (ENOENT);
+ }
+ memcpy(tokenrec, data.data, sizeof(TOKENDB_Rec));
+ if ((tokenrec->flags & TOKEN_USEMODES) == 0)
+ tokenrec->mode = tt->modes & ~TOKEN_RIM;
+ return (0);
+}
+
+/*
+ * Retrieve and lock a user record. Since there are no facilities in
+ * BSD for record locking, we hack a bit lock into the user record.
+ */
+
+int
+tokendb_lockrec(char *username, TOKENDB_Rec *tokenrec, unsigned recflags)
+{
+ DBT key;
+ DBT data;
+ int status;
+
+ key.data = username;
+ key.size = strlen(username) + 1;
+ memset(&data, 0, sizeof(data));
+
+ if (tokendb_open())
+ return(-1);
+
+ if (flock((tokendb->fd)(tokendb), LOCK_EX)) {
+ tokendb_close();
+ return(-1);
+ }
+ switch ((tokendb->get)(tokendb, &key, &data, 0)) {
+ case 1:
+ tokendb_close();
+ return (ENOENT);
+ case -1:
+ tokendb_close();
+ return(-1);
+ }
+ memcpy(tokenrec, data.data, sizeof(TOKENDB_Rec));
+
+ if ((tokenrec->flags & TOKEN_LOCKED)||(tokenrec->flags & recflags)) {
+ tokendb_close();
+ return(1);
+ }
+ data.data = tokenrec;
+ data.size = sizeof(TOKENDB_Rec);
+
+ time(&tokenrec->lock_time);
+ tokenrec->flags |= recflags;
+ status = (tokendb->put)(tokendb, &key, &data, 0);
+ tokendb_close();
+ if (status)
+ return(-1);
+ if ((tokenrec->flags & TOKEN_USEMODES) == 0)
+ tokenrec->mode = tt->modes & ~TOKEN_RIM;
+
+ return(0);
+}
+
diff --git a/libexec/login_token/tokendb.h b/libexec/login_token/tokendb.h
new file mode 100644
index 00000000000..32a80985088
--- /dev/null
+++ b/libexec/login_token/tokendb.h
@@ -0,0 +1,80 @@
+/* $OpenBSD: tokendb.h,v 1.1 2000/12/20 01:41:53 millert Exp $ */
+
+/*-
+ * Copyright (c) 1995 Berkeley Software Design, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Berkeley Software Design,
+ * Inc.
+ * 4. The name of Berkeley Software Design, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * BSDI $From: tokendb.h,v 1.1 1996/08/26 20:13:11 prb Exp $
+ */
+
+/*
+ * Structure defining a record for a user. All fields
+ * stored in ascii to facilitate backup/reconstruction.
+ * A null byte is required after the share secret field.
+ */
+
+typedef struct {
+ char uname[L_cuserid]; /* user login name */
+ char secret[16]; /* token shared secret */
+ unsigned flags; /* record flags */
+ unsigned mode; /* token mode flags */
+ time_t lock_time; /* time of record lock */
+ u_char rim[8]; /* reduced input mode */
+ char reserved_char1[8];
+ char reserved_char2[80];
+} TOKENDB_Rec;
+
+/*
+ * Record flag values
+ */
+
+#define TOKEN_LOCKED 0x1 /* record locked for updating */
+#define TOKEN_ENABLED 0x2 /* user login method enabled */
+#define TOKEN_LOGIN 0x4 /* login in progress lock */
+#define TOKEN_USEMODES 0x8 /* use the mode field */
+
+#define TOKEN_DECMODE 0x1 /* allow decimal results */
+#define TOKEN_HEXMODE 0x2 /* allow hex results */
+#define TOKEN_PHONEMODE 0x4 /* allow phone book results */
+#define TOKEN_RIM 0x8 /* reduced imput mode */
+
+/*
+ * Function prototypes for routines which manipulate the
+ * database for the token. These routines have no knowledge
+ * of DES or encryption. However, they will manipulate the
+ * flags field of the database record with complete abandon.
+ */
+
+extern int tokendb_delrec(char *);
+extern int tokendb_getrec(char *, TOKENDB_Rec *);
+extern int tokendb_putrec(char *, TOKENDB_Rec *);
+extern int tokendb_firstrec(int, TOKENDB_Rec *);
+extern int tokendb_nextrec(int, TOKENDB_Rec *);
+extern int tokendb_lockrec(char *, TOKENDB_Rec *, unsigned);