mirror of
https://github.com/paulusmack/ppp.git
synced 2024-11-23 02:13:28 +08:00
Added EAP support with MD5-Challenge and SRP-SHA1 methods. Tested
on Linux (with both methods) and on Solaris (just MD5-Challenge). Fixed several Makefiles that were missing references to required modules such as tty.o.
This commit is contained in:
parent
767b224b09
commit
d741a3b912
149
README.eap-srp
Normal file
149
README.eap-srp
Normal file
@ -0,0 +1,149 @@
|
||||
EAP with MD5-Challenge and SRP-SHA1 support
|
||||
by James Carlson, Sun Microsystems
|
||||
Version 2, September 22nd, 2002
|
||||
|
||||
|
||||
1. What it does
|
||||
|
||||
The Extensible Authentication Protocol (EAP; RFC 2284) is a
|
||||
security protocol that can be used with PPP. It provides a means
|
||||
to plug in multiple optional authentication methods.
|
||||
|
||||
This implementation includes the required default MD5-Challenge
|
||||
method, which is similar to CHAP (RFC 1994), as well as the new
|
||||
SRP-SHA1 method. This latter method relies on an exchange that is
|
||||
not vulnerable to dictionary attacks (as is CHAP), does not
|
||||
require the server to keep a cleartext copy of the secret (as in
|
||||
CHAP), supports identity privacy, and produces a temporary shared
|
||||
key that could be used for data encryption.
|
||||
|
||||
The SRP-SHA1 method is based on draft-ietf-pppext-eap-srp-03.txt,
|
||||
a work in progress.
|
||||
|
||||
2. Required libraries
|
||||
|
||||
Two other packages are required first. Download and install
|
||||
OpenSSL and Thomas Wu's SRP implementation.
|
||||
|
||||
http://www.openssl.org/ (or ftp://ftp.openssl.org/source/)
|
||||
http://srp.stanford.edu/
|
||||
|
||||
Follow the directions in each package to install the SSL and SRP
|
||||
libraries. Once SRP is installed, you may run tconf as root to
|
||||
create known fields, if desired. (This step is not required.)
|
||||
|
||||
3. Installing the patch
|
||||
|
||||
The EAP-SRP patch described here is integrated into this version
|
||||
of pppd. The following patch may be used with older pppd sources:
|
||||
|
||||
ftp://playground.sun.com/carlsonj/eap/ppp-2.4.1-eap-1.tar.gz
|
||||
|
||||
Configure, compile, and install as root. You may want to edit
|
||||
pppd/Makefile after configuring to enable or disable optional
|
||||
features.
|
||||
|
||||
% ./configure
|
||||
% make
|
||||
% su
|
||||
# make install
|
||||
|
||||
If you use csh or tcsh, run "rehash" to pick up the new commands.
|
||||
|
||||
If you're using Solaris, and you run into trouble with the
|
||||
pseudonym feature on the server side ("no DES here" shows in the
|
||||
log file), make sure that you have the "domestic" versions of the
|
||||
DES libraries linked. You should see "crypt_d" in "ldd
|
||||
/usr/local/bin/pppd". If you see "crypt_i" instead, then make
|
||||
sure that /usr/lib/libcrypt.* links to /usr/lib/libcrypt_d.*. (If
|
||||
you have the international version of Solaris, then you won't have
|
||||
crypt_d. You might want to find an alternative DES library.)
|
||||
|
||||
4. Adding the secrets
|
||||
|
||||
On the EAP SRP-SHA1 client side, access to the cleartext secret is
|
||||
required. This can be done in two ways:
|
||||
|
||||
- Enter the client name, server name, and password in the
|
||||
/etc/ppp/srp-secrets file. This file has the same format as
|
||||
the existing chap-secrets and pap-secrets files.
|
||||
|
||||
clientname servername "secret here"
|
||||
|
||||
- Use the "password" option in any of the standard
|
||||
configuration files (or the command line) to specify the
|
||||
secret.
|
||||
|
||||
password "secret here"
|
||||
|
||||
On the EAP SRP-SHA1 server side, a secret verifier is required.
|
||||
This is a one-way hash of the client's name and password. To
|
||||
generate this value, run the srp-entry program (see srp-entry(8)).
|
||||
This program prompts for the client name and the passphrase (the
|
||||
secret). The output will be an entry, such as the following,
|
||||
suitable for use in the server's srp-secrets file. Note that if
|
||||
this is transferred by cut-and-paste, the entry must be a single
|
||||
line of text in the file.
|
||||
|
||||
pppuser srpserver 0:LFDpwg4HBLi4/kWByzbZpW6pE95/iIWBSt7L.DAkHsvwQphtiq0f6reoUy/1LC1qYqjcrV97lCDmQHQd4KIACGgtkhttLdP3KMowvS0wLXLo25FPJeG2sMAUEWu/HlJPn2/gHyh9aT.ZxUs5MsoQ1E61sJkVBc.2qze1CdZiQGTK3qtWRP6DOpM1bfhKtPoVm.g.MiCcTMWzc54xJUIA0mgKtpthE3JrqCc81cXUt4DYi5yBzeeGTqrI0z2/Gj8Jp7pS4Fkq3GmnYjMxnKfQorFXNwl3m7JSaPa8Gj9/BqnorJOsnSMlIhBe6dy4CYytuTbNb4Wv/nFkmSThK782V:2cIyMp1yKslQgE *
|
||||
|
||||
The "secret" field consists of three entries separated by colons.
|
||||
The first entry is the index of the modulus and generator from
|
||||
SRP's /etc/tpasswd.conf. If the special value 0 is used, then the
|
||||
well-known modulus/generator value is used (this is recommended,
|
||||
because it is much faster). The second value is the verifier
|
||||
value. The third is the password "salt." These latter two values
|
||||
are encoded in base64 notation.
|
||||
|
||||
For EAP MD5-Challenge, both client and server use the existing
|
||||
/etc/ppp/chap-secrets file.
|
||||
|
||||
5. Configuration options
|
||||
|
||||
There are two main options relating to EAP available for the
|
||||
client. These are:
|
||||
|
||||
refuse-eap - refuse to authenticate with EAP
|
||||
srp-use-pseudonym - use the identity privacy if
|
||||
offered by server
|
||||
|
||||
The second option stores a pseudonym, if offered by the EAP
|
||||
SRP-SHA1 server, in the $HOME/.ppp_pseudonym file. The pseudonym
|
||||
is typically an encrypted version of the client identity. During
|
||||
EAP start-up, the pseudonym stored in this file is offered to the
|
||||
peer as the identity. If this is accepted by the peer, then
|
||||
eavesdroppers will be unable to determine the identity of the
|
||||
client. Each time the client is authenticated, the server will
|
||||
offer a new pseudoname to the client using an obscured (reversibly
|
||||
encrypted) message. Thus, access across successive sessions
|
||||
cannot be tracked.
|
||||
|
||||
There are two main options for EAP on the server:
|
||||
|
||||
require-eap - require client to use EAP
|
||||
srp-pn-secret "string" - set server's pseudoname secret
|
||||
|
||||
The second option sets the long-term secret used on the server to
|
||||
encrypt the user's identity to produce pseudonames. The
|
||||
pseudoname is constructed by hashing this string with the current
|
||||
date (to the nearest day) with SHA1, then using this hash as the
|
||||
key for a DES encryption of the client's name. The date is added
|
||||
to the hash for two reasons. First, this allows the pseudonym to
|
||||
change daily. Second, it allows the server to decode any previous
|
||||
pseudonym by trying previous dates.
|
||||
|
||||
See the pppd(8) man page for additional options.
|
||||
|
||||
6. Comments welcome!
|
||||
|
||||
This is still an experimental implementation. It has been tested
|
||||
and reviewed carefully for correctness, but may still be
|
||||
incomplete or have other flaws. All comments are welcome. Please
|
||||
address them to the author:
|
||||
|
||||
james.d.carlson@sun.com
|
||||
|
||||
or, for EAP itself or the SRP extensions to EAP, to the IETF PPP
|
||||
Extensions working group:
|
||||
|
||||
ietf-ppp@merit.edu
|
14
configure
vendored
14
configure
vendored
@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# $Id: configure,v 1.29 2002/09/07 05:15:25 carlsonj Exp $
|
||||
# $Id: configure,v 1.30 2002/11/02 19:48:12 carlsonj Exp $
|
||||
|
||||
# if [ -d /NextApps ]; then
|
||||
# system="NeXTStep"
|
||||
@ -21,8 +21,8 @@ case $system in
|
||||
# [0-3]*) state="ancient";;
|
||||
# 4*) state="known"; ksrc="sunos4"; makext="sunos4";;
|
||||
5.[7-9]*|5.[1-9][0-9]) state="known"; ksrc="solaris"; makext="sol2";
|
||||
case $arch in
|
||||
sun4u) archvariant='-64';;
|
||||
case "`/usr/bin/isainfo -k`" in
|
||||
sparcv9) archvariant='-64';;
|
||||
*) ;;
|
||||
esac;;
|
||||
5.[1-6]*) state="known"; ksrc="solaris"; makext="sol2";;
|
||||
@ -33,7 +33,7 @@ case $system in
|
||||
elif gcc --version >/dev/null 2>&1; then
|
||||
archvariant=gcc$archvariant
|
||||
compiletype=.gcc
|
||||
if [ "$arch" = "sun4u" ]; then
|
||||
if [ "$archvariant" = "gcc-64" ]; then
|
||||
( cd /tmp; touch ppp$$.c
|
||||
gcc -c -m64 ppp$$.c >/dev/null 2>&1 || (
|
||||
echo "gcc is unable to make 64 bit modules, and your $arch system needs them."
|
||||
@ -125,10 +125,12 @@ case $state in
|
||||
echo "This is a newer release of $system than is supported by"
|
||||
echo "this software. It may or may not work.";;
|
||||
unknown)
|
||||
echo "This software has not been ported to this system. Sorry.";;
|
||||
echo "This software has not been ported to $system. Sorry.";;
|
||||
notincluded)
|
||||
echo "Support for this system has not been included"
|
||||
echo "Support for $system has not been included"
|
||||
echo "in this distribution. Sorry.";;
|
||||
known)
|
||||
echo "Configuring for $system";;
|
||||
esac
|
||||
|
||||
if [ -d "$ksrc" ]; then
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: ppp_defs.h,v 1.15 2002/05/21 17:26:48 dfs Exp $ */
|
||||
/* $Id: ppp_defs.h,v 1.16 2002/11/02 19:48:12 carlsonj Exp $ */
|
||||
|
||||
/*
|
||||
* ppp_defs.h - PPP definitions.
|
||||
@ -85,6 +85,7 @@
|
||||
#define PPP_LQR 0xc025 /* Link Quality Report protocol */
|
||||
#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */
|
||||
#define PPP_CBCP 0xc029 /* Callback Control Protocol */
|
||||
#define PPP_EAP 0xc227 /* Extensible Authentication Protocol */
|
||||
|
||||
/*
|
||||
* Values for FCS calculations.
|
||||
|
@ -1,8 +1,8 @@
|
||||
#
|
||||
# pppd makefile for NeXT
|
||||
#
|
||||
# $Orignial: Makefile.ultrix,v 1.4 1994/09/01 00:40:40 paulus Exp $
|
||||
# $Id: Makefile.NeXT,v 1.7 2002/05/21 17:26:48 dfs Exp $
|
||||
# $Original: Makefile.ultrix,v 1.4 1994/09/01 00:40:40 paulus Exp $
|
||||
# $Id: Makefile.NeXT,v 1.8 2002/11/02 19:48:12 carlsonj Exp $
|
||||
#
|
||||
|
||||
ARCHFLAGS =
|
||||
@ -10,8 +10,8 @@ ARCHFLAGS =
|
||||
BINDIR = /usr/local/ppp/bin
|
||||
MANDIR = /usr/local/ppp/man
|
||||
|
||||
OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
|
||||
ecp.o auth.o options.o demand.o utils.o sys-NeXT.o
|
||||
OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o eap.o md5.o ccp.o \
|
||||
ecp.o auth.o options.o demand.o utils.o sys-NeXT.o tty.o
|
||||
|
||||
#
|
||||
# For HPPA and SPARC, define FIXSIGS to get around posix bugs in
|
||||
|
@ -1,6 +1,6 @@
|
||||
#
|
||||
# pppd makefile for AIX 4.1
|
||||
# $Id: Makefile.aix4,v 1.5 2002/05/21 17:26:48 dfs Exp $
|
||||
# $Id: Makefile.aix4,v 1.6 2002/11/02 19:48:12 carlsonj Exp $
|
||||
#
|
||||
#ifndef BINDIR
|
||||
BINDIR = /usr/sbin
|
||||
@ -10,12 +10,14 @@ MANDIR = /usr/man
|
||||
#ENDIF
|
||||
|
||||
PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
|
||||
ecp.c auth.c options.c demand.c utils.c sys-aix4.c \
|
||||
gencode.c grammar.c scanner.c nametoaddr.c optimize.c
|
||||
ecp.c auth.c options.c demand.c utils.c sys-aix4.c eap.c tty.c
|
||||
|
||||
PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o \
|
||||
ecp.o auth.o options.o demand.o utils.o sys-aix4.o \
|
||||
gencode.o grammar.o scanner.o nametoaddr.o optimize.o
|
||||
ecp.o auth.o options.o demand.o utils.o sys-aix4.o eap.o tty.o
|
||||
|
||||
# xxx what are these? They're not here.
|
||||
# gencode.c grammar.c scanner.c nametoaddr.c optimize.c
|
||||
# gencode.o grammar.o scanner.o nametoaddr.o optimize.o
|
||||
|
||||
CC = xlc
|
||||
DEBUG_FLAGS = -DDEBUGALL
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $Id: Makefile.bsd,v 1.16 2002/05/21 17:26:48 dfs Exp $
|
||||
# $Id: Makefile.bsd,v 1.17 2002/11/02 19:48:12 carlsonj Exp $
|
||||
|
||||
BINDIR?= /usr/sbin
|
||||
# -D_BITYPES is for FreeBSD, which doesn't define anything to
|
||||
@ -8,7 +8,7 @@ CFLAGS+= -g -I../include -DHAVE_PATHS_H -D_BITYPES
|
||||
|
||||
PROG= pppd
|
||||
SRCS= main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c \
|
||||
ecp.c demand.c auth.c options.c utils.c sys-bsd.c
|
||||
ecp.c demand.c auth.c options.c utils.c sys-bsd.c eap.c tty.c
|
||||
MAN= pppd.cat8
|
||||
MAN8= pppd.8
|
||||
BINMODE=4555
|
||||
|
@ -1,6 +1,6 @@
|
||||
#
|
||||
# pppd makefile for Linux
|
||||
# $Id: Makefile.linux,v 1.53 2002/10/27 12:56:26 fcusack Exp $
|
||||
# $Id: Makefile.linux,v 1.54 2002/11/02 19:48:12 carlsonj Exp $
|
||||
#
|
||||
|
||||
# Default installation locations
|
||||
@ -8,19 +8,19 @@ BINDIR = $(DESTDIR)/usr/sbin
|
||||
MANDIR = $(DESTDIR)/usr/man
|
||||
INCDIR = $(DESTDIR)/usr/include
|
||||
|
||||
PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c ecp.c \
|
||||
ipxcp.c auth.c options.c sys-linux.c md4.c chap_ms.c cbcp.c \
|
||||
demand.c utils.c tty.c sha1.c
|
||||
TARGETS = pppd
|
||||
|
||||
HEADERS = cbcp.h ccp.h chap.h chap_ms.h ecp.h fsm.h ipcp.h \
|
||||
ipxcp.h lcp.h magic.h md4.h md5.h patchlevel.h pathnames.h pppd.h \
|
||||
sha1.h tdb.h upap.h
|
||||
PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c ecp.c \
|
||||
ipxcp.c auth.c options.c sys-linux.c md4.c chap_ms.c \
|
||||
demand.c utils.c tty.c eap.c
|
||||
|
||||
HEADERS = ccp.h chap.h ecp.h fsm.h ipcp.h \
|
||||
ipxcp.h lcp.h magic.h md5.h patchlevel.h pathnames.h pppd.h \
|
||||
upap.h eap.h
|
||||
|
||||
MANPAGES = pppd.8
|
||||
PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o ecp.o \
|
||||
auth.o options.o demand.o utils.o sys-linux.o ipxcp.o tty.o sha1.o
|
||||
|
||||
all: pppd
|
||||
auth.o options.o demand.o utils.o sys-linux.o ipxcp.o tty.o eap.o
|
||||
|
||||
#
|
||||
# include dependencies if present
|
||||
@ -33,14 +33,11 @@ endif
|
||||
COPTS = -O2 -pipe -Wall -g
|
||||
LIBS =
|
||||
|
||||
ifneq ($(wildcard /usr/lib/libcrypt.*),)
|
||||
LIBS += -lcrypt
|
||||
endif
|
||||
|
||||
# Uncomment the next 2 lines to include support for Microsoft's
|
||||
# MS-CHAP authentication protocol. Also, edit plugins/radius/Makefile.linux.
|
||||
CHAPMS=y
|
||||
USE_CRYPT=y
|
||||
MSLANMAN=y
|
||||
# Uncomment the next line to include support for MPPE. CHAPMS (above) must
|
||||
# also be enabled. Also, edit plugins/radius/Makefile.linux.
|
||||
MPPE=y
|
||||
@ -68,10 +65,15 @@ HAS_SHADOW=y
|
||||
#USE_PAM=y
|
||||
#HAVE_INET6=y
|
||||
|
||||
# Enable plugins
|
||||
PLUGIN=y
|
||||
|
||||
# Enable Microsoft proprietary Callback Control Protocol
|
||||
#CBCP=y
|
||||
|
||||
# Enable EAP SRP-SHA1 authentication (requires libsrp)
|
||||
USE_SRP=y
|
||||
|
||||
MAXOCTETS=y
|
||||
|
||||
INCLUDE_DIRS= -I../include
|
||||
@ -82,15 +84,9 @@ CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS)
|
||||
|
||||
ifdef CHAPMS
|
||||
CFLAGS += -DCHAPMS=1
|
||||
ifndef USE_CRYPT
|
||||
LIBS := -ldes $(LIBS)
|
||||
else
|
||||
CFLAGS += -DUSE_CRYPT=1
|
||||
ifneq ($(wildcard /usr/include/crypt.h),)
|
||||
CFLAGS += -DHAVE_CRYPT_H=1
|
||||
endif
|
||||
endif
|
||||
NEEDDES=y
|
||||
PPPDOBJS += md4.o chap_ms.o
|
||||
HEADERS += md4.h chap_ms.h
|
||||
ifdef MSLANMAN
|
||||
CFLAGS += -DMSLANMAN=1
|
||||
endif
|
||||
@ -99,15 +95,49 @@ CFLAGS += -DMPPE=1
|
||||
endif
|
||||
endif
|
||||
|
||||
# EAP SRP-SHA1
|
||||
ifdef USE_SRP
|
||||
CFLAGS += -DUSE_SRP -DOPENSSL -I/usr/local/ssl/include
|
||||
LIBS += -lsrp -L/usr/local/ssl/lib -lcrypto
|
||||
TARGETS += srp-entry
|
||||
EXTRAINSTALL = $(INSTALL) -s -c -m 555 srp-entry $(BINDIR)/srp-entry
|
||||
MANPAGES += srp-entry.8
|
||||
EXTRACLEAN += srp-entry.o
|
||||
NEEDDES=y
|
||||
else
|
||||
# OpenSSL has an integrated version of SHA-1, and its implementation
|
||||
# is incompatible with this local SHA-1 implementation. We must use
|
||||
# one or the other, not both.
|
||||
PPPDSRCS += sha1.c
|
||||
HEADERS += sha1.h
|
||||
PPPDOBJS += sha1.o
|
||||
endif
|
||||
|
||||
ifdef HAS_SHADOW
|
||||
CFLAGS += -DHAS_SHADOW
|
||||
#LIBS := -lshadow $(LIBS)
|
||||
#LIBS += -lshadow $(LIBS)
|
||||
endif
|
||||
|
||||
ifdef NEEDDES
|
||||
ifndef USE_CRYPT
|
||||
LIBS += -ldes $(LIBS)
|
||||
else
|
||||
CFLAGS += -DUSE_CRYPT=1
|
||||
ifneq ($(wildcard /usr/include/crypt.h),)
|
||||
CFLAGS += -DHAVE_CRYPT_H=1
|
||||
endif
|
||||
ifneq ($(wildcard /usr/lib/libcrypt.*),)
|
||||
LIBS += -lcrypt
|
||||
endif
|
||||
endif
|
||||
PPPDOBJS += pppcrypt.o
|
||||
HEADERS += pppcrypt.h
|
||||
endif
|
||||
|
||||
# For "Pluggable Authentication Modules", see ftp.redhat.com:/pub/pam/.
|
||||
ifdef USE_PAM
|
||||
CFLAGS += -DUSE_PAM
|
||||
LIBS := -lpam -ldl $(LIBS)
|
||||
LIBS += -lpam -ldl
|
||||
endif
|
||||
|
||||
# Multi-linnk
|
||||
@ -125,11 +155,12 @@ ifdef USE_TDB
|
||||
CFLAGS += -DUSE_TDB=1
|
||||
PPPDSRCS += tdb.c
|
||||
PPPDOBJS += tdb.o
|
||||
HEADERS += tdb.h
|
||||
endif
|
||||
|
||||
# Lock library binary for Linux is included in 'linux' subdirectory.
|
||||
ifdef LOCKLIB
|
||||
LIBS := -llock $(LIBS)
|
||||
LIBS += -llock
|
||||
CFLAGS += -DLOCKLIB=1
|
||||
endif
|
||||
|
||||
@ -152,8 +183,10 @@ ifdef HAVE_INET6
|
||||
endif
|
||||
|
||||
ifdef CBCP
|
||||
PPPDSRCS += cbcp.c
|
||||
PPPDOBJS += cbcp.o
|
||||
CFLAGS += -DCBCP_SUPPORT
|
||||
HEADERS += cbcp.h
|
||||
endif
|
||||
|
||||
ifdef MAXOCTETS
|
||||
@ -162,8 +195,11 @@ endif
|
||||
|
||||
INSTALL= install -o root
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
install: pppd
|
||||
mkdir -p $(BINDIR) $(MANDIR)
|
||||
$(EXTRAINSTALL)
|
||||
$(INSTALL) -s -c -m 555 pppd $(BINDIR)/pppd
|
||||
if chgrp pppusers $(BINDIR)/pppd 2>/dev/null; then \
|
||||
chmod o-rx,u+s $(BINDIR)/pppd; fi
|
||||
@ -172,12 +208,15 @@ install: pppd
|
||||
pppd: $(PPPDOBJS)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o pppd $(PPPDOBJS) $(LIBS)
|
||||
|
||||
srp-entry: srp-entry.c
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ srp-entry.c $(LIBS)
|
||||
|
||||
install-devel:
|
||||
mkdir -p $(INCDIR)/pppd
|
||||
$(INSTALL) -c -m 644 $(HEADERS) $(INCDIR)/pppd
|
||||
|
||||
clean:
|
||||
rm -f $(PPPDOBJS) pppd *~ #* core
|
||||
rm -f $(PPPDOBJS) $(EXTRACLEAN) $(TARGETS) *~ #* core
|
||||
|
||||
depend:
|
||||
$(CPP) -M $(CFLAGS) $(PPPDSRCS) >.depend
|
||||
|
@ -4,7 +4,8 @@ PCAPDIR=${.CURDIR}/../../lib/libpcap
|
||||
|
||||
PROG= pppd
|
||||
SRCS= auth.c cbcp.c ccp.c ecp.c chap.c chap_ms.c demand.c fsm.c ipcp.c \
|
||||
ipxcp.c lcp.c magic.c main.c options.c sys-bsd.c upap.c
|
||||
ipxcp.c lcp.c magic.c main.c options.c sys-bsd.c upap.c eap.c tty.c \
|
||||
utils.c
|
||||
|
||||
.PATH: ${PCAPDIR} ${.CURDIR}/../../sys/net
|
||||
MAN= pppd.8 pppd.cbcp.8
|
||||
@ -12,6 +13,7 @@ SUBDIR= pppstats chat
|
||||
BINMODE=4555
|
||||
BINOWN= root
|
||||
|
||||
# pick up md5, md4, and sha1
|
||||
LDADD= -lpcap -lcrypt -lutil
|
||||
DPADD= ${LIBPCAP} ${LIBCRYPT} ${LIBUTIL}
|
||||
CFLAGS+= -I. -I../include -DHAVE_PATHS_H -I${PCAPDIR} -DPPP_FILTER
|
||||
|
@ -1,16 +1,18 @@
|
||||
#
|
||||
# pppd makefile for OSF/1 on DEC Alpha
|
||||
# $Id: Makefile.osf,v 1.12 2002/05/21 17:26:48 dfs Exp $
|
||||
# $Id: Makefile.osf,v 1.13 2002/11/02 19:48:12 carlsonj Exp $
|
||||
#
|
||||
|
||||
BINDIR = /usr/local/etc
|
||||
MANDIR = /usr/local/man
|
||||
|
||||
PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c ecp.c \
|
||||
auth.c options.c demand.c utils.c sys-osf.c md4.c chap_ms.c sha1.c
|
||||
auth.c options.c demand.c utils.c sys-osf.c md4.c chap_ms.c sha1.c \
|
||||
eap.c tty.c
|
||||
|
||||
PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o ecp.o \
|
||||
auth.o options.o demand.o utils.o sys-osf.o md4.o chap_ms.o sha1.o
|
||||
auth.o options.o demand.o utils.o sys-osf.o md4.o chap_ms.o sha1.o \
|
||||
eap.o tty.o
|
||||
|
||||
CC = cc
|
||||
#DEBUG_FLAGS = -DDEBUGALL
|
||||
|
@ -1,6 +1,6 @@
|
||||
#
|
||||
# Makefile for pppd under Solaris 2.
|
||||
# $Id: Makefile.sol2,v 1.22 2002/09/07 05:15:25 carlsonj Exp $
|
||||
# $Id: Makefile.sol2,v 1.23 2002/11/02 19:48:12 carlsonj Exp $
|
||||
#
|
||||
|
||||
include ../Makedefs.com
|
||||
@ -8,8 +8,8 @@ include ../Makedefs.com
|
||||
CFLAGS = -I../include -DSVR4 -DSOL2 $(COPTS)
|
||||
LIBS = -lsocket -lnsl
|
||||
|
||||
OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o tty.o \
|
||||
ccp.o ecp.o auth.o options.o demand.o utils.o sys-solaris.o tdb.o
|
||||
OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o eap.o md5.o tty.o \
|
||||
ccp.o ecp.o auth.o options.o demand.o utils.o sys-solaris.o
|
||||
|
||||
#
|
||||
# uncomment the following to enable plugins
|
||||
|
@ -1,6 +1,6 @@
|
||||
#
|
||||
# Makefile for pppd under SunOS 4.
|
||||
# $Id: Makefile.sunos4,v 1.12 2002/05/21 17:26:48 dfs Exp $
|
||||
# $Id: Makefile.sunos4,v 1.13 2002/11/02 19:48:12 carlsonj Exp $
|
||||
#
|
||||
|
||||
include ../sunos4/Makedefs
|
||||
@ -13,7 +13,7 @@ CFLAGS = $(COPTS) -I../include -DSUNOS4 -DGIDSET_TYPE=int \
|
||||
all: pppd
|
||||
|
||||
OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o ecp.o \
|
||||
auth.o options.o demand.o utils.o sys-sunos4.o tty.o
|
||||
auth.o options.o demand.o utils.o sys-sunos4.o tty.o eap.o
|
||||
|
||||
pppd: $(OBJS)
|
||||
$(CC) -o pppd $(OBJS) $(LIBS)
|
||||
|
@ -1,6 +1,6 @@
|
||||
#
|
||||
# Makefile for pppd under Solaris 2.
|
||||
# $Id: Makefile.svr4,v 1.15 2002/05/21 17:26:48 dfs Exp $
|
||||
# Makefile for pppd on generic System V release 4
|
||||
# $Id: Makefile.svr4,v 1.16 2002/11/02 19:48:12 carlsonj Exp $
|
||||
#
|
||||
|
||||
include ../svr4/Makedefs
|
||||
@ -11,7 +11,7 @@ LIBS = -lsocket -lnsl -lc -L/usr/ucblib -lucb
|
||||
all: pppd
|
||||
|
||||
OBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o ecp.o \
|
||||
auth.o options.o demand.o utils.o sys-svr4.o
|
||||
auth.o options.o demand.o utils.o sys-svr4.o eap.o tty.o
|
||||
|
||||
pppd: $(OBJS)
|
||||
$(CC) -o pppd $(OBJS) $(LIBS)
|
||||
|
@ -1,16 +1,16 @@
|
||||
#
|
||||
# pppd makefile for Ultrix
|
||||
# $Id: Makefile.ultrix,v 1.12 2002/05/21 17:26:49 dfs Exp $
|
||||
# $Id: Makefile.ultrix,v 1.13 2002/11/02 19:48:12 carlsonj Exp $
|
||||
#
|
||||
|
||||
BINDIR = /usr/local/etc
|
||||
MANDIR = /usr/local/man
|
||||
|
||||
PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap.c md5.c ccp.c ecp.c \
|
||||
auth.c options.c demand.c utils.c sys-ultrix.c
|
||||
auth.c options.c demand.c utils.c sys-ultrix.c eap.c tty.c
|
||||
|
||||
PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap.o md5.o ccp.o ecp.o \
|
||||
auth.o options.o demand.o utils.o sys-ultrix.o
|
||||
auth.o options.o demand.o utils.o sys-ultrix.o eap.o tty.o
|
||||
|
||||
# CC = gcc
|
||||
DEBUG_FLAGS =
|
||||
|
202
pppd/auth.c
202
pppd/auth.c
@ -32,7 +32,7 @@
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#define RCSID "$Id: auth.c,v 1.88 2002/10/27 12:56:26 fcusack Exp $"
|
||||
#define RCSID "$Id: auth.c,v 1.89 2002/11/02 19:48:12 carlsonj Exp $"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
@ -74,6 +74,7 @@
|
||||
#include "ipcp.h"
|
||||
#include "upap.h"
|
||||
#include "chap.h"
|
||||
#include "eap.h"
|
||||
#ifdef CBCP_SUPPORT
|
||||
#include "cbcp.h"
|
||||
#endif
|
||||
@ -180,6 +181,7 @@ bool uselogin = 0; /* Use /etc/passwd for checking PAP */
|
||||
bool cryptpap = 0; /* Passwords in pap-secrets are encrypted */
|
||||
bool refuse_pap = 0; /* Don't wanna auth. ourselves with PAP */
|
||||
bool refuse_chap = 0; /* Don't wanna auth. ourselves with CHAP */
|
||||
bool refuse_eap = 0; /* Don't wanna auth. ourselves with EAP */
|
||||
#ifdef CHAPMS
|
||||
bool refuse_mschap = 0; /* Don't wanna auth. ourselves with MS-CHAP */
|
||||
bool refuse_mschap_v2 = 0; /* Don't wanna auth. ourselves with MS-CHAPv2 */
|
||||
@ -208,10 +210,12 @@ static int null_login __P((int));
|
||||
static int get_pap_passwd __P((char *));
|
||||
static int have_pap_secret __P((int *));
|
||||
static int have_chap_secret __P((char *, char *, int, int *));
|
||||
static int have_srp_secret __P((char *client, char *server, int need_ip,
|
||||
int *lacks_ipp));
|
||||
static int ip_addr_check __P((u_int32_t, struct permitted_ip *));
|
||||
static int scan_authfile __P((FILE *, char *, char *, char *,
|
||||
struct wordlist **, struct wordlist **,
|
||||
char *));
|
||||
char *, int));
|
||||
static void free_wordlist __P((struct wordlist *));
|
||||
static void auth_script __P((char *));
|
||||
static void auth_script_done __P((void *));
|
||||
@ -301,6 +305,12 @@ option_t auth_options[] = {
|
||||
&lcp_allowoptions[0].chap_mdtype },
|
||||
#endif
|
||||
|
||||
{ "require-eap", o_bool, &lcp_wantoptions[0].neg_eap,
|
||||
"Require EAP authentication from peer", OPT_PRIOSUB | 1,
|
||||
&auth_required },
|
||||
{ "refuse-eap", o_bool, &refuse_eap,
|
||||
"Don't agree to authenticate to peer with EAP", 1 },
|
||||
|
||||
{ "name", o_string, our_name,
|
||||
"Set local name for authentication",
|
||||
OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXNAMELEN },
|
||||
@ -554,7 +564,7 @@ link_established(unit)
|
||||
&& protp->lowerup != NULL)
|
||||
(*protp->lowerup)(unit);
|
||||
|
||||
if (auth_required && !(go->neg_upap || go->neg_chap)) {
|
||||
if (auth_required && !(go->neg_upap || go->neg_chap || go->neg_eap)) {
|
||||
/*
|
||||
* We wanted the peer to authenticate itself, and it refused:
|
||||
* if we have some address(es) it can use without auth, fine,
|
||||
@ -575,14 +585,20 @@ link_established(unit)
|
||||
new_phase(PHASE_AUTHENTICATE);
|
||||
used_login = 0;
|
||||
auth = 0;
|
||||
if (go->neg_chap) {
|
||||
if (go->neg_eap) {
|
||||
eap_authpeer(unit, our_name);
|
||||
auth |= EAP_PEER;
|
||||
} else if (go->neg_chap) {
|
||||
ChapAuthPeer(unit, our_name, CHAP_DIGEST(go->chap_mdtype));
|
||||
auth |= CHAP_PEER;
|
||||
} else if (go->neg_upap) {
|
||||
upap_authpeer(unit);
|
||||
auth |= PAP_PEER;
|
||||
}
|
||||
if (ho->neg_chap) {
|
||||
if (ho->neg_eap) {
|
||||
eap_authwithpeer(unit, user);
|
||||
auth |= EAP_WITHPEER;
|
||||
} else if (ho->neg_chap) {
|
||||
ChapAuthWithPeer(unit, user, CHAP_DIGEST(ho->chap_mdtype));
|
||||
auth |= CHAP_WITHPEER;
|
||||
} else if (ho->neg_upap) {
|
||||
@ -617,7 +633,7 @@ network_phase(unit)
|
||||
/*
|
||||
* If the peer had to authenticate, run the auth-up script now.
|
||||
*/
|
||||
if (go->neg_chap || go->neg_upap) {
|
||||
if (go->neg_chap || go->neg_upap || go->neg_eap) {
|
||||
notify(auth_up_notifier, 0);
|
||||
auth_state = s_up;
|
||||
if (auth_script_state == s_down && auth_script_pid == 0) {
|
||||
@ -755,6 +771,9 @@ auth_peer_success(unit, protocol, prot_flavor, name, namelen)
|
||||
case PPP_PAP:
|
||||
bit = PAP_PEER;
|
||||
break;
|
||||
case PPP_EAP:
|
||||
bit = EAP_PEER;
|
||||
break;
|
||||
default:
|
||||
warn("auth_peer_success: unknown protocol %x", protocol);
|
||||
return;
|
||||
@ -830,6 +849,9 @@ auth_withpeer_success(unit, protocol, prot_flavor)
|
||||
BZERO(passwd, MAXSECRETLEN);
|
||||
bit = PAP_WITHPEER;
|
||||
break;
|
||||
case PPP_EAP:
|
||||
bit = EAP_WITHPEER;
|
||||
break;
|
||||
default:
|
||||
warn("auth_withpeer_success: unknown protocol %x", protocol);
|
||||
bit = 0;
|
||||
@ -1032,28 +1054,35 @@ auth_check_options()
|
||||
if (wo->chap_mdtype)
|
||||
wo->neg_chap = 1;
|
||||
|
||||
/* If authentication is required, ask peer for CHAP or PAP. */
|
||||
/* If authentication is required, ask peer for CHAP, PAP, or EAP. */
|
||||
if (auth_required) {
|
||||
allow_any_ip = 0;
|
||||
if (!wo->neg_chap && !wo->neg_upap) {
|
||||
if (!wo->neg_chap && !wo->neg_upap && !wo->neg_eap) {
|
||||
wo->neg_chap = 1; wo->chap_mdtype = MDTYPE_ALL;
|
||||
wo->neg_upap = 1;
|
||||
wo->neg_eap = 1;
|
||||
}
|
||||
} else {
|
||||
wo->neg_chap = 0; wo->chap_mdtype = MDTYPE_NONE;
|
||||
wo->neg_upap = 0;
|
||||
wo->neg_eap = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether we have appropriate secrets to use
|
||||
* to authenticate the peer.
|
||||
* to authenticate the peer. Note that EAP can authenticate by way
|
||||
* of a CHAP-like exchanges as well as SRP.
|
||||
*/
|
||||
lacks_ip = 0;
|
||||
can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip));
|
||||
if (!can_auth && (wo->neg_chap)) {
|
||||
if (!can_auth && (wo->neg_chap || wo->neg_eap)) {
|
||||
can_auth = have_chap_secret((explicit_remote? remote_name: NULL),
|
||||
our_name, 1, &lacks_ip);
|
||||
}
|
||||
if (!can_auth && wo->neg_eap) {
|
||||
can_auth = have_srp_secret((explicit_remote? remote_name: NULL),
|
||||
our_name, 1, &lacks_ip);
|
||||
}
|
||||
|
||||
if (auth_required && !can_auth && noauth_addrs == NULL) {
|
||||
if (default_auth) {
|
||||
@ -1088,21 +1117,36 @@ auth_reset(unit)
|
||||
int unit;
|
||||
{
|
||||
lcp_options *go = &lcp_gotoptions[unit];
|
||||
lcp_options *ao = &lcp_allowoptions[0];
|
||||
lcp_options *ao = &lcp_allowoptions[unit];
|
||||
int hadchap;
|
||||
|
||||
hadchap = -1;
|
||||
ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL));
|
||||
ao->neg_chap = (!refuse_chap || !refuse_mschap || !refuse_mschap_v2)
|
||||
&& (passwd[0] != 0
|
||||
|| have_chap_secret(user, (explicit_remote? remote_name: NULL),
|
||||
0, NULL));
|
||||
&& (passwd[0] != 0 ||
|
||||
(hadchap = have_chap_secret(user, (explicit_remote? remote_name:
|
||||
NULL), 0, NULL)));
|
||||
ao->neg_eap = !refuse_eap && (
|
||||
passwd[0] != 0 ||
|
||||
(hadchap == 1 || (hadchap == -1 && have_chap_secret(user,
|
||||
(explicit_remote? remote_name: NULL), 0, NULL))) ||
|
||||
have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL));
|
||||
|
||||
hadchap = -1;
|
||||
if (go->neg_upap && !uselogin && !have_pap_secret(NULL))
|
||||
go->neg_upap = 0;
|
||||
if (go->neg_chap) {
|
||||
if (!have_chap_secret((explicit_remote? remote_name: NULL),
|
||||
our_name, 1, NULL))
|
||||
if (!(hadchap = have_chap_secret((explicit_remote? remote_name: NULL),
|
||||
our_name, 1, NULL)))
|
||||
go->neg_chap = 0;
|
||||
}
|
||||
if (go->neg_eap &&
|
||||
(hadchap == 0 || (hadchap == -1 &&
|
||||
!have_chap_secret((explicit_remote? remote_name: NULL), our_name,
|
||||
1, NULL))) &&
|
||||
!have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1,
|
||||
NULL))
|
||||
go->neg_eap = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1173,7 +1217,7 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg)
|
||||
|
||||
} else {
|
||||
check_access(f, filename);
|
||||
if (scan_authfile(f, user, our_name, secret, &addrs, &opts, filename) < 0) {
|
||||
if (scan_authfile(f, user, our_name, secret, &addrs, &opts, filename, 0) < 0) {
|
||||
warn("no PAP secret found for %s", user);
|
||||
} else {
|
||||
/*
|
||||
@ -1248,8 +1292,12 @@ static pam_handle_t *pamh = NULL;
|
||||
* echo off means password.
|
||||
*/
|
||||
|
||||
static int PAM_conv (int num_msg, const struct pam_message **msg,
|
||||
struct pam_response **resp, void *appdata_ptr)
|
||||
static int PAM_conv (int num_msg,
|
||||
#ifndef SOL2
|
||||
const
|
||||
#endif
|
||||
struct pam_message **msg,
|
||||
struct pam_response **resp, void *appdata_ptr)
|
||||
{
|
||||
int replies = 0;
|
||||
struct pam_response *reply = NULL;
|
||||
@ -1486,7 +1534,7 @@ null_login(unit)
|
||||
return 0;
|
||||
check_access(f, filename);
|
||||
|
||||
i = scan_authfile(f, "", our_name, secret, &addrs, &opts, filename);
|
||||
i = scan_authfile(f, "", our_name, secret, &addrs, &opts, filename, 0);
|
||||
ret = i >= 0 && secret[0] == 0;
|
||||
BZERO(secret, sizeof(secret));
|
||||
fclose(f);
|
||||
@ -1534,7 +1582,7 @@ get_pap_passwd(passwd)
|
||||
check_access(f, filename);
|
||||
ret = scan_authfile(f, user,
|
||||
(remote_name[0]? remote_name: NULL),
|
||||
secret, NULL, NULL, filename);
|
||||
secret, NULL, NULL, filename, 0);
|
||||
fclose(f);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
@ -1571,7 +1619,7 @@ have_pap_secret(lacks_ipp)
|
||||
return 0;
|
||||
|
||||
ret = scan_authfile(f, (explicit_remote? remote_name: NULL), our_name,
|
||||
NULL, &addrs, NULL, filename);
|
||||
NULL, &addrs, NULL, filename, 0);
|
||||
fclose(f);
|
||||
if (ret >= 0 && !some_ip_ok(addrs)) {
|
||||
if (lacks_ipp != 0)
|
||||
@ -1620,7 +1668,49 @@ have_chap_secret(client, server, need_ip, lacks_ipp)
|
||||
else if (server != NULL && server[0] == 0)
|
||||
server = NULL;
|
||||
|
||||
ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename);
|
||||
ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0);
|
||||
fclose(f);
|
||||
if (ret >= 0 && need_ip && !some_ip_ok(addrs)) {
|
||||
if (lacks_ipp != 0)
|
||||
*lacks_ipp = 1;
|
||||
ret = -1;
|
||||
}
|
||||
if (addrs != 0)
|
||||
free_wordlist(addrs);
|
||||
|
||||
return ret >= 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* have_srp_secret - check whether we have a SRP file with a
|
||||
* secret that we could possibly use for authenticating `client'
|
||||
* on `server'. Either can be the null string, meaning we don't
|
||||
* know the identity yet.
|
||||
*/
|
||||
static int
|
||||
have_srp_secret(client, server, need_ip, lacks_ipp)
|
||||
char *client;
|
||||
char *server;
|
||||
int need_ip;
|
||||
int *lacks_ipp;
|
||||
{
|
||||
FILE *f;
|
||||
int ret;
|
||||
char *filename;
|
||||
struct wordlist *addrs;
|
||||
|
||||
filename = _PATH_SRPFILE;
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL)
|
||||
return 0;
|
||||
|
||||
if (client != NULL && client[0] == 0)
|
||||
client = NULL;
|
||||
else if (server != NULL && server[0] == 0)
|
||||
server = NULL;
|
||||
|
||||
ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0);
|
||||
fclose(f);
|
||||
if (ret >= 0 && need_ip && !some_ip_ok(addrs)) {
|
||||
if (lacks_ipp != 0)
|
||||
@ -1674,7 +1764,7 @@ get_secret(unit, client, server, secret, secret_len, am_server)
|
||||
}
|
||||
check_access(f, filename);
|
||||
|
||||
ret = scan_authfile(f, client, server, secbuf, &addrs, &opts, filename);
|
||||
ret = scan_authfile(f, client, server, secbuf, &addrs, &opts, filename, 0);
|
||||
fclose(f);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
@ -1699,6 +1789,56 @@ get_secret(unit, client, server, secret, secret_len, am_server)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* get_srp_secret - open the SRP secret file and return the secret
|
||||
* for authenticating the given client on the given server.
|
||||
* (We could be either client or server).
|
||||
*/
|
||||
int
|
||||
get_srp_secret(unit, client, server, secret, am_server)
|
||||
int unit;
|
||||
char *client;
|
||||
char *server;
|
||||
char *secret;
|
||||
int am_server;
|
||||
{
|
||||
FILE *fp;
|
||||
int ret;
|
||||
char *filename;
|
||||
struct wordlist *addrs, *opts;
|
||||
|
||||
if (!am_server && passwd[0] != '\0') {
|
||||
strlcpy(secret, passwd, MAXWORDLEN);
|
||||
} else {
|
||||
filename = _PATH_SRPFILE;
|
||||
addrs = NULL;
|
||||
|
||||
fp = fopen(filename, "r");
|
||||
if (fp == NULL) {
|
||||
error("Can't open srp secret file %s: %m", filename);
|
||||
return 0;
|
||||
}
|
||||
check_access(fp, filename);
|
||||
|
||||
secret[0] = '\0';
|
||||
ret = scan_authfile(fp, client, server, secret, &addrs, &opts,
|
||||
filename, am_server);
|
||||
fclose(fp);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
|
||||
if (am_server)
|
||||
set_allowed_addrs(unit, addrs, opts);
|
||||
else if (opts != NULL)
|
||||
free_wordlist(opts);
|
||||
if (addrs != NULL)
|
||||
free_wordlist(addrs);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* set_allowed_addrs() - set the list of allowed addresses.
|
||||
* Also looks for `--' indicating options to apply for this peer
|
||||
@ -1986,9 +2126,11 @@ check_access(f, filename)
|
||||
* following words (extra options) are placed in a wordlist and
|
||||
* returned in *opts.
|
||||
* We assume secret is NULL or points to MAXWORDLEN bytes of space.
|
||||
* Flags are non-zero if we need two colons in the secret in order to
|
||||
* match.
|
||||
*/
|
||||
static int
|
||||
scan_authfile(f, client, server, secret, addrs, opts, filename)
|
||||
scan_authfile(f, client, server, secret, addrs, opts, filename, flags)
|
||||
FILE *f;
|
||||
char *client;
|
||||
char *server;
|
||||
@ -1996,6 +2138,7 @@ scan_authfile(f, client, server, secret, addrs, opts, filename)
|
||||
struct wordlist **addrs;
|
||||
struct wordlist **opts;
|
||||
char *filename;
|
||||
int flags;
|
||||
{
|
||||
int newline, xxx;
|
||||
int got_flag, best_flag;
|
||||
@ -2004,6 +2147,7 @@ scan_authfile(f, client, server, secret, addrs, opts, filename)
|
||||
char word[MAXWORDLEN];
|
||||
char atfile[MAXWORDLEN];
|
||||
char lsecret[MAXWORDLEN];
|
||||
char *cp;
|
||||
|
||||
if (addrs != NULL)
|
||||
*addrs = NULL;
|
||||
@ -2062,6 +2206,14 @@ scan_authfile(f, client, server, secret, addrs, opts, filename)
|
||||
if (newline)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* SRP-SHA1 authenticator should never be reading secrets from
|
||||
* a file. (Authenticatee may, though.)
|
||||
*/
|
||||
if (flags && ((cp = strchr(word, ':')) == NULL ||
|
||||
strchr(cp + 1, ':') == NULL))
|
||||
continue;
|
||||
|
||||
if (secret != NULL) {
|
||||
/*
|
||||
* Special syntax: @/pathname means read secret from file.
|
||||
|
160
pppd/chap_ms.c
160
pppd/chap_ms.c
@ -40,7 +40,7 @@
|
||||
* Copyright (c) 2002 Google, Inc.
|
||||
*/
|
||||
|
||||
#define RCSID "$Id: chap_ms.c,v 1.22 2002/09/06 22:11:12 kad Exp $"
|
||||
#define RCSID "$Id: chap_ms.c,v 1.23 2002/11/02 19:48:12 carlsonj Exp $"
|
||||
|
||||
#ifdef CHAPMS
|
||||
|
||||
@ -51,19 +51,13 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_CRYPT_H
|
||||
#include <crypt.h>
|
||||
#endif
|
||||
|
||||
#include "pppd.h"
|
||||
#include "chap.h"
|
||||
#include "chap_ms.h"
|
||||
#include "md4.h"
|
||||
#include "sha1.h"
|
||||
|
||||
#ifndef USE_CRYPT
|
||||
#include <des.h>
|
||||
#endif
|
||||
#include "pppcrypt.h"
|
||||
|
||||
static const char rcsid[] = RCSID;
|
||||
|
||||
@ -72,9 +66,6 @@ static void ChallengeHash __P((u_char[16], u_char *, char *, u_char[8]));
|
||||
static void ascii2unicode __P((char[], int, u_char[]));
|
||||
static void NTPasswordHash __P((char *, int, u_char[MD4_SIGNATURE_SIZE]));
|
||||
static void ChallengeResponse __P((u_char *, u_char *, u_char[24]));
|
||||
static void DesEncrypt __P((u_char *, u_char *, u_char[8]));
|
||||
static void MakeKey __P((u_char *, u_char *));
|
||||
static u_char Get7Bits __P((u_char *, int));
|
||||
static void ChapMS_NT __P((u_char *, char *, int, u_char[24]));
|
||||
static void ChapMS2_NT __P((char *, u_char[16], char *, char *, int,
|
||||
u_char[24]));
|
||||
@ -85,11 +76,6 @@ static void GenerateAuthenticatorResponse __P((char*, int, u_char[24],
|
||||
static void ChapMS_LANMan __P((u_char *, char *, int, MS_ChapResponse *));
|
||||
#endif
|
||||
|
||||
#ifdef USE_CRYPT
|
||||
static void Expand __P((u_char *, u_char *));
|
||||
static void Collapse __P((u_char *, u_char *));
|
||||
#endif
|
||||
|
||||
#ifdef MPPE
|
||||
static void Set_Start_Key __P((u_char *, char *, int));
|
||||
static void SetMasterKeys __P((char *, int, u_char[24], int));
|
||||
@ -112,7 +98,7 @@ ChallengeResponse(u_char *challenge,
|
||||
u_char PasswordHash[MD4_SIGNATURE_SIZE],
|
||||
u_char response[24])
|
||||
{
|
||||
char ZPasswordHash[21];
|
||||
u_char ZPasswordHash[21];
|
||||
|
||||
BZERO(ZPasswordHash, sizeof(ZPasswordHash));
|
||||
BCOPY(PasswordHash, ZPasswordHash, MD4_SIGNATURE_SIZE);
|
||||
@ -122,138 +108,18 @@ ChallengeResponse(u_char *challenge,
|
||||
sizeof(ZPasswordHash), ZPasswordHash);
|
||||
#endif
|
||||
|
||||
DesEncrypt(challenge, ZPasswordHash + 0, &response[0]);
|
||||
DesEncrypt(challenge, ZPasswordHash + 7, &response[8]);
|
||||
DesEncrypt(challenge, ZPasswordHash + 14, &response[16]);
|
||||
(void) DesSetkey(ZPasswordHash + 0);
|
||||
DesEncrypt(challenge, response + 0);
|
||||
(void) DesSetkey(ZPasswordHash + 7);
|
||||
DesEncrypt(challenge, response + 8);
|
||||
(void) DesSetkey(ZPasswordHash + 14);
|
||||
DesEncrypt(challenge, response + 16);
|
||||
|
||||
#if 0
|
||||
dbglog("ChallengeResponse - response %.24B", response);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_CRYPT
|
||||
static void
|
||||
DesEncrypt(u_char *clear, u_char *key, u_char cipher[8])
|
||||
{
|
||||
u_char des_key[8];
|
||||
u_char crypt_key[66];
|
||||
u_char des_input[66];
|
||||
|
||||
MakeKey(key, des_key);
|
||||
|
||||
Expand(des_key, crypt_key);
|
||||
setkey(crypt_key);
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %.8B", clear));
|
||||
#endif
|
||||
|
||||
Expand(clear, des_input);
|
||||
encrypt(des_input, 0);
|
||||
Collapse(des_input, cipher);
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %.8B", cipher));
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* USE_CRYPT */
|
||||
|
||||
static void
|
||||
DesEncrypt(u_char *clear, u_char *key, u_char cipher[8])
|
||||
{
|
||||
des_cblock des_key;
|
||||
des_key_schedule key_schedule;
|
||||
|
||||
MakeKey(key, des_key);
|
||||
|
||||
des_set_key(&des_key, key_schedule);
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %.8B", clear));
|
||||
#endif
|
||||
|
||||
des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %.8B", cipher));
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* USE_CRYPT */
|
||||
|
||||
|
||||
static u_char Get7Bits(u_char *input, int startBit)
|
||||
{
|
||||
register unsigned int word;
|
||||
|
||||
word = (unsigned)input[startBit / 8] << 8;
|
||||
word |= (unsigned)input[startBit / 8 + 1];
|
||||
|
||||
word >>= 15 - (startBit % 8 + 7);
|
||||
|
||||
return word & 0xFE;
|
||||
}
|
||||
|
||||
#ifdef USE_CRYPT
|
||||
|
||||
/* in == 8-byte string (expanded version of the 56-bit key)
|
||||
* out == 64-byte string where each byte is either 1 or 0
|
||||
* Note that the low-order "bit" is always ignored by by setkey()
|
||||
*/
|
||||
static void Expand(u_char *in, u_char *out)
|
||||
{
|
||||
int j, c;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 64; in++){
|
||||
c = *in;
|
||||
for(j = 7; j >= 0; j--)
|
||||
*out++ = (c >> j) & 01;
|
||||
i += 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* The inverse of Expand
|
||||
*/
|
||||
static void Collapse(u_char *in, u_char *out)
|
||||
{
|
||||
int j;
|
||||
int i;
|
||||
unsigned int c;
|
||||
|
||||
for (i = 0; i < 64; i += 8, out++) {
|
||||
c = 0;
|
||||
for (j = 7; j >= 0; j--, in++)
|
||||
c |= *in << j;
|
||||
*out = c & 0xff;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void MakeKey(u_char *key, u_char *des_key)
|
||||
{
|
||||
des_key[0] = Get7Bits(key, 0);
|
||||
des_key[1] = Get7Bits(key, 7);
|
||||
des_key[2] = Get7Bits(key, 14);
|
||||
des_key[3] = Get7Bits(key, 21);
|
||||
des_key[4] = Get7Bits(key, 28);
|
||||
des_key[5] = Get7Bits(key, 35);
|
||||
des_key[6] = Get7Bits(key, 42);
|
||||
des_key[7] = Get7Bits(key, 49);
|
||||
|
||||
#ifndef USE_CRYPT
|
||||
des_set_odd_parity((des_cblock *)des_key);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %.7B", key));
|
||||
CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %.8B", des_key));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ChallengeHash(u_char PeerChallenge[16], u_char *rchallenge,
|
||||
char *username, u_char Challenge[8])
|
||||
@ -348,7 +214,7 @@ static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
|
||||
|
||||
static void
|
||||
ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len,
|
||||
u_char LMResponse[24])
|
||||
MS_ChapResponse *LMResponse)
|
||||
{
|
||||
int i;
|
||||
u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */
|
||||
@ -358,8 +224,10 @@ ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len,
|
||||
BZERO(UcasePassword, sizeof(UcasePassword));
|
||||
for (i = 0; i < secret_len; i++)
|
||||
UcasePassword[i] = (u_char)toupper(secret[i]);
|
||||
DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 );
|
||||
DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 );
|
||||
(void) DesSetkey(UcasePassword + 0);
|
||||
DesEncrypt( StdText, PasswordHash + 0 );
|
||||
(void) DesSetkey(UcasePassword + 7);
|
||||
DesEncrypt( StdText, PasswordHash + 8 );
|
||||
ChallengeResponse(rchallenge, PasswordHash, LMResponse);
|
||||
}
|
||||
#endif
|
||||
|
2428
pppd/eap.c
Normal file
2428
pppd/eap.c
Normal file
File diff suppressed because it is too large
Load Diff
154
pppd/eap.h
Normal file
154
pppd/eap.h
Normal file
@ -0,0 +1,154 @@
|
||||
/*
|
||||
* eap.h - Extensible Authentication Protocol for PPP (RFC 2284)
|
||||
*
|
||||
* Copyright (c) 2001 by Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Non-exclusive rights to redistribute, modify, translate, and use
|
||||
* this software in source and binary forms, in whole or in part, is
|
||||
* hereby granted, provided that the above copyright notice is
|
||||
* duplicated in any source form, and that neither the name of the
|
||||
* copyright holder nor the author is used to endorse or promote
|
||||
* products derived from this software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Original version by James Carlson
|
||||
*
|
||||
* $Id: eap.h,v 1.1 2002/11/02 19:48:12 carlsonj Exp $
|
||||
*/
|
||||
|
||||
#ifndef PPP_EAP_H
|
||||
#define PPP_EAP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Packet header = Code, id, length.
|
||||
*/
|
||||
#define EAP_HEADERLEN 4
|
||||
|
||||
|
||||
/* EAP message codes. */
|
||||
#define EAP_REQUEST 1
|
||||
#define EAP_RESPONSE 2
|
||||
#define EAP_SUCCESS 3
|
||||
#define EAP_FAILURE 4
|
||||
|
||||
/* EAP types */
|
||||
#define EAPT_IDENTITY 1
|
||||
#define EAPT_NOTIFICATION 2
|
||||
#define EAPT_NAK 3 /* (response only) */
|
||||
#define EAPT_MD5CHAP 4
|
||||
#define EAPT_OTP 5 /* One-Time Password; RFC 1938 */
|
||||
#define EAPT_TOKEN 6 /* Generic Token Card */
|
||||
/* 7 and 8 are unassigned. */
|
||||
#define EAPT_RSA 9 /* RSA Public Key Authentication */
|
||||
#define EAPT_DSS 10 /* DSS Unilateral */
|
||||
#define EAPT_KEA 11 /* KEA */
|
||||
#define EAPT_KEA_VALIDATE 12 /* KEA-VALIDATE */
|
||||
#define EAPT_TLS 13 /* EAP-TLS */
|
||||
#define EAPT_DEFENDER 14 /* Defender Token (AXENT) */
|
||||
#define EAPT_W2K 15 /* Windows 2000 EAP */
|
||||
#define EAPT_ARCOT 16 /* Arcot Systems */
|
||||
#define EAPT_CISCOWIRELESS 17 /* Cisco Wireless */
|
||||
#define EAPT_NOKIACARD 18 /* Nokia IP smart card */
|
||||
#define EAPT_SRP 19 /* Secure Remote Password */
|
||||
/* 20 is deprecated */
|
||||
|
||||
/* EAP SRP-SHA1 Subtypes */
|
||||
#define EAPSRP_CHALLENGE 1 /* Request 1 - Challenge */
|
||||
#define EAPSRP_CKEY 1 /* Response 1 - Client Key */
|
||||
#define EAPSRP_SKEY 2 /* Request 2 - Server Key */
|
||||
#define EAPSRP_CVALIDATOR 2 /* Response 2 - Client Validator */
|
||||
#define EAPSRP_SVALIDATOR 3 /* Request 3 - Server Validator */
|
||||
#define EAPSRP_ACK 3 /* Response 3 - final ack */
|
||||
#define EAPSRP_LWRECHALLENGE 4 /* Req/resp 4 - Lightweight rechal */
|
||||
|
||||
#define SRPVAL_EBIT 0x00000001 /* Use shared key for ECP */
|
||||
|
||||
#define SRP_PSEUDO_ID "pseudo_"
|
||||
#define SRP_PSEUDO_LEN 7
|
||||
|
||||
enum eap_state_code {
|
||||
eapInitial = 0, /* No EAP authentication yet requested */
|
||||
eapPending, /* Waiting for LCP (no timer) */
|
||||
eapClosed, /* Authentication not in use */
|
||||
eapListen, /* Client ready (and timer running) */
|
||||
eapIdentify, /* EAP Identify sent */
|
||||
eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */
|
||||
eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */
|
||||
eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */
|
||||
eapMD5Chall, /* Sent MD5-Challenge */
|
||||
eapOpen, /* Completed authentication */
|
||||
eapSRP4, /* Sent EAP SRP-SHA1 Subtype 4 */
|
||||
eapBadAuth /* Failed authentication */
|
||||
};
|
||||
|
||||
#define EAP_STATES \
|
||||
"Initial", "Pending", "Closed", "Listen", "Identify", \
|
||||
"SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth"
|
||||
|
||||
#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen)
|
||||
#define eap_server_active(esp) \
|
||||
((esp)->es_server.ea_state >= eapIdentify && \
|
||||
(esp)->es_server.ea_state <= eapMD5Chall)
|
||||
|
||||
struct eap_auth {
|
||||
char *ea_name; /* Our name */
|
||||
char *ea_peer; /* Peer's name */
|
||||
void *ea_session; /* Authentication library linkage */
|
||||
u_char *ea_skey; /* Shared encryption key */
|
||||
int ea_timeout; /* Time to wait (for retransmit/fail) */
|
||||
int ea_maxrequests; /* Max Requests allowed */
|
||||
u_short ea_namelen; /* Length of our name */
|
||||
u_short ea_peerlen; /* Length of peer's name */
|
||||
enum eap_state_code ea_state;
|
||||
u_char ea_id; /* Current id */
|
||||
u_char ea_requests; /* Number of Requests sent/received */
|
||||
u_char ea_responses; /* Number of Responses */
|
||||
u_char ea_type; /* One of EAPT_* */
|
||||
u_int32_t ea_keyflags; /* SRP shared key usage flags */
|
||||
};
|
||||
|
||||
/*
|
||||
* Complete EAP state for one PPP session.
|
||||
*/
|
||||
typedef struct eap_state {
|
||||
int es_unit; /* Interface unit number */
|
||||
struct eap_auth es_client; /* Client (authenticatee) data */
|
||||
struct eap_auth es_server; /* Server (authenticator) data */
|
||||
int es_savedtime; /* Saved timeout */
|
||||
int es_rechallenge; /* EAP rechallenge interval */
|
||||
int es_lwrechallenge; /* SRP lightweight rechallenge inter */
|
||||
bool es_usepseudo; /* Use SRP Pseudonym if offered one */
|
||||
int es_usedpseudo; /* Set if we already sent PN */
|
||||
int es_challen; /* Length of challenge string */
|
||||
u_char es_challenge[MAX_CHALLENGE_LENGTH];
|
||||
} eap_state;
|
||||
|
||||
/*
|
||||
* Timeouts.
|
||||
*/
|
||||
#define EAP_DEFTIMEOUT 3 /* Timeout (seconds) for rexmit */
|
||||
#define EAP_DEFTRANSMITS 10 /* max # times to transmit */
|
||||
#define EAP_DEFREQTIME 20 /* Time to wait for peer request */
|
||||
#define EAP_DEFALLOWREQ 20 /* max # times to accept requests */
|
||||
|
||||
extern eap_state eap_states[];
|
||||
|
||||
void eap_authwithpeer __P((int unit, char *localname));
|
||||
void eap_authpeer __P((int unit, char *localname));
|
||||
|
||||
extern struct protent eap_protent;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PPP_EAP_H */
|
||||
|
155
pppd/lcp.c
155
pppd/lcp.c
@ -17,7 +17,7 @@
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#define RCSID "$Id: lcp.c,v 1.62 2002/09/24 11:35:22 fcusack Exp $"
|
||||
#define RCSID "$Id: lcp.c,v 1.63 2002/11/02 19:48:12 carlsonj Exp $"
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
@ -338,6 +338,7 @@ lcp_init(unit)
|
||||
ao->neg_chap = 1;
|
||||
ao->chap_mdtype = MDTYPE_ALL;
|
||||
ao->neg_upap = 1;
|
||||
ao->neg_eap = 1;
|
||||
ao->neg_magicnumber = 1;
|
||||
ao->neg_pcompression = 1;
|
||||
ao->neg_accompression = 1;
|
||||
@ -635,13 +636,15 @@ lcp_cilen(f)
|
||||
#define LENCILQR(neg) ((neg) ? CILEN_LQR: 0)
|
||||
#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0)
|
||||
/*
|
||||
* NB: we only ask for one of CHAP and UPAP, even if we will
|
||||
* accept either.
|
||||
* NB: we only ask for one of CHAP, UPAP, or EAP, even if we will
|
||||
* accept more than one. We prefer EAP first, then CHAP, then
|
||||
* PAP.
|
||||
*/
|
||||
return (LENCISHORT(go->neg_mru && go->mru != DEFMRU) +
|
||||
LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) +
|
||||
LENCICHAP(go->neg_chap) +
|
||||
LENCISHORT(!go->neg_chap && go->neg_upap) +
|
||||
LENCISHORT(go->neg_eap) +
|
||||
LENCICHAP(!go->neg_eap && go->neg_chap) +
|
||||
LENCISHORT(!go->neg_eap && !go->neg_chap && go->neg_upap) +
|
||||
LENCILQR(go->neg_lqr) +
|
||||
LENCICBCP(go->neg_cbcp) +
|
||||
LENCILONG(go->neg_magicnumber) +
|
||||
@ -715,8 +718,10 @@ lcp_addci(f, ucp, lenp)
|
||||
ADDCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
|
||||
ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
|
||||
go->asyncmap);
|
||||
ADDCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype);
|
||||
ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
|
||||
ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
|
||||
ADDCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
|
||||
ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap,
|
||||
PPP_PAP);
|
||||
ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
|
||||
ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
|
||||
ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
|
||||
@ -862,8 +867,10 @@ lcp_ackci(f, p, len)
|
||||
ACKCISHORT(CI_MRU, go->neg_mru && go->mru != DEFMRU, go->mru);
|
||||
ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF,
|
||||
go->asyncmap);
|
||||
ACKCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype);
|
||||
ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP);
|
||||
ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP);
|
||||
ACKCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype);
|
||||
ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap,
|
||||
PPP_PAP);
|
||||
ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period);
|
||||
ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT);
|
||||
ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber);
|
||||
@ -1026,28 +1033,40 @@ lcp_nakci(f, p, len)
|
||||
* they are proposing a different protocol, or a different
|
||||
* hash algorithm for CHAP.
|
||||
*/
|
||||
if ((go->neg_chap || go->neg_upap)
|
||||
if ((go->neg_chap || go->neg_upap || go->neg_eap)
|
||||
&& len >= CILEN_SHORT
|
||||
&& p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) {
|
||||
cilen = p[1];
|
||||
len -= cilen;
|
||||
no.neg_chap = go->neg_chap;
|
||||
no.neg_upap = go->neg_upap;
|
||||
no.neg_eap = go->neg_eap;
|
||||
INCPTR(2, p);
|
||||
GETSHORT(cishort, p);
|
||||
if (cishort == PPP_PAP && cilen == CILEN_SHORT) {
|
||||
/* If we were asking for EAP, then we need to stop that. */
|
||||
if (go->neg_eap)
|
||||
try.neg_eap = 0;
|
||||
|
||||
/* If we were asking for CHAP, then we need to stop that. */
|
||||
else if (go->neg_chap)
|
||||
try.neg_chap = 0;
|
||||
/*
|
||||
* If we were asking for CHAP, they obviously don't want to do it.
|
||||
* If we weren't asking for CHAP, then we were asking for PAP,
|
||||
* in which case this Nak is bad.
|
||||
* If we weren't asking for CHAP or EAP, then we were asking for
|
||||
* PAP, in which case this Nak is bad.
|
||||
*/
|
||||
if (!go->neg_chap)
|
||||
else
|
||||
goto bad;
|
||||
try.neg_chap = 0;
|
||||
|
||||
} else if (cishort == PPP_CHAP && cilen == CILEN_CHAP) {
|
||||
GETCHAR(cichar, p);
|
||||
if (go->neg_chap) {
|
||||
/* Stop asking for EAP, if we were. */
|
||||
if (go->neg_eap) {
|
||||
try.neg_eap = 0;
|
||||
/* Try to set up to use their suggestion, if possible */
|
||||
if (CHAP_CANDIGEST(go->chap_mdtype, cichar))
|
||||
go->chap_mdtype = CHAP_MDTYPE_D(cichar);
|
||||
} else if (go->neg_chap) {
|
||||
/*
|
||||
* We were asking for our preferred algorithm, they must
|
||||
* want something different.
|
||||
@ -1077,11 +1096,21 @@ lcp_nakci(f, p, len)
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/*
|
||||
* If we were asking for EAP, and they're Conf-Naking EAP,
|
||||
* well, that's just strange. Nobody should do that.
|
||||
*/
|
||||
if (cishort == PPP_EAP && cilen == CILEN_SHORT && go->neg_eap)
|
||||
dbglog("Unexpected Conf-Nak for EAP");
|
||||
|
||||
/*
|
||||
* We don't recognize what they're suggesting.
|
||||
* Stop asking for what we were asking for.
|
||||
*/
|
||||
if (go->neg_chap)
|
||||
if (go->neg_eap)
|
||||
try.neg_eap = 0;
|
||||
else if (go->neg_chap)
|
||||
try.neg_chap = 0;
|
||||
else
|
||||
try.neg_upap = 0;
|
||||
@ -1187,7 +1216,8 @@ lcp_nakci(f, p, len)
|
||||
goto bad;
|
||||
break;
|
||||
case CI_AUTHTYPE:
|
||||
if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap)
|
||||
if (go->neg_chap || no.neg_chap || go->neg_upap || no.neg_upap ||
|
||||
go->neg_eap || no.neg_eap)
|
||||
goto bad;
|
||||
break;
|
||||
case CI_MAGICNUMBER:
|
||||
@ -1313,7 +1343,7 @@ lcp_rejci(f, p, len)
|
||||
if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \
|
||||
goto bad; \
|
||||
try.neg = 0; \
|
||||
try.neg_upap = 0; \
|
||||
try.neg_eap = try.neg_upap = 0; \
|
||||
}
|
||||
#define REJCILONG(opt, neg, val) \
|
||||
if (go->neg && \
|
||||
@ -1376,9 +1406,12 @@ lcp_rejci(f, p, len)
|
||||
|
||||
REJCISHORT(CI_MRU, neg_mru, go->mru);
|
||||
REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap);
|
||||
REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype);
|
||||
if (!go->neg_chap) {
|
||||
REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
|
||||
REJCISHORT(CI_AUTHTYPE, neg_eap, PPP_EAP);
|
||||
if (!go->neg_eap) {
|
||||
REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype);
|
||||
if (!go->neg_chap) {
|
||||
REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP);
|
||||
}
|
||||
}
|
||||
REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period);
|
||||
REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT);
|
||||
@ -1515,56 +1548,68 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
|
||||
|
||||
case CI_AUTHTYPE:
|
||||
if (cilen < CILEN_SHORT ||
|
||||
!(ao->neg_upap || ao->neg_chap)) {
|
||||
!(ao->neg_upap || ao->neg_chap || ao->neg_eap)) {
|
||||
/*
|
||||
* Reject the option if we're not willing to authenticate.
|
||||
*/
|
||||
dbglog("No auth is possible");
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
}
|
||||
GETSHORT(cishort, p);
|
||||
|
||||
/*
|
||||
* Authtype must be PAP or CHAP.
|
||||
* Authtype must be PAP, CHAP, or EAP.
|
||||
*
|
||||
* Note: if both ao->neg_upap and ao->neg_chap are set,
|
||||
* and the peer sends a Configure-Request with two
|
||||
* authenticate-protocol requests, one for CHAP and one
|
||||
* for UPAP, then we will reject the second request.
|
||||
* Whether we end up doing CHAP or UPAP depends then on
|
||||
* Note: if more than one of ao->neg_upap, ao->neg_chap, and
|
||||
* ao->neg_eap are set, and the peer sends a Configure-Request
|
||||
* with two or more authenticate-protocol requests, then we will
|
||||
* reject the second request.
|
||||
* Whether we end up doing CHAP, UPAP, or EAP depends then on
|
||||
* the ordering of the CIs in the peer's Configure-Request.
|
||||
*/
|
||||
|
||||
if (cishort == PPP_PAP) {
|
||||
if (ho->neg_chap || /* we've already accepted CHAP */
|
||||
/* we've already accepted CHAP or EAP */
|
||||
if (ho->neg_chap || ho->neg_eap ||
|
||||
cilen != CILEN_SHORT) {
|
||||
LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting..."));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
}
|
||||
if (!ao->neg_upap) { /* we don't want to do PAP */
|
||||
orc = CONFNAK; /* NAK it and suggest CHAP */
|
||||
PUTCHAR(CI_AUTHTYPE, nakp);
|
||||
PUTCHAR(CILEN_CHAP, nakp);
|
||||
PUTSHORT(PPP_CHAP, nakp);
|
||||
PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
|
||||
orc = CONFNAK; /* NAK it and suggest CHAP or EAP */
|
||||
if (ao->neg_eap) {
|
||||
PUTCHAR(CILEN_SHORT, nakp);
|
||||
PUTSHORT(PPP_EAP, nakp);
|
||||
} else {
|
||||
PUTCHAR(CI_AUTHTYPE, nakp);
|
||||
PUTCHAR(CILEN_CHAP, nakp);
|
||||
PUTSHORT(PPP_CHAP, nakp);
|
||||
PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
ho->neg_upap = 1;
|
||||
break;
|
||||
}
|
||||
if (cishort == PPP_CHAP) {
|
||||
if (ho->neg_upap || /* we've already accepted PAP */
|
||||
/* we've already accepted PAP or EAP */
|
||||
if (ho->neg_upap || ho->neg_eap ||
|
||||
cilen != CILEN_CHAP) {
|
||||
LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting..."));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
}
|
||||
if (!ao->neg_chap) { /* we don't want to do CHAP */
|
||||
orc = CONFNAK; /* NAK it and suggest PAP */
|
||||
orc = CONFNAK; /* NAK it and suggest EAP or PAP */
|
||||
PUTCHAR(CI_AUTHTYPE, nakp);
|
||||
PUTCHAR(CILEN_SHORT, nakp);
|
||||
PUTSHORT(PPP_PAP, nakp);
|
||||
if (ao->neg_eap) {
|
||||
PUTSHORT(PPP_EAP, nakp);
|
||||
} else {
|
||||
PUTSHORT(PPP_PAP, nakp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
GETCHAR(cichar, p); /* get digest type */
|
||||
@ -1584,15 +1629,42 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
|
||||
ho->neg_chap = 1;
|
||||
break;
|
||||
}
|
||||
if (cishort == PPP_EAP) {
|
||||
/* we've already accepted CHAP or PAP */
|
||||
if (ho->neg_chap || ho->neg_upap || cilen != CILEN_SHORT) {
|
||||
LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE EAP, rejecting..."));
|
||||
orc = CONFREJ;
|
||||
break;
|
||||
}
|
||||
if (!ao->neg_eap) { /* we don't want to do EAP */
|
||||
orc = CONFNAK; /* NAK it and suggest CHAP or PAP */
|
||||
PUTCHAR(CI_AUTHTYPE, nakp);
|
||||
if (ao->neg_chap) {
|
||||
PUTCHAR(CILEN_CHAP, nakp);
|
||||
PUTSHORT(PPP_CHAP, nakp);
|
||||
PUTCHAR(ao->chap_mdtype, nakp);
|
||||
} else {
|
||||
PUTCHAR(CILEN_SHORT, nakp);
|
||||
PUTSHORT(PPP_PAP, nakp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
ho->neg_eap = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't recognize the protocol they're asking for.
|
||||
* Nak it with something we're willing to do.
|
||||
* (At this point we know ao->neg_upap || ao->neg_chap.)
|
||||
* (At this point we know ao->neg_upap || ao->neg_chap ||
|
||||
* ao->neg_eap.)
|
||||
*/
|
||||
orc = CONFNAK;
|
||||
PUTCHAR(CI_AUTHTYPE, nakp);
|
||||
if (ao->neg_chap) {
|
||||
if (ao->neg_eap) {
|
||||
PUTCHAR(CILEN_SHORT, nakp);
|
||||
PUTSHORT(PPP_EAP, nakp);
|
||||
} else if (ao->neg_chap) {
|
||||
PUTCHAR(CILEN_CHAP, nakp);
|
||||
PUTSHORT(PPP_CHAP, nakp);
|
||||
PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakp);
|
||||
@ -1956,6 +2028,9 @@ lcp_printpkt(p, plen, printer, arg)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PPP_EAP:
|
||||
printer(arg, "eap");
|
||||
break;
|
||||
default:
|
||||
printer(arg, "0x%x", cishort);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: lcp.h,v 1.17 2002/03/01 14:39:18 dfs Exp $
|
||||
* $Id: lcp.h,v 1.18 2002/11/02 19:48:12 carlsonj Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -54,6 +54,7 @@ typedef struct lcp_options {
|
||||
bool neg_asyncmap; /* Negotiate the async map? */
|
||||
bool neg_upap; /* Ask for UPAP authentication? */
|
||||
bool neg_chap; /* Ask for CHAP authentication? */
|
||||
bool neg_eap; /* Ask for EAP authentication? */
|
||||
bool neg_magicnumber; /* Ask for magic number? */
|
||||
bool neg_pcompression; /* HDLC Protocol Field Compression? */
|
||||
bool neg_accompression; /* HDLC Address/Control Field Compression? */
|
||||
|
13
pppd/main.c
13
pppd/main.c
@ -17,7 +17,7 @@
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#define RCSID "$Id: main.c,v 1.118 2002/10/27 12:19:58 fcusack Exp $"
|
||||
#define RCSID "$Id: main.c,v 1.119 2002/11/02 19:48:12 carlsonj Exp $"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
@ -52,6 +52,7 @@
|
||||
#endif
|
||||
#include "upap.h"
|
||||
#include "chap.h"
|
||||
#include "eap.h"
|
||||
#include "ccp.h"
|
||||
#include "ecp.h"
|
||||
#include "pathnames.h"
|
||||
@ -229,6 +230,7 @@ struct protent *protocols[] = {
|
||||
#ifdef AT_CHANGE
|
||||
&atcp_protent,
|
||||
#endif
|
||||
&eap_protent,
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -990,7 +992,7 @@ get_input()
|
||||
* Toss all non-LCP packets unless LCP is OPEN.
|
||||
*/
|
||||
if (protocol != PPP_LCP && lcp_fsm[0].state != OPENED) {
|
||||
MAINDEBUG(("get_input: Received non-LCP packet when LCP not open."));
|
||||
dbglog("Discarded non-LCP packet when LCP not open");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1000,9 +1002,10 @@ get_input()
|
||||
*/
|
||||
if (phase <= PHASE_AUTHENTICATE
|
||||
&& !(protocol == PPP_LCP || protocol == PPP_LQR
|
||||
|| protocol == PPP_PAP || protocol == PPP_CHAP)) {
|
||||
MAINDEBUG(("get_input: discarding proto 0x%x in phase %d",
|
||||
protocol, phase));
|
||||
|| protocol == PPP_PAP || protocol == PPP_CHAP ||
|
||||
protocol == PPP_EAP)) {
|
||||
dbglog("discarding proto 0x%x in phase %d",
|
||||
protocol, phase);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* define path names
|
||||
*
|
||||
* $Id: pathnames.h,v 1.14 2001/03/08 05:15:37 paulus Exp $
|
||||
* $Id: pathnames.h,v 1.15 2002/11/02 19:48:13 carlsonj Exp $
|
||||
*/
|
||||
|
||||
#ifdef HAVE_PATHS_H
|
||||
@ -20,6 +20,7 @@
|
||||
|
||||
#define _PATH_UPAPFILE _ROOT_PATH "/etc/ppp/pap-secrets"
|
||||
#define _PATH_CHAPFILE _ROOT_PATH "/etc/ppp/chap-secrets"
|
||||
#define _PATH_SRPFILE _ROOT_PATH "/etc/ppp/srp-secrets"
|
||||
#define _PATH_SYSOPTIONS _ROOT_PATH "/etc/ppp/options"
|
||||
#define _PATH_IPUP _ROOT_PATH "/etc/ppp/ip-up"
|
||||
#define _PATH_IPDOWN _ROOT_PATH "/etc/ppp/ip-down"
|
||||
@ -31,6 +32,7 @@
|
||||
#define _PATH_RESOLV _ROOT_PATH "/etc/ppp/resolv.conf"
|
||||
|
||||
#define _PATH_USEROPT ".ppprc"
|
||||
#define _PATH_PSEUDONYM ".ppp_pseudonym"
|
||||
|
||||
#ifdef INET6
|
||||
#define _PATH_IPV6UP _ROOT_PATH "/etc/ppp/ipv6-up"
|
||||
|
185
pppd/pppcrypt.c
Normal file
185
pppd/pppcrypt.c
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1
|
||||
*
|
||||
* Extracted from chap_ms.c by James Carlson.
|
||||
*
|
||||
* Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
|
||||
* http://www.strataware.com/
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Eric Rosenquist. The name of the author may not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include "pppd.h"
|
||||
#include "pppcrypt.h"
|
||||
|
||||
static u_char
|
||||
Get7Bits(input, startBit)
|
||||
u_char *input;
|
||||
int startBit;
|
||||
{
|
||||
unsigned int word;
|
||||
|
||||
word = (unsigned)input[startBit / 8] << 8;
|
||||
word |= (unsigned)input[startBit / 8 + 1];
|
||||
|
||||
word >>= 15 - (startBit % 8 + 7);
|
||||
|
||||
return word & 0xFE;
|
||||
}
|
||||
|
||||
static void
|
||||
MakeKey(key, des_key)
|
||||
u_char *key; /* IN 56 bit DES key missing parity bits */
|
||||
u_char *des_key; /* OUT 64 bit DES key with parity bits added */
|
||||
{
|
||||
des_key[0] = Get7Bits(key, 0);
|
||||
des_key[1] = Get7Bits(key, 7);
|
||||
des_key[2] = Get7Bits(key, 14);
|
||||
des_key[3] = Get7Bits(key, 21);
|
||||
des_key[4] = Get7Bits(key, 28);
|
||||
des_key[5] = Get7Bits(key, 35);
|
||||
des_key[6] = Get7Bits(key, 42);
|
||||
des_key[7] = Get7Bits(key, 49);
|
||||
|
||||
#ifndef USE_CRYPT
|
||||
des_set_odd_parity((des_cblock *)des_key);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef USE_CRYPT
|
||||
/*
|
||||
* in == 8-byte string (expanded version of the 56-bit key)
|
||||
* out == 64-byte string where each byte is either 1 or 0
|
||||
* Note that the low-order "bit" is always ignored by by setkey()
|
||||
*/
|
||||
static void
|
||||
Expand(in, out)
|
||||
u_char *in;
|
||||
u_char *out;
|
||||
{
|
||||
int j, c;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 64; in++){
|
||||
c = *in;
|
||||
for (j = 7; j >= 0; j--)
|
||||
*out++ = (c >> j) & 01;
|
||||
i += 8;
|
||||
}
|
||||
}
|
||||
|
||||
/* The inverse of Expand
|
||||
*/
|
||||
static void
|
||||
Collapse(in, out)
|
||||
u_char *in;
|
||||
u_char *out;
|
||||
{
|
||||
int j;
|
||||
int i;
|
||||
unsigned int c;
|
||||
|
||||
for (i = 0; i < 64; i += 8, out++) {
|
||||
c = 0;
|
||||
for (j = 7; j >= 0; j--, in++)
|
||||
c |= *in << j;
|
||||
*out = c & 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
DesSetkey(key)
|
||||
u_char *key;
|
||||
{
|
||||
u_char des_key[8];
|
||||
u_char crypt_key[66];
|
||||
|
||||
MakeKey(key, des_key);
|
||||
Expand(des_key, crypt_key);
|
||||
errno = 0;
|
||||
setkey((const char *)crypt_key);
|
||||
if (errno != 0)
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
bool
|
||||
DesEncrypt(clear, cipher)
|
||||
u_char *clear; /* IN 8 octets */
|
||||
u_char *cipher; /* OUT 8 octets */
|
||||
{
|
||||
u_char des_input[66];
|
||||
|
||||
Expand(clear, des_input);
|
||||
errno = 0;
|
||||
encrypt((char *)des_input, 0);
|
||||
if (errno != 0)
|
||||
return (0);
|
||||
Collapse(des_input, cipher);
|
||||
return (1);
|
||||
}
|
||||
|
||||
bool
|
||||
DesDecrypt(cipher, clear)
|
||||
u_char *cipher; /* IN 8 octets */
|
||||
u_char *clear; /* OUT 8 octets */
|
||||
{
|
||||
u_char des_input[66];
|
||||
|
||||
Expand(cipher, des_input);
|
||||
errno = 0;
|
||||
encrypt((char *)des_input, 1);
|
||||
if (errno != 0)
|
||||
return (0);
|
||||
Collapse(des_input, clear);
|
||||
return (1);
|
||||
}
|
||||
|
||||
#else /* USE_CRYPT */
|
||||
static des_key_schedule key_schedule;
|
||||
|
||||
bool
|
||||
DesSetkey(key)
|
||||
u_char *key;
|
||||
{
|
||||
des_cblock des_key;
|
||||
MakeKey(key, des_key);
|
||||
des_set_key(&des_key, key_schedule);
|
||||
return (1);
|
||||
}
|
||||
|
||||
bool
|
||||
DesEncrypt(clear, key, cipher)
|
||||
u_char *clear; /* IN 8 octets */
|
||||
u_char *cipher; /* OUT 8 octets */
|
||||
{
|
||||
des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher,
|
||||
key_schedule, 1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
bool
|
||||
DesDecrypt(cipher, clear)
|
||||
u_char *cipher; /* IN 8 octets */
|
||||
u_char *clear; /* OUT 8 octets */
|
||||
{
|
||||
des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear,
|
||||
key_schedule, 0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
#endif /* USE_CRYPT */
|
40
pppd/pppcrypt.h
Normal file
40
pppd/pppcrypt.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1
|
||||
*
|
||||
* Extracted from chap_ms.c by James Carlson.
|
||||
*
|
||||
* Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
|
||||
* http://www.strataware.com/
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Eric Rosenquist. The name of the author may not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#ifndef PPPCRYPT_H
|
||||
#define PPPCRYPT_H
|
||||
|
||||
#ifdef HAVE_CRYPT_H
|
||||
#include <crypt.h>
|
||||
#endif
|
||||
|
||||
#ifndef USE_CRYPT
|
||||
#include <des.h>
|
||||
#endif
|
||||
|
||||
extern bool DesSetkey __P((u_char *));
|
||||
extern bool DesEncrypt __P((u_char *, u_char *));
|
||||
extern bool DesDecrypt __P((u_char *, u_char *));
|
||||
|
||||
#endif /* PPPCRYPT_H */
|
144
pppd/pppd.8
144
pppd/pppd.8
@ -1,5 +1,5 @@
|
||||
.\" manual page [] for pppd 2.4
|
||||
.\" $Id: pppd.8,v 1.66 2002/10/10 05:47:34 fcusack Exp $
|
||||
.\" $Id: pppd.8,v 1.67 2002/11/02 19:48:13 carlsonj Exp $
|
||||
.\" SH section heading
|
||||
.\" SS subsection heading
|
||||
.\" LP paragraph
|
||||
@ -331,6 +331,28 @@ the MAC type, the value may also be the name of an ethernet or similar
|
||||
network interface. This option is currently only available under
|
||||
Linux.
|
||||
.TP
|
||||
.B eap-interval \fIn
|
||||
If this option is given and pppd authenticates the peer with EAP
|
||||
(i.e., is the server), pppd will restart EAP authentication every
|
||||
\fIn\fR seconds. For EAP SRP-SHA1, see also the \fBsrp-interval\fR
|
||||
option, which enables lightweight rechallenge.
|
||||
.TP
|
||||
.B eap-max-rreq \fIn
|
||||
Set the maximum number of EAP Requests to which pppd will respond (as
|
||||
a client) without hearing EAP Success or Failure. (Default is 20.)
|
||||
.TP
|
||||
.B eap-max-sreq \fIn
|
||||
Set the maximum number of EAP Requests that pppd will issue (as a
|
||||
server) while attempting authentication. (Default is 10.)
|
||||
.TP
|
||||
.B eap-restart \fIn
|
||||
Set the retransmit timeout for EAP Requests when acting as a server
|
||||
(authenticator). (Default is 3 seconds.)
|
||||
.TP
|
||||
.B eap-timeout \fIn
|
||||
Set the maximum time to wait for the peer to send an EAP Request when
|
||||
acting as a client (authenticatee). (Default is 20 seconds.)
|
||||
.TP
|
||||
.B hide-password
|
||||
When logging the contents of PAP packets, this option causes pppd to
|
||||
exclude the password string from the log. This is the default.
|
||||
@ -885,6 +907,10 @@ peer using MS-CHAP.
|
||||
With this option, pppd will not agree to authenticate itself to the
|
||||
peer using MS-CHAPv2.
|
||||
.TP
|
||||
.B refuse-eap
|
||||
With this option, pppd will not agree to authenticate itself to the
|
||||
peer using EAP.
|
||||
.TP
|
||||
.B refuse-pap
|
||||
With this option, pppd will not agree to authenticate itself to the
|
||||
peer using PAP.
|
||||
@ -915,6 +941,10 @@ Handshake Authentication Protocol] authentication.
|
||||
Require the peer to authenticate itself using MS-CHAPv2 [Microsft Challenge
|
||||
Handshake Authentication Protocol, Version 2] authentication.
|
||||
.TP
|
||||
.B require-eap
|
||||
Require the peer to authenticate itself using EAP [Extensible
|
||||
Authentication Protocol] authentication.
|
||||
.TP
|
||||
.B require-pap
|
||||
Require the peer to authenticate itself using PAP [Password
|
||||
Authentication Protocol] authentication.
|
||||
@ -928,6 +958,27 @@ With this option, pppd will not transmit LCP packets to initiate a
|
||||
connection until a valid LCP packet is received from the peer (as for
|
||||
the `passive' option with ancient versions of pppd).
|
||||
.TP
|
||||
.B srp-interval \fIn
|
||||
If this parameter is given and pppd uses EAP SRP-SHA1 to authenticate
|
||||
the peer (i.e., is the server), then pppd will use the optional
|
||||
lightweight SRP rechallenge mechanism at intervals of \fIn\fR
|
||||
seconds. This option is faster than \fBeap-interval\fR
|
||||
reauthentication because it uses a hash-based mechanism and does not
|
||||
derive a new session key.
|
||||
.TP
|
||||
.B srp-pn-secret \fIstring
|
||||
Set the long-term pseudonym-generating secret for the server. This
|
||||
value is optional and if set, needs to be known at the server
|
||||
(authenticator) side only, and should be different for each server (or
|
||||
poll of identical servers). It is used along with the current date to
|
||||
generate a key to encrypt and decrypt the client's identity contained
|
||||
in the pseudonym.
|
||||
.TP
|
||||
.B srp-use-pseudonym
|
||||
When operating as an EAP SRP-SHA1 client, attempt to use the pseudonym
|
||||
stored in ~/.ppp_psuedonym first as the identity, and save in this
|
||||
file any pseudonym offered by the peer during authentication.
|
||||
.TP
|
||||
.B sync
|
||||
Use synchronous HDLC serial encoding instead of asynchronous.
|
||||
The device used by pppd with this option must have sync support.
|
||||
@ -1044,15 +1095,18 @@ knows that secret. Very often, the names used for authentication
|
||||
correspond to the internet hostnames of the peers, but this is not
|
||||
essential.
|
||||
.LP
|
||||
At present, pppd supports two authentication protocols: the Password
|
||||
Authentication Protocol (PAP) and the Challenge Handshake
|
||||
Authentication Protocol (CHAP). PAP involves the client sending its
|
||||
name and a cleartext password to the server to authenticate itself.
|
||||
In contrast, the server initiates the CHAP authentication exchange by
|
||||
sending a challenge to the client (the challenge packet includes the
|
||||
server's name). The client must respond with a response which
|
||||
includes its name plus a hash value derived from the shared secret and
|
||||
the challenge, in order to prove that it knows the secret.
|
||||
At present, pppd supports three authentication protocols: the Password
|
||||
Authentication Protocol (PAP), Challenge Handshake Authentication
|
||||
Protocol (CHAP), and Extensible Authentication Protocol (EAP). PAP
|
||||
involves the client sending its name and a cleartext password to the
|
||||
server to authenticate itself. In contrast, the server initiates the
|
||||
CHAP authentication exchange by sending a challenge to the client (the
|
||||
challenge packet includes the server's name). The client must respond
|
||||
with a response which includes its name plus a hash value derived from
|
||||
the shared secret and the challenge, in order to prove that it knows
|
||||
the secret. EAP supports CHAP-style authentication, and also includes
|
||||
the SRP-SHA1 mechanism, which is resistant to dictionary-based attacks
|
||||
and does not require a cleartext password on the server side.
|
||||
.LP
|
||||
The PPP protocol, being symmetrical, allows both peers to require the
|
||||
other to authenticate itself. In that case, two separate and
|
||||
@ -1066,9 +1120,10 @@ pppd will not agree to authenticate itself with a particular protocol
|
||||
if it has no secrets which could be used to do so.
|
||||
.LP
|
||||
Pppd stores secrets for use in authentication in secrets
|
||||
files (/etc/ppp/pap-secrets for PAP, /etc/ppp/chap-secrets for
|
||||
CHAP/MS-CHAP/MS-CHAPv2).
|
||||
Both secrets files have the same format. The secrets files can
|
||||
files (/etc/ppp/pap-secrets for PAP, /etc/ppp/chap-secrets for CHAP,
|
||||
MS-CHAP, MS-CHAPv2, and EAP MD5-Challenge, and /etc/ppp/srp-secrets
|
||||
for EAP SRP-SHA1).
|
||||
All secrets files have the same format. The secrets files can
|
||||
contain secrets for pppd to use in authenticating itself to other
|
||||
systems, as well as secrets for pppd to use when authenticating other
|
||||
systems to itself.
|
||||
@ -1113,7 +1168,9 @@ field and the name of the local system in the second field. The
|
||||
name of the local system defaults to the hostname, with the domain
|
||||
name appended if the \fIdomain\fR option is used. This default can be
|
||||
overridden with the \fIname\fR option, except when the
|
||||
\fIusehostname\fR option is used.
|
||||
\fIusehostname\fR option is used. (For EAP SRP-SHA1, see the
|
||||
srp-entry(8) utility for generating proper validator entries to be
|
||||
used in the "secret" field.)
|
||||
.LP
|
||||
When pppd is choosing a secret to use in authenticating itself to the
|
||||
peer, it first determines what name it is going to use to identify
|
||||
@ -1122,14 +1179,14 @@ itself to the peer. This name can be specified by the user with the
|
||||
the name of the local system, determined as described in the previous
|
||||
paragraph. Then pppd looks for a secret with this name in the first
|
||||
field and the peer's name in the second field. Pppd will know the
|
||||
name of the peer if CHAP authentication is being used, because the
|
||||
peer will have sent it in the challenge packet. However, if PAP is being
|
||||
used, pppd will have to determine the peer's name from the options
|
||||
specified by the user. The user can specify the peer's name directly
|
||||
with the \fIremotename\fR option. Otherwise, if the remote IP address
|
||||
was specified by a name (rather than in numeric form), that name will
|
||||
be used as the peer's name. Failing that, pppd will use the null
|
||||
string as the peer's name.
|
||||
name of the peer if CHAP or EAP authentication is being used, because
|
||||
the peer will have sent it in the challenge packet. However, if PAP
|
||||
is being used, pppd will have to determine the peer's name from the
|
||||
options specified by the user. The user can specify the peer's name
|
||||
directly with the \fIremotename\fR option. Otherwise, if the remote
|
||||
IP address was specified by a name (rather than in numeric form), that
|
||||
name will be used as the peer's name. Failing that, pppd will use the
|
||||
null string as the peer's name.
|
||||
.LP
|
||||
When authenticating the peer with PAP, the supplied password is first
|
||||
compared with the secret from the secrets file. If the password
|
||||
@ -1295,16 +1352,18 @@ pppd proxyarp
|
||||
.LP
|
||||
To allow a user to use the PPP facilities, you need to allocate an IP
|
||||
address for that user's machine and create an entry in
|
||||
/etc/ppp/pap-secrets or /etc/ppp/chap-secrets (depending on which
|
||||
authentication method the PPP implementation on the user's machine
|
||||
supports), so that the user's
|
||||
machine can authenticate itself. For example, if Joe has a machine
|
||||
called "joespc" which is to be allowed to dial in to the machine
|
||||
called "server" and use the IP address joespc.my.net, you would add an
|
||||
entry like this to /etc/ppp/pap-secrets or /etc/ppp/chap-secrets:
|
||||
/etc/ppp/pap-secrets, /etc/ppp/chap-secrets, or /etc/ppp/srp-secrets
|
||||
(depending on which authentication method the PPP implementation on
|
||||
the user's machine supports), so that the user's machine can
|
||||
authenticate itself. For example, if Joe has a machine called
|
||||
"joespc" that is to be allowed to dial in to the machine called
|
||||
"server" and use the IP address joespc.my.net, you would add an entry
|
||||
like this to /etc/ppp/pap-secrets or /etc/ppp/chap-secrets:
|
||||
.IP
|
||||
joespc server "joe's secret" joespc.my.net
|
||||
.LP
|
||||
(See srp-entry(8) for a means to generate the server's entry when
|
||||
SRP-SHA1 is in use.)
|
||||
Alternatively, you can create a username called (for example) "ppp",
|
||||
whose login shell is pppd and whose home directory is /etc/ppp.
|
||||
Options to be used when pppd is run this way can be put in
|
||||
@ -1329,7 +1388,7 @@ and debug messages, you will need to edit your /etc/syslog.conf file
|
||||
to direct the messages to the desired output device or file.
|
||||
.LP
|
||||
The \fIdebug\fR option causes the contents of all control packets sent
|
||||
or received to be logged, that is, all LCP, PAP, CHAP or IPCP packets.
|
||||
or received to be logged, that is, all LCP, PAP, CHAP, EAP, or IPCP packets.
|
||||
This can be useful if the PPP negotiation does not succeed or if
|
||||
authentication fails.
|
||||
If debugging is enabled at compile time, the \fIdebug\fR option also
|
||||
@ -1561,6 +1620,16 @@ As for /etc/ppp/pap-secrets, this file should be owned by root and not
|
||||
readable or writable by any other user. Pppd will log a warning if
|
||||
this is not the case.
|
||||
.TP
|
||||
.B /etc/ppp/srp-secrets
|
||||
Names, secrets, and IP addresses for EAP authentication. As for
|
||||
/etc/ppp/pap-secrets, this file should be owned by root and not
|
||||
readable or writable by any other user. Pppd will log a warning if
|
||||
this is not the case.
|
||||
.TP
|
||||
.B ~/.ppp_pseudonym
|
||||
Saved client-side SRP-SHA1 pseudonym. See the \fIsrp-use-pseudonym\fR
|
||||
option for details.
|
||||
.TP
|
||||
.B /etc/ppp/options
|
||||
System default options for pppd, read before user default options or
|
||||
command-line options.
|
||||
@ -1613,10 +1682,25 @@ Simpson, W.A.
|
||||
.I PPP in HDLC-like Framing.
|
||||
July 1994.
|
||||
.TP
|
||||
.B RFC2284
|
||||
Blunk, L.; Vollbrecht, J.,
|
||||
.I PPP Extensible Authentication Protocol (EAP).
|
||||
March 1998.
|
||||
.TP
|
||||
.B RFC2472
|
||||
Haskin, D.
|
||||
.I IP Version 6 over PPP
|
||||
December 1998.
|
||||
.TP
|
||||
.B RFC2945
|
||||
Wu, T.,
|
||||
.I The SRP Authentication and Key Exchange System
|
||||
September 2000.
|
||||
.TP
|
||||
.B draft-ietf-pppext-eap-srp-03.txt
|
||||
Carlson, J.; et al.,
|
||||
.I EAP SRP-SHA1 Authentication Protocol.
|
||||
July 2001.
|
||||
.SH NOTES
|
||||
The following signals have the specified effect when sent to pppd.
|
||||
.TP
|
||||
|
22
pppd/pppd.h
22
pppd/pppd.h
@ -16,7 +16,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: pppd.h,v 1.76 2002/10/27 12:30:54 fcusack Exp $
|
||||
* $Id: pppd.h,v 1.77 2002/11/02 19:48:13 carlsonj Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -317,15 +317,18 @@ extern bool ms_lanman; /* Use LanMan password instead of NT */
|
||||
#define PAP_PEER 0x2
|
||||
#define CHAP_WITHPEER 0x4
|
||||
#define CHAP_PEER 0x8
|
||||
#define EAP_WITHPEER 0x10
|
||||
#define EAP_PEER 0x20
|
||||
|
||||
/* Values for auth_done only */
|
||||
#define CHAP_MD5_WITHPEER 0x10
|
||||
#define CHAP_MD5_PEER 0x20
|
||||
#define CHAP_MD5_WITHPEER 0x40
|
||||
#define CHAP_MD5_PEER 0x80
|
||||
#ifdef CHAPMS
|
||||
#define CHAP_MS_SHIFT 6 /* LSB position for MS auths */
|
||||
#define CHAP_MS_WITHPEER 0x40
|
||||
#define CHAP_MS_PEER 0x80
|
||||
#define CHAP_MS2_WITHPEER 0x100
|
||||
#define CHAP_MS2_PEER 0x200
|
||||
#define CHAP_MS_SHIFT 8 /* LSB position for MS auths */
|
||||
#define CHAP_MS_WITHPEER 0x100
|
||||
#define CHAP_MS_PEER 0x200
|
||||
#define CHAP_MS2_WITHPEER 0x400
|
||||
#define CHAP_MS2_PEER 0x800
|
||||
#endif
|
||||
|
||||
extern char *current_option; /* the name of the option being parsed */
|
||||
@ -514,6 +517,8 @@ int check_passwd __P((int, char *, int, char *, int, char **));
|
||||
/* Check peer-supplied username/password */
|
||||
int get_secret __P((int, char *, char *, char *, int *, int));
|
||||
/* get "secret" for chap */
|
||||
int get_srp_secret __P((int unit, char *client, char *server, char *secret,
|
||||
int am_server));
|
||||
int auth_ip_addr __P((int, u_int32_t));
|
||||
/* check if IP address is authorized */
|
||||
int auth_number __P((void)); /* check if remote number is authorized */
|
||||
@ -719,6 +724,7 @@ extern void (*snoop_send_hook) __P((unsigned char *p, int len));
|
||||
|
||||
#define BCOPY(s, d, l) memcpy(d, s, l)
|
||||
#define BZERO(s, n) memset(s, 0, n)
|
||||
#define BCMP(s1, s2, l) memcmp(s1, s2, l)
|
||||
|
||||
#define PRINTMSG(m, l) { info("Remote message: %0.*v", l, m); }
|
||||
|
||||
|
16
pppd/sha1.h
16
pppd/sha1.h
@ -1,5 +1,11 @@
|
||||
/* sha1.h */
|
||||
|
||||
/* If OpenSSL is in use, then use that version of SHA-1 */
|
||||
#ifdef OPENSSL
|
||||
#include <t_sha.h>
|
||||
#define __SHA1_INCLUDE_
|
||||
#endif
|
||||
|
||||
#ifndef __SHA1_INCLUDE_
|
||||
|
||||
typedef struct {
|
||||
@ -8,11 +14,17 @@ typedef struct {
|
||||
unsigned char buffer[64];
|
||||
} SHA1_CTX;
|
||||
|
||||
#define SHA1_SIGNATURE_SIZE 20
|
||||
|
||||
extern void SHA1_Init(SHA1_CTX *);
|
||||
extern void SHA1_Update(SHA1_CTX *, const unsigned char *, unsigned int);
|
||||
extern void SHA1_Final(unsigned char[SHA1_SIGNATURE_SIZE], SHA1_CTX *);
|
||||
|
||||
#define __SHA1_INCLUDE_
|
||||
#endif /* __SHA1_INCLUDE_ */
|
||||
|
||||
#ifndef SHA1_SIGNATURE_SIZE
|
||||
#ifdef SHA_DIGESTSIZE
|
||||
#define SHA1_SIGNATURE_SIZE SHA_DIGESTSIZE
|
||||
#else
|
||||
#define SHA1_SIGNATURE_SIZE 20
|
||||
#endif
|
||||
#endif
|
||||
|
83
pppd/srp-entry.8
Normal file
83
pppd/srp-entry.8
Normal file
@ -0,0 +1,83 @@
|
||||
.\" manual page [] for srp-entry
|
||||
.\" $Id: srp-entry.8,v 1.1 2002/11/02 19:48:13 carlsonj Exp $
|
||||
.\" SH section heading
|
||||
.\" SS subsection heading
|
||||
.\" LP paragraph
|
||||
.\" IP indented paragraph
|
||||
.\" TP hanging label
|
||||
.TH SRP-ENTRY 8
|
||||
.SH NAME
|
||||
srp-entry \- Generate a SRP-SHA1 Server Entry
|
||||
.SH SYNOPSIS
|
||||
.B srp-entry
|
||||
[
|
||||
.I -i index
|
||||
] [
|
||||
.I clientname
|
||||
]
|
||||
.SH DESCRIPTION
|
||||
.LP
|
||||
This utility generates an entry suitable for use in the
|
||||
/etc/ppp/srp-secrets file on a PPP EAP SRP-SHA1 authenticator
|
||||
("server"). This file has the same basic layout as the other pppd(8)
|
||||
authentication files, /etc/ppp/pap-secrets and /etc/ppp/chap-secrets.
|
||||
Thus, the entry generated has at least four main fields separated by
|
||||
spaces. The first field is the authenticatee ("client") name. The
|
||||
second is the server name. The third is the secret. The fourth is
|
||||
the allowed (or assigned) IP address for the client, and defaults to
|
||||
"*". Additional fields can contain additional IP addresses or pppd
|
||||
options; see pppd(8) for details.
|
||||
.LP
|
||||
The third field has three subfields, separated by colons. The first
|
||||
subfield is the index of the modulus and generator from SRP's
|
||||
/etc/tpasswd.conf. The special value 0 is used to represent the
|
||||
well-known modulus and generator specified in the EAP SRP-SHA1 draft.
|
||||
The second subfield is the password validator. The third is the
|
||||
password salt. These latter two values are encoded in base64 notation.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.I -i <index>
|
||||
Specifies the modulus/generator index in /etc/tpasswd.conf. In order
|
||||
to use this option, you will need to run the "tconf" utility from the
|
||||
SRP package to generate local entries for this file. Note that if
|
||||
these values are not known to the client, the client will be forced to
|
||||
run time-consuming safety tests on the values used. For this reason,
|
||||
using the well-known values is recommended.
|
||||
.TP
|
||||
.I <clientname>
|
||||
Specifies the client name. The password validator is a hashed
|
||||
combination of the client's name and password, and both are required.
|
||||
If the client name is not supplied on the command line, srp-entry will
|
||||
prompt for the client name first.
|
||||
.SH FILES
|
||||
.TP
|
||||
.B /etc/ppp/srp-secrets
|
||||
Usernames, passwords and IP addresses for SRP authentication. This
|
||||
file should be owned by root and not readable or writable by any other
|
||||
user. Pppd will log a warning if this is not the case. Note that
|
||||
srp-entry does not write to this file. The user is responsible for
|
||||
copying the output of srp-entry into this file.
|
||||
.TP
|
||||
.B /etc/tpasswd.conf
|
||||
Indexed copies of tested modulus/generator combinations; part of the
|
||||
SRP package.
|
||||
.SH SEE ALSO
|
||||
.TP
|
||||
pppd(8)
|
||||
.TP
|
||||
.B RFC2284
|
||||
Blunk, L., Vollbrecht, J.,
|
||||
.I PPP Extensible Authentication Protocol (EAP).
|
||||
March 1998.
|
||||
.TP
|
||||
.B draft-ietf-pppext-eap-srp-03.txt
|
||||
Carlson, J., et al.,
|
||||
.I EAP SRP-SHA1 Authentication Protocol.
|
||||
July 2001.
|
||||
.TP
|
||||
.B RFC2945
|
||||
Wu, T.,
|
||||
.I The SRP Authentication and Key Exchange System
|
||||
September 2000.
|
||||
.SH AUTHOR
|
||||
James Carlson (james.d.carlson@sun.com)
|
190
pppd/srp-entry.c
Normal file
190
pppd/srp-entry.c
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Utility program for generating entries in /etc/ppp/srp-secrets
|
||||
*
|
||||
* Copyright (c) 2001 by Sun Microsystems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Non-exclusive rights to redistribute, modify, translate, and use
|
||||
* this software in source and binary forms, in whole or in part, is
|
||||
* hereby granted, provided that the above copyright notice is
|
||||
* duplicated in any source form, and that neither the name of the
|
||||
* copyright holder nor the author is used to endorse or promote
|
||||
* products derived from this software.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Original version by James Carlson
|
||||
*
|
||||
* Usage:
|
||||
* srp-entry [-i index] [clientname]
|
||||
*
|
||||
* Index, if supplied, is the modulus/generator index from
|
||||
* /etc/tpasswd.conf. If not supplied, then the last (highest
|
||||
* numbered) entry from that file is used. If the file doesn't exist,
|
||||
* then the default "well known" EAP SRP-SHA1 modulus/generator is
|
||||
* used.
|
||||
*
|
||||
* The default modulus/generator can be requested as index 0.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <t_pwd.h>
|
||||
|
||||
#ifndef SOL2
|
||||
#define getpassphrase getpass
|
||||
#endif
|
||||
|
||||
#define HAS_SPACE 1
|
||||
#define HAS_DQUOTE 2
|
||||
#define HAS_SQUOTE 4
|
||||
#define HAS_BACKSLASH 8
|
||||
|
||||
static const u_char wkmodulus[] = {
|
||||
0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B,
|
||||
0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F,
|
||||
0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07,
|
||||
0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50,
|
||||
0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED,
|
||||
0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D,
|
||||
0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D,
|
||||
0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50,
|
||||
0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0,
|
||||
0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3,
|
||||
0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8,
|
||||
0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8,
|
||||
0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA,
|
||||
0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74,
|
||||
0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7,
|
||||
0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B,
|
||||
0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16,
|
||||
0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81,
|
||||
0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A,
|
||||
0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48,
|
||||
0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D,
|
||||
0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA,
|
||||
0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78,
|
||||
0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6,
|
||||
0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29,
|
||||
0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8,
|
||||
0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82,
|
||||
0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6,
|
||||
0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4,
|
||||
0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75,
|
||||
0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2,
|
||||
0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73
|
||||
};
|
||||
|
||||
static const char *myname;
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void) fprintf(stderr, "Usage:\n\t%s [-i index] [clientname]\n",
|
||||
myname);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct t_conf *tc;
|
||||
struct t_confent *tcent, mytce;
|
||||
struct t_pw pwval;
|
||||
char *name;
|
||||
char pname[256];
|
||||
char *pass1, *pass2;
|
||||
int flags, idx;
|
||||
char *cp;
|
||||
char delimit;
|
||||
char strbuf[MAXB64PARAMLEN];
|
||||
char saltbuf[MAXB64SALTLEN];
|
||||
|
||||
if ((myname = *argv) == NULL)
|
||||
myname = "srp-entry";
|
||||
else
|
||||
argv++;
|
||||
|
||||
idx = -1;
|
||||
if (*argv != NULL && strcmp(*argv, "-i") == 0) {
|
||||
if (*++argv == NULL)
|
||||
usage();
|
||||
idx = atoi(*argv++);
|
||||
}
|
||||
|
||||
tcent = NULL;
|
||||
if (idx != 0 && (tc = t_openconf(NULL)) != NULL) {
|
||||
if (idx == -1)
|
||||
tcent = t_getconflast(tc);
|
||||
else
|
||||
tcent = t_getconfbyindex(tc, idx);
|
||||
}
|
||||
if (idx <= 0 && tcent == NULL) {
|
||||
mytce.index = 0;
|
||||
mytce.modulus.data = (u_char *)wkmodulus;
|
||||
mytce.modulus.len = sizeof (wkmodulus);
|
||||
mytce.generator.data = (u_char *)"\002";
|
||||
mytce.generator.len = 1;
|
||||
tcent = &mytce;
|
||||
}
|
||||
if (tcent == NULL) {
|
||||
(void) fprintf(stderr, "SRP modulus/generator %d not found\n",
|
||||
idx);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((name = *argv) == NULL) {
|
||||
(void) printf("Client name: ");
|
||||
if (fgets(pname, sizeof (pname), stdin) == NULL)
|
||||
exit(1);
|
||||
if ((cp = strchr(pname, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
name = pname;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if ((pass1 = getpassphrase("Pass phrase: ")) == NULL)
|
||||
exit(1);
|
||||
pass1 = strdup(pass1);
|
||||
if ((pass2 = getpassphrase("Re-enter phrase: ")) == NULL)
|
||||
exit(1);
|
||||
if (strcmp(pass1, pass2) == 0)
|
||||
break;
|
||||
free(pass1);
|
||||
(void) printf("Phrases don't match; try again.\n");
|
||||
}
|
||||
|
||||
memset(&pwval, 0, sizeof (pwval));
|
||||
t_makepwent(&pwval, name, pass1, NULL, tcent);
|
||||
flags = 0;
|
||||
for (cp = name; *cp != '\0'; cp++)
|
||||
if (isspace(*cp))
|
||||
flags |= HAS_SPACE;
|
||||
else if (*cp == '"')
|
||||
flags |= HAS_DQUOTE;
|
||||
else if (*cp == '\'')
|
||||
flags |= HAS_SQUOTE;
|
||||
else if (*cp == '\\')
|
||||
flags |= HAS_BACKSLASH;
|
||||
delimit = flags == 0 ? '\0' : (flags & HAS_DQUOTE) ? '\'' : '"';
|
||||
if (delimit != '\0')
|
||||
(void) putchar(delimit);
|
||||
for (cp = name; *cp != '\0'; cp++) {
|
||||
if (*cp == delimit || *cp == '\\')
|
||||
(void) putchar('\\');
|
||||
(void) putchar(*cp);
|
||||
}
|
||||
if (delimit != '\0')
|
||||
(void) putchar(delimit);
|
||||
(void) printf(" * %d:%s:%s *\n",
|
||||
pwval.pebuf.index, t_tob64(strbuf,
|
||||
(char *)pwval.pebuf.password.data, pwval.pebuf.password.len),
|
||||
t_tob64(saltbuf, (char *)pwval.pebuf.salt.data,
|
||||
pwval.pebuf.salt.len));
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user