mirror of
https://github.com/adulau/ootp.git
synced 2024-12-26 10:46:07 +00:00
ootp-snap-05-15-2011-r184 imported
This commit is contained in:
parent
9a903d7a74
commit
b48b72effd
72 changed files with 3354 additions and 916 deletions
1
VERSION
Normal file
1
VERSION
Normal file
|
@ -0,0 +1 @@
|
|||
snap-r184
|
|
@ -24,7 +24,7 @@
|
|||
' OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
' SUCH DAMAGE.
|
||||
'
|
||||
' $Id: HOTPC.BAS 92 2009-12-28 02:45:54Z maf $
|
||||
' $Id: HOTPC.BAS 148 2011-03-31 00:46:42Z maf $
|
||||
'
|
||||
#include "sha-1.def"
|
||||
#include "preader.def"
|
||||
|
@ -56,6 +56,7 @@ Const HOTPNum = 50
|
|||
' to global, reorg balance reader code
|
||||
' naming consistency, default 50 systems
|
||||
' Rev 8 - release Rev7
|
||||
' Rev 9 - CheckPIN for GetHOTP*, myReaderKey
|
||||
|
||||
' 20 byte scratch area addressable as 5 32bit vars
|
||||
public str20 as String*20
|
||||
|
@ -83,7 +84,7 @@ public u32b3 as Byte at u32+3
|
|||
public HOTPfmt as Byte
|
||||
|
||||
' Code version
|
||||
Const HOTPCodeVersion = 8
|
||||
Const HOTPCodeVersion = 9
|
||||
|
||||
' Capabilities (conditionally compiled in functions)
|
||||
eeprom Capabilities as Long = CAPSETHOST + CAPGETHOST + CAPGETHOSTNAME + _
|
||||
|
@ -153,7 +154,7 @@ eeprom eestr20 as String*20
|
|||
eeprom PIN as String*5 = DefaultPIN
|
||||
|
||||
' Reader Key. Weak authentication for reader
|
||||
eeprom readerKey as String*5 = "00000"
|
||||
eeprom ReaderKey as String*5 = "00000"
|
||||
|
||||
' The balance card can only use one of the host definitions.
|
||||
eeprom BalanceCardIndex = 255 ' Disabled
|
||||
|
@ -163,17 +164,17 @@ eeprom AdminMode as Byte = 1
|
|||
|
||||
' Keep track of PIN failures
|
||||
eeprom PINFailCount as Byte = 0
|
||||
eeprom readerKeyFailCount as Byte = 0
|
||||
eeprom ReaderKeyFailCount as Byte = 0
|
||||
Const MaxPINFail = 10
|
||||
Const MaxReaderKeyFail = 2
|
||||
|
||||
declare Sub Truncate(Idx as Byte)
|
||||
|
||||
declare Sub HOTPCommon(ReadOnly Idx as Byte, ReadOnly Count as Long, _
|
||||
ReadOnly myPIN as String*5, ReadOnly readerKey as String*5)
|
||||
ReadOnly myPIN as String*5, ReadOnly myReaderKey as String*5)
|
||||
|
||||
declare Function CheckReaderKey(ReadOnly Idx as Byte, _
|
||||
ReadOnly myKey as String*5) as Byte
|
||||
ReadOnly myReaderKey as String*5) as Byte
|
||||
|
||||
declare Function CheckPIN(ReadOnly myPIN as String*5) as Byte
|
||||
|
||||
|
@ -184,7 +185,7 @@ declare Function CheckIndex(Idx as Byte) as Byte
|
|||
|
||||
' Common HOTP generation code
|
||||
Sub HOTPCommon(ReadOnly Idx as Byte, ReadOnly Count32 as Long, _
|
||||
ReadOnly myPIN as String*5, ReadOnly readerKey as String*5)
|
||||
ReadOnly myPIN as String*5, ReadOnly myReaderKey as String*5)
|
||||
|
||||
' disable admin mode on first use.
|
||||
if (AdminMode = 1) then
|
||||
|
@ -196,9 +197,15 @@ Sub HOTPCommon(ReadOnly Idx as Byte, ReadOnly Count32 as Long, _
|
|||
SW1SW2 = swAccessDenied
|
||||
Exit
|
||||
end if
|
||||
|
||||
' check PIN
|
||||
if CheckPIN(myPIN) <> 0 then
|
||||
SW1SW2 = swAccessDenied
|
||||
Exit
|
||||
end if
|
||||
|
||||
' Check reader access
|
||||
if CheckReaderKey(Idx, readerKey) <> 0 then
|
||||
if CheckReaderKey(Idx, myReaderKey) <> 0 then
|
||||
SW1SW2 = swAccessDenied
|
||||
Exit
|
||||
end if
|
||||
|
@ -300,7 +307,6 @@ Function CheckPIN(ReadOnly myPIN as String*5) as Byte
|
|||
|
||||
if AdminMode = 1 then
|
||||
CheckPIN = 0 ' success
|
||||
PINFailCount = 0 ' reset
|
||||
else
|
||||
if PINFailCount >= MaxPINFail then
|
||||
CheckPIN = 2 ' fail
|
||||
|
@ -318,18 +324,20 @@ Function CheckPIN(ReadOnly myPIN as String*5) as Byte
|
|||
End Function ' CheckPIN
|
||||
|
||||
Function CheckReaderKey(ReadOnly Idx as Byte, _
|
||||
ReadOnly myKey as String*5) as Byte
|
||||
ReadOnly myReaderKey as String*5) as Byte
|
||||
|
||||
if (Asc(HOTPHost(Idx)(2)) AND &H80) then
|
||||
if myKey <> readerKey then
|
||||
readerKeyFailCount = readerKeyFailCount + 1
|
||||
if (readerKeyFailCount >= MAXReaderKeyFail) then
|
||||
PINFailCount = MaxPINFail ' Lock card
|
||||
end if
|
||||
CheckReaderKey = 1 ' Fail
|
||||
if (ReaderKeyFailCount >= MAXReaderKeyFail) then
|
||||
PINFailCount = MaxPINFail ' Lock card
|
||||
CheckReaderKey = 1 ' fail
|
||||
else
|
||||
readerKeyFailCount = 0
|
||||
CheckReaderKey = 0 ' Success
|
||||
if myReaderKey <> ReaderKey then
|
||||
CheckReaderKey = 1 ' Fail
|
||||
ReaderKeyFailCount = ReaderKeyFailCount + 1
|
||||
else
|
||||
CheckReaderKey = 0 ' Success
|
||||
ReaderKeyFailCount = 0 ' reset on good key
|
||||
end if
|
||||
end if
|
||||
else
|
||||
CheckReaderKey = 0 'Success
|
||||
|
@ -466,6 +474,11 @@ Command &H80 &H48 SetAdminMode(Mode as Byte, K as String*20)
|
|||
AdminMode = Mode
|
||||
end if
|
||||
|
||||
if AdminMode = 1 then
|
||||
ReaderKeyFailCount = 0 ' reset
|
||||
PINFailCount = 0 ' reset
|
||||
end if
|
||||
|
||||
End Command ' SetAdminMode
|
||||
#endif 'ENABLECSETADMINMODE
|
||||
|
||||
|
@ -628,7 +641,7 @@ End Command ' GetHOTPHost
|
|||
Command &H80 &H5C GetHOTPHostCount32(Idx as Byte, myPIN as String*5,_
|
||||
Count32 as Long, HOTP as String*5, HostName as String*12)
|
||||
|
||||
Call HOTPCommon(Idx, Count32, myPIN, readerKey)
|
||||
Call HOTPCommon(Idx, Count32, myPIN, HOTP)
|
||||
HOTP = HOTPTruncated
|
||||
HostName = HOTPHost(Idx)
|
||||
|
||||
|
@ -656,7 +669,7 @@ Command &H80 &H5E ClearAll()
|
|||
|
||||
PINFailCount = 0
|
||||
|
||||
readerKeyFailCount = 0
|
||||
ReaderKeyFailCount = 0
|
||||
|
||||
AdminMode = 1
|
||||
|
||||
|
@ -667,18 +680,18 @@ Command &H80 &H5E ClearAll()
|
|||
End Command ' ClearAll
|
||||
#endif 'ENABLECCLEARALL
|
||||
|
||||
#ifdef ENABLESETREADERKEY
|
||||
Command &H80 &H60 SetReaderKey(myKey as String*5)
|
||||
#ifdef ENABLESETReaderKey
|
||||
Command &H80 &H60 SetReaderKey(myReaderKey as String*5)
|
||||
|
||||
if CheckAdmin() <> 0 then
|
||||
SW1SW2 = swAccessDenied
|
||||
Exit
|
||||
else
|
||||
ReaderKey = myReaderKey
|
||||
end if
|
||||
|
||||
readerKey = myKey
|
||||
|
||||
End Command ' SetReaderKey
|
||||
#endif 'ENABLECSETREADERKEY
|
||||
#endif 'ENABLECSETReaderKey
|
||||
|
||||
Command &H80 &H90 GetCapabilities(C as Long)
|
||||
|
||||
|
|
Binary file not shown.
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile 13 2009-11-26 16:37:03Z maf $
|
||||
# $Id: Makefile 127 2010-06-15 14:24:34Z maf $
|
||||
|
||||
what:
|
||||
@echo
|
||||
|
@ -25,22 +25,27 @@ INSTALL=install -c -m0755
|
|||
|
||||
.c.o:; $(CC) $(CFLAGS) -c $*.c -o $*.o
|
||||
|
||||
OBJS = ../common/xerr.o ../common/str.o ../common/acr30.o ../common/scr.o ../common/sccmd.o
|
||||
|
||||
BINS = bcload
|
||||
BIN = bcload
|
||||
COBJS = ../common/xerr.o ../common/str.o ../common/acr30.o ../common/scr.o ../common/sccmd.o
|
||||
OBJS = version.o ${BIN}.o
|
||||
|
||||
BINDIR=/usr/local/ootp/bin
|
||||
|
||||
all: bcload.c ${OBJS} ${BINS}
|
||||
all: version ${COBJS} ${OBJS} ${BIN}
|
||||
|
||||
version:
|
||||
rm -f version.c; ../build/version ../VERSION ${BIN} > version.c
|
||||
|
||||
version.c:
|
||||
|
||||
install:
|
||||
mkdir -p ${BINDIR}
|
||||
${INSTALL} ${BINS} ${BINDIR}
|
||||
${INSTALL} ${BIN} ${BINDIR}
|
||||
@echo files installed in ${BINDIR}
|
||||
|
||||
clean:
|
||||
/bin/rm -f ${BINS} bcload.o
|
||||
/bin/rm -f ${BIN} ${OBJS} version.c
|
||||
|
||||
bcload: ${OBJS} bcload.o
|
||||
$(CC) $(CFLAGS) $(LFLAGS) $(INC) -o bcload ${OBJS} bcload.o $(LIBS)
|
||||
${BIN}: ${COBJS} ${OBJS}
|
||||
$(CC) $(CFLAGS) $(LFLAGS) $(INC) -o ${BIN} ${COBJS} ${OBJS} $(LIBS)
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
*
|
||||
* Ported from ZeitControl bcload.bas and download.bas sample source
|
||||
*
|
||||
* $Id: bcload.c 90 2009-12-28 02:44:52Z maf $
|
||||
* $Id: bcload.c 127 2010-06-15 14:24:34Z maf $
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
@ -34,6 +34,7 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/errno.h>
|
||||
#include <getopt.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -98,6 +99,7 @@ void bcimg_read_eeprom_section(struct bcimg *bcimg, uint16_t *img_EEAddr,
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
extern char *ootp_version;
|
||||
struct scr_ctx *scrctx;
|
||||
struct bcimg bcimg;
|
||||
uint32_t chunk_start, bytes_left, chunk_working;
|
||||
|
@ -109,13 +111,28 @@ int main(int argc, char **argv)
|
|||
uint8_t img_state, *img_pgmdata, img_EELoadLen, sname[4];
|
||||
uint8_t sc_EEStart[2], sc_EELen[2], sc_EEAddr[2];
|
||||
uint8_t sc_state, sc_version[256], sc_version_len, sc_CRC[2];
|
||||
int i, r;
|
||||
int i, r, opt_version;
|
||||
int list_readers, verbose, paranoid, force_test;
|
||||
char *reader, *endptr, *c, *img_fname;
|
||||
|
||||
struct option longopts[] = {
|
||||
{ "debug", 1, (void*)0L, 'd'},
|
||||
{ "image", 1, (void*)0L, 'f'},
|
||||
{ "help", 0, (void*)0L, 'h'},
|
||||
{ "help", 0, (void*)0L, '?'},
|
||||
{ "list-readers", 0, (void*)0L, 'l'},
|
||||
{ "no-paranoid", 0, (void*)0L, 'p'},
|
||||
{ "reader", 1, (void*)0L, 'r'},
|
||||
{ "force-test", 0, (void*)0L, 't'},
|
||||
{ "verbose", 0, (void*)0L, 'v'},
|
||||
{ "version", 0, &opt_version, 1},
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
/* init xerr */
|
||||
xerr_setid(argv[0]);
|
||||
|
||||
opt_version = 0;
|
||||
force_test = 0;
|
||||
paranoid = 1;
|
||||
debug = 0;
|
||||
|
@ -126,7 +143,8 @@ int main(int argc, char **argv)
|
|||
img_fname = "HOTPC.IMG";
|
||||
bzero(&bcimg, sizeof bcimg);
|
||||
|
||||
while ((i = getopt(argc, argv, "d:f:hlpr:tv?")) != -1) {
|
||||
while ((i = getopt_long(argc, argv, "d:f:hlpr:tv?", longopts,
|
||||
(int*)0L)) != -1) {
|
||||
|
||||
switch (i) {
|
||||
|
||||
|
@ -144,7 +162,7 @@ int main(int argc, char **argv)
|
|||
case '?':
|
||||
help();
|
||||
exit(0);
|
||||
break; /* notreached */
|
||||
break; /* not reached */
|
||||
|
||||
case 'l':
|
||||
list_readers = 1;
|
||||
|
@ -166,6 +184,17 @@ int main(int argc, char **argv)
|
|||
verbose = 1;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if (opt_version) {
|
||||
printf("%s\n", ootp_version);
|
||||
exit(0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
xerr_errx(1, "getopt_long(): fatal.");
|
||||
break; /* not reached */
|
||||
|
||||
} /* switch */
|
||||
|
||||
} /* while getopt() */
|
||||
|
@ -510,7 +539,7 @@ main_out:
|
|||
|
||||
void help(void)
|
||||
{
|
||||
fprintf(stderr, "bcload [hlptv?] [-d debug_level] [-f fname] [-r reader]\n");
|
||||
fprintf(stderr, "bcload [hlptv?] [-d debug_level] [-f image] [-r reader]\n");
|
||||
fprintf(stderr, " -h : help\n");
|
||||
fprintf(stderr, " -l : list SC readers\n");
|
||||
fprintf(stderr, " -t : force to TEST state\n");
|
||||
|
|
29
build/version
Executable file
29
build/version
Executable file
|
@ -0,0 +1,29 @@
|
|||
#!/bin/sh
|
||||
|
||||
ME=`whoami`
|
||||
DATE=`date`
|
||||
HOST=`hostname`
|
||||
|
||||
if [ "X$1" = "X" ]; then
|
||||
echo "Usage: version <idfile> <program>" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "X$2" = "X" ]; then
|
||||
PGM="ootp"
|
||||
else
|
||||
PGM="$2"
|
||||
fi
|
||||
|
||||
# if VERSION file exists, then this is a snapshot or release build,
|
||||
if [ -e $1 ]; then
|
||||
R=`cat $1`
|
||||
# else assume building in sandbox
|
||||
else
|
||||
SVN=`which svn`
|
||||
RR=`svn info | grep "^Repository Root:" | awk '{print $3}'`
|
||||
R=`svn info $RR | grep "^Revision:" | awk '{print $2}'`
|
||||
R="devel r$R"
|
||||
fi
|
||||
|
||||
echo "char *ootp_version = \"$PGM $R $ME@$HOST $DATE\";"
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile 13 2009-11-26 16:37:03Z maf $
|
||||
# $Id: Makefile 134 2010-06-15 14:31:25Z maf $
|
||||
|
||||
what:
|
||||
@echo
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: ffdb.c 13 2009-11-26 16:37:03Z maf $
|
||||
* $Id: ffdb.c 117 2010-03-08 04:24:07Z maf $
|
||||
*/
|
||||
|
||||
#include <sys/fcntl.h>
|
||||
|
@ -504,6 +504,7 @@ struct ffdb_ctx *ffdb_db_open(char *base_dir_pn, size_t max_key_size,
|
|||
else
|
||||
verbose = 0;
|
||||
|
||||
ffdbctx = (struct ffdb_ctx*)0L;
|
||||
ret = -1; /* fail */
|
||||
|
||||
base_dir_pn_size = strlen(base_dir_pn) + 1;
|
||||
|
|
269
common/otplib.c
269
common/otplib.c
|
@ -24,7 +24,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: otplib.c 84 2009-12-27 17:29:51Z maf $
|
||||
* $Id: otplib.c 174 2011-05-16 02:09:26Z maf $
|
||||
*/
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
|
@ -34,9 +34,13 @@
|
|||
|
||||
#include <sys/errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/un.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -49,11 +53,15 @@
|
|||
#include "otpsc.h"
|
||||
|
||||
char *otp_status_l[] = {"error", "active", "inactive", "disabled"};
|
||||
|
||||
char *otp_format_l[] = {"error", "hex40", "dhex40", "dec31.6", "dec31.7",
|
||||
"dec31.8", "dec31.9", "dec31.10"};
|
||||
|
||||
char *otp_type_l[] = {"error", "HOTP"};
|
||||
|
||||
char *otp_flags_l[] = {"display-count"};
|
||||
char *otp_flags_l[] = {"display-count", "send-token"};
|
||||
|
||||
char *sc_flags_l[] = {"challenge","readerkey"};
|
||||
|
||||
/*
|
||||
* One Time Password library with HOTP implementation.
|
||||
|
@ -86,6 +94,7 @@ char *otp_flags_l[] = {"display-count"};
|
|||
* otp_user_exists() user exists in OTP db?
|
||||
* otp_user_rm() remove user from OTP db
|
||||
* otp_user_auth() authenticate user from OTP db
|
||||
* otp_user_send_token() send token to user via some OOB method
|
||||
*
|
||||
****
|
||||
*
|
||||
|
@ -180,6 +189,17 @@ int otp_ou_toascii(struct otp_ctx *otpctx, struct otp_user *ou)
|
|||
str_hex_dump(c, (void*)&ou->last, 8);
|
||||
c += 16;
|
||||
|
||||
if ((n = strlen(ou->loc)) > OTP_USER_LOC_LEN) {
|
||||
xerr_warnx("otp_ou_toascii(): location length invalid.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*c++ = ':';
|
||||
if (n) {
|
||||
strcpy(c, ou->loc);
|
||||
c += n;
|
||||
}
|
||||
|
||||
*c++ = 0;
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
|
@ -211,7 +231,7 @@ int otp_ou_toascii(struct otp_ctx *otpctx, struct otp_user *ou)
|
|||
*/
|
||||
int otp_ou_fromascii(struct otp_ctx *otpctx, struct otp_user *ou)
|
||||
{
|
||||
int field, ret, n, i;
|
||||
int field, ret, n, i, n_fields, l_field;
|
||||
char *c;
|
||||
|
||||
if (otp_db_valid(otpctx, "otp_ou_fromascii") < 0)
|
||||
|
@ -237,7 +257,7 @@ int otp_ou_fromascii(struct otp_ctx *otpctx, struct otp_user *ou)
|
|||
*c = 0;
|
||||
++c;
|
||||
++field;
|
||||
if (field > (OTP_USER_N_FIELDS-1)) /* too many fields */
|
||||
if (field > (OTP_USER_N_FIELDS_MAX-1)) /* too many fields */
|
||||
break;
|
||||
} else if (*c == 0) {
|
||||
break;
|
||||
|
@ -246,12 +266,18 @@ int otp_ou_fromascii(struct otp_ctx *otpctx, struct otp_user *ou)
|
|||
}
|
||||
}
|
||||
|
||||
if (field != (OTP_USER_N_FIELDS-1)) {
|
||||
/* last field does not have a : */
|
||||
if ((field > OTP_USER_N_FIELDS_MAX-1) ||
|
||||
(field < OTP_USER_N_FIELDS_MIN-1)) {
|
||||
if (otpctx->verbose)
|
||||
xerr_warnx("expecting %d fields, got %d.", OTP_USER_N_FIELDS, field+1);
|
||||
xerr_warnx("expecting min=%d max=%d fields, got %d.",
|
||||
OTP_USER_N_FIELDS_MIN, OTP_USER_N_FIELDS_MAX, field+1);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* look ahead */
|
||||
l_field = field;
|
||||
|
||||
#define CHK_STRLEN(N,L)\
|
||||
n = strlen(c);\
|
||||
if (n != L) {\
|
||||
|
@ -274,8 +300,11 @@ int otp_ou_fromascii(struct otp_ctx *otpctx, struct otp_user *ou)
|
|||
xerr_warnx("%s: str_hex_decode(%s): failed.", __func__, N);\
|
||||
goto otp_ou_fromascii_out;\
|
||||
}\
|
||||
|
||||
/* may be changed after reading version field */
|
||||
n_fields = OTP_USER_N_FIELDS;
|
||||
|
||||
for (field = 0, c = ou->ascii_encoded; field < OTP_USER_N_FIELDS; ++field) {
|
||||
for (field = 0, c = ou->ascii_encoded; field < n_fields; ++field) {
|
||||
|
||||
if (field == 0) { /* version */
|
||||
CHK_STRLEN("version", 2)
|
||||
|
@ -287,8 +316,20 @@ int otp_ou_fromascii(struct otp_ctx *otpctx, struct otp_user *ou)
|
|||
OTP_VERSION_MAX);
|
||||
return -1;
|
||||
}
|
||||
if (ou->version == 1)
|
||||
n_fields = OTP_USER_N_FIELDS_V1;
|
||||
if ((ou->version == 1) && (l_field != OTP_USER_N_FIELDS_V1-1)) {
|
||||
xerr_warnx("v1 format has %d fields, not %d.",
|
||||
OTP_USER_N_FIELDS_V1, l_field+1);
|
||||
return -1;
|
||||
}
|
||||
if ((ou->version == 2) && (l_field != OTP_USER_N_FIELDS_V2-1)) {
|
||||
xerr_warnx("v2 format has %d fields, not %d.",
|
||||
OTP_USER_N_FIELDS_V2, l_field+1);
|
||||
return -1;
|
||||
}
|
||||
} else if (field == 1) { /* username */
|
||||
CHK_STRRANGE("username", 1, 32)
|
||||
CHK_STRRANGE("username", 1, OTP_USER_NAME_LEN)
|
||||
strcpy(ou->username, c);
|
||||
} else if (field == 2) { /* key */
|
||||
CHK_STRRANGE("key", 1, 40);
|
||||
|
@ -314,7 +355,10 @@ int otp_ou_fromascii(struct otp_ctx *otpctx, struct otp_user *ou)
|
|||
} else if (field == 9) { /* last */
|
||||
CHK_STRLEN("last", 16);
|
||||
HEX_DECODE("last", last, 16)
|
||||
}
|
||||
} else if (field == 10) { /* location */
|
||||
CHK_STRRANGE("loc", 0, OTP_USER_LOC_LEN)
|
||||
strcpy(ou->loc, c);
|
||||
}
|
||||
|
||||
/* skip to next field */
|
||||
for (; *c; ++c);
|
||||
|
@ -333,6 +377,9 @@ int otp_ou_fromascii(struct otp_ctx *otpctx, struct otp_user *ou)
|
|||
ou->db_key.key = &ou->username;
|
||||
ou->db_key.size = strlen(ou->username);
|
||||
|
||||
/* up convert */
|
||||
ou->version = OTP_VERSION;
|
||||
|
||||
ret = OTP_SUCCESS;
|
||||
|
||||
otp_ou_fromascii_out:
|
||||
|
@ -730,6 +777,7 @@ struct otp_ctx *otp_db_open(char *dbname, int flags)
|
|||
|
||||
bzero(otpctx, sizeof *otpctx);
|
||||
otpctx->verbose = verbose;
|
||||
otpctx->send_token_pathname = OTP_SEND_TOKEN_PATHNAME;
|
||||
|
||||
if (!(otpctx->ffdbctx = ffdb_db_open(dbname, OTP_USER_NAME_LEN,
|
||||
OTP_USER_ASCII_LEN, ffdb_flags, S_IRUSR|S_IWUSR, S_IRWXU))) {
|
||||
|
@ -922,6 +970,7 @@ int otp_db_load(struct otp_ctx *otpctx, char *u_username)
|
|||
return -1;
|
||||
|
||||
ret = -1; /* fail */
|
||||
bzero(&ou, sizeof(ou));
|
||||
|
||||
while (!feof(stdin)) {
|
||||
|
||||
|
@ -1021,6 +1070,7 @@ otp_db_load_out:
|
|||
* arguments:
|
||||
* otpctx - otp db context returned by otp_db_open()
|
||||
* u_username - username
|
||||
* u_loc - location
|
||||
* u_key_val - key value
|
||||
* u_key_size - length of key in bytes
|
||||
* u_count - initial count
|
||||
|
@ -1036,9 +1086,9 @@ otp_db_load_out:
|
|||
*
|
||||
*/
|
||||
int otp_user_add(struct otp_ctx *otpctx, char *u_username,
|
||||
uint8_t *u_key_val, uint16_t u_key_size, uint64_t u_count,
|
||||
uint64_t u_count_ceil, uint8_t u_status, uint8_t u_type,
|
||||
uint8_t u_format, uint8_t u_version)
|
||||
char *u_loc, uint8_t *u_key_val, uint16_t u_key_size,
|
||||
uint64_t u_count, uint64_t u_count_ceil, uint8_t u_status,
|
||||
uint8_t u_type, uint8_t u_format, uint8_t u_version)
|
||||
{
|
||||
struct otp_user ou;
|
||||
int ret, r;
|
||||
|
@ -1066,11 +1116,19 @@ int otp_user_add(struct otp_ctx *otpctx, char *u_username,
|
|||
goto otp_user_add_out;
|
||||
}
|
||||
|
||||
if (strlen(u_loc) > OTP_USER_LOC_LEN) {
|
||||
if (otpctx->verbose)
|
||||
xerr_warnx("strlen(u_loc) > OTP_USER_LOC_LEN.");
|
||||
goto otp_user_add_out;
|
||||
}
|
||||
|
||||
/*
|
||||
* copy in user fields to ou
|
||||
*/
|
||||
|
||||
strcpy(ou.username, u_username);
|
||||
/* lengths checked above */
|
||||
strncpy(ou.username, u_username, OTP_USER_NAME_LEN);
|
||||
strncpy(ou.loc, u_loc, OTP_USER_LOC_LEN);
|
||||
bcopy(u_key_val, &ou.key, u_key_size);
|
||||
ou.key_size = u_key_size;
|
||||
ou.count = u_count;
|
||||
|
@ -1162,13 +1220,15 @@ int otp_user_exists(struct otp_ctx *otpctx, char *u_username)
|
|||
if (otp_db_valid(otpctx, "otp_user_exists") < 0)
|
||||
return -1;
|
||||
|
||||
/* paranoia */
|
||||
str_safe(u_username, OTP_USER_NAME_LEN);
|
||||
|
||||
ret = OTP_ERROR; /* fail */
|
||||
db_key.key = u_username;
|
||||
db_key.size = strlen(u_username);
|
||||
|
||||
/* paranoia */
|
||||
str_safe(u_username, OTP_USER_NAME_LEN, ".", STR_SAFE_CHECK_LEN|
|
||||
STR_SAFE_CHECK_ALPHA|STR_SAFE_CHECK_SET|STR_SAFE_CHECK_NUM|
|
||||
STR_SAFE_FIX|STR_SAFE_WARN);
|
||||
|
||||
/*
|
||||
* sanity checks
|
||||
*/
|
||||
|
@ -1213,14 +1273,15 @@ int otp_user_rm(struct otp_ctx *otpctx, char *u_username)
|
|||
if (otp_db_valid(otpctx, "otp_user_rm") < 0)
|
||||
return -1;
|
||||
|
||||
/* paranoia */
|
||||
str_safe(u_username, OTP_USER_NAME_LEN);
|
||||
|
||||
ret = -1; /* fail */
|
||||
|
||||
db_key.key = u_username;
|
||||
db_key.size = strlen(u_username);
|
||||
|
||||
/* paranoia */
|
||||
str_safe(u_username, OTP_USER_NAME_LEN, ".", STR_SAFE_CHECK_LEN|
|
||||
STR_SAFE_CHECK_ALPHA|STR_SAFE_CHECK_SET|STR_SAFE_CHECK_NUM|
|
||||
STR_SAFE_FIX|STR_SAFE_WARN);
|
||||
|
||||
/*
|
||||
* sanity checks
|
||||
*/
|
||||
|
@ -1275,8 +1336,12 @@ int otp_user_auth(struct otp_ctx *otpctx, char *u_username,
|
|||
(OTP_HOTP_HEX40_LEN<<1) : OTP_HOTP_DEC31_LEN;
|
||||
|
||||
/* paranoia */
|
||||
str_safe(u_username, OTP_USER_NAME_LEN);
|
||||
str_safe(u_crsp, crsp_max<<1);
|
||||
str_safe(u_username, OTP_USER_NAME_LEN, ".", STR_SAFE_CHECK_LEN|
|
||||
STR_SAFE_CHECK_ALPHA|STR_SAFE_CHECK_SET|
|
||||
STR_SAFE_CHECK_NUM|STR_SAFE_FIX|STR_SAFE_WARN);
|
||||
|
||||
str_safe(u_crsp, crsp_max<<1, (char*)0L, STR_SAFE_CHECK_LEN|
|
||||
STR_SAFE_CHECK_ALPHA|STR_SAFE_CHECK_NUM|STR_SAFE_FIX|STR_SAFE_WARN);
|
||||
|
||||
/* open user record */
|
||||
if (otp_urec_open(otpctx, u_username, &ou, O_RDWR, FFDB_OP_LOCK_EX) < 0) {
|
||||
|
@ -1356,6 +1421,111 @@ otp_user_auth_out:
|
|||
|
||||
} /* otp_user_auth */
|
||||
|
||||
/*
|
||||
* otp_user_send_token
|
||||
*
|
||||
* returns: <0 failure
|
||||
*/
|
||||
int otp_user_send_token(struct otp_ctx *otpctx, char *u_username,
|
||||
char *service)
|
||||
{
|
||||
struct sockaddr_un tx_path;
|
||||
char crsp_tmp[32], tx_buf[1024];
|
||||
struct otp_user ou;
|
||||
int ret, r, tx_sock, tx_buf_len;
|
||||
|
||||
if (otp_db_valid(otpctx, "otp_user_send") < 0)
|
||||
return -1;
|
||||
|
||||
ret = -1; /* fail */
|
||||
tx_sock = -1;
|
||||
bzero(&ou, sizeof ou);
|
||||
|
||||
/* paranoia */
|
||||
str_safe(u_username, OTP_USER_NAME_LEN, ".", STR_SAFE_CHECK_LEN|
|
||||
STR_SAFE_CHECK_ALPHA|STR_SAFE_CHECK_SET| STR_SAFE_CHECK_NUM|
|
||||
STR_SAFE_FIX|STR_SAFE_WARN);
|
||||
|
||||
/* open user record */
|
||||
if (otp_urec_open(otpctx, u_username, &ou, O_RDWR, FFDB_OP_LOCK_EX) < 0) {
|
||||
if (otpctx->verbose)
|
||||
xerr_warnx("otp_urec_open(%s): failed.", u_username);
|
||||
goto otp_user_send_token_out;
|
||||
}
|
||||
|
||||
/* get user record */
|
||||
if (otp_urec_get(otpctx, &ou) < 0) {
|
||||
if (otpctx->verbose)
|
||||
xerr_warnx("otp_urec_get(%s): failed.", u_username);
|
||||
goto otp_user_send_token_out;
|
||||
}
|
||||
|
||||
if (otp_urec_sanity(otpctx, &ou) < 0) {
|
||||
if (otpctx->verbose)
|
||||
xerr_warnx("otp_urec_sanity(): failed.");
|
||||
goto otp_user_send_token_out;
|
||||
}
|
||||
|
||||
/* generate next token */
|
||||
if (otp_urec_crsp(otpctx, &ou, 0, crsp_tmp, sizeof(crsp_tmp)) < 0) {
|
||||
if (otpctx->verbose)
|
||||
xerr_warnx("otp_urec_crsp(): failed.");
|
||||
goto otp_user_send_token_out;
|
||||
}
|
||||
|
||||
/* format tx buffer */
|
||||
if ((tx_buf_len = snprintf(tx_buf, sizeof(tx_buf), "%s\n%s\n%s\n%s\n",
|
||||
service, ou.username, ou.loc, crsp_tmp)) >= sizeof(tx_buf)) {
|
||||
if (otpctx->verbose)
|
||||
xerr_warnx("snprintf(tx_buf): overflow");
|
||||
goto otp_user_send_token_out;
|
||||
}
|
||||
|
||||
/* setup to transmit UDP datagram */
|
||||
if ((tx_sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
|
||||
if (otpctx->verbose)
|
||||
xerr_warn("socket(AF_UNIX, SOCK_DGRAM)");
|
||||
goto otp_user_send_token_out;
|
||||
}
|
||||
|
||||
bzero(&tx_path, sizeof (tx_path));
|
||||
tx_path.sun_family = AF_UNIX;
|
||||
if (strlen(otpctx->send_token_pathname) >= sizeof (tx_path.sun_path)) {
|
||||
xerr_warnx("send_token_pathname too long.");
|
||||
goto otp_user_send_token_out;
|
||||
}
|
||||
strncpy(tx_path.sun_path, otpctx->send_token_pathname,
|
||||
sizeof(tx_path.sun_path));
|
||||
|
||||
/* send token */
|
||||
if (sendto(tx_sock, tx_buf, tx_buf_len+1, 0, (struct sockaddr*)&tx_path,
|
||||
sizeof(tx_path)) < 0) {
|
||||
if (otpctx->verbose)
|
||||
xerr_warn("sendto(%s)", otpctx->send_token_pathname);
|
||||
goto otp_user_send_token_out;
|
||||
}
|
||||
|
||||
/* success */
|
||||
ret = 0;
|
||||
|
||||
otp_user_send_token_out:
|
||||
|
||||
if (tx_sock != -1)
|
||||
close(tx_sock);
|
||||
|
||||
/* close record */
|
||||
if (ou.db_key.fd && (ou.db_key.fd != -1)) {
|
||||
if ((r = otp_urec_close(otpctx, &ou)) < 0) {
|
||||
if (otpctx->verbose)
|
||||
xerr_warnx("otp_urec_close(): failed.");
|
||||
ret = r;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
} /* otp_user_send_token */
|
||||
|
||||
/*
|
||||
* function: otp_urec_open()
|
||||
*
|
||||
|
@ -1405,13 +1575,15 @@ int otp_urec_open(struct otp_ctx *otpctx, char *u_username,
|
|||
if (otp_db_valid(otpctx, "otp_urec_open") < 0)
|
||||
return -1;
|
||||
|
||||
/* paranoia */
|
||||
str_safe(u_username, OTP_USER_NAME_LEN);
|
||||
|
||||
ret = -1; /* fail */
|
||||
bzero(ou, sizeof *ou);
|
||||
ou->db_key.fd = -1; /* invalid */
|
||||
|
||||
/* paranoia */
|
||||
str_safe(u_username, OTP_USER_NAME_LEN, ".", STR_SAFE_CHECK_LEN|
|
||||
STR_SAFE_CHECK_ALPHA|STR_SAFE_CHECK_SET|STR_SAFE_CHECK_NUM|
|
||||
STR_SAFE_FIX|STR_SAFE_WARN);
|
||||
|
||||
ou->db_key.key = u_username;
|
||||
ou->db_key.size = strlen(u_username);
|
||||
|
||||
|
@ -1716,6 +1888,8 @@ void otp_urec_disp(struct otp_ctx *otpctx, struct otp_user *ou)
|
|||
str_hex_dump(tmp, ou->key, 20);
|
||||
|
||||
printf("Username.......%s\n", ou->username);
|
||||
if (ou->loc[0])
|
||||
printf("Location.......%s\n", ou->loc);
|
||||
printf("Key............%s\n", tmp);
|
||||
printf("Count..........%" PRIu64 " (0x%" PRIx64 ")\n", ou->count, ou->count);
|
||||
printf("Count Ceiling..%" PRIu64 " (0x%" PRIx64 ")\n", ou->count_ceil,
|
||||
|
@ -1772,6 +1946,51 @@ uint8_t sc_index, char *sc_hostname, uint8_t *sc_flags)
|
|||
for (l = 0; l < SC_HOSTNAME_LEN; ++l)
|
||||
tmp_sc_hostname[l] |= sc_flags[l];
|
||||
|
||||
/* format is encoded in flag bits */
|
||||
if ((ou->format == OTP_FORMAT_DEC31_6) ||
|
||||
(ou->format == OTP_FORMAT_DEC31_7) ||
|
||||
(ou->format == OTP_FORMAT_DEC31_8) ||
|
||||
(ou->format == OTP_FORMAT_DEC31_9) ||
|
||||
(ou->format == OTP_FORMAT_DEC31_10))
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT] |= HOSTNAME_FLAG_MASK;
|
||||
|
||||
if (ou->format == OTP_FORMAT_HEX40) {
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT3] &= ~HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT2] &= ~HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT1] &= ~HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT0] &= ~HOSTNAME_FLAG_MASK;
|
||||
} else if (ou->format == OTP_FORMAT_DHEX40) {
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT3] &= ~HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT2] |= HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT1] |= HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT0] |= HOSTNAME_FLAG_MASK;
|
||||
} else if (ou->format == OTP_FORMAT_DEC31_6) {
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT3] &= ~HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT2] &= ~HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT1] |= HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT0] &= ~HOSTNAME_FLAG_MASK;
|
||||
} else if (ou->format == OTP_FORMAT_DEC31_7) {
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT3] &= ~HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT2] &= ~HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT1] |= HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT0] |= HOSTNAME_FLAG_MASK;
|
||||
} else if (ou->format == OTP_FORMAT_DEC31_8) {
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT3] &= ~HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT2] |= HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT1] &= ~HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT0] &= ~HOSTNAME_FLAG_MASK;
|
||||
} else if (ou->format == OTP_FORMAT_DEC31_9) {
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT3] &= ~HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT2] |= HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT1] &= ~HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT0] |= HOSTNAME_FLAG_MASK;
|
||||
} else if (ou->format == OTP_FORMAT_DEC31_10) {
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT3] &= ~HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT2] |= HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT1] |= HOSTNAME_FLAG_MASK;
|
||||
tmp_sc_hostname[HOSTNAME_POS_FMT0] &= ~HOSTNAME_FLAG_MASK;
|
||||
}
|
||||
|
||||
tmpc32 = ou->count;
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: otplib.h 61 2009-12-17 03:57:22Z maf $
|
||||
* $Id: otplib.h 174 2011-05-16 02:09:26Z maf $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -69,7 +69,7 @@
|
|||
|
||||
|
||||
#define OTP_DB_FNAME "/etc/otpdb" /* location of user database */
|
||||
#define OTP_VERSION 1 /* version of library */
|
||||
#define OTP_VERSION 2 /* version of library */
|
||||
|
||||
#define OTP_FORMAT_HEX40 1 /* 40 bits in hex */
|
||||
#define OTP_FORMAT_DHEX40 2 /* 40 bits in hex w. RFC 4226 DT */
|
||||
|
@ -87,7 +87,7 @@
|
|||
#define OTP_WINDOW_MAX 255 /* max challenge window */
|
||||
|
||||
#define OTP_VERSION_MIN 1 /* min version for this code */
|
||||
#define OTP_VERSION_MAX 1 /* max version for this code */
|
||||
#define OTP_VERSION_MAX 2 /* max version for this code */
|
||||
|
||||
#define OTP_HOTP_KEY_SIZE 20 /* HMAC SHA160 key length */
|
||||
#define OTP_HOTP_HEX40_LEN 5 /* HOTP challenge hex 40 bits */
|
||||
|
@ -105,14 +105,22 @@
|
|||
#define OTP_STATUS_MAX 3 /* highest valid status enum */
|
||||
|
||||
|
||||
#define OTP_USER_N_FIELDS 10 /* n fields in ASCII encoding */
|
||||
#define OTP_USER_ASCII_LEN 139 /* max ASCII encoded length (w/o null) */
|
||||
#define OTP_USER_N_FIELDS 11 /* n fields in ASCII encoding */
|
||||
#define OTP_USER_N_FIELDS_V1 10 /* n fields in ASCII encoding for v1 */
|
||||
#define OTP_USER_N_FIELDS_V2 11 /* n fields in ASCII encoding for v2 */
|
||||
#define OTP_USER_ASCII_LEN 180 /* max ASCII encoded length (w/o null) */
|
||||
#define OTP_USER_N_FIELDS_MAX 11 /* max # fields (all versions */
|
||||
#define OTP_USER_N_FIELDS_MIN 10 /* min # fields (all versions */
|
||||
|
||||
#define OTP_FLAGS_DSPCNT 0x1 /* force display count */
|
||||
#define OTP_FLAGS_BITS 1 /* bits used */
|
||||
#define OTP_FLAGS_SEND_TOKEN 0x2 /* execute send token script for user */
|
||||
#define OTP_FLAGS_BITS 2 /* bits used */
|
||||
|
||||
#define OTP_SEND_TOKEN_PATHNAME "/var/run/otp-tokend"
|
||||
|
||||
#define OTP_USER_NAME_LEN 32 /* max length of username (w/o null)*/
|
||||
#define OTP_USER_KEY_LEN 64 /* key length */
|
||||
#define OTP_USER_LOC_LEN 40 /* locatation identifier */
|
||||
|
||||
#define OTP_DB_VERBOSE 0x01 /* verbose error messages */
|
||||
#define OTP_DB_CREATE 0x02 /* create database? */
|
||||
|
@ -135,6 +143,7 @@ struct otp_user {
|
|||
uint16_t key_size; /* bytes used in key */
|
||||
unsigned char key[OTP_USER_KEY_LEN]; /* shared key (may not all be used */
|
||||
char username[OTP_USER_NAME_LEN+1]; /* name, null terminated */
|
||||
char loc[OTP_USER_LOC_LEN+1]; /* location to send token */
|
||||
char ascii_encoded[OTP_USER_ASCII_LEN+1]; /* null terminated */
|
||||
|
||||
/*
|
||||
|
@ -142,17 +151,20 @@ struct otp_user {
|
|||
* version:name:key:status:format:type:count_cur:count_ceil:last
|
||||
* n encoding decoded size encoded size
|
||||
* --------------------------------------
|
||||
* version 1 ASCII HEX 8 bits 2 bytes + 1
|
||||
* username 2 ASCII 32 bytes 1..32 bytes + 1
|
||||
* key 3 ASCII HEX 20 bytes 40 bytes + 1
|
||||
* status 4 ASCII HEX 8 bits 2 bytes + 1
|
||||
* format 5 ASCII HEX 8 bits 2 bytes + 1
|
||||
* type 6 ASCII HEX 8 bits 2 bytes + 1
|
||||
* flags 7 ASCII HEX 8 bits 2 bytes + 1
|
||||
* count_cur 8 ASCII HEX 64 bits 16 bytes + 1
|
||||
* count_ceil 9 ASCII HEX 64 bits 16 bytes + 1
|
||||
* last 10 ASCII HEX 64 bits 16 bytes + 1 null
|
||||
* total bytes = 2+32+40+2+2+2+2_16+16+16+10 = 140
|
||||
* version 1 ASCII HEX 8 bits 2 bytes
|
||||
* username 2 ASCII 32 bytes 1..32 bytes
|
||||
* key 3 ASCII HEX 20 bytes 40 bytes
|
||||
* status 4 ASCII HEX 8 bits 2 bytes
|
||||
* format 5 ASCII HEX 8 bits 2 bytes
|
||||
* type 6 ASCII HEX 8 bits 2 bytes
|
||||
* flags 7 ASCII HEX 8 bits 2 bytes
|
||||
* count_cur 8 ASCII HEX 64 bits 16 bytes
|
||||
* count_ceil 9 ASCII HEX 64 bits 16 bytes
|
||||
* last 10 ASCII HEX 64 bits 16 bytes
|
||||
* location 11 ASCII 40 bytes 1..40 bytes
|
||||
* delimiters - 1 * (n-1) 10 bytes
|
||||
* null - 1 byte
|
||||
* total bytes = 2+32+40+2+2+2+2+16+16+16+40+10+1 = 181
|
||||
*/
|
||||
|
||||
};
|
||||
|
@ -160,6 +172,7 @@ struct otp_user {
|
|||
|
||||
struct otp_ctx {
|
||||
struct ffdb_ctx *ffdbctx;
|
||||
char *send_token_pathname;
|
||||
int valid;
|
||||
int verbose;
|
||||
};
|
||||
|
@ -180,13 +193,15 @@ int otp_db_dump(struct otp_ctx *otpctx, char *u_username);
|
|||
int otp_db_load(struct otp_ctx *otpctx, char *u_username);
|
||||
|
||||
int otp_user_add(struct otp_ctx *otpctx, char *u_username,
|
||||
uint8_t *u_key_val, uint16_t u_key_size, uint64_t u_count,
|
||||
uint64_t u_count_ceil, uint8_t u_status, uint8_t u_type,
|
||||
uint8_t u_format, uint8_t u_version);
|
||||
char *u_loc, uint8_t *u_key_val, uint16_t u_key_size,
|
||||
uint64_t u_count, uint64_t u_count_ceil, uint8_t u_status,
|
||||
uint8_t u_type, uint8_t u_format, uint8_t u_version);
|
||||
int otp_user_exists(struct otp_ctx *otpctx, char *u_username);
|
||||
int otp_user_rm(struct otp_ctx *otpctx, char *u_username);
|
||||
int otp_user_auth(struct otp_ctx *otpctx, char *u_username,
|
||||
char *u_crsp, int u_window);
|
||||
int otp_user_send_token(struct otp_ctx *otpctx, char *u_username,
|
||||
char *service);
|
||||
|
||||
int otp_urec_open(struct otp_ctx *otpctx, char *u_username,
|
||||
struct otp_user *ou, int open_flags, int op_flags);
|
||||
|
|
129
common/str.c
129
common/str.c
|
@ -24,7 +24,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: str.c 87 2009-12-28 00:05:53Z maf $
|
||||
* $Id: str.c 164 2011-05-11 03:57:41Z maf $
|
||||
*/
|
||||
|
||||
#include <termios.h>
|
||||
|
@ -279,6 +279,9 @@ int str_input(const char *prompt, char *buf, size_t buf_size, int flags)
|
|||
|
||||
t.c_lflag &= ~ECHO;
|
||||
|
||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &t) < 0)
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
printf("%s", prompt); fflush(stdout);
|
||||
|
@ -326,6 +329,9 @@ str_input_out:
|
|||
|
||||
t.c_lflag |= ECHO;
|
||||
|
||||
if (tcsetattr(STDIN_FILENO, TCSANOW, &t) < 0)
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -335,58 +341,106 @@ str_input_out:
|
|||
/*
|
||||
* function: str_safe
|
||||
*
|
||||
* Ensure length of string is not > len
|
||||
* note n is the length of the string
|
||||
* where n+1 bytes are required to store
|
||||
* it with trailing null.
|
||||
*
|
||||
* Ensure string is limited to [a-zA-Z0-9.]
|
||||
*
|
||||
* First invalid character is set to 0.
|
||||
*
|
||||
* returns "safe" string
|
||||
* see STR_SAFE_*
|
||||
*
|
||||
*/
|
||||
int str_safe(char *input, size_t len)
|
||||
int str_safe(char *input, size_t input_len_max, char *ok_set, int flags)
|
||||
{
|
||||
size_t n;
|
||||
int ret;
|
||||
size_t n, input_len, ok_len, s;
|
||||
int ret, null_flag, ok_flag;
|
||||
|
||||
ret = 0; /* success */
|
||||
|
||||
n = strlen(input);
|
||||
null_flag = 0;
|
||||
for (input_len = 0; input_len <= input_len_max; ++input_len) {
|
||||
|
||||
if (input[input_len] == 0) {
|
||||
|
||||
null_flag = 1;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
/* bounds verification */
|
||||
if (n > len) {
|
||||
input[len] = 0;
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
for (n = 0; n < len; ++n) {
|
||||
if (flags & STR_SAFE_CHECK_LEN) {
|
||||
|
||||
/* a-z */
|
||||
if ((input[n] >= 'a') && (input[n] <= 'z'))
|
||||
continue;
|
||||
if (!null_flag) {
|
||||
|
||||
/* A-Z */
|
||||
if ((input[n] >= 'A') && (input[n] <= 'Z'))
|
||||
continue;
|
||||
if (flags & STR_SAFE_WARN)
|
||||
xerr_warnx("%s: size overrun", __func__);
|
||||
|
||||
/* 0-9 */
|
||||
if ((input[n] >= '0') && (input[n] <= '9'))
|
||||
continue;
|
||||
if (flags & STR_SAFE_FIX) {
|
||||
|
||||
/* . */
|
||||
if (input[n] == '.')
|
||||
continue;
|
||||
input[input_len_max] = 0;
|
||||
input_len = input_len_max;
|
||||
|
||||
/* unsafe */
|
||||
}
|
||||
|
||||
input[n] = 0;
|
||||
ret = -1;
|
||||
break;
|
||||
ret |= STR_SAFE_FAIL_LEN;
|
||||
|
||||
} /* for each byte in input */
|
||||
}
|
||||
|
||||
} /* STR_SAFE_CHECK_LEN */
|
||||
|
||||
if (flags & (STR_SAFE_CHECK_ALPHA|STR_SAFE_CHECK_NUM|STR_SAFE_CHECK_SET)) {
|
||||
|
||||
for (n = 0; n < input_len; ++n) {
|
||||
|
||||
if (flags & STR_SAFE_CHECK_ALPHA) {
|
||||
|
||||
/* a-z */
|
||||
if ((input[n] >= 'a') && (input[n] <= 'z'))
|
||||
continue;
|
||||
|
||||
/* A-Z */
|
||||
if ((input[n] >= 'A') && (input[n] <= 'Z'))
|
||||
continue;
|
||||
|
||||
} /* STR_SAFE_CHECK_ALPHA */
|
||||
|
||||
if (flags & STR_SAFE_CHECK_NUM) {
|
||||
|
||||
/* 0-9 */
|
||||
if ((input[n] >= '0') && (input[n] <= '9'))
|
||||
continue;
|
||||
|
||||
} /* STR_SAFE_CHECK_NUM */
|
||||
|
||||
if (flags & STR_SAFE_CHECK_SET) {
|
||||
|
||||
ok_len = strlen(ok_set);
|
||||
|
||||
ok_flag = 0; /* bad */
|
||||
for (s = 0; s < ok_len; ++s) {
|
||||
|
||||
if (input[n] == ok_set[s]) {
|
||||
|
||||
ok_flag = 1; /* good */
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
} /* test char in ok_set */
|
||||
|
||||
if (ok_flag)
|
||||
continue;
|
||||
|
||||
} /* STR_SAFE_CHECK_SET */
|
||||
|
||||
ret |= STR_SAFE_FAIL_CHAR;
|
||||
|
||||
/* unsafe */
|
||||
if (flags & STR_SAFE_WARN)
|
||||
xerr_warnx("%s: illegal char @ index=%d", __func__, n);
|
||||
|
||||
if (flags & STR_SAFE_FIX)
|
||||
input[input_len] = '_';
|
||||
|
||||
} /* for each byte in input */
|
||||
|
||||
} /* STR_SAFE_CHECK_FNAME */
|
||||
|
||||
return ret;
|
||||
|
||||
|
@ -501,7 +555,6 @@ int str_setflag8(char *list[], uint8_t *flags, char *s, uint8_t min,
|
|||
uint8_t max)
|
||||
{
|
||||
int i;
|
||||
*flags = 0;
|
||||
|
||||
for (i = min; i < max; ++i) {
|
||||
if (!strcasecmp(s, list[i]))
|
||||
|
|
14
common/str.h
14
common/str.h
|
@ -24,7 +24,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: str.h 85 2009-12-28 00:05:02Z maf $
|
||||
* $Id: str.h 154 2011-04-06 02:21:29Z maf $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -42,7 +42,7 @@ int str_hex_dump(char *buf, u_char *b, size_t n);
|
|||
int str_hex_decode(char *in, size_t in_len, u_char *out, size_t out_len);
|
||||
void str_ftoc(char *buf, char *f, size_t n);
|
||||
int str_input(const char *prompt, char *buf, size_t buf_size, int flags);
|
||||
int str_safe(char *input, size_t len);
|
||||
int str_safe(char *input, size_t input_max_len, char *ok_set, int flags);
|
||||
int str_uint32toa(char *s, uint32_t u);
|
||||
|
||||
char *str_lookup8(char *list[], uint8_t id, uint8_t min, uint8_t max);
|
||||
|
@ -59,4 +59,14 @@ int str_find8(char *list[], uint8_t *id, char *s, uint8_t min, uint8_t max);
|
|||
|
||||
#define STR_UINT32_LEN 11 /* 2^32-1=4294967295 + NULL = 11 bytes */
|
||||
|
||||
#define STR_SAFE_CHECK_LEN 0x0001 /* length */
|
||||
#define STR_SAFE_CHECK_ALPHA 0x0002 /* a-zA-Z */
|
||||
#define STR_SAFE_CHECK_NUM 0x0004 /* 0-9 */
|
||||
#define STR_SAFE_CHECK_FNAME 0x000E /* ALPHA+NUM+ .-_ */
|
||||
#define STR_SAFE_CHECK_SET 0x0010 /* elements are all in char_set */
|
||||
#define STR_SAFE_FIX 0x1000 /* fix problem string */
|
||||
#define STR_SAFE_WARN 0x2000 /* enable warnings */
|
||||
|
||||
#define STR_SAFE_FAIL_CHAR 0x1
|
||||
#define STR_SAFE_FAIL_LEN 0x2
|
||||
|
||||
|
|
BIN
doc/BCTutorial.pdf
Normal file
BIN
doc/BCTutorial.pdf
Normal file
Binary file not shown.
49
doc/CHANGES
49
doc/CHANGES
|
@ -1,5 +1,54 @@
|
|||
# $Id:$
|
||||
|
||||
urd/rc.d/urd: updated for new flags
|
||||
|
||||
otp-control: mode generate will honor -c
|
||||
|
||||
send-tokendd: reference implementation of OOB token. Sends token to web
|
||||
page via ssl. Used internally for SMS gateway.
|
||||
|
||||
send-token feature. Send to token to user via flexible OOB method.
|
||||
|
||||
HOTPC.BAS rev 9. Check PIN, readerKey
|
||||
|
||||
otp-sca support SC_SETREADERKEY_CAP
|
||||
|
||||
pam_otp.so: require_db_entry is now defaulted to enabled. A new option
|
||||
allow_unknown_user which is mutually exclusive to require_db_entry is
|
||||
accepted for consistency with urd and openvpn. kyriacou@osc.edu
|
||||
|
||||
otpdb2sc missing quote. kyriacou@osc.edu
|
||||
|
||||
openvpn plugin accepts otp-allow-unknown-user
|
||||
|
||||
otp-control will by default create a new user with count=1. BasicCard
|
||||
code treats count=0 as a special case when a challenge (count) is supplied.
|
||||
0 is ignore challenge and use EEPROM stored count.
|
||||
|
||||
getopt_long() support. All binaries support --version.
|
||||
|
||||
honor OTP_FLAGS_DISPNT in urd. Use -c to force display
|
||||
|
||||
urd will omit password when packed decode debug is enabled
|
||||
|
||||
fix state hex encoding in urd when state > 127
|
||||
|
||||
fix soft reload option in urd
|
||||
|
||||
add PAM password authentication to urd
|
||||
|
||||
str.c: tcsetattr() missing in str_input()
|
||||
|
||||
otp-control -m list-sc will automatically set the correct FMT flags
|
||||
|
||||
document behavior of count=0 in otp-sct, otp-sca, and spyrus-reader
|
||||
|
||||
add urd/rc.d script to dist
|
||||
|
||||
add rfc.card to dist
|
||||
|
||||
spyrus1.4.hex installed instead of 1.3. Also in QUICKSTART
|
||||
|
||||
### ootp-1.03.tar.gz
|
||||
|
||||
add CHANGES and TODO to dist
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile 13 2009-11-26 16:37:03Z maf $
|
||||
# $Id: Makefile 153 2011-04-01 02:38:36Z maf $
|
||||
|
||||
INSTALL=install -c -m0644
|
||||
|
||||
|
@ -16,7 +16,7 @@ MISCDIR=/usr/local/ootp/doc
|
|||
docbook-to-man $*.sgml > $@
|
||||
|
||||
.sgml.html:
|
||||
openjade -V nochunks -c /usr/local/share/sgml/docbook/dsssl/modular/catalog -c /usr/local/share/sgml/docbook/catalog -c /usr/local/share/sgml/jade/catalog -d /usr/local/share/sgml/docbook/dsssl/modular/html/docbook.dsl -t sgml $*.sgml > $*.html
|
||||
openjade -V nochunks -c /usr/local/share/sgml/docbook/dsssl/modular/catalog -c /usr/local/share/sgml/docbook/3.1/dtd/catalog -c /usr/local/share/sgml/jade/catalog -d /usr/local/share/sgml/docbook/dsssl/modular/html/docbook.dsl -t sgml $*.sgml > $*.html
|
||||
|
||||
MAN1S = htsoft-downloader.1 bcload.1 otp-control.1 otp-ov-plugin.1\
|
||||
pam_otp.1 urd.1 otp-sca.1 otp-sct.1
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# $Id: QUICKSTART 76 2009-12-26 21:04:01Z maf $
|
||||
# $Id: QUICKSTART 114 2010-02-25 18:23:44Z maf $
|
||||
#
|
||||
|
||||
OpenOTP is an implementation of the HOTP protocol using a ZeitControl
|
||||
|
@ -326,7 +326,7 @@ semanage fcontext -a -t textrel_shlib_t /lib/security/pam_otp.so
|
|||
|
||||
# create the OTP database with one inactive user (joe)
|
||||
otp-control -n -u joe -m add
|
||||
otp-control -u joe -m set-status inactive
|
||||
otp-control -u joe -m set-status -s inactive
|
||||
otp-control -u joe -m list
|
||||
|
||||
>Username.......joe
|
||||
|
@ -408,7 +408,7 @@ Last login: Wed Sep 2 00:22:03 2009 from 10.1.0.26
|
|||
|
||||
#### Downloading firmware to the Spyrus reader
|
||||
|
||||
The Spyrus PAR II will be programmed with the spyrus1.3.hex application
|
||||
The Spyrus PAR II will be programmed with the spyrus1.4.hex application
|
||||
included in the OTP distribution. This will be done once per new reader,
|
||||
or when new application software is required. An proprietary RS232 serial
|
||||
programming cable available from Spyrus is needed.
|
||||
|
@ -425,10 +425,10 @@ arrow until the "DownloadApp" menu item is present.
|
|||
Start the htsoft-downloader utility using serial port at /dev/cuaU0 :
|
||||
|
||||
# FreeBSD USB Serial Adapter
|
||||
htsoft-downloader -v1 -i -f /dev/cuaU0 < $OOTP/firmware/spyrus1.3.hex
|
||||
htsoft-downloader -v1 -i -f /dev/cuaU0 < $OOTP/firmware/spyrus1.4.hex
|
||||
|
||||
# Linux USB Serial Adapter
|
||||
htsoft-downloader -v1 -i -f /dev/ttyS0 < $OOTP/firmware/spyrus1.3.hex
|
||||
htsoft-downloader -v1 -i -f /dev/ttyS0 < $OOTP/firmware/spyrus1.4.hex
|
||||
|
||||
Press Enter on the spyrus reader to start the download application:
|
||||
|
||||
|
|
BIN
doc/REF_ACx30.pdf
Normal file
BIN
doc/REF_ACx30.pdf
Normal file
Binary file not shown.
39
doc/TODO
39
doc/TODO
|
@ -1,7 +1,18 @@
|
|||
autoconf/automake
|
||||
urd option c should not require arg
|
||||
urd_oareng_pgm support in rc.d
|
||||
urd opt n should include character list
|
||||
man page for option n
|
||||
|
||||
RADIUS optionally encode HOTP count in challenge message
|
||||
RADIUS dspcnt flag urd, force display count
|
||||
tokend
|
||||
man page
|
||||
usage
|
||||
|
||||
urd,openvpn
|
||||
send-token
|
||||
|
||||
Enter PIN code does not issue a \n
|
||||
|
||||
autoconf/automake
|
||||
|
||||
RADIUS proxy support
|
||||
|
||||
|
@ -10,17 +21,12 @@ ACS balance reader support dec31.6?
|
|||
|
||||
break out htsoft-downloader, urd, bcload?
|
||||
|
||||
architecture document
|
||||
formats
|
||||
post
|
||||
|
||||
basiccard build notes
|
||||
|
||||
full coverage testing for otplib and ffdb
|
||||
|
||||
otp-token (soft token)
|
||||
|
||||
count use 64 bit current time option
|
||||
count use 64 bit current time option, store last time delta for each user to
|
||||
help compensate for reader drift.
|
||||
|
||||
balance reader simulator
|
||||
|
||||
|
@ -33,3 +39,16 @@ Spyrus main.c missing
|
|||
U8 Temp[4];
|
||||
RESP_INFO *respDump = (RESP_INFO*) Temp;
|
||||
|
||||
-S in otp-control - use symbolic names
|
||||
|
||||
option in otp-sca to list symbolic names of flags
|
||||
|
||||
otp-sca
|
||||
make sure d modifier still works
|
||||
tail -1 in otp-control example
|
||||
use RFC keys for examples
|
||||
|
||||
urd - wtmp
|
||||
|
||||
otp-control -c should do the right thing when generating otp
|
||||
|
||||
|
|
BIN
doc/balanceR.pdf
Normal file
BIN
doc/balanceR.pdf
Normal file
Binary file not shown.
20
doc/bcload.1
20
doc/bcload.1
|
@ -66,19 +66,19 @@ off the bcload example included in the development environment\&.
|
|||
hardware\&. Small changes would be required to support the Professional
|
||||
line of cards\&.
|
||||
.SH "OPTIONS"
|
||||
.IP "-d\fI debug_level\fP" 10
|
||||
.IP "-d, --debug=\fI debug_level\fP" 10
|
||||
Set debug level\&.
|
||||
.IP "-f\fI fname\fP" 10
|
||||
.IP "-f, --image=\fI fname\fP" 10
|
||||
Name of BasicCard Image file\&. Defaults to HOTPC\&.IMG
|
||||
.IP "-h" 10
|
||||
.IP "-h, --help" 10
|
||||
Help\&.
|
||||
.IP "-l" 10
|
||||
.IP "-l, --list-readers" 10
|
||||
List SC Readers
|
||||
.IP "-p" 10
|
||||
.IP "-p, --no-paranoid" 10
|
||||
Disable paranoid check for ZC3\&.9 hardware\&. Enhanced Smart Cards will
|
||||
probably work, support for the professional cards require changes
|
||||
to \fBbcload\&.c\fP\&.
|
||||
.IP "-r\fI reader\fP" 10
|
||||
.IP "-r, --reader=\fI reader\fP" 10
|
||||
Set Smart Card reader\&. Use -l to list available readers\&. A reader
|
||||
is defined as class:reader:[option]\&. PCSC and embedded
|
||||
are the two available classes\&. The embedded class contains the acr30s driver
|
||||
|
@ -87,11 +87,13 @@ If pcscd is running the first PC/SC reader will be the default followed by
|
|||
the embedded acr30s driver\&. Use PCSC: for the first available PC/SC
|
||||
reader\&. Use embedded:acr30s:/dev/cuaU0 for the embedded acr30s driver
|
||||
with serial port /dev/cuaU0\&.
|
||||
.IP "-t" 10
|
||||
.IP "-t, --force-test" 10
|
||||
Force card mode to TEST after programming\&. Defaults to the mode
|
||||
specified in the image file\&.
|
||||
.IP "-v" 10
|
||||
.IP "-v, --verbose" 10
|
||||
Display verbose status messages while programming the card\&.
|
||||
.IP "--version" 10
|
||||
Display software version\&.
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
Download the HOTPC\&.IMG file to the default Smart Card reader\&. Display
|
||||
|
@ -134,4 +136,4 @@ Mark Fullmer maf@splintered\&.net
|
|||
\fBotp-ov-plugin\fP(1)
|
||||
\fBurd\fP(1)
|
||||
spyrus-par2(7)
|
||||
...\" created by instant / docbook-to-man, Sun 27 Dec 2009, 22:01
|
||||
...\" created by instant / docbook-to-man, Sun 15 May 2011, 23:57
|
||||
|
|
|
@ -97,7 +97,7 @@ NAME="AEN26"
|
|||
CLASS="VARIABLELIST"
|
||||
><DL
|
||||
><DT
|
||||
>-d<TT
|
||||
>-d, --debug=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> debug_level</I
|
||||
|
@ -108,7 +108,7 @@ CLASS="REPLACEABLE"
|
|||
>Set debug level.</P
|
||||
></DD
|
||||
><DT
|
||||
>-f<TT
|
||||
>-f, --image=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> fname</I
|
||||
|
@ -119,19 +119,19 @@ CLASS="REPLACEABLE"
|
|||
>Name of BasicCard Image file. Defaults to HOTPC.IMG</P
|
||||
></DD
|
||||
><DT
|
||||
>-h</DT
|
||||
>-h, --help</DT
|
||||
><DD
|
||||
><P
|
||||
>Help.</P
|
||||
></DD
|
||||
><DT
|
||||
>-l</DT
|
||||
>-l, --list-readers</DT
|
||||
><DD
|
||||
><P
|
||||
>List SC Readers</P
|
||||
></DD
|
||||
><DT
|
||||
>-p</DT
|
||||
>-p, --no-paranoid</DT
|
||||
><DD
|
||||
><P
|
||||
>Disable paranoid check for ZC3.9 hardware. Enhanced Smart Cards will
|
||||
|
@ -142,7 +142,7 @@ CLASS="FILENAME"
|
|||
>.</P
|
||||
></DD
|
||||
><DT
|
||||
>-r<TT
|
||||
>-r, --reader=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> reader</I
|
||||
|
@ -166,25 +166,31 @@ reader. Use embedded:acr30s:/dev/cuaU0 for the embedded acr30s driver
|
|||
with serial port /dev/cuaU0.</P
|
||||
></DD
|
||||
><DT
|
||||
>-t</DT
|
||||
>-t, --force-test</DT
|
||||
><DD
|
||||
><P
|
||||
>Force card mode to TEST after programming. Defaults to the mode
|
||||
specified in the image file.</P
|
||||
></DD
|
||||
><DT
|
||||
>-v</DT
|
||||
>-v, --verbose</DT
|
||||
><DD
|
||||
><P
|
||||
>Display verbose status messages while programming the card.</P
|
||||
></DD
|
||||
><DT
|
||||
>--version</DT
|
||||
><DD
|
||||
><P
|
||||
>Display software version.</P
|
||||
></DD
|
||||
></DL
|
||||
></DIV
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN67"
|
||||
NAME="AEN71"
|
||||
></A
|
||||
><H2
|
||||
>EXAMPLES</H2
|
||||
|
@ -193,7 +199,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN69"
|
||||
NAME="AEN73"
|
||||
></A
|
||||
><P
|
||||
>Download the HOTPC.IMG file to the default Smart Card reader. Display
|
||||
|
@ -236,7 +242,7 @@ BCSetState: test</SAMP
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN74"
|
||||
NAME="AEN78"
|
||||
></A
|
||||
><H2
|
||||
>AUTHOR</H2
|
||||
|
@ -253,7 +259,7 @@ HREF="mailto:maf@splintered.net"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN81"
|
||||
NAME="AEN85"
|
||||
></A
|
||||
><H2
|
||||
>SEE ALSO</H2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE refentry PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
|
||||
|
||||
<!-- $Id: bcload.sgml 62 2009-12-18 17:26:31Z maf $ -->
|
||||
<!-- $Id: bcload.sgml 126 2010-06-15 14:23:02Z maf $ -->
|
||||
|
||||
<refentry>
|
||||
<refmeta>
|
||||
|
@ -45,7 +45,7 @@ line of cards.
|
|||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term>-d<replaceable> debug_level</replaceable></term>
|
||||
<term>-d, --debug=<replaceable> debug_level</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set debug level.
|
||||
|
@ -54,7 +54,7 @@ Set debug level.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-f<replaceable> fname</replaceable></term>
|
||||
<term>-f, --image=<replaceable> fname</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Name of BasicCard Image file. Defaults to HOTPC.IMG
|
||||
|
@ -63,7 +63,7 @@ Name of BasicCard Image file. Defaults to HOTPC.IMG
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-h</term>
|
||||
<term>-h, --help</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Help.
|
||||
|
@ -72,7 +72,7 @@ Help.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-l</term>
|
||||
<term>-l, --list-readers</term>
|
||||
<listitem>
|
||||
<para>
|
||||
List SC Readers
|
||||
|
@ -81,7 +81,7 @@ List SC Readers
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-p</term>
|
||||
<term>-p, --no-paranoid</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable paranoid check for ZC3.9 hardware. Enhanced Smart Cards will
|
||||
|
@ -92,7 +92,7 @@ to <filename>bcload.c</filename>.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-r<replaceable> reader</replaceable></term>
|
||||
<term>-r, --reader=<replaceable> reader</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set Smart Card reader. Use -l to list available readers. A reader
|
||||
|
@ -108,7 +108,7 @@ with serial port /dev/cuaU0.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-t</term>
|
||||
<term>-t, --force-test</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Force card mode to TEST after programming. Defaults to the mode
|
||||
|
@ -118,7 +118,7 @@ specified in the image file.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-v</term>
|
||||
<term>-v, --verbose</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Display verbose status messages while programming the card.
|
||||
|
@ -126,6 +126,14 @@ Display verbose status messages while programming the card.
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>--version</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Display software version.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
|
|
@ -67,11 +67,7 @@ file from picc, MPLAB, gpasm, or other PIC compatible toolchains) is read
|
|||
on standard output and downloaded to a PIC on the
|
||||
\fIserial_device\fP\&.
|
||||
.SH "OPTIONS"
|
||||
.IP "-h" 10
|
||||
Help
|
||||
.IP "-i" 10
|
||||
Ignore timeout for last WOK after sending reset\&.
|
||||
.IP "-f\fI serial_device\fP" 10
|
||||
.IP "-f, --serial-device=\fI serial_device\fP" 10
|
||||
Serial device filename\&. Examples:
|
||||
.IP "" 10
|
||||
\fB/dev/ttyUSB0\fP (Linux USB Serial Adapter)
|
||||
|
@ -80,14 +76,20 @@ Serial device filename\&. Examples:
|
|||
.IP "" 10
|
||||
The default is \fB/dev/cuaU0\fP, a
|
||||
Prolific PL2303 USB to serial adaptor on FreeBSD\&.
|
||||
.IP "-r\fI retries\fP" 10
|
||||
.IP "-h, --help" 10
|
||||
Help
|
||||
.IP "-i, --ignore-last-wok-timeout" 10
|
||||
Ignore timeout for last WOK after sending reset\&.
|
||||
.IP "-r, --pic-retries=\fI retries\fP" 10
|
||||
Number of times to retry a block\&. Defaults to 5\&.
|
||||
.IP "-t\fI timeout\fP" 10
|
||||
.IP "-t, --pic-timeout=\fI timeout\fP" 10
|
||||
Timeout in \&.1 second intervals\&. Defaults to 25\&.
|
||||
.IP "-v\fI verbose_level\fP" 10
|
||||
.IP "-v, --verbose=\fI verbose_level\fP" 10
|
||||
Increasing the verbosity level will produce debug messages indicating
|
||||
the status of the download\&. A level of 9 will include all debugging
|
||||
output\&. A level of 1 will indicate the overall status of the transfer\&.
|
||||
.IP "--version" 10
|
||||
Display software version\&.
|
||||
.SH "EXAMPLE"
|
||||
.PP
|
||||
Transfer the HEX file spyrus1\&.1\&.hex to a PIC connected to
|
||||
|
@ -125,4 +127,4 @@ Intel Hexadecimal Object File Format Specification Rev A
|
|||
www\&.htsoft\&.com
|
||||
.PP
|
||||
http://www\&.ehl\&.cz/pic/pic_e\&.htm
|
||||
...\" created by instant / docbook-to-man, Sun 27 Dec 2009, 22:01
|
||||
...\" created by instant / docbook-to-man, Sun 15 May 2011, 23:57
|
||||
|
|
|
@ -102,19 +102,7 @@ NAME="AEN27"
|
|||
CLASS="VARIABLELIST"
|
||||
><DL
|
||||
><DT
|
||||
>-h</DT
|
||||
><DD
|
||||
><P
|
||||
>Help</P
|
||||
></DD
|
||||
><DT
|
||||
>-i</DT
|
||||
><DD
|
||||
><P
|
||||
>Ignore timeout for last WOK after sending reset.</P
|
||||
></DD
|
||||
><DT
|
||||
>-f<TT
|
||||
>-f, --serial-device=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> serial_device</I
|
||||
|
@ -141,7 +129,19 @@ CLASS="FILENAME"
|
|||
Prolific PL2303 USB to serial adaptor on FreeBSD.</P
|
||||
></DD
|
||||
><DT
|
||||
>-r<TT
|
||||
>-h, --help</DT
|
||||
><DD
|
||||
><P
|
||||
>Help</P
|
||||
></DD
|
||||
><DT
|
||||
>-i, --ignore-last-wok-timeout</DT
|
||||
><DD
|
||||
><P
|
||||
>Ignore timeout for last WOK after sending reset.</P
|
||||
></DD
|
||||
><DT
|
||||
>-r, --pic-retries=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> retries</I
|
||||
|
@ -152,7 +152,7 @@ CLASS="REPLACEABLE"
|
|||
>Number of times to retry a block. Defaults to 5.</P
|
||||
></DD
|
||||
><DT
|
||||
>-t<TT
|
||||
>-t, --pic-timeout=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> timeout</I
|
||||
|
@ -163,7 +163,7 @@ CLASS="REPLACEABLE"
|
|||
>Timeout in .1 second intervals. Defaults to 25.</P
|
||||
></DD
|
||||
><DT
|
||||
>-v<TT
|
||||
>-v, --verbose=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> verbose_level</I
|
||||
|
@ -175,13 +175,19 @@ CLASS="REPLACEABLE"
|
|||
the status of the download. A level of 9 will include all debugging
|
||||
output. A level of 1 will indicate the overall status of the transfer.</P
|
||||
></DD
|
||||
><DT
|
||||
>--version</DT
|
||||
><DD
|
||||
><P
|
||||
>Display software version.</P
|
||||
></DD
|
||||
></DL
|
||||
></DIV
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN64"
|
||||
NAME="AEN68"
|
||||
></A
|
||||
><H2
|
||||
>EXAMPLE</H2
|
||||
|
@ -190,7 +196,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN66"
|
||||
NAME="AEN70"
|
||||
></A
|
||||
><P
|
||||
>Transfer the HEX file spyrus1.1.hex to a PIC connected to
|
||||
|
@ -230,7 +236,7 @@ wDONE: reply=F0, expecting E4wPIC reset sent.</PRE
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN72"
|
||||
NAME="AEN76"
|
||||
></A
|
||||
><H2
|
||||
>AUTHOR</H2
|
||||
|
@ -247,7 +253,7 @@ HREF="mailto:maf@splintered.net"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN79"
|
||||
NAME="AEN83"
|
||||
></A
|
||||
><H2
|
||||
>SEE ALSO</H2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE refentry PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
|
||||
|
||||
<!-- $Id: htsoft-downloader.sgml 74 2009-12-26 20:40:57Z maf $ -->
|
||||
<!-- $Id: htsoft-downloader.sgml 126 2010-06-15 14:23:02Z maf $ -->
|
||||
|
||||
<refentry>
|
||||
|
||||
|
@ -50,25 +50,7 @@ on standard output and downloaded to a PIC on the
|
|||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term>-h</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Help
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-i</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Ignore timeout for last WOK after sending reset.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-f<replaceable> serial_device</replaceable></term>
|
||||
<term>-f, --serial-device=<replaceable> serial_device</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Serial device filename. Examples:
|
||||
|
@ -87,7 +69,25 @@ Prolific PL2303 USB to serial adaptor on FreeBSD.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-r<replaceable> retries</replaceable></term>
|
||||
<term>-h, --help</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Help
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-i, --ignore-last-wok-timeout</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Ignore timeout for last WOK after sending reset.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-r, --pic-retries=<replaceable> retries</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Number of times to retry a block. Defaults to 5.
|
||||
|
@ -96,7 +96,7 @@ Number of times to retry a block. Defaults to 5.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-t<replaceable> timeout</replaceable></term>
|
||||
<term>-t, --pic-timeout=<replaceable> timeout</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Timeout in .1 second intervals. Defaults to 25.
|
||||
|
@ -105,7 +105,7 @@ Timeout in .1 second intervals. Defaults to 25.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-v<replaceable> verbose_level</replaceable></term>
|
||||
<term>-v, --verbose=<replaceable> verbose_level</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Increasing the verbosity level will produce debug messages indicating
|
||||
|
@ -115,6 +115,15 @@ output. A level of 1 will indicate the overall status of the transfer.
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>--version</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Display software version.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
|
BIN
doc/ootp-arch-overview.pdf
Normal file
BIN
doc/ootp-arch-overview.pdf
Normal file
Binary file not shown.
|
@ -56,16 +56,16 @@
|
|||
\fBotp-control\fP \(em Local user database configuration for One Time Password package\&.
|
||||
.SH "SYNOPSIS"
|
||||
.PP
|
||||
\fBotp-control\fP [-?hnv] [-c\fI count\fP] [-C\fI count_ceil\fP] [-f\fI format\fP] [-F\fI flags\fP] [-H\fI sc_hostname\fP] [-I\fI sc_index\fP] [-k\fI key\fP] [-m\fI command_mode\fP] [-o\fI otpdb_pathname\fP] [-s\fI status\fP] [-S\fI sc_flags\fP] [-t\fI type\fP] [-u\fI username\fP] [-w\fI window\fP]
|
||||
\fBotp-control\fP [-?hnv] [-c\fI count\fP] [-C\fI count_ceiling\fP] [-f\fI format\fP] [-F\fI flag\fP] [-H\fI sc_hostname\fP] [-I\fI sc_index\fP] [-k\fI key\fP] [-l\fI location\fP] [-m\fI command_mode\fP] [-o\fI otp_db\fP] [-s\fI status\fP] [-S\fI sc_flags\fP] [-t\fI type\fP] [-u\fI username\fP] [-V\fI service_name\fP] [-w\fI window\fP]
|
||||
.SH "DESCRIPTION"
|
||||
.PP
|
||||
The \fBotp-control\fP command is a front end to the
|
||||
local One Time Password database\&. Users can be added, modified
|
||||
and removed by \fBotp-control\&.\fP
|
||||
.SH "OPTIONS"
|
||||
.IP "-c\fI count\fP" 10
|
||||
.IP "-c, --count= \fI count\fP" 10
|
||||
User count\&. The count increases with each OTP transaction\&.
|
||||
.IP "-C\fI count_ceil\fP" 10
|
||||
.IP "-C, --count-ceil= \fI count_ceiling\fP" 10
|
||||
User count ceiling\&. Highest count allowed for this user\&. Configuring
|
||||
the count_ceiling allows a user key to be shared among multiple
|
||||
systems each with a unique count window, where count <= count_ceiling\&.
|
||||
|
@ -74,9 +74,9 @@ A count value must only be allowed for authentication once\&.
|
|||
.IP "" 10
|
||||
Example:
|
||||
.IP "" 10
|
||||
host=h1, user=bob, count_current=0, count_ceil=10000\&.
|
||||
host=h1, user=bob, count_current=0, count_ceiling=10000\&.
|
||||
.IP "" 10
|
||||
host=h2, user=bob, count_current=10001, count_ceil=20000\&.
|
||||
host=h2, user=bob, count_current=10001, count_ceiling=20000\&.
|
||||
.IP "" 10
|
||||
The number of keys a user must possess is decreased at the expense
|
||||
of security dependencies among multiple systems\&. If system A is
|
||||
|
@ -86,34 +86,37 @@ must be presented to the OTP generator\&. The additional step of entering
|
|||
the count to the OTP generator is not necessary when keys are not
|
||||
shared, as the currrent count will increase on the OTP generator and
|
||||
system database during authentication\&.
|
||||
.IP "-f" 10
|
||||
.IP "-f, --format=" 10
|
||||
OTP format\&. One of hex40 dhex40 dec31\&.6 dec31\&.7 dec31\&.8 dec31\&.9 dec31\&.10\&.
|
||||
hex40 (40 bit hex) is the default\&. dec31\&.6 (31 bit decimal truncated to 6
|
||||
digits) is suggested by RFC 4226 and may be required to interoperate with
|
||||
other HOTP implementations\&. dhex40 uses the dynamic truncate function
|
||||
in RFC 4226, where hex40 always uses the top 40 bits\&. dhex40 may be the
|
||||
default in future releases\&.
|
||||
.IP "-F" 10
|
||||
OTP flags\&. All flags are unset by default\&.
|
||||
.IP "-F, --flag=" 10
|
||||
OTP flag\&. All flags are unset by default\&.
|
||||
.PP
|
||||
.nf
|
||||
Flag Description
|
||||
-----------------------------------------------------------------
|
||||
display-count : Display HOTP count when prompted for challenge\&.
|
||||
send-token : Send token to user out of band\&.
|
||||
.fi
|
||||
.IP "-h" 10
|
||||
.IP "-h, --help" 10
|
||||
Help\&.
|
||||
.IP "-H\fI sc_hostname\fP" 10
|
||||
Set the SC hostname with the list-sc command mode\&.
|
||||
.IP "-I\fI sc_index\fP" 10
|
||||
Set the SC index with the list-sc command mode\&.
|
||||
.IP "-k\fI key\fP" 10
|
||||
.IP "-H, --sc_hostname=\fI sc_hostname\fP" 10
|
||||
Set the SC hostname for the list-sc command mode\&.
|
||||
.IP "-I, --sc_index=\fI sc_index\fP" 10
|
||||
Set the SC index for the list-sc command mode\&.
|
||||
.IP "-k, --key=\fI key\fP" 10
|
||||
160 bit shared secret key in ASCII HEX\&. The secret key is shared between
|
||||
the OTP generation hardware/software for a user and the local OTP database\&.
|
||||
Each user typically will have a unique key unless a shared key with
|
||||
unique count space is provisioned\&. Use - for stdin\&. Example key:
|
||||
C0C3D47F1CC68ECE0DF81D008F0C0D72D43EB745
|
||||
.IP "-m\fI command_mode\fP" 10
|
||||
.IP "-l, --location=\fI location\fP" 10
|
||||
Location to send token to when SEND_TOKEN flag is set\&.
|
||||
.IP "-m, --command_mode=\fI command_mode\fP" 10
|
||||
.PP
|
||||
.nf
|
||||
Mode Description
|
||||
|
@ -126,6 +129,7 @@ C0C3D47F1CC68ECE0DF81D008F0C0D72D43EB745
|
|||
list-sc - List user record (SC friendly)
|
||||
load - ASCII load user record(s)
|
||||
remove - Remove user
|
||||
send-token - Send token to user
|
||||
set-count - Set user count
|
||||
set-count-ceil - Set user count ceiling
|
||||
set-flags - Set user flags
|
||||
|
@ -134,11 +138,11 @@ C0C3D47F1CC68ECE0DF81D008F0C0D72D43EB745
|
|||
set-type - Set user OTP type
|
||||
test - Test user
|
||||
.fi
|
||||
.IP "-n" 10
|
||||
.IP "-n, --create_database" 10
|
||||
Create new database if one does not exist\&.
|
||||
.IP "-o\fI otp_pathname\fP" 10
|
||||
.IP "-o, --otp-db=\fI otp_db\fP" 10
|
||||
Pathname of OTP database\&.
|
||||
.IP "-s\fI otp_pathname\fP" 10
|
||||
.IP "-s, --status=\fI status\fP" 10
|
||||
OTP Status\&. The default status is active\&.
|
||||
.PP
|
||||
.nf
|
||||
|
@ -148,18 +152,23 @@ OTP Status\&. The default status is active\&.
|
|||
inactive : OTP may not be required for successful authentication\&.
|
||||
The OTP authentication module may be configured to allow
|
||||
inactive accounts to authenticate\&. This may be used to
|
||||
temporarily remove the OTP authentication method for a user\&.
|
||||
temporarily remove the OTP authentication method for a
|
||||
user\&.
|
||||
disabled : Account is disabled\&. OTP authentication will fail\&.
|
||||
.fi
|
||||
.IP "-S\fI sc_flags\fP" 10
|
||||
Set the SC flags with the list-sc command mode\&. 0=CHALLENGE, 1=READERKEY\&.
|
||||
.IP "-t\fI type\fP" 10
|
||||
.IP "-S, --sc-flags=\fI sc_flags\fP" 10
|
||||
Set the SC flags for the list-sc command mode\&. 0=CHALLENGE, 1=READERKEY\&.
|
||||
.IP "-t, --type=\fI type\fP" 10
|
||||
OTP Type\&. RFC 4226 HOTP is only supported type\&.
|
||||
.IP "-u\fI username\fP" 10
|
||||
.IP "-u, --username=\fI username\fP" 10
|
||||
Username to perform database operation on\&.
|
||||
.IP "-v" 10
|
||||
.IP "-v, --verbose" 10
|
||||
Enable verbose output (debugging)\&.
|
||||
.IP "-w\fI window\fP" 10
|
||||
.IP "-V, --service-name=\fI service_name\fP" 10
|
||||
Set service name for send-token function\&.
|
||||
.IP "--version" 10
|
||||
Display software version\&.
|
||||
.IP "-w, --challenge-window=\fI window\fP" 10
|
||||
Set the maximum window (count above the system count) where an OTP
|
||||
will successfully authenticate\&. For user bob with with OTP generator
|
||||
count_current=30, and system OTP database for bob count_current 15, the
|
||||
|
@ -182,7 +191,7 @@ user stored in a separate ASCII : delimited file in base_dir/d\&.
|
|||
\fBdump\fP : dump user database in ASCII\&. User records are separated by a newline\&.
|
||||
Fields are : separated\&. All fields except the username are HEX encoded\&.
|
||||
.PP
|
||||
#version:user:key:status:format:type:flags:count_cur:count_ceil:last
|
||||
#version:user:key:status:format:type:flags:count_cur:count_ceiling:last
|
||||
01:test:1111111111111111111111111111111111111111:01:01:01:00:00000000000003E8:00000000000007D0:0000000000000000
|
||||
.PP
|
||||
\fBgenerate\fP : generate OTP for user\&. The -w flag may be used to generate multiple
|
||||
|
@ -263,7 +272,7 @@ Use the load command to import records in this format\&.
|
|||
\fBotp-control -m dump\fP
|
||||
.PP
|
||||
.nf
|
||||
#version:user:key:status:format:type:flags:count_cur:count_ceil:last
|
||||
#version:user:key:status:format:type:flags:count_cur:count_ceiling:last
|
||||
01:bob:C381739834A63A67B0B9F7F7D36C8C567F6BFB3D:01:01:01:00:0000000000000001:FFFFFFFFFFFFFFFF:000000004AA02F9E
|
||||
.fi
|
||||
.PP
|
||||
|
@ -290,4 +299,4 @@ Mark Fullmer maf@splintered\&.net
|
|||
\fBurd\fP(1)
|
||||
\fBbcload\fP(1)
|
||||
spyrus-par2(7)
|
||||
...\" created by instant / docbook-to-man, Sun 27 Dec 2009, 22:01
|
||||
...\" created by instant / docbook-to-man, Sun 15 May 2011, 23:57
|
||||
|
|
|
@ -51,7 +51,7 @@ CLASS="REPLACEABLE"
|
|||
>] [-C<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> count_ceil</I
|
||||
> count_ceiling</I
|
||||
></TT
|
||||
>] [-f<TT
|
||||
CLASS="REPLACEABLE"
|
||||
|
@ -61,7 +61,7 @@ CLASS="REPLACEABLE"
|
|||
>] [-F<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> flags</I
|
||||
> flag</I
|
||||
></TT
|
||||
>] [-H<TT
|
||||
CLASS="REPLACEABLE"
|
||||
|
@ -78,6 +78,11 @@ CLASS="REPLACEABLE"
|
|||
><I
|
||||
> key</I
|
||||
></TT
|
||||
>] [-l<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> location</I
|
||||
></TT
|
||||
>] [-m<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
|
@ -86,7 +91,7 @@ CLASS="REPLACEABLE"
|
|||
>] [-o<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> otpdb_pathname</I
|
||||
> otp_db</I
|
||||
></TT
|
||||
>] [-s<TT
|
||||
CLASS="REPLACEABLE"
|
||||
|
@ -108,6 +113,11 @@ CLASS="REPLACEABLE"
|
|||
><I
|
||||
> username</I
|
||||
></TT
|
||||
>] [-V<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> service_name</I
|
||||
></TT
|
||||
>] [-w<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
|
@ -118,7 +128,7 @@ CLASS="REPLACEABLE"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN42"
|
||||
NAME="AEN46"
|
||||
></A
|
||||
><H2
|
||||
>DESCRIPTION</H2
|
||||
|
@ -136,7 +146,7 @@ CLASS="COMMAND"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN47"
|
||||
NAME="AEN51"
|
||||
></A
|
||||
><H2
|
||||
>OPTIONS</H2
|
||||
|
@ -146,7 +156,7 @@ NAME="AEN47"
|
|||
CLASS="VARIABLELIST"
|
||||
><DL
|
||||
><DT
|
||||
>-c<TT
|
||||
>-c, --count= <TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> count</I
|
||||
|
@ -157,10 +167,10 @@ CLASS="REPLACEABLE"
|
|||
>User count. The count increases with each OTP transaction.</P
|
||||
></DD
|
||||
><DT
|
||||
>-C<TT
|
||||
>-C, --count-ceil= <TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> count_ceil</I
|
||||
> count_ceiling</I
|
||||
></TT
|
||||
></DT
|
||||
><DD
|
||||
|
@ -173,9 +183,9 @@ systems each with a unique count window, where count <= count_ceiling.</P
|
|||
><P
|
||||
>Example:</P
|
||||
><P
|
||||
>host=h1, user=bob, count_current=0, count_ceil=10000.</P
|
||||
>host=h1, user=bob, count_current=0, count_ceiling=10000.</P
|
||||
><P
|
||||
>host=h2, user=bob, count_current=10001, count_ceil=20000.</P
|
||||
>host=h2, user=bob, count_current=10001, count_ceiling=20000.</P
|
||||
><P
|
||||
>The number of keys a user must possess is decreased at the expense
|
||||
of security dependencies among multiple systems. If system A is
|
||||
|
@ -187,7 +197,7 @@ shared, as the currrent count will increase on the OTP generator and
|
|||
system database during authentication.</P
|
||||
></DD
|
||||
><DT
|
||||
>-f</DT
|
||||
>-f, --format=</DT
|
||||
><DD
|
||||
><P
|
||||
>OTP format. One of hex40 dhex40 dec31.6 dec31.7 dec31.8 dec31.9 dec31.10.
|
||||
|
@ -198,25 +208,26 @@ in RFC 4226, where hex40 always uses the top 40 bits. dhex40 may be the
|
|||
default in future releases.</P
|
||||
></DD
|
||||
><DT
|
||||
>-F</DT
|
||||
>-F, --flag=</DT
|
||||
><DD
|
||||
><P
|
||||
>OTP flags. All flags are unset by default.
|
||||
>OTP flag. All flags are unset by default.
|
||||
<PRE
|
||||
CLASS="SCREEN"
|
||||
> Flag Description
|
||||
-----------------------------------------------------------------
|
||||
display-count : Display HOTP count when prompted for challenge.</PRE
|
||||
display-count : Display HOTP count when prompted for challenge.
|
||||
send-token : Send token to user out of band.</PRE
|
||||
></P
|
||||
></DD
|
||||
><DT
|
||||
>-h</DT
|
||||
>-h, --help</DT
|
||||
><DD
|
||||
><P
|
||||
>Help.</P
|
||||
></DD
|
||||
><DT
|
||||
>-H<TT
|
||||
>-H, --sc_hostname=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> sc_hostname</I
|
||||
|
@ -224,10 +235,10 @@ CLASS="REPLACEABLE"
|
|||
></DT
|
||||
><DD
|
||||
><P
|
||||
>Set the SC hostname with the list-sc command mode.</P
|
||||
>Set the SC hostname for the list-sc command mode.</P
|
||||
></DD
|
||||
><DT
|
||||
>-I<TT
|
||||
>-I, --sc_index=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> sc_index</I
|
||||
|
@ -235,10 +246,10 @@ CLASS="REPLACEABLE"
|
|||
></DT
|
||||
><DD
|
||||
><P
|
||||
>Set the SC index with the list-sc command mode.</P
|
||||
>Set the SC index for the list-sc command mode.</P
|
||||
></DD
|
||||
><DT
|
||||
>-k<TT
|
||||
>-k, --key=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> key</I
|
||||
|
@ -253,7 +264,18 @@ unique count space is provisioned. Use - for stdin. Example key:
|
|||
C0C3D47F1CC68ECE0DF81D008F0C0D72D43EB745</P
|
||||
></DD
|
||||
><DT
|
||||
>-m<TT
|
||||
>-l, --location=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> location</I
|
||||
></TT
|
||||
></DT
|
||||
><DD
|
||||
><P
|
||||
>Location to send token to when SEND_TOKEN flag is set.</P
|
||||
></DD
|
||||
><DT
|
||||
>-m, --command_mode=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> command_mode</I
|
||||
|
@ -274,6 +296,7 @@ CLASS="SCREEN"
|
|||
list-sc - List user record (SC friendly)
|
||||
load - ASCII load user record(s)
|
||||
remove - Remove user
|
||||
send-token - Send token to user
|
||||
set-count - Set user count
|
||||
set-count-ceil - Set user count ceiling
|
||||
set-flags - Set user flags
|
||||
|
@ -283,16 +306,16 @@ CLASS="SCREEN"
|
|||
test - Test user</PRE
|
||||
></DD
|
||||
><DT
|
||||
>-n</DT
|
||||
>-n, --create_database</DT
|
||||
><DD
|
||||
><P
|
||||
>Create new database if one does not exist.</P
|
||||
></DD
|
||||
><DT
|
||||
>-o<TT
|
||||
>-o, --otp-db=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> otp_pathname</I
|
||||
> otp_db</I
|
||||
></TT
|
||||
></DT
|
||||
><DD
|
||||
|
@ -300,10 +323,10 @@ CLASS="REPLACEABLE"
|
|||
>Pathname of OTP database.</P
|
||||
></DD
|
||||
><DT
|
||||
>-s<TT
|
||||
>-s, --status=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> otp_pathname</I
|
||||
> status</I
|
||||
></TT
|
||||
></DT
|
||||
><DD
|
||||
|
@ -317,12 +340,13 @@ CLASS="SCREEN"
|
|||
inactive : OTP may not be required for successful authentication.
|
||||
The OTP authentication module may be configured to allow
|
||||
inactive accounts to authenticate. This may be used to
|
||||
temporarily remove the OTP authentication method for a user.
|
||||
temporarily remove the OTP authentication method for a
|
||||
user.
|
||||
disabled : Account is disabled. OTP authentication will fail.</PRE
|
||||
></P
|
||||
></DD
|
||||
><DT
|
||||
>-S<TT
|
||||
>-S, --sc-flags=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> sc_flags</I
|
||||
|
@ -330,10 +354,10 @@ CLASS="REPLACEABLE"
|
|||
></DT
|
||||
><DD
|
||||
><P
|
||||
>Set the SC flags with the list-sc command mode. 0=CHALLENGE, 1=READERKEY.</P
|
||||
>Set the SC flags for the list-sc command mode. 0=CHALLENGE, 1=READERKEY.</P
|
||||
></DD
|
||||
><DT
|
||||
>-t<TT
|
||||
>-t, --type=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> type</I
|
||||
|
@ -344,7 +368,7 @@ CLASS="REPLACEABLE"
|
|||
>OTP Type. RFC 4226 HOTP is only supported type.</P
|
||||
></DD
|
||||
><DT
|
||||
>-u<TT
|
||||
>-u, --username=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> username</I
|
||||
|
@ -355,13 +379,30 @@ CLASS="REPLACEABLE"
|
|||
>Username to perform database operation on.</P
|
||||
></DD
|
||||
><DT
|
||||
>-v</DT
|
||||
>-v, --verbose</DT
|
||||
><DD
|
||||
><P
|
||||
>Enable verbose output (debugging).</P
|
||||
></DD
|
||||
><DT
|
||||
>-w<TT
|
||||
>-V, --service-name=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> service_name</I
|
||||
></TT
|
||||
></DT
|
||||
><DD
|
||||
><P
|
||||
>Set service name for send-token function.</P
|
||||
></DD
|
||||
><DT
|
||||
>--version</DT
|
||||
><DD
|
||||
><P
|
||||
>Display software version.</P
|
||||
></DD
|
||||
><DT
|
||||
>-w, --challenge-window=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> window</I
|
||||
|
@ -385,7 +426,7 @@ of tokens generated.</P
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN139"
|
||||
NAME="AEN157"
|
||||
></A
|
||||
><H2
|
||||
>OTP-CONTROL COMMANDS</H2
|
||||
|
@ -413,7 +454,7 @@ CLASS="COMMAND"
|
|||
: dump user database in ASCII. User records are separated by a newline.
|
||||
Fields are : separated. All fields except the username are HEX encoded.</P
|
||||
><P
|
||||
>#version:user:key:status:format:type:flags:count_cur:count_ceil:last
|
||||
>#version:user:key:status:format:type:flags:count_cur:count_ceiling:last
|
||||
01:test:1111111111111111111111111111111111111111:01:01:01:00:00000000000003E8:00000000000007D0:0000000000000000</P
|
||||
><P
|
||||
><B
|
||||
|
@ -495,7 +536,7 @@ CLASS="COMMAND"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN172"
|
||||
NAME="AEN190"
|
||||
></A
|
||||
><H2
|
||||
>EXAMPLES</H2
|
||||
|
@ -504,7 +545,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN174"
|
||||
NAME="AEN192"
|
||||
></A
|
||||
><P
|
||||
>Create a new OTP database /etc/otpdb. Add user bob with random key.</P
|
||||
|
@ -525,7 +566,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN179"
|
||||
NAME="AEN197"
|
||||
></A
|
||||
><P
|
||||
>Display user bob OTP database entry.</P
|
||||
|
@ -553,7 +594,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN184"
|
||||
NAME="AEN202"
|
||||
></A
|
||||
><P
|
||||
>Generate OTP for user bob.</P
|
||||
|
@ -573,7 +614,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN189"
|
||||
NAME="AEN207"
|
||||
></A
|
||||
><P
|
||||
>Test OTP for user bob.</P
|
||||
|
@ -595,7 +636,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN194"
|
||||
NAME="AEN212"
|
||||
></A
|
||||
><P
|
||||
>Dump OTP database to stdout. Fields other than username are hex encoded.
|
||||
|
@ -607,7 +648,7 @@ CLASS="COMMAND"
|
|||
></P
|
||||
><PRE
|
||||
CLASS="SCREEN"
|
||||
>#version:user:key:status:format:type:flags:count_cur:count_ceil:last
|
||||
>#version:user:key:status:format:type:flags:count_cur:count_ceiling:last
|
||||
01:bob:C381739834A63A67B0B9F7F7D36C8C567F6BFB3D:01:01:01:00:0000000000000001:FFFFFFFFFFFFFFFF:000000004AA02F9E</PRE
|
||||
><P
|
||||
></P
|
||||
|
@ -617,7 +658,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN199"
|
||||
NAME="AEN217"
|
||||
></A
|
||||
><P
|
||||
>Dump OTP user to stdout in format friendly to <B
|
||||
|
@ -645,7 +686,7 @@ CLASS="COMPUTEROUTPUT"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN206"
|
||||
NAME="AEN224"
|
||||
></A
|
||||
><H2
|
||||
>AUTHOR</H2
|
||||
|
@ -662,7 +703,7 @@ HREF="mailto:maf@splintered.net"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN213"
|
||||
NAME="AEN231"
|
||||
></A
|
||||
><H2
|
||||
>SEE ALSO</H2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE refentry PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
|
||||
|
||||
<!-- $Id: otp-control.sgml 80 2009-12-26 23:25:04Z maf $ -->
|
||||
<!-- $Id: otp-control.sgml 169 2011-05-11 04:10:57Z maf $ -->
|
||||
|
||||
<refentry>
|
||||
|
||||
|
@ -25,18 +25,20 @@ Local user database configuration for One Time Password package.
|
|||
<command>otp-control</command>
|
||||
<arg>-?hnv</arg>
|
||||
<arg>-c<replaceable> count</replaceable></arg>
|
||||
<arg>-C<replaceable> count_ceil</replaceable></arg>
|
||||
<arg>-C<replaceable> count_ceiling</replaceable></arg>
|
||||
<arg>-f<replaceable> format</replaceable></arg>
|
||||
<arg>-F<replaceable> flags</replaceable></arg>
|
||||
<arg>-F<replaceable> flag</replaceable></arg>
|
||||
<arg>-H<replaceable> sc_hostname</replaceable></arg>
|
||||
<arg>-I<replaceable> sc_index</replaceable></arg>
|
||||
<arg>-k<replaceable> key</replaceable></arg>
|
||||
<arg>-l<replaceable> location</replaceable></arg>
|
||||
<arg>-m<replaceable> command_mode</replaceable></arg>
|
||||
<arg>-o<replaceable> otpdb_pathname</replaceable></arg>
|
||||
<arg>-o<replaceable> otp_db</replaceable></arg>
|
||||
<arg>-s<replaceable> status</replaceable></arg>
|
||||
<arg>-S<replaceable> sc_flags</replaceable></arg>
|
||||
<arg>-t<replaceable> type</replaceable></arg>
|
||||
<arg>-u<replaceable> username</replaceable></arg>
|
||||
<arg>-V<replaceable> service_name</replaceable></arg>
|
||||
<arg>-w<replaceable> window</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
@ -56,7 +58,7 @@ and removed by <command>otp-control.</command>
|
|||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term>-c<replaceable> count</replaceable></term>
|
||||
<term>-c, --count= <replaceable> count</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
User count. The count increases with each OTP transaction.
|
||||
|
@ -65,7 +67,7 @@ User count. The count increases with each OTP transaction.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-C<replaceable> count_ceil</replaceable></term>
|
||||
<term>-C, --count-ceil= <replaceable> count_ceiling</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
User count ceiling. Highest count allowed for this user. Configuring
|
||||
|
@ -76,9 +78,9 @@ A count value must only be allowed for authentication once.
|
|||
</para><para>
|
||||
Example:
|
||||
</para><para>
|
||||
host=h1, user=bob, count_current=0, count_ceil=10000.
|
||||
host=h1, user=bob, count_current=0, count_ceiling=10000.
|
||||
</para><para>
|
||||
host=h2, user=bob, count_current=10001, count_ceil=20000.
|
||||
host=h2, user=bob, count_current=10001, count_ceiling=20000.
|
||||
</para><para>
|
||||
The number of keys a user must possess is decreased at the expense
|
||||
of security dependencies among multiple systems. If system A is
|
||||
|
@ -93,7 +95,7 @@ system database during authentication.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-f</term>
|
||||
<term>-f, --format=</term>
|
||||
<listitem>
|
||||
<para>
|
||||
OTP format. One of hex40 dhex40 dec31.6 dec31.7 dec31.8 dec31.9 dec31.10.
|
||||
|
@ -107,14 +109,15 @@ default in future releases.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-F</term>
|
||||
<term>-F, --flag=</term>
|
||||
<listitem>
|
||||
<para>
|
||||
OTP flags. All flags are unset by default.
|
||||
OTP flag. All flags are unset by default.
|
||||
<screen>
|
||||
Flag Description
|
||||
-----------------------------------------------------------------
|
||||
display-count : Display HOTP count when prompted for challenge.
|
||||
send-token : Send token to user out of band.
|
||||
</screen>
|
||||
</para>
|
||||
</listitem>
|
||||
|
@ -122,7 +125,7 @@ OTP flags. All flags are unset by default.
|
|||
|
||||
|
||||
<varlistentry>
|
||||
<term>-h</term>
|
||||
<term>-h, --help</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Help.
|
||||
|
@ -132,25 +135,25 @@ Help.
|
|||
|
||||
|
||||
<varlistentry>
|
||||
<term>-H<replaceable> sc_hostname</replaceable></term>
|
||||
<term>-H, --sc_hostname=<replaceable> sc_hostname</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the SC hostname with the list-sc command mode.
|
||||
Set the SC hostname for the list-sc command mode.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-I<replaceable> sc_index</replaceable></term>
|
||||
<term>-I, --sc_index=<replaceable> sc_index</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the SC index with the list-sc command mode.
|
||||
Set the SC index for the list-sc command mode.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-k<replaceable> key</replaceable></term>
|
||||
<term>-k, --key=<replaceable> key</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
160 bit shared secret key in ASCII HEX. The secret key is shared between
|
||||
|
@ -163,7 +166,16 @@ C0C3D47F1CC68ECE0DF81D008F0C0D72D43EB745
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-m<replaceable> command_mode</replaceable></term>
|
||||
<term>-l, --location=<replaceable> location</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Location to send token to when SEND_TOKEN flag is set.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-m, --command_mode=<replaceable> command_mode</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
</para>
|
||||
|
@ -178,6 +190,7 @@ C0C3D47F1CC68ECE0DF81D008F0C0D72D43EB745
|
|||
list-sc - List user record (SC friendly)
|
||||
load - ASCII load user record(s)
|
||||
remove - Remove user
|
||||
send-token - Send token to user
|
||||
set-count - Set user count
|
||||
set-count-ceil - Set user count ceiling
|
||||
set-flags - Set user flags
|
||||
|
@ -190,7 +203,7 @@ C0C3D47F1CC68ECE0DF81D008F0C0D72D43EB745
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-n</term>
|
||||
<term>-n, --create_database</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Create new database if one does not exist.
|
||||
|
@ -199,7 +212,7 @@ Create new database if one does not exist.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-o<replaceable> otp_pathname</replaceable></term>
|
||||
<term>-o, --otp-db=<replaceable> otp_db</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Pathname of OTP database.
|
||||
|
@ -208,7 +221,7 @@ Pathname of OTP database.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-s<replaceable> otp_pathname</replaceable></term>
|
||||
<term>-s, --status=<replaceable> status</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
OTP Status. The default status is active.
|
||||
|
@ -219,7 +232,8 @@ OTP Status. The default status is active.
|
|||
inactive : OTP may not be required for successful authentication.
|
||||
The OTP authentication module may be configured to allow
|
||||
inactive accounts to authenticate. This may be used to
|
||||
temporarily remove the OTP authentication method for a user.
|
||||
temporarily remove the OTP authentication method for a
|
||||
user.
|
||||
disabled : Account is disabled. OTP authentication will fail.
|
||||
</screen>
|
||||
</para>
|
||||
|
@ -228,16 +242,16 @@ OTP Status. The default status is active.
|
|||
|
||||
|
||||
<varlistentry>
|
||||
<term>-S<replaceable> sc_flags</replaceable></term>
|
||||
<term>-S, --sc-flags=<replaceable> sc_flags</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the SC flags with the list-sc command mode. 0=CHALLENGE, 1=READERKEY.
|
||||
Set the SC flags for the list-sc command mode. 0=CHALLENGE, 1=READERKEY.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-t<replaceable> type</replaceable></term>
|
||||
<term>-t, --type=<replaceable> type</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
OTP Type. RFC 4226 HOTP is only supported type.
|
||||
|
@ -246,7 +260,7 @@ OTP Type. RFC 4226 HOTP is only supported type.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-u<replaceable> username</replaceable></term>
|
||||
<term>-u, --username=<replaceable> username</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Username to perform database operation on.
|
||||
|
@ -255,7 +269,7 @@ Username to perform database operation on.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-v</term>
|
||||
<term>-v, --verbose</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable verbose output (debugging).
|
||||
|
@ -264,7 +278,25 @@ Enable verbose output (debugging).
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-w<replaceable> window</replaceable></term>
|
||||
<term>-V, --service-name=<replaceable> service_name</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set service name for send-token function.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>--version</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Display software version.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-w, --challenge-window=<replaceable> window</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the maximum window (count above the system count) where an OTP
|
||||
|
@ -305,7 +337,7 @@ user stored in a separate ASCII : delimited file in base_dir/d.
|
|||
: dump user database in ASCII. User records are separated by a newline.
|
||||
Fields are : separated. All fields except the username are HEX encoded.
|
||||
</para><para>
|
||||
#version:user:key:status:format:type:flags:count_cur:count_ceil:last
|
||||
#version:user:key:status:format:type:flags:count_cur:count_ceiling:last
|
||||
01:test:1111111111111111111111111111111111111111:01:01:01:00:00000000000003E8:00000000000007D0:0000000000000000
|
||||
</para>
|
||||
|
||||
|
@ -446,7 +478,7 @@ Use the load command to import records in this format.
|
|||
<command>otp-control -m dump</command>
|
||||
</para>
|
||||
<screen>
|
||||
#version:user:key:status:format:type:flags:count_cur:count_ceil:last
|
||||
#version:user:key:status:format:type:flags:count_cur:count_ceiling:last
|
||||
01:bob:C381739834A63A67B0B9F7F7D36C8C567F6BFB3D:01:01:01:00:0000000000000001:FFFFFFFFFFFFFFFF:000000004AA02F9E
|
||||
</screen>
|
||||
</informalexample>
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
\fBotp-ov-plugin\fP \(em OpenVPN plug-in authentication module for OTP database\&.
|
||||
.SH "SYNOPSIS"
|
||||
.PP
|
||||
\fBotp-ov-plugin\fP [-?hv] [-o\fI otpdb_fname\fP] [-w\fI otp_window\fP]
|
||||
\fBotp-ov-plugin\fP [-?hv] [-o\fI otpdb_fname\fP] [-V\fI service_name\fP] [-w\fI otp_window\fP]
|
||||
.SH "DESCRIPTION"
|
||||
.PP
|
||||
The \fBotp-ov-plugin\fP command is plug-in authentication
|
||||
|
@ -68,14 +68,21 @@ A successful authentication will set a return code of
|
|||
\fB1\fR, and program failure
|
||||
\fB-1\fR\&.
|
||||
.SH "OPTIONS"
|
||||
.IP "-h" 10
|
||||
.IP "-h, --help" 10
|
||||
Help
|
||||
.IP "-o\fI otpdb_pathname\fP" 10
|
||||
.IP "-o, --otp-db=\fI otpdb_pathname\fP" 10
|
||||
Pathname of OTP database\&.
|
||||
.IP "-v" 10
|
||||
.IP "-u, --otp-allow-unknown-user" 10
|
||||
Allow users which do not exist in the OTP database to successfully
|
||||
authenticate without using a One Time Password\&.
|
||||
.IP "-V, --service-name=\fI service_name\fP" 10
|
||||
Set service name for send-token function\&.
|
||||
.IP "-v, --verbose" 10
|
||||
Verbose
|
||||
.IP "-w" 10
|
||||
.IP "-w, --otp-challenge-window=" 10
|
||||
Set the OTP challenge window\&.
|
||||
.IP "--version" 10
|
||||
Display software version\&.
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
Test the module with user bob\&.
|
||||
|
@ -103,4 +110,4 @@ Mark Fullmer maf@splintered\&.net
|
|||
\fBbcload\fP(1)
|
||||
\fBOpenVPN\fP(8)
|
||||
spyrus-par2(7)
|
||||
...\" created by instant / docbook-to-man, Sun 27 Dec 2009, 22:01
|
||||
...\" created by instant / docbook-to-man, Sun 15 May 2011, 23:57
|
||||
|
|
|
@ -48,6 +48,11 @@ CLASS="REPLACEABLE"
|
|||
><I
|
||||
> otpdb_fname</I
|
||||
></TT
|
||||
>] [-V<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> service_name</I
|
||||
></TT
|
||||
>] [-w<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
|
@ -58,7 +63,7 @@ CLASS="REPLACEABLE"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN18"
|
||||
NAME="AEN20"
|
||||
></A
|
||||
><H2
|
||||
>DESCRIPTION</H2
|
||||
|
@ -99,7 +104,7 @@ CLASS="RETURNVALUE"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN27"
|
||||
NAME="AEN29"
|
||||
></A
|
||||
><H2
|
||||
>OPTIONS</H2
|
||||
|
@ -109,13 +114,13 @@ NAME="AEN27"
|
|||
CLASS="VARIABLELIST"
|
||||
><DL
|
||||
><DT
|
||||
>-h</DT
|
||||
>-h, --help</DT
|
||||
><DD
|
||||
><P
|
||||
>Help</P
|
||||
></DD
|
||||
><DT
|
||||
>-o<TT
|
||||
>-o, --otp-db=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> otpdb_pathname</I
|
||||
|
@ -126,24 +131,48 @@ CLASS="REPLACEABLE"
|
|||
>Pathname of OTP database.</P
|
||||
></DD
|
||||
><DT
|
||||
>-v</DT
|
||||
>-u, --otp-allow-unknown-user</DT
|
||||
><DD
|
||||
><P
|
||||
>Allow users which do not exist in the OTP database to successfully
|
||||
authenticate without using a One Time Password.</P
|
||||
></DD
|
||||
><DT
|
||||
>-V, --service-name=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> service_name</I
|
||||
></TT
|
||||
></DT
|
||||
><DD
|
||||
><P
|
||||
>Set service name for send-token function.</P
|
||||
></DD
|
||||
><DT
|
||||
>-v, --verbose</DT
|
||||
><DD
|
||||
><P
|
||||
>Verbose</P
|
||||
></DD
|
||||
><DT
|
||||
>-w</DT
|
||||
>-w, --otp-challenge-window=</DT
|
||||
><DD
|
||||
><P
|
||||
>Set the OTP challenge window.</P
|
||||
></DD
|
||||
><DT
|
||||
>--version</DT
|
||||
><DD
|
||||
><P
|
||||
>Display software version.</P
|
||||
></DD
|
||||
></DL
|
||||
></DIV
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN47"
|
||||
NAME="AEN62"
|
||||
></A
|
||||
><H2
|
||||
>EXAMPLES</H2
|
||||
|
@ -152,7 +181,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN49"
|
||||
NAME="AEN64"
|
||||
></A
|
||||
><P
|
||||
>Test the module with user bob.</P
|
||||
|
@ -181,7 +210,7 @@ CLASS="SCREEN"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN58"
|
||||
NAME="AEN73"
|
||||
></A
|
||||
><H2
|
||||
>AUTHOR</H2
|
||||
|
@ -198,7 +227,7 @@ HREF="mailto:maf@splintered.net"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN65"
|
||||
NAME="AEN80"
|
||||
></A
|
||||
><H2
|
||||
>SEE ALSO</H2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE refentry PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
|
||||
|
||||
<!-- $Id: otp-ov-plugin.sgml 50 2009-12-15 01:37:19Z maf $ -->
|
||||
<!-- $Id: otp-ov-plugin.sgml 177 2011-05-16 02:37:28Z maf $ -->
|
||||
|
||||
<refentry>
|
||||
|
||||
|
@ -25,6 +25,7 @@ OpenVPN plug-in authentication module for OTP database.
|
|||
<command>otp-ov-plugin</command>
|
||||
<arg>-?hv</arg>
|
||||
<arg>-o<replaceable> otpdb_fname</replaceable></arg>
|
||||
<arg>-V<replaceable> service_name</replaceable></arg>
|
||||
<arg>-w<replaceable> otp_window</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
@ -49,7 +50,7 @@ A successful authentication will set a return code of
|
|||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term>-h</term>
|
||||
<term>-h, --help</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Help
|
||||
|
@ -58,7 +59,7 @@ Help
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-o<replaceable> otpdb_pathname</replaceable></term>
|
||||
<term>-o, --otp-db=<replaceable> otpdb_pathname</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Pathname of OTP database.
|
||||
|
@ -67,7 +68,26 @@ Pathname of OTP database.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-v</term>
|
||||
<term>-u, --otp-allow-unknown-user</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Allow users which do not exist in the OTP database to successfully
|
||||
authenticate without using a One Time Password.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-V, --service-name=<replaceable> service_name</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set service name for send-token function.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-v, --verbose</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Verbose
|
||||
|
@ -76,7 +96,7 @@ Verbose
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-w</term>
|
||||
<term>-w, --otp-challenge-window=</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the OTP challenge window.
|
||||
|
@ -84,6 +104,14 @@ Set the OTP challenge window.
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>--version</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Display software version.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
|
|
@ -66,28 +66,30 @@ of {hostname,count,shared_key} are downloaded to the Smart Card using
|
|||
Smart Card such as HOTP generation and PIN maintenance can be executed
|
||||
with the appropriate administratative key\&.
|
||||
.SH "OPTIONS"
|
||||
.IP "-a\fI admin_keyfile\fP" 10
|
||||
.IP "-a, --sc-admin-key=\fI admin_keyfile\fP" 10
|
||||
Smart Card administratative key\&. The admin-enable command and
|
||||
administratative key are used to toggle the Smart Card into admin mode\&.
|
||||
Once in admin mode commands admin-disable, adminkey-set, balancecard-set,
|
||||
host-get, host-set, pin-set, and sc-clear can be executed\&. The default admin
|
||||
key, "3030303030303030303030303030303030303030" (HEX), should be changed to
|
||||
restrict access to the above commands\&.
|
||||
.IP "-c\fI count\fP" 10
|
||||
.IP "-c, --sc-count=\fI count\fP" 10
|
||||
Configure the count parameter optionally used by the hotp-gen command\&.
|
||||
.IP "-d\fI debug_level\fP" 10
|
||||
A count value of 0 indicates the HOTP value is to be calculated with the
|
||||
current stored count\&.
|
||||
.IP "-d, --debug=\fI debug_level\fP" 10
|
||||
Set debug level\&.
|
||||
.IP "-h" 10
|
||||
.IP "-h, --help" 10
|
||||
Help\&.
|
||||
.IP "-i\fI index\fP" 10
|
||||
.IP "-i, --sc-index=\fI index\fP" 10
|
||||
Set the 8 bit index\&. The Smart Card contains numerically indexed records
|
||||
for each host of the form {hostname,count,shared_key}\&. The firmware
|
||||
will support indexes in the range 0\&.\&.254\&. 255 is reserved\&. Memory
|
||||
capacity on the Smart Card may further restrict the index range\&. The
|
||||
ZC3\&.9 BasicCard with firmware revision 3 supports up to 85 records\&.
|
||||
.IP "-l" 10
|
||||
.IP "-l, --list-readers" 10
|
||||
List SC Readers
|
||||
.IP "-m\fI command_mode\fP" 10
|
||||
.IP "-m, --sc-command=\fI command_mode\fP" 10
|
||||
.PP
|
||||
.nf
|
||||
Command Mode Description Notes Modifiers
|
||||
|
@ -121,14 +123,16 @@ List SC Readers
|
|||
d output in otpdb load friendly format\&.
|
||||
r include reader key in request\&.
|
||||
.fi
|
||||
.IP "-M\fI modifiers\fP" 10
|
||||
.IP "-M, --sc-command-modifier=\fI modifiers\fP" 10
|
||||
Configure command_mode modifiers\&. Modifier d applied to the host-get
|
||||
command will generate output in otpdb format\&. Count (c) and Host (h)
|
||||
used with hotp-gen allow passing the Count and Host parameters
|
||||
respectively\&. The Smart Card may not be configured to support
|
||||
all variations of a command\&.
|
||||
variations
|
||||
.IP "-r\fI reader\fP" 10
|
||||
.IP "-p, --no-pin" 10
|
||||
Do not prompt for PIN\&. The Smart Card does not require a PIN when admin
|
||||
mode is enabled\&.
|
||||
.IP "-r, --reader=\fI reader\fP" 10
|
||||
Set Smart Card reader\&. Use -l to list available readers\&. A reader
|
||||
is defined as class:reader:[option]\&. PCSC and embedded
|
||||
are the two available classes\&. The embedded class contains the acr30s driver
|
||||
|
@ -137,7 +141,7 @@ If pcscd is running the first PC/SC reader will be the default followed by
|
|||
the embedded acr30s driver\&. Use PCSC: for the first available PC/SC
|
||||
reader\&. Use embedded:acr30s:/dev/cuaU0 for the embedded acr30s driver
|
||||
with serial port /dev/cuaU0\&.
|
||||
.IP "-R\fI reader_keyfile\fP" 10
|
||||
.IP "-R, --sc-reader-key=\fI reader_keyfile\fP" 10
|
||||
Smart Card Reader key\&. The reader-key-set command can be used
|
||||
to set this key in the Smart Card\&. To emulate the behavior of
|
||||
a reader using the key the r modifier may be used with this option
|
||||
|
@ -148,20 +152,22 @@ key is "00000" or 3030303030\&.
|
|||
.IP "" 10
|
||||
This key must match the key set in the reader\&. With the Spyrus
|
||||
PAR II reader this is set in the PAR II EEProm\&.
|
||||
.IP "-u\fI username\fP" 10
|
||||
.IP "-u, --sc-username=\fI username\fP" 10
|
||||
Set username\&. The username is used with the host-get command and
|
||||
d modifier\&.
|
||||
.IP "-v\fI card_api_version\fP" 10
|
||||
.IP "-v, --sc-version=\fI card_api_version\fP" 10
|
||||
Set the Smart Card API version\&. The binary API between the terminal
|
||||
and Smart Card changed between version 2 and 3\&. See command_mode notes
|
||||
above\&. The default version is 3\&. Configuring version 2 will allow
|
||||
maintenance of Smart Card with version 2 firmware\&.
|
||||
.IP "--version" 10
|
||||
Display software version\&.
|
||||
.SH "SMART CARD COMMANDS"
|
||||
.PP
|
||||
\fBadmin-enable\fP : enable administrative mode\&. The commands admin-disable, admin-key-set,
|
||||
balancecard-set, host-get, and sc-clear require admin mode to be enabled\&.
|
||||
pin-set and commands requiring a PIN will not require a valid PIN while
|
||||
the SC is in admin mode\&. A new key can be generated with
|
||||
pin-set and commands accepting a PIN will not require the PIN to be valid
|
||||
while the SC is in admin mode\&. A new key can be generated with
|
||||
\fBopenssl rand 160 | openssl sha1\fP\&. The hotp-gen
|
||||
command will automatically disable admin mode\&.
|
||||
.PP
|
||||
|
@ -229,7 +235,12 @@ F0: challenge (count) input is required by the user\&.
|
|||
|
||||
F1: enable reader authentication by the SC for the GetHOTP* commands\&.
|
||||
|
||||
F2\&.\&.F11: reserved
|
||||
F2: enable base10 display
|
||||
|
||||
F3\&.\&.F7: reserved
|
||||
|
||||
F8-11: FMT3-FMT0\&. 0000=HEX40 0001=HEX40 0010=DEC31\&.6 0011=DEC31\&.7
|
||||
0100=DEC31\&.8 0101=DEC31\&.9 0110=DEC31\&.10 0011=DHEX40
|
||||
|
||||
Example host record with index=0, count=7, hostname=dev1\&.eng,
|
||||
key=E4AACE5EC7291C405ED28949BB6DACA05768319D
|
||||
|
@ -417,4 +428,4 @@ Mark Fullmer maf@splintered\&.net
|
|||
\fBbcload\fP(1)
|
||||
\fBurd\fP(1)
|
||||
spyrus-par2(7)
|
||||
...\" created by instant / docbook-to-man, Sun 27 Dec 2009, 22:01
|
||||
...\" created by instant / docbook-to-man, Sun 15 May 2011, 23:57
|
||||
|
|
|
@ -129,7 +129,7 @@ NAME="AEN39"
|
|||
CLASS="VARIABLELIST"
|
||||
><DL
|
||||
><DT
|
||||
>-a<TT
|
||||
>-a, --sc-admin-key=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> admin_keyfile</I
|
||||
|
@ -145,7 +145,7 @@ key, "3030303030303030303030303030303030303030" (HEX), should be changed to
|
|||
restrict access to the above commands.</P
|
||||
></DD
|
||||
><DT
|
||||
>-c<TT
|
||||
>-c, --sc-count=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> count</I
|
||||
|
@ -153,10 +153,12 @@ CLASS="REPLACEABLE"
|
|||
></DT
|
||||
><DD
|
||||
><P
|
||||
>Configure the count parameter optionally used by the hotp-gen command.</P
|
||||
>Configure the count parameter optionally used by the hotp-gen command.
|
||||
A count value of 0 indicates the HOTP value is to be calculated with the
|
||||
current stored count.</P
|
||||
></DD
|
||||
><DT
|
||||
>-d<TT
|
||||
>-d, --debug=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> debug_level</I
|
||||
|
@ -167,13 +169,13 @@ CLASS="REPLACEABLE"
|
|||
>Set debug level.</P
|
||||
></DD
|
||||
><DT
|
||||
>-h</DT
|
||||
>-h, --help</DT
|
||||
><DD
|
||||
><P
|
||||
>Help.</P
|
||||
></DD
|
||||
><DT
|
||||
>-i<TT
|
||||
>-i, --sc-index=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> index</I
|
||||
|
@ -188,13 +190,13 @@ capacity on the Smart Card may further restrict the index range. The
|
|||
ZC3.9 BasicCard with firmware revision 3 supports up to 85 records.</P
|
||||
></DD
|
||||
><DT
|
||||
>-l</DT
|
||||
>-l, --list-readers</DT
|
||||
><DD
|
||||
><P
|
||||
>List SC Readers</P
|
||||
></DD
|
||||
><DT
|
||||
>-m<TT
|
||||
>-m, --sc-command=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> command_mode</I
|
||||
|
@ -237,7 +239,7 @@ CLASS="SCREEN"
|
|||
r include reader key in request. </PRE
|
||||
></DD
|
||||
><DT
|
||||
>-M<TT
|
||||
>-M, --sc-command-modifier=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> modifiers</I
|
||||
|
@ -249,11 +251,17 @@ CLASS="REPLACEABLE"
|
|||
command will generate output in otpdb format. Count (c) and Host (h)
|
||||
used with hotp-gen allow passing the Count and Host parameters
|
||||
respectively. The Smart Card may not be configured to support
|
||||
all variations of a command.
|
||||
variations </P
|
||||
all variations of a command.</P
|
||||
></DD
|
||||
><DT
|
||||
>-r<TT
|
||||
>-p, --no-pin</DT
|
||||
><DD
|
||||
><P
|
||||
>Do not prompt for PIN. The Smart Card does not require a PIN when admin
|
||||
mode is enabled.</P
|
||||
></DD
|
||||
><DT
|
||||
>-r, --reader=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> reader</I
|
||||
|
@ -277,7 +285,7 @@ reader. Use embedded:acr30s:/dev/cuaU0 for the embedded acr30s driver
|
|||
with serial port /dev/cuaU0.</P
|
||||
></DD
|
||||
><DT
|
||||
>-R<TT
|
||||
>-R, --sc-reader-key=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> reader_keyfile</I
|
||||
|
@ -297,7 +305,7 @@ key is "00000" or 3030303030.</P
|
|||
PAR II reader this is set in the PAR II EEProm.</P
|
||||
></DD
|
||||
><DT
|
||||
>-u<TT
|
||||
>-u, --sc-username=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> username</I
|
||||
|
@ -309,7 +317,7 @@ CLASS="REPLACEABLE"
|
|||
d modifier.</P
|
||||
></DD
|
||||
><DT
|
||||
>-v<TT
|
||||
>-v, --sc-version=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> card_api_version</I
|
||||
|
@ -322,13 +330,19 @@ and Smart Card changed between version 2 and 3. See command_mode notes
|
|||
above. The default version is 3. Configuring version 2 will allow
|
||||
maintenance of Smart Card with version 2 firmware.</P
|
||||
></DD
|
||||
><DT
|
||||
>--version</DT
|
||||
><DD
|
||||
><P
|
||||
>Display software version.</P
|
||||
></DD
|
||||
></DL
|
||||
></DIV
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN105"
|
||||
NAME="AEN113"
|
||||
></A
|
||||
><H2
|
||||
>SMART CARD COMMANDS</H2
|
||||
|
@ -339,8 +353,8 @@ CLASS="COMMAND"
|
|||
>
|
||||
: enable administrative mode. The commands admin-disable, admin-key-set,
|
||||
balancecard-set, host-get, and sc-clear require admin mode to be enabled.
|
||||
pin-set and commands requiring a PIN will not require a valid PIN while
|
||||
the SC is in admin mode. A new key can be generated with
|
||||
pin-set and commands accepting a PIN will not require the PIN to be valid
|
||||
while the SC is in admin mode. A new key can be generated with
|
||||
<B
|
||||
CLASS="COMMAND"
|
||||
>openssl rand 160 | openssl sha1</B
|
||||
|
@ -434,7 +448,12 @@ CLASS="SCREEN"
|
|||
|
||||
F1: enable reader authentication by the SC for the GetHOTP* commands.
|
||||
|
||||
F2..F11: reserved
|
||||
F2: enable base10 display
|
||||
|
||||
F3..F7: reserved
|
||||
|
||||
F8-11: FMT3-FMT0. 0000=HEX40 0001=HEX40 0010=DEC31.6 0011=DEC31.7
|
||||
0100=DEC31.8 0101=DEC31.9 0110=DEC31.10 0011=DHEX40
|
||||
|
||||
Example host record with index=0, count=7, hostname=dev1.eng,
|
||||
key=E4AACE5EC7291C405ED28949BB6DACA05768319D
|
||||
|
@ -573,7 +592,7 @@ CLASS="COMMAND"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN147"
|
||||
NAME="AEN155"
|
||||
></A
|
||||
><H2
|
||||
>EXAMPLES</H2
|
||||
|
@ -582,7 +601,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN149"
|
||||
NAME="AEN157"
|
||||
></A
|
||||
><P
|
||||
>Change the administratative key from the default. Disable admin mode
|
||||
|
@ -636,7 +655,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN160"
|
||||
NAME="AEN168"
|
||||
></A
|
||||
><P
|
||||
>Use <B
|
||||
|
@ -697,7 +716,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN172"
|
||||
NAME="AEN180"
|
||||
></A
|
||||
><P
|
||||
>Dump card contents to stdout. Note fields are encoded in HEX including
|
||||
|
@ -725,7 +744,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN177"
|
||||
NAME="AEN185"
|
||||
></A
|
||||
><P
|
||||
>Reset user PIN for card with secret.key as the admin key.</P
|
||||
|
@ -770,7 +789,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN186"
|
||||
NAME="AEN194"
|
||||
></A
|
||||
><P
|
||||
>Generate HOTP for dev1. Use hostname-get to find the index for dev1. Use
|
||||
|
@ -811,7 +830,7 @@ HOTP: 52DCD05FE5 -- dev1</SAMP
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN193"
|
||||
NAME="AEN201"
|
||||
></A
|
||||
><H2
|
||||
>AUTHOR</H2
|
||||
|
@ -828,7 +847,7 @@ HREF="mailto:maf@splintered.net"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN200"
|
||||
NAME="AEN208"
|
||||
></A
|
||||
><H2
|
||||
>SEE ALSO</H2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE refentry PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
|
||||
|
||||
<!-- $Id: otp-sca.sgml 62 2009-12-18 17:26:31Z maf $ -->
|
||||
<!-- $Id: otp-sca.sgml 126 2010-06-15 14:23:02Z maf $ -->
|
||||
|
||||
<refentry>
|
||||
|
||||
|
@ -55,7 +55,7 @@ with the appropriate administratative key.
|
|||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term>-a<replaceable> admin_keyfile</replaceable></term>
|
||||
<term>-a, --sc-admin-key=<replaceable> admin_keyfile</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Smart Card administratative key. The admin-enable command and
|
||||
|
@ -69,16 +69,18 @@ restrict access to the above commands.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-c<replaceable> count</replaceable></term>
|
||||
<term>-c, --sc-count=<replaceable> count</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Configure the count parameter optionally used by the hotp-gen command.
|
||||
A count value of 0 indicates the HOTP value is to be calculated with the
|
||||
current stored count.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-d<replaceable> debug_level</replaceable></term>
|
||||
<term>-d, --debug=<replaceable> debug_level</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set debug level.
|
||||
|
@ -87,7 +89,7 @@ Set debug level.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-h</term>
|
||||
<term>-h, --help</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Help.
|
||||
|
@ -96,7 +98,7 @@ Help.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-i<replaceable> index</replaceable></term>
|
||||
<term>-i, --sc-index=<replaceable> index</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the 8 bit index. The Smart Card contains numerically indexed records
|
||||
|
@ -108,7 +110,7 @@ ZC3.9 BasicCard with firmware revision 3 supports up to 85 records.
|
|||
</listitem>
|
||||
|
||||
<varlistentry>
|
||||
<term>-l</term>
|
||||
<term>-l, --list-readers</term>
|
||||
<listitem>
|
||||
<para>
|
||||
List SC Readers
|
||||
|
@ -117,7 +119,7 @@ List SC Readers
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-m<replaceable> command_mode</replaceable></term>
|
||||
<term>-m, --sc-command=<replaceable> command_mode</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
</para>
|
||||
|
@ -158,7 +160,7 @@ List SC Readers
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-M<replaceable> modifiers</replaceable></term>
|
||||
<term>-M, --sc-command-modifier=<replaceable> modifiers</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Configure command_mode modifiers. Modifier d applied to the host-get
|
||||
|
@ -166,13 +168,22 @@ command will generate output in otpdb format. Count (c) and Host (h)
|
|||
used with hotp-gen allow passing the Count and Host parameters
|
||||
respectively. The Smart Card may not be configured to support
|
||||
all variations of a command.
|
||||
variations
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-r<replaceable> reader</replaceable></term>
|
||||
<term>-p, --no-pin</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Do not prompt for PIN. The Smart Card does not require a PIN when admin
|
||||
mode is enabled.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-r, --reader=<replaceable> reader</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set Smart Card reader. Use -l to list available readers. A reader
|
||||
|
@ -188,7 +199,7 @@ with serial port /dev/cuaU0.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-R<replaceable> reader_keyfile</replaceable></term>
|
||||
<term>-R, --sc-reader-key=<replaceable> reader_keyfile</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Smart Card Reader key. The reader-key-set command can be used
|
||||
|
@ -208,7 +219,7 @@ PAR II reader this is set in the PAR II EEProm.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-u<replaceable> username</replaceable></term>
|
||||
<term>-u, --sc-username=<replaceable> username</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set username. The username is used with the host-get command and
|
||||
|
@ -218,7 +229,7 @@ d modifier.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-v<replaceable> card_api_version</replaceable></term>
|
||||
<term>-v, --sc-version=<replaceable> card_api_version</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the Smart Card API version. The binary API between the terminal
|
||||
|
@ -229,6 +240,14 @@ maintenance of Smart Card with version 2 firmware.
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>--version</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Display software version.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
@ -240,8 +259,8 @@ maintenance of Smart Card with version 2 firmware.
|
|||
<command>admin-enable</command>
|
||||
: enable administrative mode. The commands admin-disable, admin-key-set,
|
||||
balancecard-set, host-get, and sc-clear require admin mode to be enabled.
|
||||
pin-set and commands requiring a PIN will not require a valid PIN while
|
||||
the SC is in admin mode. A new key can be generated with
|
||||
pin-set and commands accepting a PIN will not require the PIN to be valid
|
||||
while the SC is in admin mode. A new key can be generated with
|
||||
<command>openssl rand 160 | openssl sha1</command>. The hotp-gen
|
||||
command will automatically disable admin mode.
|
||||
</para>
|
||||
|
@ -318,7 +337,12 @@ F0: challenge (count) input is required by the user.
|
|||
|
||||
F1: enable reader authentication by the SC for the GetHOTP* commands.
|
||||
|
||||
F2..F11: reserved
|
||||
F2: enable base10 display
|
||||
|
||||
F3..F7: reserved
|
||||
|
||||
F8-11: FMT3-FMT0. 0000=HEX40 0001=HEX40 0010=DEC31.6 0011=DEC31.7
|
||||
0100=DEC31.8 0101=DEC31.9 0110=DEC31.10 0011=DHEX40
|
||||
|
||||
Example host record with index=0, count=7, hostname=dev1.eng,
|
||||
key=E4AACE5EC7291C405ED28949BB6DACA05768319D
|
||||
|
|
|
@ -62,23 +62,25 @@
|
|||
The \fBotp-sct\fP command is a user interface to generating
|
||||
One Time Passwords with a Smart Card loaded with OTP software\&.
|
||||
.SH "OPTIONS"
|
||||
.IP "-c\fI count\fP" 10
|
||||
.IP "-c, --sc-count=\fI count\fP" 10
|
||||
Configure the optional count parameter to sync a Smart Card to a challenge\&.
|
||||
.IP "-d\fI debug_level\fP" 10
|
||||
A count value of 0 indicates the HOTP value is to be calculated with the
|
||||
current stored count\&.
|
||||
.IP "-d, --debug=\fI debug_level\fP" 10
|
||||
Set debug level\&.
|
||||
.IP "-h" 10
|
||||
.IP "-h, --help" 10
|
||||
Help\&.
|
||||
.IP "-i\fI index\fP" 10
|
||||
.IP "-i, --sc-index=\fI index\fP" 10
|
||||
Set the 8 bit index\&. The Smart Card contains numerically indexed records
|
||||
for each host system\&. Use the -l option to list hostnames associated with
|
||||
the index\&. The default index is 0\&.
|
||||
.IP "-l" 10
|
||||
.IP "-l, --list-readers" 10
|
||||
List SC Readers
|
||||
.IP "-L" 10
|
||||
.IP "-L, --sc-list-hostnames" 10
|
||||
List host systems configured on the Smart Card\&. The index is used with the -i option\&.
|
||||
.IP "-o" 10
|
||||
.IP "-p, --sc-reset-pin" 10
|
||||
Set new PIN\&.
|
||||
.IP "-r\fI reader\fP" 10
|
||||
.IP "-r, --reader=\fI reader\fP" 10
|
||||
Set Smart Card reader\&. Use -l to list available readers\&. A reader
|
||||
is defined as class:reader:[option]\&. PCSC and embedded
|
||||
are the two available classes\&. The embedded class contains the acr30s driver
|
||||
|
@ -87,17 +89,19 @@ If pcscd is running the first PC/SC reader will be the default followed by
|
|||
the embedded acr30s driver\&. Use PCSC: for the first available PC/SC
|
||||
reader\&. Use embedded:acr30s:/dev/cuaU0 for the embedded acr30s driver
|
||||
with serial port /dev/cuaU0\&.
|
||||
.IP "-v\fI card_api_version\fP" 10
|
||||
.IP "-v, --sc-version=\fI card_api_version\fP" 10
|
||||
Set the Smart Card API version\&. The binary API between the terminal
|
||||
and Smart Card changed between version 2 and 3\&. See command mode notes
|
||||
above\&. The default version is 3\&. Configuring version 2 will allow
|
||||
maintenance of Smart Card with version 2 firmware\&.
|
||||
.IP "-V" 10
|
||||
.IP "-V, --sc-list-version" 10
|
||||
List the Smart Card firmware version\&.
|
||||
.IP "-1" 10
|
||||
.IP "-1, --sc-get-hostp-v1" 10
|
||||
Use the version 1 GetHOTP command instead of the default GetHOTPHostCount32\&.
|
||||
The latter is not available on firmware revision 1\&. GetHOTP may be conditionally
|
||||
compiled out of newer firmware\&.
|
||||
.IP "--version" 10
|
||||
Display software version\&.
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
Generate a HOTP for the first system on the first PCSC reader found\&.
|
||||
|
@ -138,4 +142,4 @@ Mark Fullmer maf@splintered\&.net
|
|||
\fBbcload\fP(1)
|
||||
\fBurd\fP(1)
|
||||
spyrus-par2(7)
|
||||
...\" created by instant / docbook-to-man, Sun 27 Dec 2009, 22:01
|
||||
...\" created by instant / docbook-to-man, Sun 15 May 2011, 23:57
|
||||
|
|
|
@ -97,7 +97,7 @@ NAME="AEN28"
|
|||
CLASS="VARIABLELIST"
|
||||
><DL
|
||||
><DT
|
||||
>-c<TT
|
||||
>-c, --sc-count=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> count</I
|
||||
|
@ -105,10 +105,12 @@ CLASS="REPLACEABLE"
|
|||
></DT
|
||||
><DD
|
||||
><P
|
||||
>Configure the optional count parameter to sync a Smart Card to a challenge.</P
|
||||
>Configure the optional count parameter to sync a Smart Card to a challenge.
|
||||
A count value of 0 indicates the HOTP value is to be calculated with the
|
||||
current stored count.</P
|
||||
></DD
|
||||
><DT
|
||||
>-d<TT
|
||||
>-d, --debug=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> debug_level</I
|
||||
|
@ -119,13 +121,13 @@ CLASS="REPLACEABLE"
|
|||
>Set debug level.</P
|
||||
></DD
|
||||
><DT
|
||||
>-h</DT
|
||||
>-h, --help</DT
|
||||
><DD
|
||||
><P
|
||||
>Help.</P
|
||||
></DD
|
||||
><DT
|
||||
>-i<TT
|
||||
>-i, --sc-index=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> index</I
|
||||
|
@ -138,25 +140,25 @@ for each host system. Use the -l option to list hostnames associated with
|
|||
the index. The default index is 0.</P
|
||||
></DD
|
||||
><DT
|
||||
>-l</DT
|
||||
>-l, --list-readers</DT
|
||||
><DD
|
||||
><P
|
||||
>List SC Readers</P
|
||||
></DD
|
||||
><DT
|
||||
>-L</DT
|
||||
>-L, --sc-list-hostnames</DT
|
||||
><DD
|
||||
><P
|
||||
>List host systems configured on the Smart Card. The index is used with the -i option.</P
|
||||
></DD
|
||||
><DT
|
||||
>-o</DT
|
||||
>-p, --sc-reset-pin</DT
|
||||
><DD
|
||||
><P
|
||||
>Set new PIN.</P
|
||||
></DD
|
||||
><DT
|
||||
>-r<TT
|
||||
>-r, --reader=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> reader</I
|
||||
|
@ -180,7 +182,7 @@ reader. Use embedded:acr30s:/dev/cuaU0 for the embedded acr30s driver
|
|||
with serial port /dev/cuaU0.</P
|
||||
></DD
|
||||
><DT
|
||||
>-v<TT
|
||||
>-v, --sc-version=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> card_api_version</I
|
||||
|
@ -194,26 +196,32 @@ above. The default version is 3. Configuring version 2 will allow
|
|||
maintenance of Smart Card with version 2 firmware.</P
|
||||
></DD
|
||||
><DT
|
||||
>-V</DT
|
||||
>-V, --sc-list-version</DT
|
||||
><DD
|
||||
><P
|
||||
>List the Smart Card firmware version.</P
|
||||
></DD
|
||||
><DT
|
||||
>-1</DT
|
||||
>-1, --sc-get-hostp-v1</DT
|
||||
><DD
|
||||
><P
|
||||
>Use the version 1 GetHOTP command instead of the default GetHOTPHostCount32.
|
||||
The latter is not available on firmware revision 1. GetHOTP may be conditionally
|
||||
compiled out of newer firmware.</P
|
||||
></DD
|
||||
><DT
|
||||
>--version</DT
|
||||
><DD
|
||||
><P
|
||||
>Display software version.</P
|
||||
></DD
|
||||
></DL
|
||||
></DIV
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN82"
|
||||
NAME="AEN86"
|
||||
></A
|
||||
><H2
|
||||
>EXAMPLES</H2
|
||||
|
@ -222,7 +230,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN84"
|
||||
NAME="AEN88"
|
||||
></A
|
||||
><P
|
||||
>Generate a HOTP for the first system on the first PCSC reader found.</P
|
||||
|
@ -246,7 +254,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN89"
|
||||
NAME="AEN93"
|
||||
></A
|
||||
><P
|
||||
>List systems configured on Smart Card in default reader. Generate HOTP
|
||||
|
@ -290,7 +298,7 @@ CLASS="COMMAND"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN98"
|
||||
NAME="AEN102"
|
||||
></A
|
||||
><H2
|
||||
>AUTHOR</H2
|
||||
|
@ -307,7 +315,7 @@ HREF="mailto:maf@splintered.net"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN105"
|
||||
NAME="AEN109"
|
||||
></A
|
||||
><H2
|
||||
>SEE ALSO</H2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE refentry PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
|
||||
|
||||
<!-- $Id: otp-sct.sgml 62 2009-12-18 17:26:31Z maf $ -->
|
||||
<!-- $Id: otp-sct.sgml 126 2010-06-15 14:23:02Z maf $ -->
|
||||
|
||||
<refentry>
|
||||
|
||||
|
@ -32,7 +32,6 @@ Smart Card Terminal for One Time Password package.
|
|||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
|
||||
<refsect1>
|
||||
<title>DESCRIPTION</title>
|
||||
<para>
|
||||
|
@ -46,16 +45,18 @@ One Time Passwords with a Smart Card loaded with OTP software.
|
|||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term>-c<replaceable> count</replaceable></term>
|
||||
<term>-c, --sc-count=<replaceable> count</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Configure the optional count parameter to sync a Smart Card to a challenge.
|
||||
A count value of 0 indicates the HOTP value is to be calculated with the
|
||||
current stored count.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-d<replaceable> debug_level</replaceable></term>
|
||||
<term>-d, --debug=<replaceable> debug_level</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set debug level.
|
||||
|
@ -64,7 +65,7 @@ Set debug level.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-h</term>
|
||||
<term>-h, --help</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Help.
|
||||
|
@ -73,7 +74,7 @@ Help.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-i<replaceable> index</replaceable></term>
|
||||
<term>-i, --sc-index=<replaceable> index</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the 8 bit index. The Smart Card contains numerically indexed records
|
||||
|
@ -83,7 +84,7 @@ the index. The default index is 0.
|
|||
</listitem>
|
||||
|
||||
<varlistentry>
|
||||
<term>-l</term>
|
||||
<term>-l, --list-readers</term>
|
||||
<listitem>
|
||||
<para>
|
||||
List SC Readers
|
||||
|
@ -92,7 +93,7 @@ List SC Readers
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-L</term>
|
||||
<term>-L, --sc-list-hostnames</term>
|
||||
<listitem>
|
||||
<para>
|
||||
List host systems configured on the Smart Card. The index is used with the -i option.
|
||||
|
@ -101,7 +102,7 @@ List host systems configured on the Smart Card. The index is used with the -i o
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-o</term>
|
||||
<term>-p, --sc-reset-pin</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set new PIN.
|
||||
|
@ -110,7 +111,7 @@ Set new PIN.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-r<replaceable> reader</replaceable></term>
|
||||
<term>-r, --reader=<replaceable> reader</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set Smart Card reader. Use -l to list available readers. A reader
|
||||
|
@ -126,7 +127,7 @@ with serial port /dev/cuaU0.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-v<replaceable> card_api_version</replaceable></term>
|
||||
<term>-v, --sc-version=<replaceable> card_api_version</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the Smart Card API version. The binary API between the terminal
|
||||
|
@ -138,7 +139,7 @@ maintenance of Smart Card with version 2 firmware.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-V</term>
|
||||
<term>-V, --sc-list-version</term>
|
||||
<listitem>
|
||||
<para>
|
||||
List the Smart Card firmware version.
|
||||
|
@ -147,7 +148,7 @@ List the Smart Card firmware version.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-1</term>
|
||||
<term>-1, --sc-get-hostp-v1</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Use the version 1 GetHOTP command instead of the default GetHOTPHostCount32.
|
||||
|
@ -157,6 +158,15 @@ compiled out of newer firmware.
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>--version</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Display software version.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
|
|
@ -75,10 +75,18 @@ the display_count option is set\&. The default behavior will not display
|
|||
the count unless the user record flags field has OTP_USER_FLAGS_DSPCNT set\&.
|
||||
.IP "\fIrequire_db_entry\fP" 10
|
||||
A user not in the OTP database will be denied access with the
|
||||
require_db_entry option is set\&. By default users not in the OTP
|
||||
database are permitted\&.
|
||||
require_db_entry option is set\&. This option is set by default\&.
|
||||
require_db_entry and allow_unknown user set the same flag and are
|
||||
mutually exclusive\&.
|
||||
.IP "\fIallow_unknown_user\fP" 10
|
||||
A user not in the OTP database will be allowed access with the
|
||||
allow_unknown_user option set\&. This option is disabled by default\&.
|
||||
require_db_entry and allow_unknown user set the same flag and are
|
||||
mutually exclusive\&.
|
||||
.IP "\fIotpdb=\fP\fBalternate_otpdb\fP" 10
|
||||
\fBalternate_otpdb\fP is used as the OTP database\&.
|
||||
.IP "\fIservice=\fP\fBservice_name\fP" 10
|
||||
Service name for use with send-token option\&.
|
||||
.IP "\fIwindow=window\fP" 10
|
||||
Set OTP challenge window\&.
|
||||
.SH "AUTHOR"
|
||||
|
@ -95,4 +103,4 @@ Mark Fullmer maf@splintered\&.net
|
|||
\fBbcload\fP(1)
|
||||
\fBpam\fP(8)
|
||||
spyrus-par2(7)
|
||||
...\" created by instant / docbook-to-man, Sun 27 Dec 2009, 22:01
|
||||
...\" created by instant / docbook-to-man, Sun 15 May 2011, 23:57
|
||||
|
|
|
@ -128,8 +128,23 @@ CLASS="REPLACEABLE"
|
|||
><DD
|
||||
><P
|
||||
>A user not in the OTP database will be denied access with the
|
||||
require_db_entry option is set. By default users not in the OTP
|
||||
database are permitted.</P
|
||||
require_db_entry option is set. This option is set by default.
|
||||
require_db_entry and allow_unknown user set the same flag and are
|
||||
mutually exclusive.</P
|
||||
></DD
|
||||
><DT
|
||||
><TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
>allow_unknown_user</I
|
||||
></TT
|
||||
></DT
|
||||
><DD
|
||||
><P
|
||||
>A user not in the OTP database will be allowed access with the
|
||||
allow_unknown_user option set. This option is disabled by default.
|
||||
require_db_entry and allow_unknown user set the same flag and are
|
||||
mutually exclusive.</P
|
||||
></DD
|
||||
><DT
|
||||
><TT
|
||||
|
@ -152,6 +167,20 @@ CLASS="FILENAME"
|
|||
><TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
>service=</I
|
||||
></TT
|
||||
><TT
|
||||
CLASS="FILENAME"
|
||||
>service_name</TT
|
||||
></DT
|
||||
><DD
|
||||
><P
|
||||
>Service name for use with send-token option.</P
|
||||
></DD
|
||||
><DT
|
||||
><TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
>window=window</I
|
||||
></TT
|
||||
></DT
|
||||
|
@ -165,7 +194,7 @@ CLASS="REPLACEABLE"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN58"
|
||||
NAME="AEN69"
|
||||
></A
|
||||
><H2
|
||||
>AUTHOR</H2
|
||||
|
@ -182,7 +211,7 @@ HREF="mailto:maf@splintered.net"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN65"
|
||||
NAME="AEN76"
|
||||
></A
|
||||
><H2
|
||||
>SEE ALSO</H2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE refentry PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
|
||||
|
||||
<!-- $Id: pam_otp.sgml 50 2009-12-15 01:37:19Z maf $ -->
|
||||
<!-- $Id: pam_otp.sgml 169 2011-05-11 04:10:57Z maf $ -->
|
||||
|
||||
<refentry>
|
||||
|
||||
|
@ -80,8 +80,21 @@ the count unless the user record flags field has OTP_USER_FLAGS_DSPCNT set.
|
|||
<listitem>
|
||||
<para>
|
||||
A user not in the OTP database will be denied access with the
|
||||
require_db_entry option is set. By default users not in the OTP
|
||||
database are permitted.
|
||||
require_db_entry option is set. This option is set by default.
|
||||
require_db_entry and allow_unknown user set the same flag and are
|
||||
mutually exclusive.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable>allow_unknown_user</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
A user not in the OTP database will be allowed access with the
|
||||
allow_unknown_user option set. This option is disabled by default.
|
||||
require_db_entry and allow_unknown user set the same flag and are
|
||||
mutually exclusive.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -95,6 +108,15 @@ database are permitted.
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable>service=</replaceable><filename>service_name</filename></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Service name for use with send-token option.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><replaceable>window=window</replaceable></term>
|
||||
<listitem>
|
||||
|
|
|
@ -100,7 +100,8 @@ index 0\&.
|
|||
.PP
|
||||
\fB<#>\fP Toggle Challenge/Count input\&. The per-host count, incremented
|
||||
by 1 and stored on the SC after each HOTP generation can be overridden
|
||||
with this option\&.
|
||||
with this option\&. A count value of 0 indicates the HOTP value is to be
|
||||
calculated with the current stored count\&.
|
||||
.PP
|
||||
\fB<DOWN>\fP Enable host menu\&.
|
||||
.SS "Host Selection With Menu:"
|
||||
|
@ -201,4 +202,4 @@ may not\&.
|
|||
\fBurd\fP(1)
|
||||
\fBbcload\fP(1)
|
||||
\fBOpenVPN\fP(8)
|
||||
...\" created by instant / docbook-to-man, Sun 27 Dec 2009, 22:01
|
||||
...\" created by instant / docbook-to-man, Sun 15 May 2011, 23:57
|
||||
|
|
|
@ -150,7 +150,8 @@ CLASS="KEYSYM"
|
|||
>#</SPAN
|
||||
> Toggle Challenge/Count input. The per-host count, incremented
|
||||
by 1 and stored on the SC after each HOTP generation can be overridden
|
||||
with this option. </P
|
||||
with this option. A count value of 0 indicates the HOTP value is to be
|
||||
calculated with the current stored count. </P
|
||||
><P
|
||||
><SPAN
|
||||
CLASS="KEYSYM"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE refentry PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
|
||||
|
||||
<!-- $Id: spyrus-par2.sgml 78 2009-12-26 23:23:40Z maf $ -->
|
||||
<!-- $Id: spyrus-par2.sgml 106 2009-12-30 10:24:34Z maf $ -->
|
||||
|
||||
<refentry>
|
||||
|
||||
|
@ -105,7 +105,8 @@ index 0.
|
|||
<para>
|
||||
<keysym>#</keysym> Toggle Challenge/Count input. The per-host count, incremented
|
||||
by 1 and stored on the SC after each HOTP generation can be overridden
|
||||
with this option.
|
||||
with this option. A count value of 0 indicates the HOTP value is to be
|
||||
calculated with the current stored count.
|
||||
|
||||
<para>
|
||||
<keysym>DOWN</keysym> Enable host menu.
|
||||
|
|
63
doc/urd.1
63
doc/urd.1
|
@ -56,14 +56,14 @@
|
|||
\fBurd\fP \(em Micro footprint RADIUS daemon with One Time Password support\&.
|
||||
.SH "SYNOPSIS"
|
||||
.PP
|
||||
\fBurd\fP [-?AhdDOux] [-a\fI allowed_users_file\fP] [-b\fI local_ip\fP] [-B\fI local_port\fP] [-o\fI otp_db\fP] [-p\fI passwd_file\fP] [-P\fI pid_file\fP] [-s\fI secret_file\fP] [-w\fI otp_window\fP]
|
||||
\fBurd\fP [-?AhcdDmMOux] [-a\fI authorized_users_file\fP] [-b\fI local_ip\fP] [-B\fI local_port\fP] [-o\fI otp_db\fP] [-p\fI passwd_file\fP] [-P\fI pid_file\fP] [-s\fI secret_file\fP] [-S\fI auth_service_name\fP] [-V\fI service_name\fP] [-w\fI otp_window\fP]
|
||||
.SH "DESCRIPTION"
|
||||
.PP
|
||||
The \fBurd\fP daemon implements a minimal subset
|
||||
of the RADIUS protocol for user authentication with optional
|
||||
One Time Passwords\&. Accounting is not supported\&. Configuration
|
||||
files include a \fBpasswd\fP file in Unix passwd(5)
|
||||
format, an optional \fBallowed_users\fP file for
|
||||
format, an optional \fBauthorized_users\fP file for
|
||||
authenticating with a subset of the \fBpasswd\fP file, a
|
||||
\fBsecret\fP file for the shared RADIUS secret, and
|
||||
\fBotp_db\fP for One Time Password support\&.
|
||||
|
@ -83,6 +83,12 @@ before any Read Modify Write operations are performed\&.
|
|||
.PP
|
||||
An alternate OTP database can be specified as \fBotb_db\fP\&.
|
||||
.PP
|
||||
PAM authentication is optionally supported for passwords\&. PAM can
|
||||
be configured as the sole means of authentication, or the locally
|
||||
configured password file may be used as a method of selecting valid
|
||||
users to later be authenticated with PAM\&. PAM can be used for the
|
||||
reusable password, the OTP API is always used for two factor authentication\&.
|
||||
.PP
|
||||
The \fBsecret\fP file contains the key shared
|
||||
by the RADIUS NAS and RADIUS server\&. It must be less than 32 bytes\&.
|
||||
.PP
|
||||
|
@ -91,56 +97,71 @@ to authenticate successfully will toggle debugging and dump the internal
|
|||
state and request cache respectively\&. If these users are not configured
|
||||
with a password this feature will be disabled\&.
|
||||
.SH "OPTIONS"
|
||||
.IP "-a\fI allowed_users_file\fP" 10
|
||||
Specify an alternate location for the \fBallowed_users_file\fP\&.
|
||||
.IP "-a, --authorized-users-db=\fI authorized_users_file\fP" 10
|
||||
Specify an alternate location for the \fBauthorized_users_file\fP\&.
|
||||
.IP "" 10
|
||||
The \fBallowed_users_file\fP contains one username per line\&.
|
||||
The \fBauthorized_users_file\fP contains one username per line\&.
|
||||
When configured this option requires a user to be listed
|
||||
in \fBallowed_users_file\fP for authentication to proceed
|
||||
in \fBauthorized_users_file\fP for authentication to proceed
|
||||
with the password and One Time Password functions\&.
|
||||
.IP "-A" 10
|
||||
.IP "-A, --disable-authorized-users" 10
|
||||
Disable \fBauthorized_users\fP feature\&. This option must
|
||||
be set if the \fBauthorized_users_file\fP is not used\&.
|
||||
.IP "-b\fI local_ip\fP" 10
|
||||
.IP "-b, --bind-ip-address=\fI local_ip\fP" 10
|
||||
Specify an IP address to bind(2) to\&. The default behavior will bind to
|
||||
INADDR_ANY\&.
|
||||
.IP "-B\fI local_port\fP" 10
|
||||
.IP "-B, --bind-udp-port=\fI local_port\fP" 10
|
||||
Specify the local UDP port to bind(2) to\&. The default behavior will bind
|
||||
to UDP port 1812\&.
|
||||
.IP "-d" 10
|
||||
.IP "-c, --display-count" 10
|
||||
Force count to be passed to RADIUS NAS\&. Not all devices will be able to
|
||||
display this field\&.
|
||||
.IP "-d, --debug=\fI debug_level\fP" 10
|
||||
Enable verbose debugging\&.
|
||||
.IP "-D" 10
|
||||
.IP "-D, --disable-daemon-mode" 10
|
||||
Disable daemon mode\&. When specified \fBurd\fP will not
|
||||
run in the background and stdout is available for debugging information\&.
|
||||
.IP "-o\fI otp_db\fP" 10
|
||||
.IP "-m, --pam-authentication-enable" 10
|
||||
Authenticate with PAM\&. The user must be present in the local password
|
||||
and optionally authorized users files before PAM authentication\&.
|
||||
.IP "-M, --pam-authentication-exclusive" 10
|
||||
Authenticate with PAM\&. The local password file is not consulted\&.
|
||||
.IP "-o, --otp-db=\fI otp_db\fP" 10
|
||||
Specify an alternate location for the One Time Password database
|
||||
\fBotp_db\fP\&.
|
||||
.IP "-O" 10
|
||||
.IP "-O, --otp-disable" 10
|
||||
Disable the use of One Time Passwords\&.
|
||||
.IP "-p\fI passwd_file\fP" 10
|
||||
.IP "-p, --password-db=\fI passwd_file\fP" 10
|
||||
Specify an alternate location for the \fBpasswd\fP file\&. The \fBpasswd\fP file is in Unix passwd(5) format\&.
|
||||
Fields beyond the username and password hash are ignored\&. The users
|
||||
password is hashed with crypt(3) and compared to the hash stored in this file
|
||||
for authentication\&.
|
||||
.IP "-P\fI pid_file\fP" 10
|
||||
.IP "-P, --pidfile=\fI pid_file\fP" 10
|
||||
Specify an alternate location for a file containing the process ID
|
||||
of the RADIUS server\&. If a listen IP address or non standard UDP listen
|
||||
port is configured the PID filename will contain the IP address and
|
||||
port to differentiate it from other instances of \fBurd\fP running on the same server\&.
|
||||
.IP "-s\fI secret_file\fP" 10
|
||||
.IP "-s, --server-secret=\fI secret_file\fP" 10
|
||||
Specify an alternate location for the \fBsecret_file\fP\&.
|
||||
The \fBsecret_file\fP contains the shared secret between
|
||||
the NAS and RADIUS server and must be less than 32 bytes\&.
|
||||
.IP "-u" 10
|
||||
.IP "-S, --pam-service-name=\fI auth_service_name\fP" 10
|
||||
Specify an alternate name for the PAM authentication service\&. Defaults
|
||||
to urd\&.
|
||||
.IP "-u, --otp-allow-unknown-user" 10
|
||||
Allow users which do not exist in the OTP database to successfully
|
||||
authenticate without using a One Time Password, only a valid password
|
||||
will be required\&.
|
||||
.IP "-x" 10
|
||||
.IP "-V, --service-name=\fI service_name\fP" 10
|
||||
Set service name for send-token function\&.
|
||||
.IP "--version" 10
|
||||
Display software version\&.
|
||||
.IP "-w, --otp-challenge-window=\fI window\fP" 10
|
||||
Set the OTP challenge window\&.
|
||||
.IP "-x, --debug-drop-udp-packets" 10
|
||||
Drop every other RADIUS request from a NAS\&. This is a debugging feature
|
||||
intended to stress test the reply cache code\&. The reply cache
|
||||
implements state retention required for the use of One Time Passwords\&.
|
||||
.IP "-w" 10
|
||||
Set the OTP challenge window\&.
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
The following command will start the urd server, bind it to IP address
|
||||
|
@ -168,4 +189,4 @@ Mark Fullmer maf@splintered\&.net
|
|||
\fBbcload\fP(1)
|
||||
\fBotp-ov-plugin\fP(1)
|
||||
spyrus-par2(7)
|
||||
...\" created by instant / docbook-to-man, Sun 27 Dec 2009, 22:01
|
||||
...\" created by instant / docbook-to-man, Sun 15 May 2011, 23:57
|
||||
|
|
139
doc/urd.html
139
doc/urd.html
|
@ -43,10 +43,10 @@ NAME="AEN10"
|
|||
><B
|
||||
CLASS="COMMAND"
|
||||
>urd</B
|
||||
> [-?AhdDOux] [-a<TT
|
||||
> [-?AhcdDmMOux] [-a<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> allowed_users_file</I
|
||||
> authorized_users_file</I
|
||||
></TT
|
||||
>] [-b<TT
|
||||
CLASS="REPLACEABLE"
|
||||
|
@ -78,6 +78,16 @@ CLASS="REPLACEABLE"
|
|||
><I
|
||||
> secret_file</I
|
||||
></TT
|
||||
>] [-S<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> auth_service_name</I
|
||||
></TT
|
||||
>] [-V<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> service_name</I
|
||||
></TT
|
||||
>] [-w<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
|
@ -88,7 +98,7 @@ CLASS="REPLACEABLE"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN30"
|
||||
NAME="AEN34"
|
||||
></A
|
||||
><H2
|
||||
>DESCRIPTION</H2
|
||||
|
@ -105,7 +115,7 @@ CLASS="FILENAME"
|
|||
> file in Unix passwd(5)
|
||||
format, an optional <TT
|
||||
CLASS="FILENAME"
|
||||
>allowed_users</TT
|
||||
>authorized_users</TT
|
||||
> file for
|
||||
authenticating with a subset of the <TT
|
||||
CLASS="FILENAME"
|
||||
|
@ -168,6 +178,12 @@ CLASS="FILENAME"
|
|||
>otb_db</TT
|
||||
>.</P
|
||||
><P
|
||||
>PAM authentication is optionally supported for passwords. PAM can
|
||||
be configured as the sole means of authentication, or the locally
|
||||
configured password file may be used as a method of selecting valid
|
||||
users to later be authenticated with PAM. PAM can be used for the
|
||||
reusable password, the OTP API is always used for two factor authentication.</P
|
||||
><P
|
||||
>The <TT
|
||||
CLASS="FILENAME"
|
||||
>secret</TT
|
||||
|
@ -182,7 +198,7 @@ with a password this feature will be disabled.</P
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN55"
|
||||
NAME="AEN60"
|
||||
></A
|
||||
><H2
|
||||
>OPTIONS</H2
|
||||
|
@ -192,32 +208,32 @@ NAME="AEN55"
|
|||
CLASS="VARIABLELIST"
|
||||
><DL
|
||||
><DT
|
||||
>-a<TT
|
||||
>-a, --authorized-users-db=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> allowed_users_file</I
|
||||
> authorized_users_file</I
|
||||
></TT
|
||||
></DT
|
||||
><DD
|
||||
><P
|
||||
>Specify an alternate location for the <TT
|
||||
CLASS="FILENAME"
|
||||
>allowed_users_file</TT
|
||||
>authorized_users_file</TT
|
||||
>.</P
|
||||
><P
|
||||
>The <TT
|
||||
CLASS="FILENAME"
|
||||
>allowed_users_file</TT
|
||||
>authorized_users_file</TT
|
||||
> contains one username per line.
|
||||
When configured this option requires a user to be listed
|
||||
in <TT
|
||||
CLASS="FILENAME"
|
||||
>allowed_users_file</TT
|
||||
>authorized_users_file</TT
|
||||
> for authentication to proceed
|
||||
with the password and One Time Password functions.</P
|
||||
></DD
|
||||
><DT
|
||||
>-A</DT
|
||||
>-A, --disable-authorized-users</DT
|
||||
><DD
|
||||
><P
|
||||
>Disable <TT
|
||||
|
@ -230,7 +246,7 @@ CLASS="FILENAME"
|
|||
> is not used.</P
|
||||
></DD
|
||||
><DT
|
||||
>-b<TT
|
||||
>-b, --bind-ip-address=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> local_ip</I
|
||||
|
@ -242,7 +258,7 @@ CLASS="REPLACEABLE"
|
|||
INADDR_ANY.</P
|
||||
></DD
|
||||
><DT
|
||||
>-B<TT
|
||||
>-B, --bind-udp-port=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> local_port</I
|
||||
|
@ -254,13 +270,25 @@ CLASS="REPLACEABLE"
|
|||
to UDP port 1812.</P
|
||||
></DD
|
||||
><DT
|
||||
>-d</DT
|
||||
>-c, --display-count</DT
|
||||
><DD
|
||||
><P
|
||||
>Force count to be passed to RADIUS NAS. Not all devices will be able to
|
||||
display this field.</P
|
||||
></DD
|
||||
><DT
|
||||
>-d, --debug=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> debug_level</I
|
||||
></TT
|
||||
></DT
|
||||
><DD
|
||||
><P
|
||||
>Enable verbose debugging.</P
|
||||
></DD
|
||||
><DT
|
||||
>-D</DT
|
||||
>-D, --disable-daemon-mode</DT
|
||||
><DD
|
||||
><P
|
||||
>Disable daemon mode. When specified <B
|
||||
|
@ -270,7 +298,20 @@ CLASS="COMMAND"
|
|||
run in the background and stdout is available for debugging information.</P
|
||||
></DD
|
||||
><DT
|
||||
>-o<TT
|
||||
>-m, --pam-authentication-enable</DT
|
||||
><DD
|
||||
><P
|
||||
>Authenticate with PAM. The user must be present in the local password
|
||||
and optionally authorized users files before PAM authentication.</P
|
||||
></DD
|
||||
><DT
|
||||
>-M, --pam-authentication-exclusive</DT
|
||||
><DD
|
||||
><P
|
||||
>Authenticate with PAM. The local password file is not consulted.</P
|
||||
></DD
|
||||
><DT
|
||||
>-o, --otp-db=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> otp_db</I
|
||||
|
@ -285,13 +326,13 @@ CLASS="FILENAME"
|
|||
>.</P
|
||||
></DD
|
||||
><DT
|
||||
>-O</DT
|
||||
>-O, --otp-disable</DT
|
||||
><DD
|
||||
><P
|
||||
>Disable the use of One Time Passwords.</P
|
||||
></DD
|
||||
><DT
|
||||
>-p<TT
|
||||
>-p, --password-db=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> passwd_file</I
|
||||
|
@ -312,7 +353,7 @@ password is hashed with crypt(3) and compared to the hash stored in this file
|
|||
for authentication.</P
|
||||
></DD
|
||||
><DT
|
||||
>-P<TT
|
||||
>-P, --pidfile=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> pid_file</I
|
||||
|
@ -330,7 +371,7 @@ CLASS="COMMAND"
|
|||
running on the same server.</P
|
||||
></DD
|
||||
><DT
|
||||
>-s<TT
|
||||
>-s, --server-secret=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> secret_file</I
|
||||
|
@ -349,7 +390,19 @@ CLASS="FILENAME"
|
|||
the NAS and RADIUS server and must be less than 32 bytes.</P
|
||||
></DD
|
||||
><DT
|
||||
>-u</DT
|
||||
>-S, --pam-service-name=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> auth_service_name</I
|
||||
></TT
|
||||
></DT
|
||||
><DD
|
||||
><P
|
||||
>Specify an alternate name for the PAM authentication service. Defaults
|
||||
to urd.</P
|
||||
></DD
|
||||
><DT
|
||||
>-u, --otp-allow-unknown-user</DT
|
||||
><DD
|
||||
><P
|
||||
>Allow users which do not exist in the OTP database to successfully
|
||||
|
@ -357,26 +410,48 @@ authenticate without using a One Time Password, only a valid password
|
|||
will be required.</P
|
||||
></DD
|
||||
><DT
|
||||
>-x</DT
|
||||
>-V, --service-name=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> service_name</I
|
||||
></TT
|
||||
></DT
|
||||
><DD
|
||||
><P
|
||||
>Set service name for send-token function.</P
|
||||
></DD
|
||||
><DT
|
||||
>--version</DT
|
||||
><DD
|
||||
><P
|
||||
>Display software version.</P
|
||||
></DD
|
||||
><DT
|
||||
>-w, --otp-challenge-window=<TT
|
||||
CLASS="REPLACEABLE"
|
||||
><I
|
||||
> window</I
|
||||
></TT
|
||||
></DT
|
||||
><DD
|
||||
><P
|
||||
>Set the OTP challenge window.</P
|
||||
></DD
|
||||
><DT
|
||||
>-x, --debug-drop-udp-packets</DT
|
||||
><DD
|
||||
><P
|
||||
>Drop every other RADIUS request from a NAS. This is a debugging feature
|
||||
intended to stress test the reply cache code. The reply cache
|
||||
implements state retention required for the use of One Time Passwords.</P
|
||||
></DD
|
||||
><DT
|
||||
>-w</DT
|
||||
><DD
|
||||
><P
|
||||
>Set the OTP challenge window.</P
|
||||
></DD
|
||||
></DL
|
||||
></DIV
|
||||
></DIV
|
||||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN134"
|
||||
NAME="AEN167"
|
||||
></A
|
||||
><H2
|
||||
>EXAMPLES</H2
|
||||
|
@ -385,7 +460,7 @@ CLASS="INFORMALEXAMPLE"
|
|||
><P
|
||||
></P
|
||||
><A
|
||||
NAME="AEN136"
|
||||
NAME="AEN169"
|
||||
></A
|
||||
><P
|
||||
>The following command will start the urd server, bind it to IP address
|
||||
|
@ -419,7 +494,7 @@ CLASS="SCREEN"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN144"
|
||||
NAME="AEN177"
|
||||
></A
|
||||
><H2
|
||||
>AUTHOR</H2
|
||||
|
@ -436,7 +511,7 @@ HREF="mailto:maf@splintered.net"
|
|||
><DIV
|
||||
CLASS="REFSECT1"
|
||||
><A
|
||||
NAME="AEN151"
|
||||
NAME="AEN184"
|
||||
></A
|
||||
><H2
|
||||
>SEE ALSO</H2
|
||||
|
|
114
doc/urd.sgml
114
doc/urd.sgml
|
@ -1,6 +1,6 @@
|
|||
<!DOCTYPE refentry PUBLIC "-//Davenport//DTD DocBook V3.0//EN">
|
||||
|
||||
<!-- $Id: urd.sgml 50 2009-12-15 01:37:19Z maf $ -->
|
||||
<!-- $Id: urd.sgml 178 2011-05-16 02:39:04Z maf $ -->
|
||||
|
||||
<refentry>
|
||||
|
||||
|
@ -23,14 +23,16 @@ Micro footprint RADIUS daemon with One Time Password support.
|
|||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>urd</command>
|
||||
<arg>-?AhdDOux</arg>
|
||||
<arg>-a<replaceable> allowed_users_file</replaceable></arg>
|
||||
<arg>-?AhcdDmMOux</arg>
|
||||
<arg>-a<replaceable> authorized_users_file</replaceable></arg>
|
||||
<arg>-b<replaceable> local_ip</replaceable></arg>
|
||||
<arg>-B<replaceable> local_port</replaceable></arg>
|
||||
<arg>-o<replaceable> otp_db</replaceable></arg>
|
||||
<arg>-p<replaceable> passwd_file</replaceable></arg>
|
||||
<arg>-P<replaceable> pid_file</replaceable></arg>
|
||||
<arg>-s<replaceable> secret_file</replaceable></arg>
|
||||
<arg>-S<replaceable> auth_service_name</replaceable></arg>
|
||||
<arg>-V<replaceable> service_name</replaceable></arg>
|
||||
<arg>-w<replaceable> otp_window</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
@ -43,7 +45,7 @@ The <command>urd</command> daemon implements a minimal subset
|
|||
of the RADIUS protocol for user authentication with optional
|
||||
One Time Passwords. Accounting is not supported. Configuration
|
||||
files include a <filename>passwd</filename> file in Unix passwd(5)
|
||||
format, an optional <filename>allowed_users</filename> file for
|
||||
format, an optional <filename>authorized_users</filename> file for
|
||||
authenticating with a subset of the <filename>passwd</filename> file, a
|
||||
<filename>secret</filename> file for the shared RADIUS secret, and
|
||||
<filename>otp_db</filename> for One Time Password support.
|
||||
|
@ -70,6 +72,13 @@ before any Read Modify Write operations are performed.
|
|||
An alternate OTP database can be specified as <filename>otb_db</filename>.
|
||||
</para>
|
||||
<para>
|
||||
PAM authentication is optionally supported for passwords. PAM can
|
||||
be configured as the sole means of authentication, or the locally
|
||||
configured password file may be used as a method of selecting valid
|
||||
users to later be authenticated with PAM. PAM can be used for the
|
||||
reusable password, the OTP API is always used for two factor authentication.
|
||||
</para>
|
||||
<para>
|
||||
The <filename>secret</filename> file contains the key shared
|
||||
by the RADIUS NAS and RADIUS server. It must be less than 32 bytes.
|
||||
</para>
|
||||
|
@ -86,22 +95,22 @@ with a password this feature will be disabled.
|
|||
<variablelist>
|
||||
|
||||
<varlistentry>
|
||||
<term>-a<replaceable> allowed_users_file</replaceable></term>
|
||||
<term>-a, --authorized-users-db=<replaceable> authorized_users_file</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specify an alternate location for the <filename>allowed_users_file</filename>.
|
||||
Specify an alternate location for the <filename>authorized_users_file</filename>.
|
||||
</para>
|
||||
<para>
|
||||
The <filename>allowed_users_file</filename> contains one username per line.
|
||||
The <filename>authorized_users_file</filename> contains one username per line.
|
||||
When configured this option requires a user to be listed
|
||||
in <filename>allowed_users_file</filename> for authentication to proceed
|
||||
in <filename>authorized_users_file</filename> for authentication to proceed
|
||||
with the password and One Time Password functions.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-A</term>
|
||||
<term>-A, --disable-authorized-users</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable <filename>authorized_users</filename> feature. This option must
|
||||
|
@ -111,7 +120,7 @@ be set if the <filename>authorized_users_file</filename> is not used.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-b<replaceable> local_ip</replaceable></term>
|
||||
<term>-b, --bind-ip-address=<replaceable> local_ip</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specify an IP address to bind(2) to. The default behavior will bind to
|
||||
|
@ -121,7 +130,7 @@ INADDR_ANY.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-B<replaceable> local_port</replaceable></term>
|
||||
<term>-B, --bind-udp-port=<replaceable> local_port</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specify the local UDP port to bind(2) to. The default behavior will bind
|
||||
|
@ -131,7 +140,17 @@ to UDP port 1812.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-d</term>
|
||||
<term>-c, --display-count</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Force count to be passed to RADIUS NAS. Not all devices will be able to
|
||||
display this field.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-d, --debug=<replaceable> debug_level</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Enable verbose debugging.
|
||||
|
@ -140,7 +159,7 @@ Enable verbose debugging.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-D</term>
|
||||
<term>-D, --disable-daemon-mode</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable daemon mode. When specified <command>urd</command> will not
|
||||
|
@ -150,7 +169,26 @@ run in the background and stdout is available for debugging information.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-o<replaceable> otp_db</replaceable></term>
|
||||
<term>-m, --pam-authentication-enable</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Authenticate with PAM. The user must be present in the local password
|
||||
and optionally authorized users files before PAM authentication.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-M, --pam-authentication-exclusive</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Authenticate with PAM. The local password file is not consulted.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-o, --otp-db=<replaceable> otp_db</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specify an alternate location for the One Time Password database
|
||||
|
@ -160,7 +198,7 @@ Specify an alternate location for the One Time Password database
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-O</term>
|
||||
<term>-O, --otp-disable</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Disable the use of One Time Passwords.
|
||||
|
@ -169,7 +207,7 @@ Disable the use of One Time Passwords.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-p<replaceable> passwd_file</replaceable></term>
|
||||
<term>-p, --password-db=<replaceable> passwd_file</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specify an alternate location for the <filename>passwd</filename>
|
||||
|
@ -182,7 +220,7 @@ for authentication.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-P<replaceable> pid_file</replaceable></term>
|
||||
<term>-P, --pidfile=<replaceable> pid_file</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specify an alternate location for a file containing the process ID
|
||||
|
@ -195,7 +233,7 @@ running on the same server.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-s<replaceable> secret_file</replaceable></term>
|
||||
<term>-s, --server-secret=<replaceable> secret_file</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specify an alternate location for the <filename>secret_file</filename>.
|
||||
|
@ -206,7 +244,17 @@ the NAS and RADIUS server and must be less than 32 bytes.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-u</term>
|
||||
<term>-S, --pam-service-name=<replaceable> auth_service_name</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Specify an alternate name for the PAM authentication service. Defaults
|
||||
to urd.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-u, --otp-allow-unknown-user</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Allow users which do not exist in the OTP database to successfully
|
||||
|
@ -217,18 +265,25 @@ will be required.
|
|||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-x</term>
|
||||
<term>-V, --service-name=<replaceable> service_name</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Drop every other RADIUS request from a NAS. This is a debugging feature
|
||||
intended to stress test the reply cache code. The reply cache
|
||||
implements state retention required for the use of One Time Passwords.
|
||||
Set service name for send-token function.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-w</term>
|
||||
<term>--version</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Display software version.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-w, --otp-challenge-window=<replaceable> window</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Set the OTP challenge window.
|
||||
|
@ -236,6 +291,17 @@ Set the OTP challenge window.
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>-x, --debug-drop-udp-packets</term>
|
||||
<listitem>
|
||||
<para>
|
||||
Drop every other RADIUS request from a NAS. This is a debugging feature
|
||||
intended to stress test the reply cache code. The reply cache
|
||||
implements state retention required for the use of One Time Passwords.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile 13 2009-11-26 16:37:03Z maf $
|
||||
# $Id: Makefile 128 2010-06-15 14:25:09Z maf $
|
||||
|
||||
what:
|
||||
@echo
|
||||
|
@ -22,13 +22,18 @@ INSTALL=install -c -m0755
|
|||
|
||||
.c.o:; $(CC) $(CFLAGS) -c $*.c -o $*.o
|
||||
|
||||
OBJS = ../common/xerr.o
|
||||
|
||||
BINS = htsoft-downloader
|
||||
BIN = htsoft-downloader
|
||||
COBJS = ../common/xerr.o
|
||||
OBJS = version.o ${BIN}.o
|
||||
|
||||
BINDIR=/usr/local/ootp/bin
|
||||
|
||||
all: htsoft-downloader.c ${OBJS} ${BINS}
|
||||
all: version ${COBJS} ${OBJS} ${BIN}
|
||||
|
||||
version:
|
||||
rm -f version.c; ../build/version ../VERSION ${BIN} > version.c
|
||||
|
||||
version.c:
|
||||
|
||||
install:
|
||||
mkdir -p ${BINDIR}
|
||||
|
@ -36,8 +41,8 @@ install:
|
|||
@echo files installed in ${BINDIR}
|
||||
|
||||
clean:
|
||||
/bin/rm -f ${BINS} htsoft-downloader.o
|
||||
/bin/rm -f ${BINS} ${OBJS} version.c
|
||||
|
||||
htsoft-downloader: ${OBJS} htsoft-downloader.o
|
||||
$(CC) $(CFLAGS) $(LFLAGS) $(INC) -o htsoft-downloader ${OBJS} htsoft-downloader.o $(LIBS)
|
||||
${BIN}: ${COBJS} ${OBJS}
|
||||
$(CC) $(CFLAGS) $(LFLAGS) $(INC) -o ${BIN} ${COBJS} ${OBJS} $(LIBS)
|
||||
|
||||
|
|
|
@ -24,12 +24,13 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: htsoft-downloader.c 75 2009-12-26 20:59:23Z maf $
|
||||
* $Id: htsoft-downloader.c 128 2010-06-15 14:25:09Z maf $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
@ -89,6 +90,7 @@ int n2b(char *h, u_char *b);
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
extern char *ootp_version;
|
||||
struct termios pic_term;
|
||||
char lbuf[1024];
|
||||
char *c;
|
||||
|
@ -97,9 +99,21 @@ int main(int argc, char **argv)
|
|||
uint8_t ld_buf[256], ld_buf_len;
|
||||
uint16_t h_load_offset, tmp_load_offset, buf_load_offset;
|
||||
int i, r, pic_fd, lineno, lbuf_len, got_eof, pic_tmout, verbose;
|
||||
int max_retries, ignore_last_wok_timeout;
|
||||
int max_retries, ignore_last_wok_timeout, opt_version;
|
||||
char *pic_dev;
|
||||
|
||||
struct option longopts[] = {
|
||||
{ "serial-device", 1, (void*)0L, 'f'},
|
||||
{ "help", 0, (void*)0L, 'h'},
|
||||
{ "help", 0, (void*)0L, '?'},
|
||||
{ "ignore-last-wok-timeout", 0, (void*)0L, 'i'},
|
||||
{ "retries", 1, (void*)0L, 'r'},
|
||||
{ "pic-timeout", 1, (void*)0L, 't'},
|
||||
{ "verbose", 0, (void*)0L, 'v'},
|
||||
{ "version", 0, &opt_version, 1},
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
xerr_setid(argv[0]);
|
||||
lineno = 0;
|
||||
ld_buf_len = 0;
|
||||
|
@ -111,8 +125,10 @@ int main(int argc, char **argv)
|
|||
h_load_offset = 0;
|
||||
buf_load_offset = 0;
|
||||
ignore_last_wok_timeout = 0;
|
||||
opt_version = 0;
|
||||
|
||||
while ((i = getopt(argc, argv, "f:h?ir:t:v:")) != -1) {
|
||||
while ((i = getopt_long(argc, argv, "f:h?ir:t:v:", longopts,
|
||||
(int*)0L)) != -1) {
|
||||
|
||||
switch (i) {
|
||||
|
||||
|
@ -142,14 +158,19 @@ int main(int argc, char **argv)
|
|||
verbose = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if (opt_version) {
|
||||
printf("%s\n", ootp_version);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
default:
|
||||
help();
|
||||
exit(1);
|
||||
break; /* notreached */
|
||||
xerr_errx(1, "getopt_long(): fatal.");
|
||||
break; /* not reached */
|
||||
|
||||
} /* switch */
|
||||
|
||||
} /* getopt */
|
||||
} /* while getopt_long() */
|
||||
|
||||
/* open and setup serial communications port */
|
||||
if ((pic_fd = open(pic_dev, O_RDWR)) < 0)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile 13 2009-11-26 16:37:03Z maf $
|
||||
# $Id: Makefile 129 2010-06-15 14:25:43Z maf $
|
||||
|
||||
what:
|
||||
@echo
|
||||
|
@ -22,22 +22,27 @@ INSTALL=install -c -m0755
|
|||
|
||||
.c.o:; $(CC) $(CFLAGS) -c $*.c -o $*.o
|
||||
|
||||
OBJS = ../common/xerr.o ../common/str.o ../common/otplib.o ../common/ffdb.o
|
||||
|
||||
BINS = otp-control
|
||||
BIN = otp-control
|
||||
COBJS = ../common/xerr.o ../common/str.o ../common/otplib.o ../common/ffdb.o
|
||||
OBJS = version.o ${BIN}.o
|
||||
|
||||
BINDIR=/usr/local/ootp/bin
|
||||
|
||||
all: otp-control.c ${OBJS} ${BINS}
|
||||
all: version ${COBJS} ${OBJS} ${BIN}
|
||||
|
||||
version:
|
||||
rm -f version.c; ../build/version ../VERSION ${BIN} > version.c
|
||||
|
||||
version.c:
|
||||
|
||||
install:
|
||||
mkdir -p ${BINDIR}
|
||||
${INSTALL} ${BINS} ${BINDIR}
|
||||
${INSTALL} ${BIN} ${BINDIR}
|
||||
@echo files installed in ${BINDIR}
|
||||
|
||||
clean:
|
||||
/bin/rm -f ${BINS} otp-control.o
|
||||
/bin/rm -f ${BIN} ${OBJS} version.c
|
||||
|
||||
otp-control: ${OBJS} otp-control.o
|
||||
$(CC) $(CFLAGS) $(LFLAGS) $(INC) -o otp-control ${OBJS} otp-control.o $(LIBS)
|
||||
${BIN}: ${COBJS} ${OBJS}
|
||||
$(CC) $(CFLAGS) $(LFLAGS) $(INC) -o ${BIN} ${COBJS} ${OBJS} $(LIBS)
|
||||
|
||||
|
|
|
@ -24,14 +24,15 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: otp-control.c 55 2009-12-17 01:59:35Z maf $
|
||||
* $Id: otp-control.c 179 2011-05-16 02:48:42Z maf $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include "otplib.h"
|
||||
#include "otpsc.h"
|
||||
|
@ -49,11 +50,13 @@
|
|||
#define MODE_SET_COUNT_CEIL 11
|
||||
#define MODE_TEST 12
|
||||
#define MODE_CREATE 13
|
||||
#define MODE_SEND_TOKEN 14
|
||||
#define MODE_LIST_SC 18
|
||||
#define MODE_SET_STATUS 19
|
||||
#define MODE_SET_TYPE 20
|
||||
#define MODE_SET_FORMAT 21
|
||||
#define MODE_SET_FLAGS 22
|
||||
#define MODE_SET_LOCATION 23
|
||||
|
||||
#define KEY_HEX160_LEN 40
|
||||
|
||||
|
@ -65,9 +68,11 @@ void help(void);
|
|||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
extern char *ootp_version;
|
||||
struct otp_ctx *otpctx;
|
||||
struct otp_user ou;
|
||||
int i, j, r, mode, window, db_flags, open_mode, open_op, verbose;
|
||||
int opt_version, u_count_set;
|
||||
char *otpdb_fname;
|
||||
uint64_t u_count, u_count_ceil, count_offset, tmp64u;
|
||||
uint8_t u_version, u_status, u_format, u_type, u_flags, sc_index;
|
||||
|
@ -75,17 +80,42 @@ int main (int argc, char **argv)
|
|||
unsigned char u_key160[20];
|
||||
char key_hex160[KEY_HEX160_LEN+1];
|
||||
char crsp_tmp[11];
|
||||
char *u_username, *u_key_ascii, *sc_hostname;
|
||||
char *endptr, *i_status, *i_format, *i_type, *i_flags;
|
||||
char *u_username, *u_loc, *u_key_ascii, *sc_hostname;
|
||||
char *endptr, *i_status, *i_format, *i_type, *i_flags, *service;
|
||||
|
||||
struct option longopts[] = {
|
||||
{ "count", 1, (void*)0L, 'c'},
|
||||
{ "count-ceil", 1, (void*)0L, 'C'},
|
||||
{ "format", 1, (void*)0L, 'f'},
|
||||
{ "flags", 1, (void*)0L, 'F'},
|
||||
{ "sc-hostname", 1, (void*)0L, 'H'},
|
||||
{ "sc-index", 1, (void*)0L, 'I'},
|
||||
{ "key", 1, (void*)0L, 'k'},
|
||||
{ "location", 1, (void*)0L, 'l'},
|
||||
{ "command-mode", 1, (void*)0L, 'm'},
|
||||
{ "otp-db", 1, (void*)0L, 'o'},
|
||||
{ "status", 1, (void*)0L, 's'},
|
||||
{ "sc-flags", 1, (void*)0L, 'S'},
|
||||
{ "type", 1, (void*)0L, 't'},
|
||||
{ "username", 1, (void*)0L, 'u'},
|
||||
{ "challenge-window", 1, (void*)0L, 'w'},
|
||||
{ "help", 0, (void*)0L, 'h'},
|
||||
{ "create-database", 0, (void*)0L, 'n'},
|
||||
{ "verbose", 0, (void*)0L, 'v'},
|
||||
{ "service-name", 0, (void*)0L, 'V'},
|
||||
{ "version", 0, &opt_version, 1},
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
otpdb_fname = OTP_DB_FNAME;
|
||||
sc_index = 0;
|
||||
mode = 0;
|
||||
window = 1;
|
||||
verbose = 0;
|
||||
u_count_set = 0;
|
||||
db_flags = 0;
|
||||
/* user defaults */
|
||||
u_count = 0;
|
||||
u_count = 1;
|
||||
u_count_ceil = 0xFFFFFFFFFFFFFFFFLL;
|
||||
u_version = OTP_VERSION;
|
||||
u_format = OTP_FORMAT_HEX40;
|
||||
|
@ -94,15 +124,19 @@ int main (int argc, char **argv)
|
|||
u_flags = 0;
|
||||
u_username = (char*)0L;
|
||||
u_key_ascii = (char*)0L;
|
||||
u_loc = (char*)0L;
|
||||
endptr = (char*)0L;
|
||||
sc_hostname = (char*)0L;
|
||||
service = "otp-control";
|
||||
bzero(sc_flags, SC_HOSTNAME_LEN);
|
||||
i_status = i_type = i_format = i_flags = (char*)0L;
|
||||
opt_version = 0;
|
||||
|
||||
/* init xerr */
|
||||
xerr_setid(argv[0]);
|
||||
|
||||
while ((i = getopt(argc, argv, "c:C:hf:F:H:I:?k:m:no:s:S:t:u:w:v")) != -1) {
|
||||
while ((i = getopt_long(argc, argv, "c:C:hf:F:H:I:?k:l:m:no:s:S:t:u:w:vV:",
|
||||
longopts, (int*)0L)) != -1) {
|
||||
|
||||
switch (i) {
|
||||
|
||||
|
@ -110,6 +144,7 @@ int main (int argc, char **argv)
|
|||
u_count = strtoull(optarg, &endptr, 0);
|
||||
if (*endptr)
|
||||
xerr_errx(1, "strtoull(%s): failed at %c.", optarg, *endptr);
|
||||
u_count_set = 1;
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
|
@ -146,6 +181,12 @@ int main (int argc, char **argv)
|
|||
u_key_ascii = optarg;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
u_loc = optarg;
|
||||
if (strlen(u_loc) > OTP_USER_LOC_LEN)
|
||||
xerr_errx(1, "u_loc > OTP_USER_LOC_LEN");
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (mode)
|
||||
xerr_errx(1, "mode previously set.");
|
||||
|
@ -166,6 +207,8 @@ int main (int argc, char **argv)
|
|||
mode = MODE_LOAD;
|
||||
} else if (!strcasecmp(optarg, "remove")) {
|
||||
mode = MODE_REMOVE;
|
||||
} else if (!strcasecmp(optarg, "send-token")) {
|
||||
mode = MODE_SEND_TOKEN;
|
||||
} else if (!strcasecmp(optarg, "set-count")) {
|
||||
mode = MODE_SET_COUNT;
|
||||
} else if (!strcasecmp(optarg, "set-count-ceil")) {
|
||||
|
@ -174,6 +217,8 @@ int main (int argc, char **argv)
|
|||
mode = MODE_SET_FLAGS;
|
||||
} else if (!strcasecmp(optarg, "set-format")) {
|
||||
mode = MODE_SET_FORMAT;
|
||||
} else if (!strcasecmp(optarg, "set-location")) {
|
||||
mode = MODE_SET_LOCATION;
|
||||
} else if (!strcasecmp(optarg, "set-status")) {
|
||||
mode = MODE_SET_STATUS;
|
||||
} else if (!strcasecmp(optarg, "set-type")) {
|
||||
|
@ -221,6 +266,10 @@ int main (int argc, char **argv)
|
|||
verbose = 1;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
service = optarg;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
|
@ -230,6 +279,17 @@ int main (int argc, char **argv)
|
|||
window = atoi(optarg);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if (opt_version) {
|
||||
printf("%s\n", ootp_version);
|
||||
exit(0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
xerr_errx(1, "getopt_long(): fatal.");
|
||||
break; /* not reached */
|
||||
|
||||
} /* switch */
|
||||
|
||||
} /* while */
|
||||
|
@ -272,6 +332,9 @@ int main (int argc, char **argv)
|
|||
if ((mode == MODE_SET_STATUS) && (!i_status))
|
||||
xerr_errx(1, "Status value not specified.");
|
||||
|
||||
if ((mode == MODE_SET_LOCATION) && (!u_loc))
|
||||
xerr_errx(1, "Location value not specified.");
|
||||
|
||||
/* type */
|
||||
if (i_type)
|
||||
if (str_find8(otp_type_l, &u_type, i_type, 1, OTP_TYPE_MAX))
|
||||
|
@ -334,7 +397,7 @@ int main (int argc, char **argv)
|
|||
|
||||
if (mode == MODE_ADD) {
|
||||
printf("Adding user %s.\n", u_username);
|
||||
if (otp_user_add(otpctx, u_username, u_key160, OTP_HOTP_KEY_SIZE,
|
||||
if (otp_user_add(otpctx, u_username, u_loc, u_key160, OTP_HOTP_KEY_SIZE,
|
||||
u_count, u_count_ceil, u_status, u_type, u_format, u_version))
|
||||
xerr_errx(1, "otp_user_add(): failed.");
|
||||
goto mode_done;
|
||||
|
@ -343,10 +406,16 @@ int main (int argc, char **argv)
|
|||
if (mode == MODE_REMOVE) {
|
||||
printf("Removing user %s.\n", u_username);
|
||||
if (otp_user_rm(otpctx, u_username) < 0)
|
||||
xerr_errx(1, "ot_user_rm(): failed.");
|
||||
xerr_errx(1, "otp_user_rm(): failed.");
|
||||
goto mode_done;
|
||||
} /* MODE_REMOVE */
|
||||
|
||||
if (mode == MODE_SEND_TOKEN) {
|
||||
if (otp_user_send_token(otpctx, u_username, service) < 0)
|
||||
xerr_errx(1, "otp_user_send_token(): failed.");
|
||||
goto mode_done;
|
||||
} /* MODE_SEND_TOKEN */
|
||||
|
||||
/*
|
||||
* modes requiring open and get of user record:
|
||||
*/
|
||||
|
@ -355,6 +424,7 @@ int main (int argc, char **argv)
|
|||
(mode == MODE_LIST_SC) ||
|
||||
(mode == MODE_SET_COUNT) ||
|
||||
(mode == MODE_SET_COUNT_CEIL) ||
|
||||
(mode == MODE_SET_LOCATION) ||
|
||||
(mode == MODE_SET_FLAGS) ||
|
||||
(mode == MODE_SET_FORMAT) ||
|
||||
(mode == MODE_SET_STATUS) ||
|
||||
|
@ -408,6 +478,9 @@ int main (int argc, char **argv)
|
|||
|
||||
for (count_offset = 0; count_offset < window; ++count_offset) {
|
||||
|
||||
if (u_count_set == 1)
|
||||
ou.count = u_count;
|
||||
|
||||
if (otp_urec_crsp(otpctx, &ou, count_offset, crsp_tmp, 11) < 0)
|
||||
xerr_errx(1, "otp_urec_crsp(): failed.");
|
||||
|
||||
|
@ -422,6 +495,7 @@ int main (int argc, char **argv)
|
|||
if ((mode == MODE_SET_COUNT) ||
|
||||
(mode == MODE_SET_COUNT_CEIL) ||
|
||||
(mode == MODE_SET_FLAGS) ||
|
||||
(mode == MODE_SET_LOCATION) ||
|
||||
(mode == MODE_SET_FORMAT) ||
|
||||
(mode == MODE_SET_STATUS) ||
|
||||
(mode == MODE_SET_TYPE)) {
|
||||
|
@ -438,6 +512,10 @@ int main (int argc, char **argv)
|
|||
ou.status = u_status;
|
||||
else if (mode == MODE_SET_TYPE)
|
||||
ou.type = u_type;
|
||||
else if (mode == MODE_SET_LOCATION) {
|
||||
strncpy(ou.loc, u_loc, sizeof(ou.loc));
|
||||
ou.loc[sizeof(ou.loc)-1] = 0;
|
||||
}
|
||||
|
||||
if (otp_urec_put(otpctx, &ou) < 0)
|
||||
xerr_errx(1, "otp_urec_put(): failed.");
|
||||
|
@ -473,15 +551,17 @@ mode_done:
|
|||
|
||||
void help(void)
|
||||
{
|
||||
extern char *ootp_version;
|
||||
int i;
|
||||
|
||||
fprintf(stderr, "otp-control [-?hnv] [-c count] [-C count_ceil] [-f format] [-F flags]\n");
|
||||
fprintf(stderr, " [-H sc_hostname] [-I sc_index] [-k key] [-m command_mode]\n");
|
||||
fprintf(stderr, " [-o otbdb_pathname] [-s status] [-S sc_flags] [ -t type]\n");
|
||||
fprintf(stderr, " [-u username] [-w window]\n");
|
||||
fprintf(stderr, " -h : help\n");
|
||||
fprintf(stderr, " -n : create database\n");
|
||||
fprintf(stderr, " -v : enable verbose output\n\n");
|
||||
fprintf(stderr, "otp-control [-?hnv] [-c count] [-C count_ceil] [-f format] [-F flag]\n");
|
||||
fprintf(stderr, " [-H sc_hostname] [-I sc_index] [-k key] [-l location]\n");
|
||||
fprintf(stderr, " [-m command_mode] [-o otbdb_pathname] [-s status] [-S sc_flags] [-V service]\n");
|
||||
fprintf(stderr, " [-t type] [-u username] [-w window]\n");
|
||||
fprintf(stderr, " -h : help\n");
|
||||
fprintf(stderr, " -n : create database\n");
|
||||
fprintf(stderr, " -v : enable verbose output\n");
|
||||
fprintf(stderr, " --version : build version\n\n");
|
||||
fprintf(stderr, " sc_flags : 0=CHALLENGE 1=READERKEY\n");
|
||||
|
||||
fprintf(stderr, " flags : ");
|
||||
|
@ -515,6 +595,7 @@ void help(void)
|
|||
fprintf(stderr, " list-sc - List user record (SC friendly)\n");
|
||||
fprintf(stderr, " load - ASCII load user record(s)\n");
|
||||
fprintf(stderr, " remove - Remove user\n");
|
||||
fprintf(stderr, " send-token - Send token to user\n");
|
||||
fprintf(stderr, " set-count - Set user count\n");
|
||||
fprintf(stderr, " set-count-ceil - Set user count ceiling\n");
|
||||
fprintf(stderr, " set-flags - Set user flags\n");
|
||||
|
@ -522,6 +603,7 @@ void help(void)
|
|||
fprintf(stderr, " set-status - Set user status\n");
|
||||
fprintf(stderr, " set-type - Set user OTP type\n");
|
||||
fprintf(stderr, " test - Test user\n");
|
||||
printf("%s\n", ootp_version);
|
||||
}
|
||||
|
||||
int get_random(char *dev, unsigned char *entropy, int bits)
|
||||
|
@ -548,3 +630,4 @@ int get_random(char *dev, unsigned char *entropy, int bits)
|
|||
return 0;
|
||||
|
||||
} /* get_random */
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile 13 2009-11-26 16:37:03Z maf $
|
||||
# $Id: Makefile 133 2010-06-15 14:30:14Z maf $
|
||||
|
||||
what:
|
||||
@echo
|
||||
|
@ -22,22 +22,28 @@ INSTALL=install -c -m0755
|
|||
|
||||
.c.o:; $(CC) $(CFLAGS) -c $*.c -o $*.o
|
||||
|
||||
OBJS = ../common/xerr.o ../common/str.o ../common/otplib.o ../common/ffdb.o
|
||||
BIN = otp-ov-plugin
|
||||
COBJS = ../common/xerr.o ../common/str.o ../common/otplib.o ../common/ffdb.o
|
||||
OBJS = version.o ${BIN}.o
|
||||
|
||||
BINS = otp-ov-plugin
|
||||
|
||||
BINDIR=/usr/local/ootp/bin
|
||||
|
||||
all: otp-ov-plugin.c ${OBJS} ${BINS}
|
||||
all: version ${COBJS} ${OBJS} ${BIN}
|
||||
|
||||
version:
|
||||
rm -f version.c; ../build/version ../VERSION ${BIN} > version.c
|
||||
|
||||
version.c:
|
||||
|
||||
install:
|
||||
mkdir -p ${BINDIR}
|
||||
${INSTALL} ${BINS} ${BINDIR}
|
||||
${INSTALL} ${BIN} ${BINDIR}
|
||||
@echo files installed in ${BINDIR}
|
||||
|
||||
clean:
|
||||
/bin/rm -f ${BINS} otp-ov-plugin.o
|
||||
/bin/rm -f ${BIN} ${OBJS} version.c
|
||||
|
||||
otp-ov-plugin: ${OBJS} otp-ov-plugin.o
|
||||
$(CC) $(CFLAGS) $(LFLAGS) $(INC) -o otp-ov-plugin ${OBJS} otp-ov-plugin.o $(LIBS)
|
||||
${BIN}: ${COBJS} ${OBJS}
|
||||
$(CC) $(CFLAGS) $(LFLAGS) $(INC) -o ${BIN} ${COBJS} ${OBJS} $(LIBS)
|
||||
|
||||
|
|
|
@ -24,14 +24,15 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: otp-ov-plugin.c 50 2009-12-15 01:37:19Z maf $
|
||||
* $Id: otp-ov-plugin.c 177 2011-05-16 02:37:28Z maf $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
#include "ffdb.h"
|
||||
#include "otplib.h"
|
||||
#include "xerr.h"
|
||||
|
@ -40,10 +41,24 @@ void help(void);
|
|||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
extern char *ootp_version;
|
||||
struct otp_ctx *otpctx;
|
||||
struct otp_user ou;
|
||||
u_long tmpul;
|
||||
char *otpdb_fname, *username, *pass, *endptr;
|
||||
int db_flags, i, r, ret, otp_window;
|
||||
char *otpdb_fname, *username, *pass, *endptr, *service;
|
||||
int db_flags, i, r, ret, otp_window, opt_version, otp_allow_unknown;
|
||||
|
||||
struct option longopts[] = {
|
||||
{ "otp-allow-unknown-user", 0, (void*)0L, 'u'},
|
||||
{ "help", 0, (void*)0L, 'h'},
|
||||
{ "help", 0, (void*)0L, '?'},
|
||||
{ "otp-db", 1, (void*)0L, 'o'},
|
||||
{ "verbose", 0, (void*)0L, 'v'},
|
||||
{ "service-name", 0, (void*)0L, 'V'},
|
||||
{ "otp-challenge-window", 1, (void*)0L, 'w'},
|
||||
{ "version", 0, &opt_version, 1},
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
/* init xerr */
|
||||
xerr_setid(argv[0]);
|
||||
|
@ -51,12 +66,17 @@ int main (int argc, char **argv)
|
|||
otpdb_fname = OTP_DB_FNAME;
|
||||
db_flags = 0;
|
||||
otp_window = OTP_WINDOW_DEFAULT;
|
||||
opt_version = 0;
|
||||
otp_allow_unknown = 0;
|
||||
service = "otp-openvpn";
|
||||
bzero(&ou, sizeof(ou));
|
||||
ret = -1; /* fail */
|
||||
|
||||
while ((i = getopt(argc, argv, "h?o:vw:")) != -1) {
|
||||
while ((i = getopt_long(argc, argv, "h?o:uvV:w:", longopts,
|
||||
(int*)0L)) != -1) {
|
||||
|
||||
switch (i) {
|
||||
|
||||
switch (i) {
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
help();
|
||||
|
@ -66,10 +86,18 @@ int main (int argc, char **argv)
|
|||
otpdb_fname = optarg;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
otp_allow_unknown = 1;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
db_flags |= OTP_DB_VERBOSE;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
service = optarg;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
tmpul = strtoul(optarg, &endptr, 0);
|
||||
if (*endptr)
|
||||
|
@ -79,9 +107,16 @@ int main (int argc, char **argv)
|
|||
otp_window = tmpul;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if (opt_version) {
|
||||
printf("%s\n", ootp_version);
|
||||
exit(0);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
help();
|
||||
exit(1);
|
||||
xerr_errx(1, "getopt_long(): fatal.");
|
||||
break; /* not reached */
|
||||
|
||||
} /* switch */
|
||||
|
||||
|
@ -99,8 +134,39 @@ int main (int argc, char **argv)
|
|||
if ((r = otp_user_exists(otpctx, username)) < 0)
|
||||
xerr_errx(1, "otp_user_exists(): failed.");
|
||||
|
||||
if ((r == 1) && (otp_allow_unknown == 0)) {
|
||||
|
||||
xerr_info("OTP_AUTH_FAIL via otp_user_exists() allow_unknown=0");
|
||||
ret = 1;
|
||||
goto done;
|
||||
|
||||
}
|
||||
|
||||
if ((r == 1) && (otp_allow_unknown == 1)) {
|
||||
|
||||
xerr_info("OTP_AUTH_PASS via unknown user and allow_unknown=1");
|
||||
ret = 0;
|
||||
goto done;
|
||||
|
||||
}
|
||||
|
||||
if (r != 0)
|
||||
xerr_errx(1, "User %s does not exist in otp database.", username);
|
||||
|
||||
if (otp_urec_open(otpctx, username, &ou, O_RDONLY,
|
||||
FFDB_OP_LOCK_EX) < 0)
|
||||
xerr_errx(1, "otp_urec_open(%s): failed.", username);
|
||||
|
||||
if (otp_urec_get(otpctx, &ou) < 0)
|
||||
xerr_errx(1, "otp_urec_get(): failed.");
|
||||
|
||||
if (otp_urec_close(otpctx, &ou) < 0)
|
||||
xerr_errx(1, "otp_urec_close(): failed.");
|
||||
|
||||
if (ou.flags & OTP_FLAGS_SEND_TOKEN) {
|
||||
if (otp_user_send_token(otpctx, username, service) < 0)
|
||||
xerr_warnx("otp_user_send_token(): failed.");
|
||||
}
|
||||
|
||||
if ((r = otp_user_auth(otpctx, username, pass, otp_window)) < 0)
|
||||
xerr_errx(1, "otp_user_auth(): failed.");
|
||||
|
@ -110,15 +176,15 @@ int main (int argc, char **argv)
|
|||
|
||||
/* convert otp auth status to openvpn auth return code space */
|
||||
if (r == OTP_AUTH_PASS) {
|
||||
if (db_flags & OTP_DB_VERBOSE)
|
||||
xerr_info("OTP_AUTH_PASS");
|
||||
xerr_info("OTP_AUTH_PASS");
|
||||
ret = 0;
|
||||
} else {
|
||||
if (db_flags & OTP_DB_VERBOSE)
|
||||
xerr_info("OTP_AUTH_FAIL");
|
||||
xerr_info("OTP_AUTH_FAIL");
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
return ret;
|
||||
|
||||
} /* main.c */
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: pam_otp.c 56 2009-12-17 02:08:05Z maf $
|
||||
* $Id: pam_otp.c 168 2011-05-11 04:03:38Z maf $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -79,9 +79,10 @@ struct opts {
|
|||
int expose_account;
|
||||
int display_count;
|
||||
int allow_inactive;
|
||||
int require_db_entry;
|
||||
int allow_unknown;
|
||||
int otp_window;
|
||||
char *otpdb_fname;
|
||||
char *service;
|
||||
};
|
||||
|
||||
void load_opts(struct opts *opts, int argc, const char **argv);
|
||||
|
@ -99,10 +100,11 @@ int pam_sm_authenticate(pam_handle_t *ph, int flags, int argc,
|
|||
struct opts opts;
|
||||
int r, ret, otpdb_flags;
|
||||
const char *user;
|
||||
char message[64];
|
||||
char message[64], *cs;
|
||||
|
||||
ppam_msg = &pam_msg;
|
||||
bzero(&pam_msg, sizeof (pam_msg));
|
||||
bzero(&opts, sizeof opts);
|
||||
pam_conv = 0L;
|
||||
pam_resp = 0L;
|
||||
ret = PAM_SERVICE_ERR;
|
||||
|
@ -146,15 +148,27 @@ int pam_sm_authenticate(pam_handle_t *ph, int flags, int argc,
|
|||
*
|
||||
*/
|
||||
if (r == 1) {
|
||||
if (!opts.require_db_entry)
|
||||
if (opts.allow_unknown) {
|
||||
ret = PAM_SUCCESS;
|
||||
else
|
||||
xerr_info("%s: user=%s pass otp_user_exists() allow_unknown=1",
|
||||
pam_strerror(ph, ret), user);
|
||||
} else {
|
||||
ret = PAM_AUTH_ERR;
|
||||
xerr_info("%s: user=%s not in OTP db", pam_strerror(ph, ret), user);
|
||||
xerr_info("%s: user=%s via otp_user_exists() allow_unknown=0",
|
||||
pam_strerror(ph, ret), user);
|
||||
}
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* unknown response from otp_user_exists()
|
||||
*/
|
||||
if (r != 0) {
|
||||
xerr_warnx("otp_user_exists() unknown response r=%d", r);
|
||||
ret = PAM_SERVICE_ERR;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* get otp user record */
|
||||
if (otp_urec_open(otpctx, (char*)user, &ou, O_RDONLY, FFDB_OP_LOCK_EX) < 0) {
|
||||
xerr_warnx("otp_urec_open(%s): failed.", user);
|
||||
ret = PAM_SERVICE_ERR;
|
||||
|
@ -212,11 +226,25 @@ int pam_sm_authenticate(pam_handle_t *ph, int flags, int argc,
|
|||
pam_msg.msg_style = PAM_PROMPT_ECHO_ON;
|
||||
pam_msg.msg = (char *)&message;
|
||||
|
||||
/* send token to user? */
|
||||
if (ou.flags & OTP_FLAGS_SEND_TOKEN) {
|
||||
|
||||
cs = "HOTP Sent";
|
||||
|
||||
if (otp_user_send_token(otpctx, (char*)user, opts.service) < 0)
|
||||
xerr_warnx("otp_user_send_token(): failed.");
|
||||
|
||||
} else {
|
||||
|
||||
cs = "HOTP Challenge";
|
||||
|
||||
} /* OTP_FLAGS_SEND_TOKEN */
|
||||
|
||||
/* prompt for challenge with optional count */
|
||||
if (opts.display_count || (ou.flags & OTP_FLAGS_DSPCNT))
|
||||
sprintf(message, "HOTP Challenge (%" PRIu64 "): ", ou.count);
|
||||
snprintf(message, sizeof(message), "%s (%" PRIu64 "): ", cs, ou.count);
|
||||
else
|
||||
sprintf(message, "HOTP Challenge: ");
|
||||
snprintf(message, sizeof(message), "%s: ", cs);
|
||||
|
||||
/* use application conversation function to ask for challenge */
|
||||
if (pam_conv->conv(1, &ppam_msg, &pam_resp, pam_conv->appdata_ptr)
|
||||
|
@ -331,6 +359,7 @@ void load_opts(struct opts *opts, int argc, const char **argv)
|
|||
bzero(opts, sizeof *opts);
|
||||
opts->otpdb_fname = OTP_DB_FNAME;
|
||||
opts->otp_window = OTP_WINDOW_DEFAULT;
|
||||
opts->service = "pam";
|
||||
|
||||
/* foreach argument */
|
||||
while (argc--) {
|
||||
|
@ -348,9 +377,13 @@ void load_opts(struct opts *opts, int argc, const char **argv)
|
|||
} else if (!strcmp(*argv, "allow_inactive")) {
|
||||
opts->allow_inactive = 1;
|
||||
} else if (!strcmp(*argv, "require_db_entry")) {
|
||||
opts->require_db_entry = 1;
|
||||
opts->allow_unknown = 0;
|
||||
} else if (!strcmp(*argv, "allown_unknown")) {
|
||||
opts->allow_unknown = 1;
|
||||
} else if (!strncmp(*argv, "otpdb=", 6)) {
|
||||
opts->otpdb_fname=(char*)(*argv)+6;
|
||||
} else if (!strncmp(*argv, "service=", 8)) {
|
||||
opts->service=(char*)(*argv)+8;
|
||||
} else if (!strncmp(*argv, "window=", 7)) {
|
||||
tmpul = strtoul(optarg, &endptr, 0);
|
||||
if (*endptr)
|
||||
|
@ -366,10 +399,10 @@ void load_opts(struct opts *opts, int argc, const char **argv)
|
|||
}
|
||||
|
||||
if (opts->debug) {
|
||||
xerr_info("use_first_pass=%d, try_first_pass=%d, expose_account=%d, display_count=%d, allow_inactive=%d, require_db_entry=%d, otpdb=%s",
|
||||
xerr_info("use_first_pass=%d, try_first_pass=%d, expose_account=%d, display_count=%d, allow_inactive=%d, allow_unknown=%d, otpdb=%s service=%s",
|
||||
opts->use_first_pass, opts->use_first_pass, opts->expose_account,
|
||||
opts->display_count, opts->allow_inactive, opts->require_db_entry,
|
||||
opts->otpdb_fname);
|
||||
opts->display_count, opts->allow_inactive, opts->allow_unknown,
|
||||
opts->otpdb_fname, opts->service);
|
||||
}
|
||||
|
||||
} /* load_opts */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile 13 2009-11-26 16:37:03Z maf $
|
||||
# $Id: Makefile 130 2010-06-15 14:26:10Z maf $
|
||||
|
||||
what:
|
||||
@echo
|
||||
|
@ -25,22 +25,28 @@ INSTALL=install -c -m0755
|
|||
|
||||
.c.o:; $(CC) $(CFLAGS) -c $*.c -o $*.o
|
||||
|
||||
OBJS = ../common/xerr.o ../common/str.o ../common/acr30.o ../common/scr.o ../common/sccmd.o
|
||||
BIN = otp-sca
|
||||
COBJS = ../common/xerr.o ../common/str.o ../common/acr30.o ../common/scr.o ../common/sccmd.o
|
||||
OBJS = version.o ${BIN}.o
|
||||
|
||||
BINS = otp-sca
|
||||
|
||||
BINDIR=/usr/local/ootp/bin
|
||||
|
||||
all: otp-sca.c ${OBJS} ${BINS}
|
||||
all: version ${COBJS} ${OBJS} ${BIN}
|
||||
|
||||
version:
|
||||
rm -f version.c; ../build/version ../VERSION ${BIN} > version.c
|
||||
|
||||
version.c:
|
||||
|
||||
install:
|
||||
mkdir -p ${BINDIR}
|
||||
${INSTALL} ${BINS} ${BINDIR}
|
||||
${INSTALL} ${BIN} ${BINDIR}
|
||||
@echo files installed in ${BINDIR}
|
||||
|
||||
clean:
|
||||
/bin/rm -f ${BINS} otp-sca.o
|
||||
/bin/rm -f ${BIN} ${OBJS} version.c
|
||||
|
||||
otp-sca: ${OBJS} otp-sca.o
|
||||
$(CC) $(CFLAGS) $(LFLAGS) $(INC) -o otp-sca ${OBJS} otp-sca.o $(LIBS)
|
||||
${BIN}: ${OBJS} ${COBJS}
|
||||
$(CC) $(CFLAGS) $(LFLAGS) $(INC) -o ${BIN} ${COBJS} ${OBJS} $(LIBS)
|
||||
|
||||
|
|
|
@ -24,13 +24,14 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: otp-sca.c 88 2009-12-28 00:12:01Z maf $
|
||||
* $Id: otp-sca.c 144 2010-10-19 02:05:40Z maf $
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
#include <getopt.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -115,9 +116,10 @@ static int debug;
|
|||
/* XXX many of these +1 LEN's are not necessary */
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
extern char *ootp_version;
|
||||
struct scr_ctx *scrctx;
|
||||
int i, j, k, r, mode, sc_idx_set, j_start, j_end, done, sc_idx_tmp, opt_mod;
|
||||
int no_PIN, list_readers;
|
||||
int no_PIN, list_readers, opt_version;
|
||||
uint32_t tmp_count, tmp_cap, tmp32u;
|
||||
uint64_t tmp64u;
|
||||
char sc_hostname[SC_HOSTNAME_LEN+1], sc_PIN[SC_PIN_LEN+1];
|
||||
|
@ -136,6 +138,25 @@ int main(int argc, char **argv)
|
|||
char *adminkey_hex160_fname, *endptr, *err_msg, *username, *reader;
|
||||
char *readerkey_hex40_fname;
|
||||
|
||||
struct option longopts[] = {
|
||||
{ "sc-admin-key", 1, (void*)0L, 'a'},
|
||||
{ "sc-count", 1, (void*)0L, 'c'},
|
||||
{ "debug", 1, (void*)0L, 'd'},
|
||||
{ "help", 0, (void*)0L, 'h'},
|
||||
{ "help", 0, (void*)0L, '?'},
|
||||
{ "sc-index", 1, (void*)0L, 'i'},
|
||||
{ "list-readers", 0, (void*)0L, 'l'},
|
||||
{ "sc-command", 1, (void*)0L, 'm'},
|
||||
{ "sc-command-modifier", 1, (void*)0L, 'M'},
|
||||
{ "no-pin", 0, (void*)0L, 'p'},
|
||||
{ "reader", 1, (void*)0L, 'r'},
|
||||
{ "sc-reader-key", 1, (void*)0L, 'R'},
|
||||
{ "sc-username", 1, (void*)0L, 'u'},
|
||||
{ "sc-version", 1, (void*)0L, 'v'},
|
||||
{ "version", 0, &opt_version, 1},
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
/* init xerr */
|
||||
xerr_setid(argv[0]);
|
||||
|
||||
|
@ -144,6 +165,7 @@ int main(int argc, char **argv)
|
|||
mode = 0;
|
||||
opt_mod = 0;
|
||||
sc_idx_set = 0;
|
||||
opt_version = 0;
|
||||
adminkey_hex160_fname = (char*)0L;
|
||||
readerkey_hex40_fname = (char*)0L;
|
||||
sc_fv = 5;
|
||||
|
@ -173,7 +195,8 @@ int main(int argc, char **argv)
|
|||
bcopy(SC_PIN_DEFAULT, sc_newPIN, SC_PIN_LEN);
|
||||
bcopy(SC_ADMINKEY_DEFAULT, sc_adminkey, SC_ADMINKEY_LEN);
|
||||
|
||||
while ((i = getopt(argc, argv, "a:c:d:h?i:lm:M:pr:R:u:v:")) != -1) {
|
||||
while ((i = getopt_long(argc, argv, "a:c:d:h?i:lm:M:pr:R:u:v:", longopts,
|
||||
(int*)0L)) != -1) {
|
||||
|
||||
switch (i) {
|
||||
|
||||
|
@ -304,9 +327,18 @@ int main(int argc, char **argv)
|
|||
xerr_errx(1, "strtoul(%s): failed at %c.", optarg, *endptr);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if (opt_version) {
|
||||
printf("%s\n", ootp_version);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
default:
|
||||
xerr_errx(1, "getopt_long(): fatal.");
|
||||
|
||||
} /* switch */
|
||||
|
||||
} /* while getopt() */
|
||||
} /* while getopt_long() */
|
||||
|
||||
/* work to do? */
|
||||
if (!mode && !list_readers) {
|
||||
|
@ -579,6 +611,9 @@ int main(int argc, char **argv)
|
|||
if (tmp_cap & SC_CLEARALL_CAP)
|
||||
printf(" %s", SC_CLEARALL_STR);
|
||||
|
||||
if (tmp_cap & SC_SETREADERKEY_CAP)
|
||||
printf(" %s", SC_GETCAPABILITIES_STR);
|
||||
|
||||
printf("\n");
|
||||
|
||||
} else if (r == 1) {
|
||||
|
|
8
otp-sca/rfc.card
Normal file
8
otp-sca/rfc.card
Normal file
|
@ -0,0 +1,8 @@
|
|||
00:00000000:5246432d4845583430000000:3132333435363738393031323334353637383930
|
||||
01:00000000:5246432d4845583430000080:3132333435363738393031323334353637383930
|
||||
02:00000000:5246C32d4445432e36008000:3132333435363738393031323334353637383930
|
||||
03:00000000:5246C32d4445432e37008080:3132333435363738393031323334353637383930
|
||||
04:00000000:5246C32d4445432e38800000:3132333435363738393031323334353637383930
|
||||
05:00000000:5246C32d4445432e39800080:3132333435363738393031323334353637383930
|
||||
06:00000000:5246C32d4445432e41808000:3132333435363738393031323334353637383930
|
||||
07:00000000:5246432d4445583430808080:3132333435363738393031323334353637383930
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile 13 2009-11-26 16:37:03Z maf $
|
||||
# $Id: Makefile 131 2010-06-15 14:26:23Z maf $
|
||||
|
||||
what:
|
||||
@echo
|
||||
|
@ -25,22 +25,27 @@ INSTALL=install -c -m0755
|
|||
|
||||
.c.o:; $(CC) $(CFLAGS) -c $*.c -o $*.o
|
||||
|
||||
BIN = otp-sct
|
||||
OBJS = ../common/xerr.o ../common/str.o ../common/acr30.o ../common/scr.o ../common/sccmd.o
|
||||
|
||||
BINS = otp-sct
|
||||
COBJS = version.o ${BIN}.o
|
||||
|
||||
BINDIR=/usr/local/ootp/bin
|
||||
|
||||
all: otp-sct.c ${OBJS} ${BINS}
|
||||
all: version ${OBJS} ${BIN}
|
||||
|
||||
version:
|
||||
rm -f version.c; ../build/version ../VERSION ${BIN} > version.c
|
||||
|
||||
version.c:
|
||||
|
||||
install:
|
||||
mkdir -p ${BINDIR}
|
||||
${INSTALL} ${BINS} ${BINDIR}
|
||||
${INSTALL} ${BIN} ${BINDIR}
|
||||
@echo files installed in ${BINDIR}
|
||||
|
||||
clean:
|
||||
/bin/rm -f ${BINS} otp-sct.o
|
||||
/bin/rm -f ${BIN} otp-sct.o version.c
|
||||
|
||||
otp-sct: ${OBJS} otp-sct.o
|
||||
$(CC) $(CFLAGS) $(LFLAGS) $(INC) -o otp-sct ${OBJS} otp-sct.o $(LIBS)
|
||||
${BIN}: ${COBJS} ${OBJS}
|
||||
$(CC) $(CFLAGS) $(LFLAGS) $(INC) -o ${BIN} ${OBJS} ${COBJS} $(LIBS)
|
||||
|
||||
|
|
|
@ -24,13 +24,14 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: otp-sct.c 88 2009-12-28 00:12:01Z maf $
|
||||
* $Id: otp-sct.c 131 2010-06-15 14:26:23Z maf $
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/errno.h>
|
||||
#include <getopt.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -77,8 +78,9 @@ void help(void);
|
|||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
extern char *ootp_version;
|
||||
struct scr_ctx *scrctx;
|
||||
int i, j, k, r, sc_idx_set, sc_idx_tmp, j_start, j_end;
|
||||
int i, j, k, r, sc_idx_set, sc_idx_tmp, j_start, j_end, opt_version;
|
||||
int reset_pin, list_readers, list_version, get_hotp_version, list_hostnames;
|
||||
uint32_t tmp_count, tmp32u;
|
||||
uint64_t tmp64u;
|
||||
|
@ -90,9 +92,27 @@ int main(int argc, char **argv)
|
|||
u_char sc_fv;
|
||||
char *reader, *endptr, *err_msg;
|
||||
|
||||
struct option longopts[] = {
|
||||
{ "sc-get-hotp-v1", 0, (void*)0L, '1'},
|
||||
{ "sc-count", 1, (void*)0L, 'c'},
|
||||
{ "debug", 1, (void*)0L, 'd'},
|
||||
{ "help", 0, (void*)0L, 'h'},
|
||||
{ "help", 0, (void*)0L, '?'},
|
||||
{ "sc-index", 1, (void*)0L, 'i'},
|
||||
{ "list-readers", 0, (void*)0L, 'l'},
|
||||
{ "sc-list-hostnames", 0, (void*)0L, 'L'},
|
||||
{ "sc-reset-pin", 0, (void*)0L, 'p'},
|
||||
{ "reader", 1, (void*)0L, 'r'},
|
||||
{ "sc-version", 1, (void*)0L, 'v'},
|
||||
{ "sc-list-version", 0, (void*)0L, 'V'},
|
||||
{ "version", 0, &opt_version, 1},
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
/* init xerr */
|
||||
xerr_setid(argv[0]);
|
||||
|
||||
opt_version = 0;
|
||||
sc_fv = 5;
|
||||
debug = 0;
|
||||
sc_idx_set = 0;
|
||||
|
@ -116,7 +136,8 @@ int main(int argc, char **argv)
|
|||
bcopy(SC_PIN_DEFAULT, sc_pin, SC_PIN_LEN);
|
||||
bcopy(SC_PIN_DEFAULT, sc_newpin, SC_PIN_LEN);
|
||||
|
||||
while ((i = getopt(argc, argv, "1c:d:hi:lLpr:v:V?")) != -1) {
|
||||
while ((i = getopt_long(argc, argv, "1c:d:hi:lLpr:v:V?", longopts,
|
||||
(int*)0L)) != -1) {
|
||||
|
||||
switch (i) {
|
||||
|
||||
|
@ -189,9 +210,18 @@ int main(int argc, char **argv)
|
|||
list_version = 1;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if (opt_version) {
|
||||
printf("%s\n", ootp_version);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
default:
|
||||
xerr_errx(1, "getopt_long(): fatal.");
|
||||
|
||||
} /* switch */
|
||||
|
||||
} /* while getopt() */
|
||||
} /* while getopt_long() */
|
||||
|
||||
/* get pin */
|
||||
if (!list_readers && !list_version) {
|
||||
|
|
50
otp-tokend/Makefile
Normal file
50
otp-tokend/Makefile
Normal file
|
@ -0,0 +1,50 @@
|
|||
# $Id: Makefile 129 2010-06-15 14:25:43Z maf $
|
||||
|
||||
what:
|
||||
@echo
|
||||
@echo "make hardware-systype"
|
||||
@echo
|
||||
@echo "This Makefile knows about the following"
|
||||
@echo
|
||||
@echo i386-fbsd i386-linux i386-macosx
|
||||
@echo
|
||||
|
||||
i386-fbsd:
|
||||
@make CC="gcc" CFLAGS="-I../common -g -DHAVE_STRING_H -DHAVE_STRINGS_H -DDEBUG -Wall -std=c99 -pedantic" LIBS="-lcurl" all
|
||||
|
||||
i386-linux:
|
||||
@make CC="gcc" CFLAGS="-I../common -g -DHAVE_STRING_H -DHAVE_STRINGS_H -DDEBUG -D_BSD_SOURCE -D_XOPEN_SOURCE -Wall -std=c99 -pedantic" LIBS="-lcurl " all
|
||||
|
||||
i386-macosx:
|
||||
@make CC="gcc" CFLAGS="-I../common -g -DHAVE_STRING_H -DHAVE_STRINGS_H -DDEBUG -Wall -std=c99 -pedantic" LIBS="-lcurl" all
|
||||
|
||||
INSTALL=install -c -m0755
|
||||
|
||||
.c.o:; $(CC) $(CFLAGS) $(INC) -c $*.c -o $*.o
|
||||
|
||||
BIN = otp-tokend
|
||||
COBJS = ../common/xerr.o
|
||||
OBJS = version.o ${BIN}.o
|
||||
LFLAGS = -L/usr/local/lib
|
||||
INC = -I/usr/local/include
|
||||
|
||||
BINDIR=/usr/local/ootp/bin
|
||||
|
||||
all: version ${COBJS} ${OBJS} ${BIN}
|
||||
|
||||
version:
|
||||
rm -f version.c; ../build/version ../VERSION ${BIN} > version.c
|
||||
|
||||
version.c:
|
||||
|
||||
install:
|
||||
mkdir -p ${BINDIR}
|
||||
${INSTALL} ${BIN} ${BINDIR}
|
||||
@echo files installed in ${BINDIR}
|
||||
|
||||
clean:
|
||||
/bin/rm -f ${BIN} ${OBJS} version.c
|
||||
|
||||
${BIN}: ${COBJS} ${OBJS}
|
||||
$(CC) $(CFLAGS) $(LFLAGS) $(INC) -o ${BIN} ${COBJS} ${OBJS} $(LIBS)
|
||||
|
360
otp-tokend/otp-tokend.c
Normal file
360
otp-tokend/otp-tokend.c
Normal file
|
@ -0,0 +1,360 @@
|
|||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <curl/curl.h>
|
||||
#include <ctype.h>
|
||||
#include "xerr.h"
|
||||
#include "otplib.h"
|
||||
|
||||
/* XXX usage
|
||||
* XXX man page
|
||||
*/
|
||||
|
||||
static u_long scan_ip(char *s);
|
||||
static void usage(void);
|
||||
static int write_pidfile(char *fname);
|
||||
|
||||
#define NXT_FIELD(V1,V2)\
|
||||
f = strsep(&c, "\n");\
|
||||
if (!f) {\
|
||||
xerr_warnx("parse rx_buf fail at %s", V1);\
|
||||
continue;\
|
||||
}\
|
||||
V2 = c;\
|
||||
|
||||
size_t curl_write_cb(void *ptr, size_t size, size_t nmemb, void *userdata);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
extern char *ootp_version;
|
||||
struct sockaddr_un rx_path;
|
||||
CURL *curl;
|
||||
char rx_buf[1024], *c, *f, *msg_svc, *msg_user, *msg_loc, *msg_token;
|
||||
char msg_buf[1024], post_buf[1024], *msg_ue, *loc_ue, *rx_pathname;
|
||||
char buf[1024], *pid_fname, *url;
|
||||
int rx_sock, len, verbose, opt_version, daemon_mode, buf_l, i;
|
||||
|
||||
struct option longopts[] = {
|
||||
{ "bind-path", 1, (void*)0L, 'b'},
|
||||
{ "disable-daemon-mode", 1, (void*)0L, 'D'},
|
||||
{ "help", 0, (void*)0L, 'h'},
|
||||
{ "help", 0, (void*)0L, '?'},
|
||||
{ "pidfile", 1, (void*)0L, 'P'},
|
||||
{ "url", 1, (void*)0L, 'u'},
|
||||
{ "verbose", 0, (void*)0L, 'v'},
|
||||
{ "version", 1, &opt_version, 1},
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
daemon_mode = 1;
|
||||
opt_version = 0;
|
||||
pid_fname = (char*)0L;
|
||||
url = (char*)0L;
|
||||
verbose = 0;
|
||||
xerr_setid(argv[0]);
|
||||
rx_pathname = OTP_SEND_TOKEN_PATHNAME;
|
||||
|
||||
while ((i = getopt_long(argc, argv, "b:Dh?P:u:v", longopts,
|
||||
(int*)0L)) != -1) {
|
||||
|
||||
switch (i) {
|
||||
|
||||
case 'b':
|
||||
rx_pathname = optarg;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
daemon_mode = 0;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
case '?':
|
||||
usage();
|
||||
exit(0);
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
pid_fname = optarg;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
url = optarg;
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
++verbose;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if (opt_version) {
|
||||
printf("%s\n", ootp_version);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
default:
|
||||
xerr_errx(1, "getopt_long(): fatal.");
|
||||
|
||||
} /* switch */
|
||||
|
||||
} /* while getopt_long() */
|
||||
|
||||
if (!url)
|
||||
xerr_errx(1, "url required.");
|
||||
|
||||
if (daemon_mode) {
|
||||
|
||||
xerr_setsyslog2(1); /* use syslog for output */
|
||||
|
||||
/* run in the background */
|
||||
if (daemon(0, 0) < 0)
|
||||
xerr_err(1, "dameon()");
|
||||
|
||||
} /* daemon_mode */
|
||||
|
||||
buf_l = snprintf(buf, sizeof(buf), "tokend start:");
|
||||
if (verbose > 1) {
|
||||
for (i = 0; i < argc; ++i)
|
||||
buf_l += snprintf(buf+buf_l, sizeof(buf)-buf_l, " %s", argv[i]);
|
||||
}
|
||||
xerr_info(buf);
|
||||
|
||||
bzero(&rx_path, sizeof (rx_path));
|
||||
rx_path.sun_family = AF_UNIX;
|
||||
if (strlen(rx_pathname) >= sizeof(rx_path.sun_path))
|
||||
xerr_errx(1, "rx_pathname too long.");
|
||||
strncpy(rx_path.sun_path, rx_pathname, sizeof(rx_path.sun_path));
|
||||
|
||||
/* construct pid file name */
|
||||
if (!pid_fname) {
|
||||
|
||||
if (strcmp(rx_pathname, OTP_SEND_TOKEN_PATHNAME)) {
|
||||
|
||||
snprintf(buf, sizeof(buf), "/var/run/otp-tokend.pid.%s",
|
||||
rx_pathname);
|
||||
|
||||
} else {
|
||||
|
||||
snprintf(buf, sizeof(buf), "/var/run/otp-tokend.pid");
|
||||
|
||||
}
|
||||
|
||||
pid_fname = (char*)&buf;
|
||||
|
||||
}
|
||||
|
||||
/* write out pidfile */
|
||||
if (write_pidfile(pid_fname) < 0)
|
||||
xerr_errx(1, "write_pidfile(%s): fatal", buf);
|
||||
|
||||
if (!(curl = curl_easy_init()))
|
||||
xerr_errx(1, "curl_easy_init()");
|
||||
|
||||
if ((rx_sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
|
||||
xerr_err(1, "socket()");
|
||||
|
||||
/* fail silently */
|
||||
umask(077);
|
||||
unlink(rx_pathname);
|
||||
|
||||
if (bind(rx_sock, (struct sockaddr*)&rx_path, sizeof(rx_path)) < 0)
|
||||
xerr_err(1, "bind(%s)", rx_pathname);
|
||||
|
||||
if (verbose > 1)
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
|
||||
if (curl_easy_setopt(curl, CURLOPT_URL, url) != CURLE_OK)
|
||||
xerr_errx(1, "curl_easy_setopt(url): failed.");
|
||||
|
||||
if (curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
|
||||
&curl_write_cb) != CURLE_OK)
|
||||
xerr_errx(1, "curl_easy_setopt(CURLOPT_WRITEFUNCTION): failed.");
|
||||
|
||||
while (1) {
|
||||
|
||||
if ((len = recv(rx_sock, &rx_buf, sizeof(rx_buf), 0)) < 0)
|
||||
xerr_err(1, "recv()");
|
||||
|
||||
if (len == 0) {
|
||||
xerr_warnx("rx_buf empty.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rx_buf[len - 1] != 0) {
|
||||
xerr_warnx("recv(): rx_buf not null terminated, skipping.");
|
||||
continue;
|
||||
}
|
||||
|
||||
c = rx_buf;
|
||||
|
||||
msg_svc = rx_buf;
|
||||
NXT_FIELD("msg_user", msg_user);
|
||||
NXT_FIELD("msg_loc", msg_loc);
|
||||
NXT_FIELD("msg_token", msg_token);
|
||||
|
||||
for (c = msg_token; *c; ++c)
|
||||
if (*c == '\n')
|
||||
*c = 0;
|
||||
|
||||
snprintf(msg_buf, sizeof(msg_buf), "%s: %s", msg_svc, msg_token);
|
||||
|
||||
if (!(msg_ue = curl_escape(msg_buf, 0))) {
|
||||
xerr_warnx("curl_escape(msg_buf): failed.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(loc_ue = curl_escape(msg_loc, 0))) {
|
||||
xerr_warnx("curl_escape(msg_loc): failed.");
|
||||
free(msg_ue);
|
||||
continue;
|
||||
}
|
||||
|
||||
snprintf(post_buf, sizeof(post_buf), "to=%s&msg=%s", loc_ue, msg_ue);
|
||||
|
||||
if (curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_buf) != CURLE_OK)
|
||||
xerr_errx(1, "curl_easy_setopt(CURLOPT_POSTFIELDS, %s): failed.",
|
||||
post_buf);
|
||||
|
||||
if (curl_easy_perform(curl) != CURLE_OK)
|
||||
xerr_warnx("1, curl_easy_perform(): failed.");
|
||||
|
||||
if (verbose > 1)
|
||||
xerr_info("msg_buf=%s", msg_buf);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
size_t curl_write_cb(void *ptr, size_t size, size_t nmemb, void *userdata)
|
||||
{
|
||||
char *c;
|
||||
c = malloc((size*nmemb)+1);
|
||||
bcopy(ptr, c, size*nmemb);
|
||||
c[size*nmemb] = 0;
|
||||
xerr_info(c);
|
||||
free(c);
|
||||
return size*nmemb;
|
||||
}
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* function: write_pidfile()
|
||||
*
|
||||
* Store proces ID in ASII to fname.
|
||||
*
|
||||
* returns: < 0 : fail
|
||||
* 0 : success
|
||||
*/
|
||||
int write_pidfile(char *fname)
|
||||
{
|
||||
int fd, buf_l;
|
||||
char buf[512];
|
||||
|
||||
buf_l = snprintf(buf, sizeof(buf), "%lu\n", (unsigned long)getpid());
|
||||
|
||||
if ((fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0 ) {
|
||||
xerr_warn("open(%s)", fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (write(fd, buf, buf_l) < 0) {
|
||||
xerr_warn("write(%s)", fname);
|
||||
close (fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (close(fd));
|
||||
|
||||
} /* write_pidfile */
|
||||
|
||||
/*
|
||||
* function: scan_ip
|
||||
*
|
||||
* IP address in string S is converted to a u_long
|
||||
* (borrowed from tcpdump)
|
||||
*
|
||||
* left shift any partial dotted quads, ie 10 is 0x0a000000 not 0x0a
|
||||
* so scan_ip_prefix() works for standard prefix notation, ie 10/8
|
||||
*/
|
||||
u_long scan_ip(char *s)
|
||||
{
|
||||
struct hostent *he;
|
||||
struct in_addr *ina;
|
||||
u_long addr = 0;
|
||||
uint n;
|
||||
int dns, shift;
|
||||
char *t;
|
||||
|
||||
/* if there is anything ascii in here, this may be a hostname */
|
||||
for (dns = 0, t = s; *t; ++t) {
|
||||
if (islower((int)*t) || isupper((int)*t)) {
|
||||
dns = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dns) {
|
||||
|
||||
if (!(he = gethostbyname(s)))
|
||||
goto numeric;
|
||||
|
||||
if (he->h_addrtype != AF_INET)
|
||||
goto numeric;
|
||||
|
||||
if (he->h_length != sizeof (uint32_t))
|
||||
goto numeric;
|
||||
|
||||
ina = (struct in_addr*)*he->h_addr_list;
|
||||
return (ntohl(ina->s_addr));
|
||||
|
||||
} /* dns */
|
||||
|
||||
shift = 0;
|
||||
|
||||
numeric:
|
||||
while (1) {
|
||||
|
||||
/* n is the nibble */
|
||||
n = 0;
|
||||
|
||||
/* nibble's are . bounded */
|
||||
while (*s && (*s != '.') && (*s != ' ') && (*s != '\t'))
|
||||
n = n * 10 + *s++ - '0';
|
||||
|
||||
/* shift in the nibble */
|
||||
addr <<=8;
|
||||
addr |= n & 0xff;
|
||||
++shift;
|
||||
|
||||
/* return on end of string */
|
||||
if ((!*s) || (*s == ' ') || (*s == '\t'))
|
||||
goto ndone;
|
||||
|
||||
/* skip the . */
|
||||
++s;
|
||||
} /* forever */
|
||||
|
||||
ndone:
|
||||
|
||||
for (; shift < 4; ++shift)
|
||||
addr <<=8;
|
||||
|
||||
return addr;
|
||||
|
||||
} /* scan_ip */
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/sh -e
|
||||
|
||||
# $Id: otpdb2sc 40 2009-12-01 16:28:53Z maf $
|
||||
# $Id: otpdb2sc 138 2010-06-15 15:34:14Z maf $
|
||||
|
||||
OTPCONTROL="otp-control"
|
||||
DDIR="/priv/HOTP"
|
||||
|
@ -17,7 +17,7 @@ fi
|
|||
if [ "X$3" = "X" ]; then
|
||||
FLAGS=""
|
||||
else
|
||||
FLAGS="-F$3"
|
||||
FLAGS="-S$3"
|
||||
fi
|
||||
|
||||
if [ ! -e $OTPDB ]; then
|
||||
|
@ -26,7 +26,7 @@ fi
|
|||
|
||||
touch $CARDF
|
||||
|
||||
idx=`wc -l $CARDF | awk '{print $1}`
|
||||
idx=`wc -l $CARDF | awk '{print $1}'`
|
||||
idx2=$idx
|
||||
if [ $idx -lt 10 ]; then
|
||||
idx2="0$idx"
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# $Id: Makefile 13 2009-11-26 16:37:03Z maf $
|
||||
# $Id: Makefile 101 2009-12-28 03:04:32Z maf $
|
||||
|
||||
INSTALLI=install -c -m0644
|
||||
INSTALL=install -c -m0755
|
||||
|
||||
IMGS = spyrus1.3.hex oar.ee oar.str
|
||||
IMGS = spyrus1.4.hex oar.ee oar.str
|
||||
BINS = str2ee
|
||||
DOCS = eeprom-map.txt oar.str
|
||||
|
||||
|
|
29
urd/Makefile
29
urd/Makefile
|
@ -1,4 +1,4 @@
|
|||
# $Id: Makefile 35 2009-11-30 21:49:59Z maf $
|
||||
# $Id: Makefile 155 2011-04-06 02:25:43Z maf $
|
||||
|
||||
what:
|
||||
@echo
|
||||
|
@ -10,34 +10,39 @@ what:
|
|||
@echo
|
||||
|
||||
i386-fbsd:
|
||||
@make CC="gcc" CFLAGS="-I../common -g -DOOTP_ENABLE -DHAVE_STRING_H -DHAVE_STRINGS_H -DDEBUG -Wall -std=c99 -pedantic" LIBS="-lssl -lcrypt" all
|
||||
@make CC="gcc" CFLAGS="-I../common -g -DOOTP_ENABLE -DHAVE_STRING_H -DHAVE_STRINGS_H -DDEBUG -Wall -std=c99 -pedantic" LIBS="-lssl -lcrypt -lpam" all
|
||||
|
||||
i386-linux:
|
||||
@make CC="gcc" CFLAGS="-I../common -g -DOOTP_ENABLE -DHAVE_STRING_H -DHAVE_STRINGS_H -DDEBUG -D_BSD_SOURCE -D_XOPEN_SOURCE -Wall -std=c99 -pedantic" LIBS="-lssl -lcrypt" all
|
||||
@make CC="gcc" CFLAGS="-I../common -g -DOOTP_ENABLE -DHAVE_STRING_H -DHAVE_STRINGS_H -DDEBUG -D_BSD_SOURCE -D_XOPEN_SOURCE -Wall -std=c99 -pedantic" LIBS="-lssl -lcrypt -lpam" all
|
||||
|
||||
i386-macosx:
|
||||
@make CC="gcc" CFLAGS="-I../common -g -DOOTP_ENABLE -DHAVE_STRING_H -DHAVE_STRINGS_H -DDEBUG -Wall -std=c99 -pedantic" LIBS="-lssl -lcrypto" all
|
||||
@make CC="gcc" CFLAGS="-I../common -g -DOOTP_ENABLE -DHAVE_STRING_H -DHAVE_STRINGS_H -DDEBUG -Wall -std=c99 -pedantic" LIBS="-lssl -lcrypto -lpam" all
|
||||
|
||||
INSTALL=install -c -m0755
|
||||
|
||||
.c.o:; $(CC) $(CFLAGS) -c $*.c -o $*.o
|
||||
|
||||
OBJS = pw.o rad.o ../common/xerr.o ../common/str.o ../common/otplib.o ../common/ffdb.o
|
||||
|
||||
BINS = urd
|
||||
BIN = urd
|
||||
COBJS = ../common/xerr.o ../common/str.o ../common/otplib.o ../common/ffdb.o
|
||||
OBJS = version.o ${BIN}.o pw.o rad.o fileio.o
|
||||
|
||||
BINDIR=/usr/local/ootp/bin
|
||||
|
||||
all: pw.c rad.c urd.c ${OBJS} ${BINS}
|
||||
all: version ${COBJS} ${OBJS} ${BIN}
|
||||
|
||||
version:
|
||||
rm -f version.c; ../build/version ../VERSION ${BIN} > version.c
|
||||
|
||||
version.c:
|
||||
|
||||
install:
|
||||
mkdir -p ${BINDIR}
|
||||
${INSTALL} ${BINS} ${BINDIR}
|
||||
${INSTALL} ${BIN} ${BINDIR}
|
||||
@echo files installed in ${BINDIR}
|
||||
|
||||
clean:
|
||||
/bin/rm -f ${BINS} urd.o pw.o rad.o
|
||||
/bin/rm -f ${BIN} ${COBJS}
|
||||
|
||||
urd: ${OBJS} urd.o
|
||||
$(CC) $(CFLAGS) $(LFLAGS) $(INC) -o urd ${OBJS} urd.o $(LIBS)
|
||||
urd: ${COBJS} ${OBJS}
|
||||
$(CC) $(CFLAGS) $(LFLAGS) $(INC) -o ${BIN} ${OBJS} ${COBJS} $(LIBS)
|
||||
|
||||
|
|
67
urd/fileio.c
Normal file
67
urd/fileio.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
#include "fileio.h"
|
||||
#include "xerr.h"
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
* load file into memory.
|
||||
*/
|
||||
char *file_load(char *fname)
|
||||
{
|
||||
struct stat sb;
|
||||
char *buf;
|
||||
int fd, ret, len;
|
||||
|
||||
ret = -1; /* fail */
|
||||
buf = (char*)0L;
|
||||
fd = -1; /* invalid */
|
||||
|
||||
/* open file */
|
||||
if ((fd = open(fname, O_RDONLY, 0)) < 0) {
|
||||
xerr_warn("open(%s)", fname);
|
||||
goto file_load_out;
|
||||
}
|
||||
|
||||
/* load metadata */
|
||||
if (fstat(fd, &sb) < 0) {
|
||||
xerr_warn("stat(%s)", fname);
|
||||
goto file_load_out;
|
||||
}
|
||||
|
||||
/* allocate storage for file contents + null */
|
||||
if (!(buf = malloc(sb.st_size+1))) {
|
||||
xerr_warn("malloc(%d)", (int)sb.st_size+1);
|
||||
goto file_load_out;
|
||||
}
|
||||
|
||||
/* read file contents */
|
||||
if ((len = read(fd, buf, sb.st_size)) < 0) {
|
||||
xerr_warn("read(%s)", fname);
|
||||
goto file_load_out;
|
||||
}
|
||||
|
||||
/* null terminate */
|
||||
buf[sb.st_size] = 0;
|
||||
|
||||
if (len != sb.st_size) {
|
||||
xerr_warnx("short read(%s)", fname);
|
||||
goto file_load_out;
|
||||
}
|
||||
|
||||
ret = 0; /* success */
|
||||
|
||||
file_load_out:
|
||||
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
|
||||
if ((ret == -1) && buf) {
|
||||
free(buf);
|
||||
buf = (char*)0L;
|
||||
}
|
||||
|
||||
return buf;
|
||||
|
||||
} /* file_load */
|
4
urd/fileio.h
Normal file
4
urd/fileio.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
|
||||
char *file_load(char *fname);
|
||||
|
557
urd/pw.c
557
urd/pw.c
|
@ -24,7 +24,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: pw.c 13 2009-11-26 16:37:03Z maf $
|
||||
* $Id: pw.c 155 2011-04-06 02:25:43Z maf $
|
||||
*/
|
||||
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
|||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <security/pam_appl.h>
|
||||
|
||||
#if HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
|
@ -42,11 +43,13 @@
|
|||
#endif
|
||||
|
||||
#include "pw.h"
|
||||
#include "str.h"
|
||||
#include "xerr.h"
|
||||
#include "fileio.h"
|
||||
|
||||
/*
|
||||
* Simple user authentication based on passwd file flat db with optional
|
||||
* authorized users file. Database is cached in memory. stat(pw_fname)
|
||||
* authorized users file. Database is cached in memory. stat(loc)
|
||||
* is performed in pass_db_auth() to trigger a pass_db_load() when the
|
||||
* filesystem database is newer than the memory cache. If this file
|
||||
* does not exist the existing in memory database is used.
|
||||
|
@ -67,7 +70,8 @@
|
|||
*
|
||||
* Usage:
|
||||
* pass_db_ctx_new() : initialize context
|
||||
* pass_db_ctx_free() : free resources associated with context
|
||||
* pass_db_ctx_free() : free all resources associated with context
|
||||
* pass_db_ctx_reset() : free username/password resources
|
||||
* pass_db_load() : load and parse password file to memory
|
||||
* pass_db_auth() : authenticate user_name/u_password pair.
|
||||
* may call pass_db_load()
|
||||
|
@ -78,6 +82,13 @@
|
|||
*
|
||||
*/
|
||||
|
||||
int pam_mem_conv (int pam_nmsg, const struct pam_message **pam_msgh,
|
||||
struct pam_response **pam_resph, void *pam_app_data);
|
||||
|
||||
static int pam_auth(char *user_name, char *user_pass, char *svc_name);
|
||||
|
||||
static char *global_user_pass;
|
||||
|
||||
/*
|
||||
* function: pass_db_ctx_new()
|
||||
*
|
||||
|
@ -91,7 +102,7 @@
|
|||
* returns < 0 : fail
|
||||
* 0 : success
|
||||
*/
|
||||
struct pass_db_ctx *pass_db_ctx_new(char *pw_fname, char *au_fname)
|
||||
struct pass_db_ctx *pass_db_ctx_new(char *loc, char *au_fname, int type)
|
||||
{
|
||||
struct pass_db_ctx *pdbctx;
|
||||
int i, ret;
|
||||
|
@ -105,12 +116,14 @@ struct pass_db_ctx *pass_db_ctx_new(char *pw_fname, char *au_fname)
|
|||
|
||||
bzero(pdbctx, sizeof *pdbctx);
|
||||
|
||||
if (!(pdbctx->pw_fname = (char*)malloc(strlen(pw_fname)+1))) {
|
||||
xerr_warn("malloc(%d)", strlen(pw_fname));
|
||||
pdbctx->type = type;
|
||||
|
||||
if (!(pdbctx->loc = (char*)malloc(strlen(loc)+1))) {
|
||||
xerr_warn("malloc(%d)", strlen(loc));
|
||||
goto pass_db_ctx_new_out;
|
||||
}
|
||||
|
||||
strcpy(pdbctx->pw_fname, pw_fname);
|
||||
strcpy(pdbctx->loc, loc);
|
||||
|
||||
if (au_fname) {
|
||||
|
||||
|
@ -143,25 +156,52 @@ pass_db_ctx_new_out:
|
|||
/*
|
||||
* function: pass_db_ctx_free()
|
||||
*
|
||||
* Release resources in pass_db allocated by pass_db_init(). Must
|
||||
* be called for each invocation of pass_db_init() to prevent resource
|
||||
* Release resources in pass_db allocated by pass_db_ctx_new(). Must
|
||||
* be called for each invocation of pass_db_ctx_new() to prevent resource
|
||||
* leak.
|
||||
*
|
||||
*/
|
||||
void pass_db_ctx_free(struct pass_db_ctx *pdbctx)
|
||||
{
|
||||
if (pdbctx) {
|
||||
if (pdbctx->pw_fname);
|
||||
free(pdbctx->pw_fname);
|
||||
if (pdbctx->loc)
|
||||
free(pdbctx->loc);
|
||||
if (pdbctx->au_fname)
|
||||
free(pdbctx->au_fname);
|
||||
if (pdbctx->pw_entries);
|
||||
if (pdbctx->pw_entries)
|
||||
free(pdbctx->pw_entries);
|
||||
bzero(pdbctx, sizeof (*pdbctx));
|
||||
free(pdbctx);
|
||||
}
|
||||
} /* pass_db_ctx_free */
|
||||
|
||||
/*
|
||||
* function: pass_db_ctx_reset()
|
||||
*
|
||||
* Release username/password resources from pass_db_ctx
|
||||
*
|
||||
*/
|
||||
void pass_db_ctx_reset(struct pass_db_ctx *pdbctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (pdbctx) {
|
||||
if (pdbctx->debug)
|
||||
xerr_info("pass_db_ctx_reset()");
|
||||
if (pdbctx->pw_entries) {
|
||||
bzero(pdbctx->pw_entries,
|
||||
pdbctx->num_entries * sizeof (struct pass_db_entry));
|
||||
pdbctx->num_entries = 0;
|
||||
free(pdbctx->pw_entries);
|
||||
}
|
||||
|
||||
for (i = 0; i < 1<<PASS_DB_HASH_BUCKET_BITS; ++i) {
|
||||
SLIST_INIT(&pdbctx->bucket[i]);
|
||||
}
|
||||
|
||||
}
|
||||
} /* pass_db_ctx_reset */
|
||||
|
||||
/*
|
||||
* function: pass_db_auth()
|
||||
*
|
||||
|
@ -170,11 +210,19 @@ void pass_db_ctx_free(struct pass_db_ctx *pdbctx)
|
|||
* If au_fname was set in pass_db_ctx_new() the user must first exist
|
||||
* in the authorized_users file else authentication will fail.
|
||||
*
|
||||
* Unix crypt() is used to compute a hash of u_pass for u_name
|
||||
* in pass_db. If the hash matches the stored hash the user is
|
||||
* authenticated.
|
||||
* type=LOCAL
|
||||
* Unix crypt() is used to compute a hash of u_pass for u_name
|
||||
* in pass_db. If the hash matches the stored hash the user is
|
||||
* authenticated.
|
||||
* type=EX_LOCAL
|
||||
* same as LOCAL, do not consult authorized_users
|
||||
* type=PAM
|
||||
* user must exist in local database, PAM is used for authentication
|
||||
* type=EX_PAM
|
||||
* PAM is used for authentication. Local password and authorized_users
|
||||
* file is not consulted.
|
||||
*
|
||||
* reload pw_fname if the file is newer. If pw_fname does not
|
||||
* reload loc if the file is newer. If loc does not
|
||||
* exist, then ignore. This allows an updated password file to
|
||||
* be linked into place avoiding race conditions of writing directly
|
||||
* to the active file.
|
||||
|
@ -188,23 +236,59 @@ int pass_db_auth(struct pass_db_ctx *pdbctx, char *u_name, char *u_pass)
|
|||
struct pass_db_entry *pwe;
|
||||
struct stat cur_sb;
|
||||
char *crypt_result;
|
||||
int ret;
|
||||
int ret, need_reload;
|
||||
|
||||
ret = PASS_DB_AUTH_FAIL;
|
||||
|
||||
/* load current passwd file metadata */
|
||||
if (stat(pdbctx->pw_fname, &cur_sb) < 0) {
|
||||
goto skip_reload;
|
||||
/* optimization when local database is not used */
|
||||
if (pdbctx->type == PASS_DB_TYPE_EX_PAM)
|
||||
goto skip_exists;
|
||||
|
||||
need_reload = 0;
|
||||
|
||||
/* check authorized users for update */
|
||||
if ((pdbctx->type == PASS_DB_TYPE_LOCAL) ||
|
||||
(pdbctx->type == PASS_DB_TYPE_PAM)) {
|
||||
|
||||
/* load current passwd file metadata */
|
||||
if (stat(pdbctx->au_fname, &cur_sb) < 0) {
|
||||
xerr_info("skipping reload, no %s", pdbctx->au_fname);
|
||||
goto skip_reload;
|
||||
}
|
||||
|
||||
/* passwd file updated? */
|
||||
if (cur_sb.st_mtime != pdbctx->au_sb.st_mtime) {
|
||||
xerr_info("reload on %s time", pdbctx->au_fname);
|
||||
need_reload = 1;
|
||||
}
|
||||
|
||||
} /* check for reload of au_fname */
|
||||
|
||||
/* check passwd file for updates */
|
||||
if ((pdbctx->type == PASS_DB_TYPE_LOCAL) ||
|
||||
(pdbctx->type == PASS_DB_TYPE_EX_LOCAL)) {
|
||||
|
||||
/* load current passwd file metadata */
|
||||
if (stat(pdbctx->loc, &cur_sb) < 0) {
|
||||
need_reload = 0;
|
||||
xerr_info("skipping reload, no %s", pdbctx->loc);
|
||||
goto skip_reload;
|
||||
}
|
||||
|
||||
/* passwd file updated? */
|
||||
if (cur_sb.st_mtime != pdbctx->pw_sb.st_mtime) {
|
||||
xerr_info("reload on %s time", pdbctx->loc);
|
||||
need_reload = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* passwd file updated? */
|
||||
if (cur_sb.st_mtime != pdbctx->pw_sb.st_mtime) {
|
||||
if (need_reload)
|
||||
pdbctx->state = PASS_DB_STATE_RELOAD;
|
||||
}
|
||||
|
||||
/* reload? then dispose of old state */
|
||||
if (pdbctx->state == PASS_DB_STATE_RELOAD) {
|
||||
pass_db_ctx_free(pdbctx);
|
||||
pass_db_ctx_reset(pdbctx);
|
||||
}
|
||||
|
||||
/* reload passwd database? */
|
||||
|
@ -221,29 +305,49 @@ skip_reload:
|
|||
/* hash lookup of user name */
|
||||
if (!(pwe = pass_db_u_name_lookup(pdbctx, u_name, strlen(u_name)))) {
|
||||
if (pdbctx->debug)
|
||||
xerr_info("pass_db_auth(%s): no such user");
|
||||
xerr_info("pass_db_auth(%s): no such user", u_name);
|
||||
goto pass_db_auth_out;
|
||||
}
|
||||
|
||||
if (pwe->status != PASS_DB_ENTRY_ACTIVE) {
|
||||
if (pdbctx->debug)
|
||||
xerr_info("pass_db_auth(%s): not active");
|
||||
xerr_info("pass_db_auth(%s): not active", u_name);
|
||||
goto pass_db_auth_out;
|
||||
}
|
||||
|
||||
crypt_result = crypt(u_pass, pwe->u_hash);
|
||||
skip_exists:
|
||||
|
||||
if (crypt_result) {
|
||||
if (!strcmp(pwe->u_hash, crypt_result)) {
|
||||
ret = PASS_DB_AUTH_SUCCESS;
|
||||
if (pdbctx->debug)
|
||||
xerr_info("pass_db_auth(%s): pass authentication");
|
||||
goto pass_db_auth_out;
|
||||
if ((pdbctx->type == PASS_DB_TYPE_LOCAL) ||
|
||||
(pdbctx->type == PASS_DB_TYPE_EX_LOCAL)) {
|
||||
|
||||
/* authenticate with local crypt() */
|
||||
crypt_result = crypt(u_pass, pwe->u_hash);
|
||||
|
||||
if (crypt_result) {
|
||||
if (!strcmp(pwe->u_hash, crypt_result)) {
|
||||
ret = PASS_DB_AUTH_SUCCESS;
|
||||
if (pdbctx->debug)
|
||||
xerr_info("pass_db_auth(%s): pass LOCAL authentication", u_name);
|
||||
goto pass_db_auth_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if ((pdbctx->type == PASS_DB_TYPE_PAM) ||
|
||||
(pdbctx->type == PASS_DB_TYPE_EX_PAM)) {
|
||||
|
||||
/* authenticate with PAM */
|
||||
ret = pam_auth(u_name, u_pass, pdbctx->loc);
|
||||
|
||||
if (ret == PASS_DB_AUTH_SUCCESS) {
|
||||
if (pdbctx->debug)
|
||||
xerr_info("pass_db_auth(%s): pass PAM authentication", u_name);
|
||||
goto pass_db_auth_out;
|
||||
}
|
||||
|
||||
} /* _PAM */
|
||||
|
||||
if (pdbctx->debug)
|
||||
xerr_info("pass_db_auth(%s): fail authentication");
|
||||
xerr_info("pass_db_auth(%s): fail authentication", u_name);
|
||||
|
||||
pass_db_auth_out:
|
||||
|
||||
|
@ -265,105 +369,124 @@ pass_db_auth_out:
|
|||
int pass_db_load(struct pass_db_ctx *pdbctx)
|
||||
{
|
||||
struct pass_db_entry *pwe;
|
||||
struct stat cur_sb;
|
||||
uint16_t u_hash, u_hash_mask;
|
||||
int au_fd, pw_fd, ret, len, i;
|
||||
char *pw_buf, *au_buf;
|
||||
int ret, i;
|
||||
char *pw_buf, *au_buf, *p_buf;
|
||||
char *p, *pwdb_u_name, *pwdb_u_hash, *au_name;
|
||||
uint pw_entry, lineno;
|
||||
uint pwdb_u_name_len, pwdb_u_hash_len, au_name_len;
|
||||
int status_default;
|
||||
int local_status_default, au_only, au_active;
|
||||
|
||||
ret = -1;
|
||||
|
||||
pw_fd = -1;
|
||||
au_fd = -1;
|
||||
|
||||
pw_buf = (char*)0L;
|
||||
au_buf = (char*)0L;
|
||||
|
||||
au_only = 0; /* authorized users without passwd */
|
||||
au_active = 0; /* load and process authorized_users */
|
||||
|
||||
/* optimization, PASS_DB_TYPE_EX_PAM does not require local resources */
|
||||
if (pdbctx->type == PASS_DB_TYPE_EX_PAM)
|
||||
return 0;
|
||||
|
||||
/* using authorized_users? */
|
||||
if ((pdbctx->type == PASS_DB_TYPE_PAM) ||
|
||||
(pdbctx->type == PASS_DB_TYPE_LOCAL)) {
|
||||
|
||||
au_active = 1;
|
||||
|
||||
if (!pdbctx->au_fname) {
|
||||
xerr_warnx("Authorized users file not defined");
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
}
|
||||
|
||||
/* username hash mask */
|
||||
u_hash_mask = (uint16_t)((1<<PASS_DB_HASH_BUCKET_BITS)-1);
|
||||
|
||||
/* if no authorized users file then status defaults to active */
|
||||
if (pdbctx->au_fname)
|
||||
status_default = PASS_DB_ENTRY_INACTIVE;
|
||||
else
|
||||
status_default = PASS_DB_ENTRY_ACTIVE;
|
||||
/*
|
||||
* status default is used when the password and authorized_users are
|
||||
* both active
|
||||
*/
|
||||
|
||||
/* load password database into memory */
|
||||
/* if using authorized users, then default to inactive */
|
||||
if (pdbctx->type == PASS_DB_TYPE_LOCAL)
|
||||
local_status_default = PASS_DB_ENTRY_INACTIVE;
|
||||
else if (pdbctx->type == PASS_DB_TYPE_EX_LOCAL)
|
||||
local_status_default = PASS_DB_ENTRY_ACTIVE;
|
||||
|
||||
/* open pw database */
|
||||
if ((pw_fd = open(pdbctx->pw_fname, O_RDONLY, 0)) < 0) {
|
||||
xerr_warn("open(%s)", pdbctx->pw_fname);
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
|
||||
/* load metadata */
|
||||
if (fstat(pw_fd, &pdbctx->pw_sb) < 0) {
|
||||
xerr_warn("stat(%s)", pdbctx->pw_fname);
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
/*
|
||||
* special case, PAM + authorized users: do not load passwd database,
|
||||
* only authorized_users.
|
||||
*/
|
||||
if (pdbctx->type == PASS_DB_TYPE_PAM) {
|
||||
|
||||
/* allocate storage for pw database */
|
||||
if (!(pw_buf = malloc(pdbctx->pw_sb.st_size+1))) {
|
||||
xerr_warn("malloc(%d)", (int)pdbctx->pw_sb.st_size+1);
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
au_only = 1;
|
||||
if (pdbctx->debug)
|
||||
xerr_info("pass_db_load(): PAM, loading authorized users only");
|
||||
|
||||
/* read in pw database */
|
||||
if ((len = read(pw_fd, pw_buf, pdbctx->pw_sb.st_size)) < 0) {
|
||||
xerr_warn("read(%s)", pdbctx->pw_fname);
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
} else {
|
||||
|
||||
if (len != pdbctx->pw_sb.st_size) {
|
||||
xerr_warnx("short read(%s)", pdbctx->pw_fname);
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
|
||||
/* load authorized_users file if configured into memory */
|
||||
|
||||
if (pdbctx->au_fname) {
|
||||
|
||||
/* open au database */
|
||||
if ((au_fd = open(pdbctx->au_fname, O_RDONLY, 0)) < 0) {
|
||||
xerr_warn("open(%s)", pdbctx->au_fname);
|
||||
/* load current passwd file metadata */
|
||||
if (stat(pdbctx->loc, &cur_sb) < 0) {
|
||||
xerr_warnx("stat(%s)", pdbctx->loc);
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
|
||||
/* load metadata */
|
||||
if (fstat(au_fd, &pdbctx->au_sb) < 0) {
|
||||
xerr_warn("stat(%s)", pdbctx->au_fname);
|
||||
|
||||
pdbctx->pw_sb = cur_sb;
|
||||
|
||||
|
||||
/* load password database into memory */
|
||||
if (!(pw_buf = file_load(pdbctx->loc))) {
|
||||
xerr_warnx("file_load(%s): failed", pdbctx->loc);
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
|
||||
/* allocate storage for au database */
|
||||
if (!(au_buf = malloc(pdbctx->au_sb.st_size+1))) {
|
||||
xerr_warn("malloc(%d)", (int)pdbctx->au_sb.st_size+1);
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
|
||||
/* read in au database */
|
||||
if ((len = read(au_fd, au_buf, pdbctx->au_sb.st_size)) < 0) {
|
||||
xerr_warn("read(%s)", pdbctx->au_fname);
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
|
||||
if (len != pdbctx->au_sb.st_size) {
|
||||
xerr_warnx("short read(%s)", pdbctx->au_fname);
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
|
||||
} /* pdbctx->au_fname */
|
||||
|
||||
/****/
|
||||
|
||||
/* count number of lines in the passwd file to predict malloc size */
|
||||
for (pdbctx->num_entries = 0, p = pw_buf; *p; ++p) {
|
||||
if (*p == '\n')
|
||||
++pdbctx->num_entries;
|
||||
}
|
||||
|
||||
/* load authorized_users file if configured */
|
||||
if (au_active == 1) {
|
||||
|
||||
/* load current authorized_users file metadata */
|
||||
if (stat(pdbctx->au_fname, &cur_sb) < 0) {
|
||||
xerr_warnx("stat(%s)", pdbctx->au_fname);
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
|
||||
|
||||
pdbctx->au_sb = cur_sb;
|
||||
|
||||
if (!(au_buf = file_load(pdbctx->au_fname))) {
|
||||
xerr_warnx("file_load(%s): failed", pdbctx->au_fname);
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
|
||||
} /* au_active */
|
||||
|
||||
if (au_only) {
|
||||
|
||||
/* count number of lines in authorized_users to predict malloc size */
|
||||
for (pdbctx->num_entries = 0, p = au_buf; *p; ++p) {
|
||||
if (*p == '\n')
|
||||
++pdbctx->num_entries;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* count number of lines in passwd file to predict malloc size */
|
||||
for (pdbctx->num_entries = 0, p = pw_buf; *p; ++p) {
|
||||
if (*p == '\n')
|
||||
++pdbctx->num_entries;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (pdbctx->debug)
|
||||
xerr_info("pass_db_load(): loading %d users", pdbctx->num_entries);
|
||||
|
||||
if (!(pdbctx->pw_entries = (struct pass_db_entry*)malloc(
|
||||
pdbctx->num_entries * sizeof (struct pass_db_entry)))) {
|
||||
xerr_warn("malloc(pw_entries)");
|
||||
|
@ -373,8 +496,14 @@ int pass_db_load(struct pass_db_ctx *pdbctx)
|
|||
bzero(pdbctx->pw_entries,
|
||||
pdbctx->num_entries * sizeof (struct pass_db_entry));
|
||||
|
||||
/* if only using authorized users passwd file parsing is skipped */
|
||||
if (au_only)
|
||||
p_buf = au_buf;
|
||||
else
|
||||
p_buf = pw_buf;
|
||||
|
||||
/* while more lines */
|
||||
for (p = pw_buf, lineno = 1, pw_entry = 0; *p; ++lineno, ++pw_entry) {
|
||||
for (p = p_buf, lineno = 1, pw_entry = 0; *p; ++lineno, ++pw_entry) {
|
||||
|
||||
/* maf:$1$<hash>::::: */
|
||||
/* note only u_name:<hash> is required */
|
||||
|
@ -389,11 +518,17 @@ int pass_db_load(struct pass_db_ctx *pdbctx)
|
|||
++p;
|
||||
break;
|
||||
}
|
||||
|
||||
/* only username if au_only */
|
||||
if (au_only)
|
||||
if ((*p == 0) || (*p == '\n'))
|
||||
break;
|
||||
|
||||
/* require minimum of u_name and password field */
|
||||
if ((*p == 0) || (*p == '\n')) {
|
||||
*p = 0; /* null terminate */
|
||||
xerr_warnx("pass_db_auth(%s): lineno=%d, parse error at %s",
|
||||
pdbctx->pw_fname, lineno, pwdb_u_name);
|
||||
pdbctx->loc, lineno, pwdb_u_name);
|
||||
ret = PASS_DB_AUTH_ERROR;
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
|
@ -402,18 +537,23 @@ int pass_db_load(struct pass_db_ctx *pdbctx)
|
|||
|
||||
} /* extract u_name */
|
||||
|
||||
/* hash of u_pass is next */
|
||||
pwdb_u_hash = p;
|
||||
/* password hash is next if not au_only */
|
||||
if (!au_only) {
|
||||
|
||||
for (pwdb_u_hash_len = 0;;pwdb_u_hash_len++) {
|
||||
/* hash of u_pass is next */
|
||||
pwdb_u_hash = p;
|
||||
|
||||
/* end of u_pass hash field (possibly EOL or EOF */
|
||||
if ((*p == 0) || (*p == '\n') || (*p == ':'))
|
||||
break;
|
||||
for (pwdb_u_hash_len = 0;;pwdb_u_hash_len++) {
|
||||
|
||||
++p;
|
||||
/* end of u_pass hash field (possibly EOL or EOF */
|
||||
if ((*p == 0) || (*p == '\n') || (*p == ':'))
|
||||
break;
|
||||
|
||||
} /* extract u_pass hash */
|
||||
++p;
|
||||
|
||||
} /* extract u_pass hash */
|
||||
|
||||
}
|
||||
|
||||
/* skip to next line */
|
||||
for (; *p && *p != '\n'; ++p);
|
||||
|
@ -424,31 +564,37 @@ int pass_db_load(struct pass_db_ctx *pdbctx)
|
|||
/* u_name len 0 is illegal */
|
||||
if (pwdb_u_name_len == 0) {
|
||||
xerr_warnx("pass_db_auth(%s): lineno=%d, pwdb_u_name_len=0",
|
||||
pdbctx->pw_fname, lineno);
|
||||
pdbctx->loc, lineno);
|
||||
ret = PASS_DB_AUTH_ERROR;
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
|
||||
/* user_hash len 0 is illegel */
|
||||
if (pwdb_u_hash_len == 0) {
|
||||
xerr_warnx("pass_db_auth(%s): lineno=%d, pwdb_u_hash_len=0",
|
||||
pdbctx->pw_fname, lineno);
|
||||
ret = PASS_DB_AUTH_ERROR;
|
||||
goto pass_db_load_out;
|
||||
/* u_hash only if parsing passwd */
|
||||
if (!au_only) {
|
||||
|
||||
/* u_hash len 0 is illegel */
|
||||
if (pwdb_u_hash_len == 0) {
|
||||
xerr_warnx("pass_db_auth(%s): lineno=%d, pwdb_u_hash_len=0",
|
||||
pdbctx->loc, lineno);
|
||||
ret = PASS_DB_AUTH_ERROR;
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
|
||||
|
||||
/* bounds check u_hash_len */
|
||||
if (pwdb_u_hash_len > PASS_DB_USER_HASH_LEN) {
|
||||
xerr_warnx("pass_db_auth(%s): lineno=%d, pwdb_u_hash_len=%d >%d ",
|
||||
pdbctx->loc, lineno, pwdb_u_hash_len, PASS_DB_USER_HASH_LEN);
|
||||
ret = PASS_DB_AUTH_ERROR;
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* bounds check pwdb length */
|
||||
if (pwdb_u_hash_len > PASS_DB_USER_HASH_LEN) {
|
||||
xerr_warnx("pass_db_auth(%s): lineno=%d, pwdb_u_hash_len=%d >%d ",
|
||||
pdbctx->pw_fname, lineno, pwdb_u_hash_len, PASS_DB_USER_HASH_LEN);
|
||||
ret = PASS_DB_AUTH_ERROR;
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
|
||||
/* bounds check pwdb len */
|
||||
/* bounds check u_name_len */
|
||||
if (pwdb_u_name_len > PASS_DB_USER_NAME_LEN) {
|
||||
xerr_warnx("pass_db_auth(%s): lineno=%d, pwdb_u_name=%d >%d ",
|
||||
pdbctx->pw_fname, lineno, pwdb_u_name_len, PASS_DB_USER_NAME_LEN);
|
||||
pdbctx->loc, lineno, pwdb_u_name_len, PASS_DB_USER_NAME_LEN);
|
||||
ret = PASS_DB_AUTH_ERROR;
|
||||
goto pass_db_load_out;
|
||||
}
|
||||
|
@ -457,11 +603,17 @@ int pass_db_load(struct pass_db_ctx *pdbctx)
|
|||
|
||||
/* store as C string (null termination is handled above in bzero() ) */
|
||||
bcopy(pwdb_u_name, &pwe->u_name, pwdb_u_name_len);
|
||||
bcopy(pwdb_u_hash, &pwe->u_hash, pwdb_u_hash_len);
|
||||
pwe->status = status_default;
|
||||
pwe->u_name_len = pwdb_u_name_len;
|
||||
pwe->u_hash_len = pwdb_u_hash_len;
|
||||
|
||||
if (!au_only) {
|
||||
bcopy(pwdb_u_hash, &pwe->u_hash, pwdb_u_hash_len);
|
||||
pwe->u_hash_len = pwdb_u_hash_len;
|
||||
pwe->status = local_status_default;
|
||||
} else {
|
||||
pwe->u_hash_len = 0;
|
||||
pwe->status = PASS_DB_ENTRY_ACTIVE;
|
||||
}
|
||||
|
||||
/* populate hash lookup table */
|
||||
u_hash = 0;
|
||||
for (i = 0; i < pwdb_u_name_len; ++i) {
|
||||
|
@ -484,7 +636,7 @@ int pass_db_load(struct pass_db_ctx *pdbctx)
|
|||
* if using authorized_users mark pdbctx entries with an active
|
||||
* user as active
|
||||
*/
|
||||
if (pdbctx->au_fname) {
|
||||
if (au_active && (!au_only)) {
|
||||
|
||||
/* while more lines */
|
||||
for (p = au_buf, lineno = 1; *p; ++lineno) {
|
||||
|
@ -525,7 +677,7 @@ int pass_db_load(struct pass_db_ctx *pdbctx)
|
|||
|
||||
} /* more lines */
|
||||
|
||||
} /* au_fname */
|
||||
} /* au_active && !au_only */
|
||||
|
||||
pdbctx->state = PASS_DB_STATE_LOADED;
|
||||
|
||||
|
@ -533,12 +685,6 @@ int pass_db_load(struct pass_db_ctx *pdbctx)
|
|||
|
||||
pass_db_load_out:
|
||||
|
||||
if (pw_fd != -1)
|
||||
close (pw_fd);
|
||||
|
||||
if (au_fd != -1)
|
||||
close (au_fd);
|
||||
|
||||
if (pw_buf)
|
||||
free(pw_buf);
|
||||
|
||||
|
@ -644,3 +790,124 @@ void pass_db_stats(struct pass_db_ctx *pdbctx)
|
|||
} /* hash_bucket */
|
||||
|
||||
} /* pass_db_stat() */
|
||||
|
||||
static int pam_auth(char *user_name, char *user_pass, char *svc_name)
|
||||
{
|
||||
struct pam_conv pam_conv;
|
||||
pam_handle_t *pam_h;
|
||||
int pam_err, pass_db_ret;
|
||||
|
||||
bzero(&pam_conv, sizeof pam_conv);
|
||||
pam_h = (pam_handle_t*)0L;
|
||||
|
||||
pam_conv.conv = &pam_mem_conv;
|
||||
pam_conv.appdata_ptr = (void*)0L;
|
||||
|
||||
pass_db_ret = PASS_DB_AUTH_ERROR;
|
||||
|
||||
global_user_pass = user_pass;
|
||||
|
||||
/* PAM must run as root */
|
||||
if (getuid() != 0) {
|
||||
xerr_warnx("pam_db_auth(): getuid() != 0");
|
||||
goto pam_auth_out;
|
||||
}
|
||||
|
||||
/* startup PAM */
|
||||
if ((pam_err = pam_start (svc_name, user_name, &pam_conv,
|
||||
&pam_h)) != PAM_SUCCESS) {
|
||||
xerr_warnx("pam_start(): %s", pam_strerror(pam_h, pam_err));
|
||||
goto pam_auth_out;
|
||||
}
|
||||
|
||||
pam_err = pam_authenticate(pam_h, 0);
|
||||
|
||||
if (pam_err == PAM_SUCCESS) {
|
||||
pass_db_ret = PASS_DB_AUTH_SUCCESS;
|
||||
} else {
|
||||
pass_db_ret = PASS_DB_AUTH_FAIL;
|
||||
}
|
||||
|
||||
pam_auth_out:
|
||||
|
||||
/* shutdown PAM */
|
||||
if (pam_h)
|
||||
pam_end(pam_h, 0);
|
||||
|
||||
return pass_db_ret;
|
||||
|
||||
} /* pam_db_auth */
|
||||
|
||||
int pam_mem_conv (int pam_nmsg, const struct pam_message **pam_msgh,
|
||||
struct pam_response **pam_resph, void *pam_app_data)
|
||||
{
|
||||
int i, pam_err, pass_len;
|
||||
|
||||
*pam_resph = (void*)0L;
|
||||
|
||||
pass_len = strlen(global_user_pass);
|
||||
|
||||
if ((pam_nmsg <= 0) || (pam_nmsg >= PAM_MAX_NUM_MSG)) {
|
||||
xerr_warnx("check_conv(): invalid pam_nmsg=%d", pam_nmsg);
|
||||
pam_err = PAM_CONV_ERR;
|
||||
goto pam_mem_conv_out;
|
||||
}
|
||||
|
||||
/* allocate storage for responses, to be free()'d by caller or us on err */
|
||||
if (!(*pam_resph = (struct pam_response*)malloc(pam_nmsg *
|
||||
sizeof (struct pam_response) ))) {
|
||||
xerr_warn("malloc(pam_nmsg=%d)", pam_nmsg);
|
||||
pam_err = PAM_BUF_ERR;
|
||||
goto pam_mem_conv_out;
|
||||
}
|
||||
|
||||
bzero(*pam_resph, pam_nmsg*sizeof (struct pam_response));
|
||||
|
||||
for (i = 0; i < pam_nmsg; ++i) {
|
||||
|
||||
switch (pam_msgh[i]->msg_style) {
|
||||
|
||||
case PAM_PROMPT_ECHO_OFF:
|
||||
case PAM_PROMPT_ECHO_ON:
|
||||
|
||||
/* allocate space for password */
|
||||
if (!((*pam_resph)[i].resp = (char*)malloc(pass_len+1))) {
|
||||
xerr_warn("malloc(l_passwd):");
|
||||
pam_err = PAM_BUF_ERR;
|
||||
goto pam_mem_conv_out;
|
||||
}
|
||||
|
||||
bcopy(global_user_pass, (*pam_resph)[i].resp, pass_len+1);
|
||||
break;
|
||||
|
||||
case PAM_ERROR_MSG:
|
||||
case PAM_TEXT_INFO:
|
||||
xerr_warnx("PAM_MSG: %s", pam_msgh[i]->msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
xerr_warnx("Ignoring unexpected msg_style=%d", pam_msgh[i]->msg_style);
|
||||
break;
|
||||
|
||||
} /* switch */
|
||||
|
||||
} /* foreach message */
|
||||
|
||||
return (PAM_SUCCESS);
|
||||
|
||||
pam_mem_conv_out:
|
||||
|
||||
if (*pam_resph) {
|
||||
|
||||
for (i = 0; i < pam_nmsg; ++i)
|
||||
if ((*pam_resph)[i].resp)
|
||||
free((*pam_resph)[i].resp);
|
||||
|
||||
free(*pam_resph);
|
||||
|
||||
}
|
||||
|
||||
return pam_err;
|
||||
|
||||
} /* pam_mem_conv */
|
||||
|
||||
|
|
13
urd/pw.h
13
urd/pw.h
|
@ -24,7 +24,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: pw.h 13 2009-11-26 16:37:03Z maf $
|
||||
* $Id: pw.h 155 2011-04-06 02:25:43Z maf $
|
||||
*/
|
||||
|
||||
|
||||
|
@ -40,6 +40,10 @@
|
|||
#define PASS_DB_ENTRY_INACTIVE 0
|
||||
#define PASS_DB_ENTRY_ACTIVE 1
|
||||
|
||||
#define PASS_DB_TYPE_LOCAL 1
|
||||
#define PASS_DB_TYPE_EX_LOCAL 2 /* ignore authorized_users */
|
||||
#define PASS_DB_TYPE_PAM 3
|
||||
#define PASS_DB_TYPE_EX_PAM 4 /* ignore authorized_users */
|
||||
|
||||
#define PASS_DB_AUTH_SUCCESS 0
|
||||
#define PASS_DB_AUTH_FAIL 1
|
||||
|
@ -54,8 +58,9 @@ struct pass_db_ctx {
|
|||
struct stat pw_sb;
|
||||
struct stat au_sb;
|
||||
int state;
|
||||
char *pw_fname;
|
||||
char *au_fname;
|
||||
int type;
|
||||
char *loc; /* password filename or PAM service name */
|
||||
char *au_fname; /* authorized users filename */
|
||||
uint num_entries;
|
||||
struct pass_db_entry *pw_entries;
|
||||
SLIST_HEAD(pass_db_head, pass_db_entry) bucket[1<<PASS_DB_HASH_BUCKET_BITS];
|
||||
|
@ -71,7 +76,7 @@ struct pass_db_entry {
|
|||
char u_hash[PASS_DB_USER_HASH_LEN+1];
|
||||
};
|
||||
|
||||
struct pass_db_ctx *pass_db_ctx_new(char *pw_fname, char *au_fname);
|
||||
struct pass_db_ctx *pass_db_ctx_new(char *loc, char *au_fname, int type);
|
||||
void pass_db_ctx_free(struct pass_db_ctx *pdbctx);
|
||||
int pass_db_auth(struct pass_db_ctx *pdbctx, char *user_name, char *user_pass);
|
||||
int pass_db_load(struct pass_db_ctx *pdbctx);
|
||||
|
|
103
urd/rad.c
103
urd/rad.c
|
@ -24,7 +24,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: rad.c 13 2009-11-26 16:37:03Z maf $
|
||||
* $Id: rad.c 157 2011-04-06 03:57:29Z maf $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -194,6 +194,7 @@ int urd_req_decode(struct urd_ctx *urdctx)
|
|||
urdctx->req.tlv_NAS_Identifier = (struct urd_tlv*)0L;
|
||||
urdctx->req.tlv_User_Password = (struct urd_tlv*)0L;
|
||||
urdctx->req.tlv_State = (struct urd_tlv*)0L;
|
||||
bzero(&urdctx->req.user_name_base, URD_USER_NAME_LEN+1);
|
||||
bzero(&urdctx->req.user_name, URD_USER_NAME_LEN+1);
|
||||
bzero(&urdctx->req.user_pass, URD_USER_PASS_LEN+1);
|
||||
urdctx->req.state_counter = 0;
|
||||
|
@ -301,6 +302,19 @@ int urd_req_decode(struct urd_ctx *urdctx)
|
|||
urdctx->req.tlv_User_Name->len);
|
||||
urdctx->req.user_name[urdctx->req.tlv_User_Name->len] = 0;
|
||||
|
||||
/*
|
||||
* hack to allow multiple usernames to authenticate off the same
|
||||
* base name. Allows a single user to sign on to device more than
|
||||
* once when the device only supports single user sessions.
|
||||
*/
|
||||
bcopy(urdctx->req.tlv_User_Name->val, &urdctx->req.user_name_base,
|
||||
urdctx->req.tlv_User_Name->len);
|
||||
urdctx->req.user_name_base[urdctx->req.tlv_User_Name->len] = 0;
|
||||
|
||||
for (i = 0; i < urdctx->req.tlv_User_Name->len; ++i)
|
||||
if (urdctx->req.user_name_base[i] == '#')
|
||||
urdctx->req.user_name_base[i] = 0;
|
||||
|
||||
} /* urdctx->req.tlv_User_Name */
|
||||
|
||||
/* C string */
|
||||
|
@ -405,13 +419,13 @@ void urd_req_dump(struct urd_ctx *urdctx)
|
|||
int buf_l, i, j, decode_type;
|
||||
char buf[1024];
|
||||
|
||||
buf_l = snprintf(buf, 1024,
|
||||
buf_l = snprintf(buf, sizeof(buf),
|
||||
"pkt.code=%2.2X, pkt.id=%2.2X, pkt.len=%2.2X, pkt.auth=",
|
||||
(int)urdctx->req.dgram_header.code,
|
||||
(int)urdctx->req.dgram_header.identifier,
|
||||
(int)urdctx->req.dgram_header.length);
|
||||
for (j = 0; j < RADIUS_AUTHENTICATOR_LEN; ++j)
|
||||
buf_l += snprintf(buf+buf_l, 1024-buf_l, "%2.2X",
|
||||
buf_l += snprintf(buf+buf_l, sizeof(buf)-buf_l, "%2.2X",
|
||||
((int)urdctx->req.dgram_header.authenticator[j]));
|
||||
|
||||
xerr_info(buf);
|
||||
|
@ -428,6 +442,10 @@ void urd_req_dump(struct urd_ctx *urdctx)
|
|||
decode_type = URD_DECODE_TYPE_CHAR;
|
||||
break;
|
||||
|
||||
case RADIUS_ATTRIB_USER_PASSWORD:
|
||||
decode_type = URD_DECODE_TYPE_HIDDEN;
|
||||
break;
|
||||
|
||||
case RADIUS_ATTRIB_NAS_IP_ADDRESS:
|
||||
case RADIUS_ATTRIB_FRAMED_IP_ADDRESS:
|
||||
case RADIUS_ATTRIB_FRAMED_IP_NETMASK:
|
||||
|
@ -440,32 +458,36 @@ void urd_req_dump(struct urd_ctx *urdctx)
|
|||
|
||||
} /* switch */
|
||||
|
||||
buf_l = snprintf(buf, 1024,
|
||||
buf_l = snprintf(buf, sizeof(buf),
|
||||
" TLV type=%d, len=%d, val=", (int)urdctx->req.tlv[i].type,
|
||||
(int)urdctx->req.tlv[i].len);
|
||||
|
||||
switch (decode_type) {
|
||||
|
||||
case URD_DECODE_TYPE_HEX:
|
||||
buf_l += snprintf(buf+buf_l, 1024-buf_l, "H ");
|
||||
buf_l += snprintf(buf+buf_l, sizeof(buf)-buf_l, "H ");
|
||||
for (j = 0; j < urdctx->req.tlv[i].len; ++j)
|
||||
buf_l += snprintf(buf+buf_l, 1024-buf_l, "%2.2X",
|
||||
buf_l += snprintf(buf+buf_l, sizeof(buf)-buf_l, "%2.2X",
|
||||
(int)urdctx->req.tlv[i].val[j]);
|
||||
break;
|
||||
|
||||
case URD_DECODE_TYPE_CHAR:
|
||||
buf_l += snprintf(buf+buf_l, 1024-buf_l, "C ");
|
||||
buf_l += snprintf(buf+buf_l, sizeof(buf)-buf_l, "C ");
|
||||
for (j = 0; j < urdctx->req.tlv[i].len; ++j)
|
||||
buf_l += snprintf(buf+buf_l, 1024-buf_l, "%c",
|
||||
buf_l += snprintf(buf+buf_l, sizeof(buf)-buf_l, "%c",
|
||||
urdctx->req.tlv[i].val[j]);
|
||||
break;
|
||||
|
||||
case URD_DECODE_TYPE_IP:
|
||||
buf_l += snprintf(buf+buf_l, 1024-buf_l, "I %d.%d.%d.%d",
|
||||
buf_l += snprintf(buf+buf_l, sizeof(buf)-buf_l, "I %d.%d.%d.%d",
|
||||
(int)urdctx->req.tlv[i].val[0], (int)urdctx->req.tlv[i].val[1],
|
||||
(int)urdctx->req.tlv[i].val[2], (int)urdctx->req.tlv[i].val[3]);
|
||||
break;
|
||||
|
||||
case URD_DECODE_TYPE_HIDDEN:
|
||||
buf_l += snprintf(buf+buf_l, sizeof(buf)-buf_l, "X <hidden>");
|
||||
break;
|
||||
|
||||
} /* switch */
|
||||
|
||||
xerr_info(buf);
|
||||
|
@ -498,15 +520,15 @@ void urd_req_dump(struct urd_ctx *urdctx)
|
|||
*
|
||||
*/
|
||||
int urd_rep_encode(struct urd_ctx *urdctx, uint8_t code,
|
||||
uint64_t state_counter, int rep_encode_flags)
|
||||
uint64_t state_counter, uint64_t otp_count, int rep_encode_flags)
|
||||
{
|
||||
struct radius_dgram_header dgram_header, *dh;
|
||||
struct urd_tlv_state tlv_state;
|
||||
struct urd_tlv_rep_msg tlv_rep_msg;
|
||||
u_char md_val[EVP_MAX_MD_SIZE];
|
||||
u_char md_val[EVP_MAX_MD_SIZE], *c;
|
||||
char fmt_buf[64];
|
||||
uint md_len;
|
||||
int i, pkt_p;
|
||||
char *c;
|
||||
|
||||
bzero(&dgram_header, sizeof dgram_header);
|
||||
bzero(&tlv_state, sizeof tlv_state);
|
||||
|
@ -534,7 +556,7 @@ int urd_rep_encode(struct urd_ctx *urdctx, uint8_t code,
|
|||
tlv_state.val[0] = 'u'; tlv_state.val[1] = 'r';
|
||||
tlv_state.val[2] = 'd'; tlv_state.val[3] = ':';
|
||||
|
||||
c = (char*)&state_counter;
|
||||
c = (u_char*)&state_counter;
|
||||
i = 19;
|
||||
|
||||
while (i > 4) {
|
||||
|
@ -550,14 +572,27 @@ int urd_rep_encode(struct urd_ctx *urdctx, uint8_t code,
|
|||
/* add reply message? */
|
||||
if (rep_encode_flags & URD_ENCODE_FLAG_MSG) {
|
||||
|
||||
dgram_header.length += sizeof (tlv_rep_msg);
|
||||
i = snprintf(fmt_buf, sizeof(fmt_buf), "%" PRIu64, otp_count);
|
||||
|
||||
/* should never happen */
|
||||
if (i > URD_TLV_REPLY_MSG_LEN) {
|
||||
xerr_warnx("reply msg encode failed, i=%d", i);
|
||||
i = URD_TLV_REPLY_MSG_LEN;
|
||||
}
|
||||
|
||||
/*
|
||||
* calculate size of tlv_rep_msg. The full URD_TLV_REPLY_MSG_LEN
|
||||
* space ay not be used and is truncated. type(1) + len(1) + message(i)
|
||||
*/
|
||||
tlv_rep_msg.len = 1 + 1 + i;
|
||||
|
||||
/* add len to total encoded size */
|
||||
dgram_header.length += tlv_rep_msg.len;
|
||||
|
||||
/* XXX hard coded to ABCD... */
|
||||
tlv_rep_msg.type = RADIUS_ATTRIB_REPLY_MESSAGE;
|
||||
tlv_rep_msg.len = sizeof (tlv_rep_msg);
|
||||
for (i = 0; i < 7; ++i)
|
||||
tlv_rep_msg.val[i] = 'A'+i;
|
||||
tlv_rep_msg.val[7] = 0;
|
||||
|
||||
/* copy in otp_count in ASCII */
|
||||
bcopy(&fmt_buf, &tlv_rep_msg.val, i);
|
||||
|
||||
} /* URD_ENCODE_FLAG_MSG */
|
||||
|
||||
|
@ -582,9 +617,8 @@ int urd_rep_encode(struct urd_ctx *urdctx, uint8_t code,
|
|||
}
|
||||
|
||||
if (rep_encode_flags & URD_ENCODE_FLAG_MSG) {
|
||||
bcopy(&tlv_rep_msg, (char*)&urdctx->rep.pkt_buf + pkt_p,
|
||||
sizeof(tlv_rep_msg));
|
||||
pkt_p += sizeof(tlv_rep_msg);
|
||||
bcopy(&tlv_rep_msg, (char*)&urdctx->rep.pkt_buf + pkt_p, tlv_rep_msg.len);
|
||||
pkt_p += tlv_rep_msg.len;
|
||||
}
|
||||
|
||||
/* MD5(reply packet + secret) */
|
||||
|
@ -672,7 +706,7 @@ void urd_ctx_free(struct urd_ctx *urdctx)
|
|||
*
|
||||
*/
|
||||
int urd_req_cache_update(struct urd_ctx *urdctx, uint8_t rep_code,
|
||||
uint64_t state_counter, int req_cache_flags)
|
||||
uint64_t state_counter, uint64_t otp_count, int req_cache_flags)
|
||||
{
|
||||
uint16_t req_hash, req_hash_mask, state_hash, state_hash_mask;
|
||||
struct urd_req_cache_entry *e;
|
||||
|
@ -710,7 +744,7 @@ int urd_req_cache_update(struct urd_ctx *urdctx, uint8_t rep_code,
|
|||
/* insert entry into hash bucket state_chain */
|
||||
LIST_INSERT_HEAD(&urdctx->state_cache_bucket[state_hash], e, state_chain);
|
||||
|
||||
e->flags = URD_STATE_CACHE_FLAGS_INUSE;
|
||||
e->flags = URD_STATE_CACHE_FLAG_INUSE;
|
||||
|
||||
} /* hash table for state */
|
||||
|
||||
|
@ -729,11 +763,13 @@ int urd_req_cache_update(struct urd_ctx *urdctx, uint8_t rep_code,
|
|||
|
||||
e->rad_code = rep_code;
|
||||
|
||||
e->otp_count = otp_count;
|
||||
|
||||
e->rad_id = urdctx->req.dgram_header.identifier;
|
||||
|
||||
e->rexmit_count = 0;
|
||||
|
||||
e->flags ^= URD_REQ_CACHE_FLAGS_INUSE;
|
||||
e->flags ^= URD_REQ_CACHE_FLAG_INUSE;
|
||||
|
||||
/* rollover */
|
||||
if (urdctx->req_cache_len == URD_REQ_CACHE_ENTRIES)
|
||||
|
@ -741,23 +777,23 @@ int urd_req_cache_update(struct urd_ctx *urdctx, uint8_t rep_code,
|
|||
|
||||
/* if the current entry was previously in use, remove from hash chain */
|
||||
if (urdctx->req_cache[urdctx->req_cache_len].flags &
|
||||
URD_REQ_CACHE_FLAGS_INUSE) {
|
||||
URD_REQ_CACHE_FLAG_INUSE) {
|
||||
|
||||
LIST_REMOVE(&urdctx->req_cache[urdctx->req_cache_len], req_chain);
|
||||
|
||||
urdctx->req_cache[urdctx->req_cache_len].flags &=\
|
||||
~URD_REQ_CACHE_FLAGS_INUSE;
|
||||
~URD_REQ_CACHE_FLAG_INUSE;
|
||||
|
||||
} /* in use? */
|
||||
|
||||
/* if the current entry was previously in use, remove from hash chain */
|
||||
if (urdctx->req_cache[urdctx->req_cache_len].flags &
|
||||
URD_STATE_CACHE_FLAGS_INUSE) {
|
||||
URD_STATE_CACHE_FLAG_INUSE) {
|
||||
|
||||
LIST_REMOVE(&urdctx->req_cache[urdctx->req_cache_len], state_chain);
|
||||
|
||||
urdctx->req_cache[urdctx->req_cache_len].flags &=\
|
||||
~URD_STATE_CACHE_FLAGS_INUSE;
|
||||
~URD_STATE_CACHE_FLAG_INUSE;
|
||||
|
||||
} /* in use? */
|
||||
|
||||
|
@ -774,6 +810,9 @@ int urd_req_cache_update(struct urd_ctx *urdctx, uint8_t rep_code,
|
|||
* UserName and UserPassWord TLV's must be in request (req)
|
||||
* and be of length <= URD_USER_NAME_LEN/URD_USER_PASS_LEN
|
||||
*
|
||||
* code, otp_count, and state_counter will be updated on cache hit,
|
||||
* else they are unchanged.
|
||||
*
|
||||
* Lookup request in cache by Authenticator field. Additionally
|
||||
* verify identifier, user_name, user_pass and state (if present) match
|
||||
* the cache'd request. If the entry has not expired (older than
|
||||
|
@ -785,7 +824,7 @@ int urd_req_cache_update(struct urd_ctx *urdctx, uint8_t rep_code,
|
|||
*
|
||||
*/
|
||||
int urd_req_cache_lookup(struct urd_ctx *urdctx, uint8_t *code,
|
||||
uint64_t *state_counter)
|
||||
uint64_t *state_counter, uint64_t *otp_count, int *cache_flags)
|
||||
{
|
||||
time_t now;
|
||||
uint16_t hash, hash_mask;
|
||||
|
@ -843,6 +882,8 @@ int urd_req_cache_lookup(struct urd_ctx *urdctx, uint8_t *code,
|
|||
/* cached result code and state */
|
||||
*code = e->rad_code;
|
||||
*state_counter = e->state_counter;
|
||||
*otp_count = e->otp_count;
|
||||
*cache_flags = e->flags;
|
||||
|
||||
match = 1;
|
||||
break;
|
||||
|
@ -885,6 +926,8 @@ int urd_req_cache_lookup(struct urd_ctx *urdctx, uint8_t *code,
|
|||
* UserName and UserPassWord TLV's must be in request (req)
|
||||
* and be of length <= URD_USER_NAME_LEN/URD_USER_PASS_LEN
|
||||
*
|
||||
* code will be updated on cache hit, else it is left unchanged.
|
||||
*
|
||||
* Lookup request in cache by state field. Additionally
|
||||
* verify user_name matches the initial Access-Request.
|
||||
* If the entry has not expired (older than URD_STATE_CACHE_LIFETIME seconds
|
||||
|
|
43
urd/rad.h
43
urd/rad.h
|
@ -24,7 +24,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: rad.h 13 2009-11-26 16:37:03Z maf $
|
||||
* $Id: rad.h 157 2011-04-06 03:57:29Z maf $
|
||||
*/
|
||||
|
||||
#include <openssl/evp.h>
|
||||
|
@ -42,8 +42,9 @@
|
|||
#define URD_PACKET_LEN_MIN 20 /* minimum datagram length */
|
||||
|
||||
#define URD_TLV_STATE_LEN 20 /* length of state tlv data */
|
||||
/* XXX */
|
||||
#define URD_TLV_REPLY_MSG_LEN 8 /* length of state reply message data */
|
||||
|
||||
/* can encode a PRIu64 which is up to 20 digits in ASCII */
|
||||
#define URD_TLV_REPLY_MSG_LEN 20 /* length of state reply message data */
|
||||
|
||||
/*
|
||||
* The cache length should be a minimum (max queries/second * cache seconds)
|
||||
|
@ -64,8 +65,8 @@
|
|||
#define URD_REQ_CACHE_HIT 1 /* cache hit */
|
||||
#define URD_REQ_CACHE_MISS 0 /* cache miss */
|
||||
|
||||
#define URD_REQ_CACHE_FLAGS_INUSE 0x1 /* cache entry is in use */
|
||||
#define URD_STATE_CACHE_FLAGS_INUSE 0x2 /* cache entry is in use */
|
||||
#define URD_REQ_CACHE_FLAG_INUSE 0x1 /* cache entry is in use */
|
||||
#define URD_STATE_CACHE_FLAG_INUSE 0x2 /* cache entry is in use */
|
||||
|
||||
/* Hash buckets is dependent on the hash function.. */
|
||||
#define URD_REQ_HASH_BUCKET_BITS 16 /* number of hash buckets */
|
||||
|
@ -76,6 +77,7 @@
|
|||
#define URD_STATE_CACHE_MISS 0 /* cache miss */
|
||||
|
||||
#define URD_CACHE_FLAG_STATE 0x1 /* prep lookup by state too */
|
||||
#define URD_CACHE_FLAG_MSG 0x2 /* hint to encode message */
|
||||
|
||||
#define URD_ENCODE_FLAG_STATE 0x1 /* encode state in reply */
|
||||
#define URD_ENCODE_FLAG_MSG 0x2 /* encode message in reply */
|
||||
|
@ -139,6 +141,7 @@
|
|||
#define URD_DECODE_TYPE_HEX 0
|
||||
#define URD_DECODE_TYPE_CHAR 1
|
||||
#define URD_DECODE_TYPE_IP 2
|
||||
#define URD_DECODE_TYPE_HIDDEN 3
|
||||
|
||||
struct radius_dgram_header {
|
||||
uint8_t code;
|
||||
|
@ -170,6 +173,7 @@ struct urd_req_cache_entry {
|
|||
char user_name[URD_USER_NAME_LEN+1]; /* key */
|
||||
char user_pass[URD_USER_PASS_LEN+1]; /* key */
|
||||
uint64_t state_counter; /* state_hash/key */
|
||||
uint64_t otp_count; /* OTP count */
|
||||
time_t create_time; /* cache maintenance */
|
||||
uint8_t rad_code; /* data to be cached */
|
||||
uint8_t rad_id; /* req_hash/key */
|
||||
|
@ -187,7 +191,7 @@ struct urd_req_cache_entry {
|
|||
* rce_index = 0;
|
||||
*
|
||||
* when storing an entry (rce_index always points to the next free entry)
|
||||
* if (entry.flags & URD_REQ_CACHE_FLAGS_INUSE) then
|
||||
* if (entry.flags & URD_REQ_CACHE_FLAG_INUSE) then
|
||||
* remove entry from req_chain before using.
|
||||
*
|
||||
* counter initialized to 1, counter=0 is a stateless cache entry, ie
|
||||
|
@ -203,16 +207,17 @@ struct urd_req_cache_entry {
|
|||
*/
|
||||
|
||||
struct urd_req {
|
||||
EVP_MD_CTX mdctx; /* MD5 context */
|
||||
uint8_t pkt_buf[URD_MAX_DGRAM_LEN]; /* raw datagram */
|
||||
struct radius_dgram_header dgram_header; /* datagram header */
|
||||
struct sockaddr_in rem_addr; /* remote host */
|
||||
int pkt_len; /* packet length */
|
||||
int tlv_count; /* number TLV's */
|
||||
struct urd_tlv tlv[URD_MAX_TLV]; /* decoded TLV's */
|
||||
char user_name[URD_USER_NAME_LEN+1]; /* C string */
|
||||
char user_pass[URD_USER_PASS_LEN+1]; /* C string (clear) */
|
||||
uint64_t state_counter; /* decoded state TLV */
|
||||
EVP_MD_CTX mdctx; /* MD5 context */
|
||||
uint8_t pkt_buf[URD_MAX_DGRAM_LEN]; /* raw datagram */
|
||||
struct radius_dgram_header dgram_header; /* datagram header */
|
||||
struct sockaddr_in rem_addr; /* remote host */
|
||||
int pkt_len; /* packet length */
|
||||
int tlv_count; /* number TLV's */
|
||||
struct urd_tlv tlv[URD_MAX_TLV]; /* decoded TLV's */
|
||||
char user_name[URD_USER_NAME_LEN+1]; /* C string */
|
||||
char user_pass[URD_USER_PASS_LEN+1]; /* C string (clear) */
|
||||
char user_name_base[URD_USER_NAME_LEN+1]; /* C string (clear) */
|
||||
uint64_t state_counter; /* decoded state TLV */
|
||||
/* shortcuts */
|
||||
struct urd_tlv *tlv_User_Name;
|
||||
struct urd_tlv *tlv_NAS_IP_Address;
|
||||
|
@ -246,13 +251,13 @@ struct urd_ctx {
|
|||
int urd_req_decode(struct urd_ctx *urdctx);
|
||||
void urd_req_dump(struct urd_ctx *urdctx);
|
||||
int urd_rep_encode(struct urd_ctx *urdctx, uint8_t code,
|
||||
uint64_t state_counter, int rep_encode_flags);
|
||||
uint64_t state_counter, uint64_t otp_count, int rep_encode_flags);
|
||||
struct urd_ctx *urd_ctx_new(char *rsecret);
|
||||
void urd_ctx_free(struct urd_ctx *urdctx);
|
||||
int urd_req_cache_update(struct urd_ctx *urdctx, uint8_t code,
|
||||
uint64_t state_counter, int req_cache_flags);
|
||||
uint64_t state_counter, uint64_t otp_count, int req_cache_flags);
|
||||
int urd_req_cache_lookup(struct urd_ctx *urdctx, uint8_t *code,
|
||||
uint64_t *state_counter);
|
||||
uint64_t *state_counter, uint64_t *otp_count, int *cache_flags);
|
||||
int urd_state_cache_lookup(struct urd_ctx *urdctx, uint8_t *code);
|
||||
void urd_state_cache_stats(struct urd_ctx *urdctx);
|
||||
void urd_req_cache_stats(struct urd_ctx *urdctx);
|
||||
|
|
239
urd/rc.d/urd
Normal file
239
urd/rc.d/urd
Normal file
|
@ -0,0 +1,239 @@
|
|||
#!/bin/sh
|
||||
|
||||
# PROVIDE: urd
|
||||
# REQUIRE: DAEMON
|
||||
|
||||
. /etc/rc.subr
|
||||
|
||||
# urd_enable="YES"
|
||||
# urd_list="engvpn1 testvpn1"
|
||||
# urd_engvpn1_dir="/var/urd/engvpn1"
|
||||
# urd_engvpn1_ip="10.1.0.1"
|
||||
# urd_engvpn1_flags="-dD"
|
||||
# urd_engvpn1_passwd="passwd"
|
||||
# urd_engvpn1_authorized_users="authorized_users"
|
||||
# urd_engvpn1_otp="otp.db"
|
||||
# urd_engvpn1_secret="server_secret"
|
||||
# urd_engvpn1_pid="pid.10.1.0.1"
|
||||
# urd_engvpn1_pgm="/usr/local/ootp/bin/urd"
|
||||
# urd_engvpn1_service="urd"
|
||||
|
||||
name="urd"
|
||||
rcvar=`set_rcvar`
|
||||
start_cmd="urd_start"
|
||||
stop_cmd="urd_stop"
|
||||
status_cmd="urd_status"
|
||||
extra_commands="status list"
|
||||
extra_arg=$2
|
||||
list_cmd="urd_list"
|
||||
w="/usr/local/ootp/bin"
|
||||
RTPRIO="/usr/sbin/rtprio"
|
||||
ARGV0="/usr/local/bin/argv0"
|
||||
URD="$w/urd"
|
||||
|
||||
if [ -z "$autoboot" ]; then
|
||||
autoboot="NO"
|
||||
fi
|
||||
|
||||
# shutdown does a fast stop, use to trigger stop all
|
||||
if echo $1 | egrep '^fast'>/dev/null; then
|
||||
DO_ALL=1
|
||||
else
|
||||
DO_ALL=0
|
||||
fi
|
||||
|
||||
# startup scripts set autoboot, start all instances
|
||||
if checkyesno autoboot; then
|
||||
DO_ALL=1
|
||||
fi
|
||||
|
||||
load_rc_config $name
|
||||
|
||||
urd_debug()
|
||||
{
|
||||
echo "********"
|
||||
echo "urd_instance=$n"
|
||||
echo "dir=$urd_dir"
|
||||
echo "ip=$urd_ip"
|
||||
echo "port=$urd_port"
|
||||
echo "flags=$urd_flags"
|
||||
echo "passwd=$urd_passwd"
|
||||
echo "authorized_users=$urd_au"
|
||||
echo "otpdb=$urd_otpdb"
|
||||
echo "server_secret=$urd_ss"
|
||||
echo "pid=$urd_pid"
|
||||
echo "pgm=$urd_pgm"
|
||||
}
|
||||
|
||||
urd_expand()
|
||||
{
|
||||
eval urd_dir=\$urd_${1}_dir
|
||||
eval urd_ip=\$urd_${1}_ip
|
||||
eval urd_port=\$urd_${1}_port
|
||||
eval urd_flags=\$urd_${1}_flags
|
||||
eval urd_passwd=\$urd_${1}_passwd
|
||||
eval urd_au=\$urd_${1}_authorized_users
|
||||
eval urd_otpdb=\$urd_${1}_otpdb
|
||||
eval urd_ss=\$urd_${1}_server_secret
|
||||
eval urd_pid=\$urd_${1}_pid
|
||||
eval urd_pgm=\$urd_${1}_pgm
|
||||
eval urd_service=\$urd_${1}_service
|
||||
|
||||
if [ -z "$urd_dir" ]; then
|
||||
urd_dir="/var/urd/$1"
|
||||
fi
|
||||
|
||||
if [ -z "$urd_ip" ]; then
|
||||
urd_ip="0.0.0.0"
|
||||
fi
|
||||
|
||||
if [ -z "$urd_port" ]; then
|
||||
urd_port="1812"
|
||||
fi
|
||||
|
||||
if [ -z "$urd_passwd" ]; then
|
||||
urd_passwd="$urd_dir/passwd"
|
||||
fi
|
||||
|
||||
if [ -z "$urd_au" ]; then
|
||||
urd_au="$urd_dir/authorized_users"
|
||||
fi
|
||||
|
||||
if [ -z "$urd_otpdb" ]; then
|
||||
urd_otpdb="$urd_dir/otpdb"
|
||||
fi
|
||||
|
||||
if [ -z "$urd_pid" ]; then
|
||||
if [ "X$urd_ip" = "X0.0.0.0" ]; then
|
||||
urd_pid="$urd_dir/pid"
|
||||
else
|
||||
urd_pid="$urd_dir/pid.$urd_ip"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$urd_ss" ]; then
|
||||
urd_ss="$urd_dir/server_secret"
|
||||
fi
|
||||
|
||||
if [ -z "$urd_pgm" ]; then
|
||||
urd_pgm=$URD
|
||||
fi
|
||||
|
||||
if [ -z "$urd_service" ]; then
|
||||
urd_service="urd"
|
||||
fi
|
||||
|
||||
} # urd_expand
|
||||
|
||||
|
||||
urd_status()
|
||||
{
|
||||
|
||||
if [ ! -z "$extra_arg" ]; then
|
||||
urd_list=$extra_arg
|
||||
fi
|
||||
|
||||
for n in $urd_list; do
|
||||
|
||||
echo -n "$n "
|
||||
a0="urd.$n"
|
||||
|
||||
p=`check_process $a0`
|
||||
if [ -z "$p" ]; then
|
||||
echo "*** not running ***"
|
||||
else
|
||||
echo $p
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
} # urd_status
|
||||
|
||||
urd_list()
|
||||
{
|
||||
for n in $urd_list; do
|
||||
urd_expand $n
|
||||
urd_debug $n
|
||||
done
|
||||
} # urd_list
|
||||
|
||||
urd_start()
|
||||
{
|
||||
|
||||
if [ "$DO_ALL" -eq 0 ]; then
|
||||
|
||||
if [ -z "$extra_arg" ]; then
|
||||
err 1 "start requires config name argument. Try list."
|
||||
fi
|
||||
|
||||
urd_list=$extra_arg
|
||||
|
||||
fi
|
||||
|
||||
PATH=$w:$PATH
|
||||
|
||||
for n in $urd_list; do
|
||||
|
||||
urd_expand $n
|
||||
|
||||
if [ ! -d "$urd_dir" ]; then
|
||||
err 1 "$n: missing config dir $urd_dir"
|
||||
fi
|
||||
|
||||
a0="urd.$n"
|
||||
|
||||
echo starting urd for $n.
|
||||
|
||||
# pre 173 does not take -V
|
||||
if [ "$urd_service" = "urd" ]; then
|
||||
$ARGV0 $urd_pgm $a0 -a $urd_au -b $urd_ip -B $urd_port\
|
||||
-o $urd_otpdb -p $urd_passwd -P $urd_pid -s $urd_ss \
|
||||
$urd_flags
|
||||
else
|
||||
$ARGV0 $urd_pgm $a0 -a $urd_au -b $urd_ip -B $urd_port\
|
||||
-o $urd_otpdb -p $urd_passwd -P $urd_pid -s $urd_ss \
|
||||
-V $urd_service $urd_flags
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
} # urd_start
|
||||
|
||||
urd_stop()
|
||||
{
|
||||
|
||||
if [ "$DO_ALL" -eq 0 ]; then
|
||||
|
||||
if [ -z "$extra_arg" ]; then
|
||||
err 1 "stop requires config name argument. Try list."
|
||||
fi
|
||||
|
||||
urd_list=$extra_arg
|
||||
|
||||
fi
|
||||
|
||||
for n in $urd_list; do
|
||||
|
||||
urd_expand $n
|
||||
|
||||
if [ ! -d "$urd_dir" ]; then
|
||||
err 1 "$n: missing config dir $urd_dir"
|
||||
fi
|
||||
|
||||
a0="urd.$n"
|
||||
|
||||
pid=`check_process $a0`
|
||||
|
||||
if [ -n "$pid" ]; then
|
||||
kill -9 $pid
|
||||
echo "$n: stopped"
|
||||
else
|
||||
echo "$n: not running."
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
} # urd_stop
|
||||
|
||||
run_rc_command "$1"
|
||||
|
286
urd/urd.c
286
urd/urd.c
|
@ -24,7 +24,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: urd.c 50 2009-12-15 01:37:19Z maf $
|
||||
* $Id: urd.c 176 2011-05-16 02:17:30Z maf $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -34,6 +34,7 @@
|
|||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
|
@ -56,7 +57,6 @@
|
|||
|
||||
/*
|
||||
* XXX
|
||||
* urd_rep_msg in access-challenge hard coded to ABC..
|
||||
* copy proxy variables into reply packet per RFC?
|
||||
* packet stress testing
|
||||
*/
|
||||
|
@ -66,9 +66,12 @@ static int server_secret_load(char *fname, char *buf, int buf_len);
|
|||
static u_long scan_ip(char *s);
|
||||
static int write_pidfile(char *fname);
|
||||
|
||||
#define URDCTX_USER_NAME (allow_n_logins ?\
|
||||
urdctx->req.user_name_base : urdctx->req.user_name)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
extern char *ootp_version;
|
||||
struct sockaddr_in loc_addr;
|
||||
struct urd_ctx *urdctx;
|
||||
struct pass_db_ctx *pdbctx;
|
||||
|
@ -76,26 +79,65 @@ int main(int argc, char **argv)
|
|||
struct otp_ctx *otpctx;
|
||||
struct otp_user ou;
|
||||
char *otpdb_fname;
|
||||
int otp_skip_unknown, otpdb_flags, otp_enable;
|
||||
int otp_allow_unknown, otpdb_flags, otp_enable;
|
||||
#endif /* OOTP_ENABLE */
|
||||
fd_set rfd;
|
||||
u_long tmpul;
|
||||
uint64_t rep_state;
|
||||
uint64_t rep_state, rep_otp_count;
|
||||
uint32_t local_ip;
|
||||
uint16_t local_port;
|
||||
uint8_t rep_code;
|
||||
uint rem_addr_len;
|
||||
char *authorized_users_fname, *pwfile_fname, *server_secret_fname, *endptr;
|
||||
char server_secret[URD_SECRET_LEN+1], buf[1024], *pid_fname;
|
||||
int rep_enc_flags, rep_cache_flags, debug, daemon_mode;
|
||||
char *au_fname, *pwfile_fname, *server_secret_fname, *endptr, *loc;
|
||||
char server_secret[URD_SECRET_LEN+1], buf[1024], *pid_fname, *as_name;
|
||||
char *service;
|
||||
int rep_enc_flags, rep_cache_flags, debug, daemon_mode, pdb_type;
|
||||
int drop, drop_mode, req_cache_hit, buf_l, pkt_fd, r, i, otp_window;
|
||||
int opt_version, otp_display_count, tmp_cache_flags;
|
||||
int disable_authorized_users, allow_n_logins;
|
||||
|
||||
struct option longopts[] = {
|
||||
{ "authorized-users-db", 1, (void*)0L, 'a'},
|
||||
{ "disable-authorized-users", 0, (void*)0L, 'A'},
|
||||
{ "bind-ip-address", 1, (void*)0L, 'b'},
|
||||
{ "bind-udp-port", 1, (void*)0L, 'B'},
|
||||
#ifdef OOTP_ENABLE
|
||||
{ "display-count", 0, (void*)0L, 'c'},
|
||||
#endif /* OOTP_ENABLE */
|
||||
{ "debug", 1, (void*)0L, 'd'},
|
||||
{ "disable-daemon-mode", 0, (void*)0L, 'D'},
|
||||
{ "help", 0, (void*)0L, 'h'},
|
||||
{ "help", 0, (void*)0L, '?'},
|
||||
{ "pam-authentication-enable", 0, (void*)0L, 'm'},
|
||||
{ "pam-authentication-exclusive", 0, (void*)0L, 'M'},
|
||||
{ "n-logins-enable", 0, (void*)0L, 'n'},
|
||||
#ifdef OOTP_ENABLE
|
||||
{ "otp-db", 1, (void*)0L, 'o'},
|
||||
{ "otp-disable", 0, (void*)0L, 'O'},
|
||||
#endif /* OOTP_ENABLE */
|
||||
{ "password-db", 1, (void*)0L, 'p'},
|
||||
{ "pidfile", 1, (void*)0L, 'P'},
|
||||
{ "server-secret", 1, (void*)0L, 's'},
|
||||
{ "pam-service-name", 1, (void*)0L, 'S'},
|
||||
#ifdef OOTP_ENABLE
|
||||
{ "otp-allow-unknown-user", 0, (void*)0L, 'u'},
|
||||
{ "service-name", 0, (void*)0L, 'V'},
|
||||
{ "otp-challenge-window", 1, (void*)0L, 'w'},
|
||||
#endif /* OOTP_ENABLE */
|
||||
{ "debug-drop-udp-packets", 0, (void*)0L, 'x'},
|
||||
{ "version", 0, &opt_version, 1},
|
||||
{ 0, 0, 0, 0},
|
||||
};
|
||||
|
||||
bzero(&loc_addr, sizeof loc_addr);
|
||||
bzero(&pkt_fd, sizeof pkt_fd);
|
||||
bzero(&rfd, sizeof rfd);
|
||||
allow_n_logins = 0;
|
||||
opt_version = 0;
|
||||
debug = 0;
|
||||
daemon_mode = 1;
|
||||
authorized_users_fname = "/var/urd/authorized_users";
|
||||
au_fname = "/var/urd/authorized_users";
|
||||
disable_authorized_users = 0;
|
||||
pwfile_fname = "/var/urd/passwd";
|
||||
server_secret_fname = "/var/urd/server_secret";
|
||||
pid_fname = (char*)0L;
|
||||
|
@ -104,30 +146,36 @@ int main(int argc, char **argv)
|
|||
drop = 1;
|
||||
drop_mode = 0;
|
||||
otp_window = OTP_WINDOW_DEFAULT;
|
||||
pdb_type = PASS_DB_TYPE_LOCAL;
|
||||
as_name = "urd";
|
||||
service = "urd";
|
||||
#ifdef OOTP_ENABLE
|
||||
otpctx = (struct otp_ctx*)0L;
|
||||
otpdb_fname = OTP_DB_FNAME;
|
||||
otp_skip_unknown = 0;
|
||||
otp_allow_unknown = 0;
|
||||
otpdb_flags = 0;
|
||||
otp_enable = 1;
|
||||
otp_display_count = 0;
|
||||
#endif /* OOTP_ENABLE */
|
||||
|
||||
xerr_setid(argv[0]);
|
||||
|
||||
#ifdef OOTP_ENABLE
|
||||
while ((i = getopt(argc, argv, "AhduDOx?a:b:B:o:p:s:P:w:")) != -1) {
|
||||
while ((i = getopt_long(argc, argv, "AhduDOx?a:cb:B:mMno:p:s:S:P:V:w:",
|
||||
longopts, (int*)0L)) != -1) {
|
||||
#else
|
||||
while ((i = getopt(argc, argv, "AhdDx?a:b:B:p:s:P:w:")) != -1) {
|
||||
while ((i = getopt_long(argc, argv, "AhdDx?a:b:B:mMnp:s:S:P:V:",
|
||||
longopts, (int*)0L)) != -1) {
|
||||
#endif /* OOTP_ENABLE */
|
||||
|
||||
switch (i) {
|
||||
|
||||
case 'a':
|
||||
authorized_users_fname = optarg;
|
||||
au_fname = optarg;
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
authorized_users_fname = (char*)0L;
|
||||
disable_authorized_users = 1;
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
|
@ -144,6 +192,10 @@ int main(int argc, char **argv)
|
|||
local_port = tmpul;
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
otp_display_count = 1;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
debug ++;
|
||||
#ifdef OOTP_ENABLE
|
||||
|
@ -156,11 +208,23 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
|
||||
case 'h':
|
||||
case '"':
|
||||
case '?':
|
||||
usage();
|
||||
exit(0);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
pdb_type = PASS_DB_TYPE_PAM;
|
||||
break;
|
||||
|
||||
case 'M': /* xxx only here for compatability */
|
||||
disable_authorized_users = 1;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
allow_n_logins = 1;
|
||||
break;
|
||||
|
||||
#ifdef OOTP_ENABLE
|
||||
case 'o':
|
||||
otpdb_fname = optarg;
|
||||
|
@ -183,11 +247,18 @@ int main(int argc, char **argv)
|
|||
server_secret_fname = optarg;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
as_name = optarg;
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
service = optarg;
|
||||
break;
|
||||
|
||||
#ifdef OOTP_ENABLE
|
||||
case 'u':
|
||||
otp_skip_unknown = 1;
|
||||
otp_allow_unknown = 1;
|
||||
break;
|
||||
#endif /* OOTP_ENABLE */
|
||||
|
||||
case 'w':
|
||||
tmpul = strtoul(optarg, &endptr, 0);
|
||||
|
@ -197,14 +268,24 @@ int main(int argc, char **argv)
|
|||
xerr_errx(1, "Challenge window %lu > %lu.", tmpul, OTP_WINDOW_MAX);
|
||||
otp_window = tmpul;
|
||||
break;
|
||||
#endif /* OOTP_ENABLE */
|
||||
|
||||
case 'x':
|
||||
drop_mode = 1;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if (opt_version) {
|
||||
printf("%s\n", ootp_version);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
default:
|
||||
xerr_errx(1, "getopt_long(): fatal.");
|
||||
|
||||
} /* switch */
|
||||
|
||||
} /* while getopt() */
|
||||
} /* while getopt_long() */
|
||||
|
||||
if (daemon_mode) {
|
||||
|
||||
|
@ -216,10 +297,10 @@ int main(int argc, char **argv)
|
|||
|
||||
} /* daemon_mode */
|
||||
|
||||
buf_l = snprintf(buf, 1024, "urd start:");
|
||||
buf_l = snprintf(buf, sizeof(buf), "urd start:");
|
||||
if (debug) {
|
||||
for (i = 0; i < argc; ++i)
|
||||
buf_l += snprintf(buf+buf_l, 1024-buf_l, " %s", argv[i]);
|
||||
buf_l += snprintf(buf+buf_l, sizeof(buf)-buf_l, " %s", argv[i]);
|
||||
}
|
||||
xerr_info(buf);
|
||||
|
||||
|
@ -233,12 +314,12 @@ int main(int argc, char **argv)
|
|||
|
||||
if (local_ip || (local_port != URD_PORT)) {
|
||||
|
||||
buf_l = snprintf(buf, 1024,
|
||||
buf_l = snprintf(buf, sizeof(buf),
|
||||
"/var/urd/pid.%s.%d", inet_ntoa(loc_addr.sin_addr), (int)local_port);
|
||||
|
||||
} else {
|
||||
|
||||
buf_l = snprintf(buf, 1024, "/var/urd/pid");
|
||||
buf_l = snprintf(buf, sizeof(buf), "/var/urd/pid");
|
||||
|
||||
}
|
||||
|
||||
|
@ -255,10 +336,28 @@ int main(int argc, char **argv)
|
|||
URD_SECRET_LEN+1) < 0)
|
||||
xerr_errx(1, "server_secret_load(%s): fatal", server_secret_fname);
|
||||
|
||||
/* location is password file or pam service name */
|
||||
if (pdb_type == PASS_DB_TYPE_LOCAL)
|
||||
loc = pwfile_fname;
|
||||
else if (pdb_type == PASS_DB_TYPE_PAM)
|
||||
loc = as_name;
|
||||
else
|
||||
xerr_errx(1, "loc fatal, pdb_type=%d", pdb_type);
|
||||
|
||||
/* disable authorized users? */
|
||||
if (disable_authorized_users) {
|
||||
if (pdb_type == PASS_DB_TYPE_LOCAL)
|
||||
pdb_type = PASS_DB_TYPE_EX_LOCAL;
|
||||
else if (pdb_type == PASS_DB_TYPE_PAM)
|
||||
pdb_type = PASS_DB_TYPE_EX_PAM;
|
||||
else
|
||||
xerr_errx(1, "au fatal, pdb_type=%d", pdb_type);
|
||||
}
|
||||
|
||||
/* setup password database */
|
||||
if (!(pdbctx = pass_db_ctx_new(pwfile_fname, authorized_users_fname)))
|
||||
if (!(pdbctx = pass_db_ctx_new(loc, au_fname, pdb_type)))
|
||||
xerr_errx(1, "pass_db_ctx_new(%s,%s): fatal", pwfile_fname,
|
||||
authorized_users_fname);
|
||||
au_fname);
|
||||
|
||||
pass_db_debug(pdbctx, debug);
|
||||
|
||||
|
@ -338,7 +437,7 @@ int main(int argc, char **argv)
|
|||
* req_cache lookup:
|
||||
* hit :
|
||||
* rep_code and state_counter from cache
|
||||
* rep_msg from cache XXX future
|
||||
* rep_msg from cache
|
||||
* miss :
|
||||
* state_cache lookup :
|
||||
* hit :
|
||||
|
@ -392,6 +491,7 @@ int main(int argc, char **argv)
|
|||
rep_state = 0LL;
|
||||
rep_enc_flags = 0;
|
||||
rep_cache_flags = 0;
|
||||
rep_otp_count = 0;
|
||||
|
||||
/* initial no state access request */
|
||||
if (!urdctx->req.tlv_State) {
|
||||
|
@ -400,7 +500,8 @@ int main(int argc, char **argv)
|
|||
xerr_info("req: (no state)");
|
||||
|
||||
/* first check the cache for a previously composed reply */
|
||||
if ((r = urd_req_cache_lookup(urdctx, &rep_code, &rep_state)) < 0)
|
||||
if ((r = urd_req_cache_lookup(urdctx, &rep_code, &rep_state,
|
||||
&rep_otp_count, &tmp_cache_flags)) < 0)
|
||||
xerr_errx(1, "urd_req_cache_lookup(): fatal");
|
||||
|
||||
/* hit, then skip to response gen */
|
||||
|
@ -415,7 +516,10 @@ int main(int argc, char **argv)
|
|||
|
||||
} else if (rep_code == RADIUS_CODE_ACCESS_CHALLENGE) {
|
||||
|
||||
rep_enc_flags = URD_ENCODE_FLAG_STATE|URD_ENCODE_FLAG_MSG;
|
||||
rep_enc_flags = URD_ENCODE_FLAG_STATE;
|
||||
|
||||
if (tmp_cache_flags & URD_CACHE_FLAG_MSG)
|
||||
rep_enc_flags |= URD_ENCODE_FLAG_MSG;
|
||||
|
||||
}
|
||||
|
||||
|
@ -431,11 +535,11 @@ int main(int argc, char **argv)
|
|||
|
||||
}
|
||||
|
||||
/* default to reject */
|
||||
/* cache lookup invalid, default to ACCESS_REJECT */
|
||||
rep_code = RADIUS_CODE_ACCESS_REJECT;
|
||||
|
||||
/* check password database */
|
||||
if ((r = pass_db_auth(pdbctx, urdctx->req.user_name,
|
||||
/* authenticate user */
|
||||
if ((r = pass_db_auth(pdbctx, URDCTX_USER_NAME,
|
||||
urdctx->req.user_pass)) < 0)
|
||||
xerr_errx(1, "pass_db_auth(): fatal");
|
||||
|
||||
|
@ -492,12 +596,12 @@ int main(int argc, char **argv)
|
|||
goto access_request_rep;
|
||||
|
||||
#else /* OOTP_ENABLE */
|
||||
|
||||
/*
|
||||
* if one time passwords are disabled, then the password
|
||||
* check above meets auth requirements, reply with ACCEPT
|
||||
* if one time passwords are disabled then the password
|
||||
* check above meets auth requirements. Reply with ACCESS_ACCEPT.
|
||||
*
|
||||
*/
|
||||
|
||||
if (!otp_enable) {
|
||||
|
||||
rep_code = RADIUS_CODE_ACCESS_ACCEPT;
|
||||
|
@ -511,22 +615,67 @@ int main(int argc, char **argv)
|
|||
/*
|
||||
* check OTP
|
||||
*/
|
||||
if ((r = otp_user_exists(otpctx, urdctx->req.user_name)) < 0)
|
||||
if ((r = otp_user_exists(otpctx, URDCTX_USER_NAME)) < 0)
|
||||
xerr_errx(1, "otp_user_exists(): fail.");
|
||||
|
||||
/* if user does not exist and not okay to skip OTP users then fail */
|
||||
if ((r == 1) && (otp_skip_unknown == 0)) {
|
||||
|
||||
/*
|
||||
* if user does not exist and not okay to allow non OTP users
|
||||
* then authentication request fails with default ACCESS_REJECT.
|
||||
*/
|
||||
if ((r == 1) && (otp_allow_unknown == 0)) {
|
||||
|
||||
if (debug)
|
||||
xerr_info("req: fail via otp_user_exists() skip_unknown=0");
|
||||
xerr_info("req: fail via otp_user_exists() allow_unknown=0");
|
||||
|
||||
/* reply with an REJECT */
|
||||
rep_code = RADIUS_CODE_ACCESS_REJECT;
|
||||
|
||||
rep_enc_flags = 0x0;
|
||||
|
||||
goto access_request_rep;
|
||||
|
||||
}
|
||||
|
||||
if (otp_urec_open(otpctx, urdctx->req.user_name, &ou,
|
||||
/*
|
||||
* if user does not exist in database and okay to allow non OTP
|
||||
* users then authentication request is successful without OTP.
|
||||
* password check was done above, reply with ACCEPT
|
||||
*/
|
||||
if ((r == 1) && (otp_allow_unknown == 1)) {
|
||||
|
||||
if (debug)
|
||||
xerr_info("req: pass via otp_user_exists() allow_unknown=1");
|
||||
|
||||
/* reply with an ACCEPT, no state, no challenge message */
|
||||
rep_code = RADIUS_CODE_ACCESS_ACCEPT;
|
||||
|
||||
rep_enc_flags = 0x0;
|
||||
|
||||
goto access_request_rep;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* unknown response from otp_user_exists()
|
||||
*/
|
||||
if (r != 0) {
|
||||
|
||||
if (debug)
|
||||
xerr_info("otp_user_exists() unknown response r=%d", r);
|
||||
|
||||
/* reply with an REJECT */
|
||||
rep_code = RADIUS_CODE_ACCESS_REJECT;
|
||||
|
||||
rep_enc_flags = 0x0;
|
||||
|
||||
goto access_request_rep;
|
||||
|
||||
}
|
||||
|
||||
if (otp_urec_open(otpctx, URDCTX_USER_NAME, &ou,
|
||||
O_RDONLY, FFDB_OP_LOCK_EX) < 0)
|
||||
xerr_errx(1, "otp_urec_open(%s): failed.", urdctx->req.user_name);
|
||||
xerr_errx(1, "otp_urec_open(%s): failed.", URDCTX_USER_NAME);
|
||||
|
||||
if (otp_urec_get(otpctx, &ou) < 0)
|
||||
xerr_errx(1, "otp_urec_get(): failed.");
|
||||
|
@ -534,7 +683,7 @@ int main(int argc, char **argv)
|
|||
if (otp_urec_close(otpctx, &ou) < 0)
|
||||
xerr_errx(1, "otp_urec_close(): failed.");
|
||||
|
||||
/* disabled user is rejected */
|
||||
/* disabled user defaults to ACCESS_REJECT */
|
||||
if (ou.status == OTP_STATUS_DISABLED) {
|
||||
|
||||
if (debug)
|
||||
|
@ -579,12 +728,26 @@ int main(int argc, char **argv)
|
|||
/* reply with challenge, challenge message, new state */
|
||||
rep_code = RADIUS_CODE_ACCESS_CHALLENGE;
|
||||
|
||||
rep_enc_flags = URD_ENCODE_FLAG_STATE|URD_ENCODE_FLAG_MSG;
|
||||
rep_enc_flags = URD_ENCODE_FLAG_STATE;
|
||||
|
||||
rep_state = ++urdctx->state_counter;
|
||||
|
||||
rep_otp_count = ou.count;
|
||||
|
||||
rep_cache_flags = URD_CACHE_FLAG_STATE;
|
||||
|
||||
if (otp_display_count || ou.flags & OTP_FLAGS_DSPCNT) {
|
||||
rep_enc_flags |= URD_ENCODE_FLAG_MSG;
|
||||
rep_cache_flags |= URD_CACHE_FLAG_MSG;
|
||||
}
|
||||
|
||||
if (ou.flags & OTP_FLAGS_SEND_TOKEN) {
|
||||
|
||||
if (otp_user_send_token(otpctx, URDCTX_USER_NAME, service) < 0)
|
||||
xerr_warnx("otp_user_send_token(): failed.");
|
||||
|
||||
}
|
||||
|
||||
if (debug)
|
||||
xerr_info("req: pass via otp_user_get() (active)");
|
||||
|
||||
|
@ -606,9 +769,6 @@ int main(int argc, char **argv)
|
|||
/* reply with inbound state */
|
||||
rep_state = urdctx->req.state_counter;
|
||||
|
||||
/* default to reject */
|
||||
rep_code = RADIUS_CODE_ACCESS_REJECT;
|
||||
|
||||
if (debug)
|
||||
xerr_info("req: state set, nothing to do, REJECT.");
|
||||
|
||||
|
@ -621,7 +781,8 @@ int main(int argc, char **argv)
|
|||
if (debug)
|
||||
xerr_info("req: (state)");
|
||||
|
||||
if ((r = urd_req_cache_lookup(urdctx, &rep_code, &rep_state)) < 0)
|
||||
if ((r = urd_req_cache_lookup(urdctx, &rep_code, &rep_state,
|
||||
&rep_otp_count, &tmp_cache_flags)) < 0)
|
||||
xerr_errx(1, "urd_req_cache_lookup(): fatal");
|
||||
|
||||
/* hit, then skip to response gen */
|
||||
|
@ -641,12 +802,12 @@ int main(int argc, char **argv)
|
|||
|
||||
}
|
||||
|
||||
/* cache lookup invalid, default to ACCESS_REJECT */
|
||||
rep_code = RADIUS_CODE_ACCESS_REJECT;
|
||||
|
||||
/* reply with inbound state */
|
||||
rep_state = urdctx->req.state_counter;
|
||||
|
||||
/* default to reject */
|
||||
rep_code = RADIUS_CODE_ACCESS_REJECT;
|
||||
|
||||
/*
|
||||
* state cache lookup -- user must have previously authenticated
|
||||
* successfully to continue
|
||||
|
@ -660,6 +821,9 @@ int main(int argc, char **argv)
|
|||
if (debug)
|
||||
xerr_info("state: cache miss (user not validated with passwd)");
|
||||
|
||||
/* cache lookup invalid, default to ACCESS_REJECT */
|
||||
rep_code = RADIUS_CODE_ACCESS_REJECT;
|
||||
|
||||
goto access_request_rep;
|
||||
|
||||
} else {
|
||||
|
@ -680,12 +844,13 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
/*
|
||||
* default to reject. State cache lookup will have CHALLENGE
|
||||
* code as it is shared with the request cache.
|
||||
* default to ACCESS_REJECT. State cache lookup will have
|
||||
* ACCESS_CHALLENGE code as it is shared with the request cache.
|
||||
*/
|
||||
|
||||
rep_code = RADIUS_CODE_ACCESS_REJECT;
|
||||
|
||||
if ((r = otp_user_exists(otpctx, urdctx->req.user_name)) < 0)
|
||||
if ((r = otp_user_exists(otpctx, URDCTX_USER_NAME)) < 0)
|
||||
xerr_errx(1, "otp_user_exists(): fail.");
|
||||
|
||||
/* user exist?, if not failure */
|
||||
|
@ -699,9 +864,9 @@ int main(int argc, char **argv)
|
|||
|
||||
}
|
||||
|
||||
if (otp_urec_open(otpctx, urdctx->req.user_name, &ou,
|
||||
if (otp_urec_open(otpctx, URDCTX_USER_NAME, &ou,
|
||||
O_RDONLY, FFDB_OP_LOCK_EX) < 0)
|
||||
xerr_errx(1, "otp_urec_open(%s): failed.", urdctx->req.user_name);
|
||||
xerr_errx(1, "otp_urec_open(%s): failed.", URDCTX_USER_NAME);
|
||||
|
||||
if (otp_urec_get(otpctx, &ou) < 0)
|
||||
xerr_errx(1, "otp_urec_get(): failed.");
|
||||
|
@ -730,7 +895,7 @@ int main(int argc, char **argv)
|
|||
|
||||
}
|
||||
|
||||
if ((r = otp_user_auth(otpctx, urdctx->req.user_name,
|
||||
if ((r = otp_user_auth(otpctx, URDCTX_USER_NAME,
|
||||
urdctx->req.user_pass, otp_window)) < 0)
|
||||
xerr_errx(1, "otp_user_auth(): failed.");
|
||||
|
||||
|
@ -781,12 +946,13 @@ access_request_rep:
|
|||
* construct reply
|
||||
*/
|
||||
|
||||
if (urd_rep_encode(urdctx, rep_code, rep_state, rep_enc_flags) < 0) {
|
||||
if (urd_rep_encode(urdctx, rep_code, rep_state, rep_otp_count,
|
||||
rep_enc_flags) < 0) {
|
||||
xerr_errx(1, "urd_rep_encode(): fatal");
|
||||
}
|
||||
|
||||
/* update reply cache */
|
||||
if (urd_req_cache_update(urdctx, rep_code, rep_state,
|
||||
if (urd_req_cache_update(urdctx, rep_code, rep_state, rep_otp_count,
|
||||
rep_cache_flags) < 0)
|
||||
xerr_errx(1, "urd_req_cache_update(): fatal");
|
||||
|
||||
|
@ -973,7 +1139,7 @@ int write_pidfile(char *fname)
|
|||
int fd, buf_l;
|
||||
char buf[512];
|
||||
|
||||
buf_l = snprintf(buf, 512, "%lu\n", (unsigned long)getpid());
|
||||
buf_l = snprintf(buf, sizeof(buf), "%lu\n", (unsigned long)getpid());
|
||||
|
||||
if ((fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0 ) {
|
||||
xerr_warn("open(%s)", fname);
|
||||
|
@ -998,21 +1164,23 @@ void usage(void)
|
|||
{
|
||||
#ifdef OOTP_ENABLE
|
||||
fprintf(stderr,
|
||||
"urd [-AhdDOux?] [-a allowed_users_file] [-b local_ip] [-B local_port ]\n");
|
||||
"urd [-AhcdDmMnOux?] [-a allowed_users_file] [-b local_ip] [-B local_port ]\n");
|
||||
fprintf(stderr,
|
||||
" [-o otp_db] [-p passwd_file] [-P pid_file] [-s secret_file]\n");
|
||||
#else
|
||||
fprintf(stderr,
|
||||
"urd [-AhdDx?] [-a allowed_users_file] [-b local_ip] [-B local_port ]\n");
|
||||
"urd [-AdDmMnhx?] [-a allowed_users_file] [-b local_ip] [-B local_port ]\n");
|
||||
fprintf(stderr,
|
||||
" [-p passwd_file] [-P pid_file] [-s secret_file]\n");
|
||||
|
||||
#endif /* OOTP_ENABLE */
|
||||
fprintf(stderr, " [-w otp_window]\n\n");
|
||||
fprintf(stderr, " [-S auth_service_name] [-w otp_window]\n\n");
|
||||
fprintf(stderr, " -A disable authorized_users file (all users in passwd_file valid)\n");
|
||||
fprintf(stderr, " -h help\n");
|
||||
fprintf(stderr, " -d enable debugging\n");
|
||||
fprintf(stderr, " -D disable daemon mode\n");
|
||||
fprintf(stderr, " -m use PAM for password authentication\n");
|
||||
fprintf(stderr, " -M use PAM exclusively for password authentication\n");
|
||||
#ifdef OOTP_ENABLE
|
||||
fprintf(stderr, " -O disable one time passwords\n");
|
||||
fprintf(stderr, " -u allow users which do not exist in OTP database\n");
|
||||
|
|
Loading…
Reference in a new issue