mirror of https://gitee.com/openkylin/ppp.git
EAP-TLS authentication support for PPP
Origin: https://www.nikhef.nl/~janjust/ppp/download.html Bug-Debian: https://bugs.debian.org/602503 Bug-Ubuntu: https://launchpad.net/bugs/643417 Forwarded: not-needed Last-Update: 2018-11-04 This patch is based on ppp-2.4.7-eaptls-mppe-1.102.patch, with the following changes: - Patch refreshed to remove fuzz. - Trailing spaces removed. Gbp-Pq: Name eaptls-mppe.patch
This commit is contained in:
parent
807808369a
commit
fcacaeaf27
|
@ -0,0 +1,291 @@
|
|||
EAP-TLS authentication support for PPP
|
||||
======================================
|
||||
|
||||
1. Intro
|
||||
|
||||
The Extensible Authentication Protocol (EAP; RFC 3748) is a
|
||||
security protocol that can be used with PPP. It provides a means
|
||||
to plug in multiple optional authentication methods.
|
||||
|
||||
Transport Level Security (TLS; RFC 5216) provides for mutual
|
||||
authentication, integrity-protected ciphersuite negotiation and
|
||||
key exchange between two endpoints. It also provides for optional
|
||||
MPPE encryption.
|
||||
|
||||
EAP-TLS (RFC 2716) incapsulates the TLS messages in EAP packets,
|
||||
allowing TLS mutual authentication to be used as a generic EAP
|
||||
mechanism. It also provides optional encryption using the MPPE
|
||||
protocol.
|
||||
|
||||
This patch provide EAP-TLS support to pppd.
|
||||
This authentication method can be used in both client or server
|
||||
mode.
|
||||
|
||||
2. Building
|
||||
|
||||
To build pppd with EAP-TLS support, OpenSSL (http://www.openssl.org)
|
||||
is required. Any version from 0.9.7 should work.
|
||||
|
||||
Configure, compile, and install as usual.
|
||||
|
||||
3. Configuration
|
||||
|
||||
On the client side there are two ways to configure EAP-TLS:
|
||||
|
||||
1. supply the appropriate 'ca', 'cert' and 'key' command-line parameters
|
||||
|
||||
2. edit the /etc/ppp/eaptls-client file.
|
||||
Insert a line for each system with which you use EAP-TLS.
|
||||
The line is composed of this fields separated by tab:
|
||||
|
||||
- Client name
|
||||
The name used by the client for authentication, can be *
|
||||
- Server name
|
||||
The name of the server, can be *
|
||||
- Client certificate file
|
||||
The file containing the certificate chain for the
|
||||
client in PEM format
|
||||
- Server certificate file
|
||||
If you want to specify the certificate that the
|
||||
server is allowed to use, put the certificate file name.
|
||||
Else put a dash '-'.
|
||||
- CA certificate file
|
||||
The file containing the trusted CA certificates in PEM
|
||||
format.
|
||||
- Client private key file
|
||||
The file containing the client private key in PEM format.
|
||||
|
||||
|
||||
On the server side edit the /etc/ppp/eaptls-server file.
|
||||
Insert a line for each system with which you use EAP-TLS.
|
||||
The line is composed of this fields separated by tab:
|
||||
|
||||
- Client name
|
||||
The name used by the client for authentication, can be *
|
||||
- Server name
|
||||
The name of the server, can be *
|
||||
- Client certificate file
|
||||
If you want to specify the certificate that the
|
||||
client is allowed to use, put the certificate file name.
|
||||
Else put a dash '-'.
|
||||
- Server certificate file
|
||||
The file containing the certificate chain for the
|
||||
server in PEM format
|
||||
- CA certificate file
|
||||
The file containing the trusted CA certificates in PEM format.
|
||||
- Client private key file
|
||||
The file containing the server private key in PEM format.
|
||||
- addresses
|
||||
A list of IP addresses the client is allowed to use.
|
||||
|
||||
|
||||
OpenSSL engine support is included starting with v0.95 of this patch.
|
||||
Currently the only engine tested is the 'pkcs11' engine (hardware token
|
||||
support). To use the 'pksc11' engine:
|
||||
- Use a special private key fileiname in the /etc/ppp/eaptls-client file:
|
||||
<engine>:<identifier>
|
||||
e.g.
|
||||
pkcs11:123456
|
||||
|
||||
- The certificate can also be loaded from the 'pkcs11' engine using
|
||||
a special client certificate filename in the /etc/ppp/eaptls-client file:
|
||||
<engine>:<identifier>
|
||||
e.g.
|
||||
pkcs11:123456
|
||||
|
||||
- Create an /etc/ppp/openssl.cnf file to load the right OpenSSL engine prior
|
||||
to starting 'pppd'. A sample openssl.cnf file is
|
||||
|
||||
openssl_conf = openssl_def
|
||||
|
||||
[ openssl_def ]
|
||||
engines = engine_section
|
||||
|
||||
[ engine_section ]
|
||||
pkcs11 = pkcs11_section
|
||||
|
||||
[ pkcs11_section ]
|
||||
engine_id = pkcs11
|
||||
dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so
|
||||
MODULE_PATH = /usr/lib64/libeTPkcs11.so
|
||||
init = 0
|
||||
|
||||
- There are two ways to specify a password/PIN for the PKCS11 engine:
|
||||
- inside the openssl.cnf file using
|
||||
PIN = your-secret-pin
|
||||
Note The keyword 'PIN' is case sensitive!
|
||||
- Using the 'password' in the ppp options file.
|
||||
From v0.97 of the eap-tls patch the password can also be supplied
|
||||
using the appropriate 'eaptls_passwd_hook' (see plugins/passprompt.c
|
||||
for an example).
|
||||
|
||||
|
||||
4. Options
|
||||
|
||||
These pppd options are available:
|
||||
|
||||
ca <ca-file>
|
||||
Use the CA public certificate found in <ca-file> in PEM format
|
||||
cert <cert-file>
|
||||
Use the client public certificate found in <cert-file> in PEM format
|
||||
or in engine:engine_id format
|
||||
key <key-file>
|
||||
Use the client private key found in <key-file> in PEM format
|
||||
or in engine:engine_id format
|
||||
crl <crl-file>
|
||||
Use the Certificate Revocation List (CRL) file <crl-file> in PEM format.
|
||||
crl-dir <dir>
|
||||
Use CRL files from directory <dir>. It contains CRL files in PEM
|
||||
format and each file contains a CRL. The files are looked up
|
||||
by the issuer name hash value. Use the c_rehash utility
|
||||
to create necessary links.
|
||||
need-peer-eap
|
||||
If the peer doesn't ask us to authenticate or doesn't use eap
|
||||
to authenticate us, disconnect.
|
||||
|
||||
Note:
|
||||
password-encrypted certificates can be used as of v0.94 of this
|
||||
patch. The password for the eap-tls.key file is specified using
|
||||
the regular
|
||||
password ....
|
||||
statement in the ppp options file, or by using the appropriate
|
||||
plugin which supplies a 'eaptls_passwd_hook' routine.
|
||||
|
||||
5. Connecting
|
||||
|
||||
If you're setting up a pppd server, edit the EAP-TLS configuration file
|
||||
as written above and then run pppd with the 'auth' option to authenticate
|
||||
the client. The EAP-TLS method will be used if the other eap methods can't
|
||||
be used (no secrets).
|
||||
|
||||
If you're setting up a client, edit the configuration file and then run
|
||||
pppd with 'remotename' option to specify the server name. Add the
|
||||
'need-peer-eap' option if you want to be sure the peer ask you to
|
||||
authenticate (and to use eap) and to disconnect if it doesn't.
|
||||
|
||||
6. Example
|
||||
|
||||
The following example can be used to connect a Linux client with the 'pptp'
|
||||
package to a Linux server running the 'pptpd' (PoPToP) package. The server
|
||||
was configured with a certificate with name (CN) 'pptp-server', the client
|
||||
was configured with a certificate with name (CN) 'pptp-client', both
|
||||
signed by the same Certificate Authority (CA).
|
||||
|
||||
Server side:
|
||||
- /etc/pptpd.conf file:
|
||||
option /etc/ppp/options-pptpd-eaptls
|
||||
localip 172.16.1.1
|
||||
remoteip 172.16.1.10-20
|
||||
- /etc/ppp/options-pptpd-eaptls file:
|
||||
name pptp-server
|
||||
lock
|
||||
mtu 1500
|
||||
mru 1450
|
||||
auth
|
||||
lcp-echo-failure 3
|
||||
lcp-echo-interval 5
|
||||
nodeflate
|
||||
nobsdcomp
|
||||
nopredictor1
|
||||
nopcomp
|
||||
noaccomp
|
||||
|
||||
require-eap
|
||||
require-mppe-128
|
||||
|
||||
crl /home/janjust/ppp/keys/crl.pem
|
||||
|
||||
debug
|
||||
logfile /tmp/pppd.log
|
||||
|
||||
- /etc/ppp/eaptls-server file:
|
||||
* pptp-server - /etc/ppp/pptp-server.crt /etc/ppp/ca.crt /etc/ppp/pptp-server.key *
|
||||
|
||||
- On the server, run
|
||||
pptdp --conf /etc/pptpd.conf
|
||||
|
||||
Client side:
|
||||
- Run
|
||||
pppd noauth require-eap require-mppe-128 \
|
||||
ipcp-accept-local ipcp-accept-remote noipdefault \
|
||||
cert /etc/ppp/keys/pptp-client.crt \
|
||||
key /etc/ppp/keys/pptp-client.key \
|
||||
ca /etc/ppp/keys/ca.crt \
|
||||
name pptp-client remotename pptp-server \
|
||||
debug logfile /tmp/pppd.log
|
||||
pty "pptp pptp-server.example.com --nolaunchpppd"
|
||||
|
||||
Check /var/log/messages and the files /tmp/pppd.log on both sides for debugging info.
|
||||
|
||||
7. Notes
|
||||
|
||||
This is experimental code.
|
||||
Send suggestions and comments to Jan Just Keijser <janjust@nikhef.nl>
|
||||
|
||||
8. Changelog of ppp-<>-eaptls-mppe-* patches
|
||||
|
||||
v0.7 (22-Nov-2005)
|
||||
- First version of the patch to include MPPE support
|
||||
- ppp-2.4.3 only
|
||||
v0.9 (25-Jul-2006)
|
||||
- Bug fixes
|
||||
- First version for ppp-2.4.4
|
||||
v0.91 (03-Sep-2006)
|
||||
- Added missing #include for md5.h
|
||||
- Last version for ppp-2.4.3
|
||||
v0.92 (22-Apr-2008)
|
||||
- Fix for openssl 0.9.8 issue with md5 function overload.
|
||||
v0.93 (14-Aug-2008)
|
||||
- Make sure 'noauth' option can be used to bypass server certificate verification.
|
||||
v0.94 (15-Oct-2008)
|
||||
- Added support for password-protected private keys by (ab)using the 'password' field.
|
||||
v0.95 (23-Dec-2009)
|
||||
- First version with OpenSSL engine support.
|
||||
v0.96 (27-Jan-2010)
|
||||
- Added fully functional support for OpenSSL engines (PKCS#11)
|
||||
- First version for ppp-2.4.5
|
||||
v0.97 (20-Apr-2010)
|
||||
- Some bug fixes for v0.96
|
||||
- Added support for entering the password via a plugin. The sample plugin
|
||||
.../pppd/plugins/passprompt.c has been extended with EAP-TLS support.
|
||||
The "old" methods using the password option or the /etc/ppp/openssl.cnf file still work.
|
||||
- Added support for specifying the client CA, certificate and private key on the command-line
|
||||
or via the ppp config file.
|
||||
v0.98 (20-Apr-2010)
|
||||
- Fix initialisation bug when using ca/cert/key command-line options.
|
||||
- Last version for ppp-2.4.4
|
||||
v0.99 (05-Oct-2010)
|
||||
- Fix coredump when using multilink option.
|
||||
v0.991 (08-Aug-2011)
|
||||
- Fix compilation issue with openssl 1.0.
|
||||
v0.992 (01-Dec-2011)
|
||||
- Fix compilation issue with eaptls_check_hook and passwordfd plugin.
|
||||
v0.993 (24-Apr-2012)
|
||||
- Fix compilation issue when EAP_TLS=n in pppd/Makefile.
|
||||
v0.994 (11-Jun-2012)
|
||||
- Fix compilation issue on Ubuntu 11.10.
|
||||
v0.995 (27-May-2014)
|
||||
- Add support for a CRL file using the command-line option 'crl'
|
||||
(prior only 'crl-dir' was supported).
|
||||
- Fix segfault when pkcs11 enginename was not specified correctly.
|
||||
- Fix segfault when client was misconfigured.
|
||||
- Disable SSL Session Ticket support as Windows 8 does not support this.
|
||||
v0.996 (28-May-2014)
|
||||
- Fix minor bug where SessionTicket message was printed as 'Unknown SSL3 code 4'
|
||||
- Add EAP-TLS-specific options to pppd.8 manual page.
|
||||
- Updated README.eap-tls file with new options and provide an example.
|
||||
v0.997 (19-Jun-2014)
|
||||
- Change SSL_OP_NO_TICKETS to SSL_OP_NO_TICKET
|
||||
- Fix bug in initialisation code with fragmented packets.
|
||||
v0.998 (13-Mar-2015)
|
||||
- Add fix for https://bugzilla.redhat.com/show_bug.cgi?id=1023620
|
||||
v0.999 (11-May-2017)
|
||||
- Add support for OpenSSL 1.1: the code will now compile against OpenSSL 1.0.x or 1.1.x.
|
||||
v1.101 (1-Jun-2018)
|
||||
- Fix vulnerabilities CVE-2018-11574.
|
||||
v1.102 (2-Nov-2018)
|
||||
- Add TLS 1.2 support. Windows 7/8 will connect using TLS 1.0, Windows 10 clients using TLS 1.2.
|
||||
This works both when compiling against OpenSSL 1.0.1+ and 1.1+.
|
||||
- Print warning when certificate is either not yet valid or has expired.
|
||||
- Perform better peer certificate checks.
|
||||
- Allow certificate chain files to be used.
|
|
@ -0,0 +1,10 @@
|
|||
# Parameters for authentication using EAP-TLS (client)
|
||||
|
||||
# client name (can be *)
|
||||
# server name (can be *)
|
||||
# client certificate file (required)
|
||||
# server certificate file (optional, if unused put '-')
|
||||
# CA certificate file (required)
|
||||
# client private key file (required)
|
||||
|
||||
#client server /root/cert/client.crt - /root/cert/ca.crt /root/cert/client.key
|
|
@ -0,0 +1,11 @@
|
|||
# Parameters for authentication using EAP-TLS (server)
|
||||
|
||||
# client name (can be *)
|
||||
# server name (can be *)
|
||||
# client certificate file (optional, if unused put '-')
|
||||
# server certificate file (required)
|
||||
# CA certificate file (required)
|
||||
# server private key file (required)
|
||||
# allowed addresses (required, can be *)
|
||||
|
||||
#client server - /root/cert/server.crt /root/cert/ca.crt /root/cert/server.key 192.168.1.0/24
|
|
@ -0,0 +1,14 @@
|
|||
openssl_conf = openssl_def
|
||||
|
||||
[ openssl_def ]
|
||||
engines = engine_section
|
||||
|
||||
[ engine_section ]
|
||||
pkcs11 = pkcs11_section
|
||||
|
||||
[ pkcs11_section ]
|
||||
engine_id = pkcs11
|
||||
dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so
|
||||
MODULE_PATH = /usr/lib64/libeTPkcs11.so
|
||||
init = 0
|
||||
|
|
@ -26,7 +26,7 @@ install-progs:
|
|||
cd pppdump; $(MAKE) $(MFLAGS) install
|
||||
|
||||
install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \
|
||||
$(ETCDIR)/chap-secrets
|
||||
$(ETCDIR)/chap-secrets $(ETCDIR)/eaptls-server $(ETCDIR)/eaptls-client
|
||||
|
||||
install-devel:
|
||||
cd pppd; $(MAKE) $(MFLAGS) install-devel
|
||||
|
@ -37,6 +37,10 @@ $(ETCDIR)/pap-secrets:
|
|||
$(INSTALL) -c -m 600 etc.ppp/pap-secrets $@
|
||||
$(ETCDIR)/chap-secrets:
|
||||
$(INSTALL) -c -m 600 etc.ppp/chap-secrets $@
|
||||
$(ETCDIR)/eaptls-server:
|
||||
$(INSTALL) -c -m 600 etc.ppp/eaptls-server $@
|
||||
$(ETCDIR)/eaptls-client:
|
||||
$(INSTALL) -c -m 600 etc.ppp/eaptls-client $@
|
||||
|
||||
$(BINDIR):
|
||||
$(INSTALL) -d -m 755 $@
|
||||
|
|
|
@ -76,6 +76,9 @@ CBCP=y
|
|||
# Use libutil
|
||||
USE_LIBUTIL=y
|
||||
|
||||
# Enable EAP-TLS authentication (requires libssl and libcrypto)
|
||||
USE_EAPTLS=y
|
||||
|
||||
MAXOCTETS=y
|
||||
|
||||
INCLUDE_DIRS= -I../include
|
||||
|
@ -116,6 +119,15 @@ HEADERS += sha1.h
|
|||
PPPDOBJS += sha1.o
|
||||
endif
|
||||
|
||||
# EAP-TLS
|
||||
ifdef USE_EAPTLS
|
||||
CFLAGS += -DUSE_EAPTLS=1 -I/usr/kerberos/include
|
||||
LIBS += -lssl -lcrypto
|
||||
PPPDSRC += eap-tls.c
|
||||
HEADERS += eap-tls.h
|
||||
PPPDOBJS += eap-tls.o
|
||||
endif
|
||||
|
||||
ifdef HAS_SHADOW
|
||||
CFLAGS += -DHAS_SHADOW
|
||||
#LIBS += -lshadow $(LIBS)
|
||||
|
|
413
pppd/auth.c
413
pppd/auth.c
|
@ -109,6 +109,9 @@
|
|||
#include "upap.h"
|
||||
#include "chap-new.h"
|
||||
#include "eap.h"
|
||||
#ifdef USE_EAPTLS
|
||||
#include "eap-tls.h"
|
||||
#endif
|
||||
#ifdef CBCP_SUPPORT
|
||||
#include "cbcp.h"
|
||||
#endif
|
||||
|
@ -183,6 +186,11 @@ int (*chap_check_hook) __P((void)) = NULL;
|
|||
/* Hook for a plugin to get the CHAP password for authenticating us */
|
||||
int (*chap_passwd_hook) __P((char *user, char *passwd)) = NULL;
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
/* Hook for a plugin to get the EAP-TLS password for authenticating us */
|
||||
int (*eaptls_passwd_hook) __P((char *user, char *passwd)) = NULL;
|
||||
#endif
|
||||
|
||||
/* Hook for a plugin to say whether it is OK if the peer
|
||||
refuses to authenticate. */
|
||||
int (*null_auth_hook) __P((struct wordlist **paddrs,
|
||||
|
@ -238,6 +246,14 @@ bool explicit_remote = 0; /* User specified explicit remote name */
|
|||
bool explicit_user = 0; /* Set if "user" option supplied */
|
||||
bool explicit_passwd = 0; /* Set if "password" option supplied */
|
||||
char remote_name[MAXNAMELEN]; /* Peer's name for authentication */
|
||||
#ifdef USE_EAPTLS
|
||||
char *cacert_file = NULL; /* CA certificate file (pem format) */
|
||||
char *cert_file = NULL; /* client certificate file (pem format) */
|
||||
char *privkey_file = NULL; /* client private key file (pem format) */
|
||||
char *crl_dir = NULL; /* directory containing CRL files */
|
||||
char *crl_file = NULL; /* Certificate Revocation List (CRL) file (pem format) */
|
||||
bool need_peer_eap = 0; /* Require peer to authenticate us */
|
||||
#endif
|
||||
|
||||
static char *uafname; /* name of most recent +ua file */
|
||||
|
||||
|
@ -254,6 +270,19 @@ 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));
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
static int have_eaptls_secret_server
|
||||
__P((char *client, char *server, int need_ip, int *lacks_ipp));
|
||||
static int have_eaptls_secret_client __P((char *client, char *server));
|
||||
static int scan_authfile_eaptls __P((FILE * f, char *client, char *server,
|
||||
char *cli_cert, char *serv_cert,
|
||||
char *ca_cert, char *pk,
|
||||
struct wordlist ** addrs,
|
||||
struct wordlist ** opts,
|
||||
char *filename, int flags));
|
||||
#endif
|
||||
|
||||
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 **,
|
||||
|
@ -401,6 +430,15 @@ option_t auth_options[] = {
|
|||
"Set telephone number(s) which are allowed to connect",
|
||||
OPT_PRIV | OPT_A2LIST },
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
{ "ca", o_string, &cacert_file, "EAP-TLS CA certificate in PEM format" },
|
||||
{ "cert", o_string, &cert_file, "EAP-TLS client certificate in PEM format" },
|
||||
{ "key", o_string, &privkey_file, "EAP-TLS client private key in PEM format" },
|
||||
{ "crl-dir", o_string, &crl_dir, "Use CRLs in directory" },
|
||||
{ "crl", o_string, &crl_file, "Use specific CRL file" },
|
||||
{ "need-peer-eap", o_bool, &need_peer_eap,
|
||||
"Require the peer to authenticate us", 1 },
|
||||
#endif /* USE_EAPTLS */
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -730,6 +768,9 @@ link_established(unit)
|
|||
lcp_options *wo = &lcp_wantoptions[unit];
|
||||
lcp_options *go = &lcp_gotoptions[unit];
|
||||
lcp_options *ho = &lcp_hisoptions[unit];
|
||||
#ifdef USE_EAPTLS
|
||||
lcp_options *ao = &lcp_allowoptions[unit];
|
||||
#endif
|
||||
int i;
|
||||
struct protent *protp;
|
||||
|
||||
|
@ -764,6 +805,22 @@ link_established(unit)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
if (need_peer_eap && !ao->neg_eap) {
|
||||
warn("eap required to authenticate us but no suitable secrets");
|
||||
lcp_close(unit, "couldn't negotiate eap");
|
||||
status = EXIT_AUTH_TOPEER_FAILED;
|
||||
return;
|
||||
}
|
||||
|
||||
if (need_peer_eap && !ho->neg_eap) {
|
||||
warn("peer doesn't want to authenticate us with eap");
|
||||
lcp_close(unit, "couldn't negotiate eap");
|
||||
status = EXIT_PEER_AUTH_FAILED;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
new_phase(PHASE_AUTHENTICATE);
|
||||
auth = 0;
|
||||
if (go->neg_eap) {
|
||||
|
@ -1277,6 +1334,15 @@ auth_check_options()
|
|||
our_name, 1, &lacks_ip);
|
||||
}
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
if (!can_auth && wo->neg_eap) {
|
||||
can_auth =
|
||||
have_eaptls_secret_server((explicit_remote ? remote_name :
|
||||
NULL), our_name, 1, &lacks_ip);
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
if (auth_required && !can_auth && noauth_addrs == NULL) {
|
||||
if (default_auth) {
|
||||
option_error(
|
||||
|
@ -1331,7 +1397,11 @@ auth_reset(unit)
|
|||
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));
|
||||
have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)
|
||||
#ifdef USE_EAPTLS
|
||||
|| have_eaptls_secret_client(user, (explicit_remote? remote_name: NULL))
|
||||
#endif
|
||||
);
|
||||
|
||||
hadchap = -1;
|
||||
if (go->neg_upap && !uselogin && !have_pap_secret(NULL))
|
||||
|
@ -1346,8 +1416,14 @@ auth_reset(unit)
|
|||
!have_chap_secret((explicit_remote? remote_name: NULL), our_name,
|
||||
1, NULL))) &&
|
||||
!have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1,
|
||||
NULL))
|
||||
NULL)
|
||||
#ifdef USE_EAPTLS
|
||||
&& !have_eaptls_secret_server((explicit_remote? remote_name: NULL),
|
||||
our_name, 1, NULL)
|
||||
#endif
|
||||
)
|
||||
go->neg_eap = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1709,6 +1785,7 @@ have_srp_secret(client, server, need_ip, lacks_ipp)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* get_secret - open the CHAP secret file and return the secret
|
||||
* for authenticating the given client on the given server.
|
||||
|
@ -2361,3 +2438,335 @@ auth_script(script)
|
|||
|
||||
auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
static int
|
||||
have_eaptls_secret_server(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;
|
||||
char servcertfile[MAXWORDLEN];
|
||||
char clicertfile[MAXWORDLEN];
|
||||
char cacertfile[MAXWORDLEN];
|
||||
char pkfile[MAXWORDLEN];
|
||||
|
||||
filename = _PATH_EAPTLSSERVFILE;
|
||||
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_eaptls(f, client, server, clicertfile, servcertfile,
|
||||
cacertfile, pkfile, &addrs, NULL, filename,
|
||||
0);
|
||||
|
||||
fclose(f);
|
||||
|
||||
/*
|
||||
if (ret >= 0 && !eaptls_init_ssl(1, cacertfile, servcertfile,
|
||||
clicertfile, pkfile))
|
||||
ret = -1;
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
have_eaptls_secret_client(client, server)
|
||||
char *client;
|
||||
char *server;
|
||||
{
|
||||
FILE *f;
|
||||
int ret;
|
||||
char *filename;
|
||||
struct wordlist *addrs = NULL;
|
||||
char servcertfile[MAXWORDLEN];
|
||||
char clicertfile[MAXWORDLEN];
|
||||
char cacertfile[MAXWORDLEN];
|
||||
char pkfile[MAXWORDLEN];
|
||||
|
||||
if (client != NULL && client[0] == 0)
|
||||
client = NULL;
|
||||
else if (server != NULL && server[0] == 0)
|
||||
server = NULL;
|
||||
|
||||
if (cacert_file && cert_file && privkey_file)
|
||||
return 1;
|
||||
|
||||
filename = _PATH_EAPTLSCLIFILE;
|
||||
f = fopen(filename, "r");
|
||||
if (f == NULL)
|
||||
return 0;
|
||||
|
||||
ret =
|
||||
scan_authfile_eaptls(f, client, server, clicertfile, servcertfile,
|
||||
cacertfile, pkfile, &addrs, NULL, filename,
|
||||
0);
|
||||
fclose(f);
|
||||
|
||||
/*
|
||||
if (ret >= 0 && !eaptls_init_ssl(0, cacertfile, clicertfile,
|
||||
servcertfile, pkfile))
|
||||
ret = -1;
|
||||
*/
|
||||
|
||||
if (addrs != 0)
|
||||
free_wordlist(addrs);
|
||||
|
||||
return ret >= 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
scan_authfile_eaptls(f, client, server, cli_cert, serv_cert, ca_cert, pk,
|
||||
addrs, opts, filename, flags)
|
||||
FILE *f;
|
||||
char *client;
|
||||
char *server;
|
||||
char *cli_cert;
|
||||
char *serv_cert;
|
||||
char *ca_cert;
|
||||
char *pk;
|
||||
struct wordlist **addrs;
|
||||
struct wordlist **opts;
|
||||
char *filename;
|
||||
int flags;
|
||||
{
|
||||
int newline;
|
||||
int got_flag, best_flag;
|
||||
struct wordlist *ap, *addr_list, *alist, **app;
|
||||
char word[MAXWORDLEN];
|
||||
|
||||
if (addrs != NULL)
|
||||
*addrs = NULL;
|
||||
if (opts != NULL)
|
||||
*opts = NULL;
|
||||
addr_list = NULL;
|
||||
if (!getword(f, word, &newline, filename))
|
||||
return -1; /* file is empty??? */
|
||||
newline = 1;
|
||||
best_flag = -1;
|
||||
for (;;) {
|
||||
/*
|
||||
* Skip until we find a word at the start of a line.
|
||||
*/
|
||||
while (!newline && getword(f, word, &newline, filename));
|
||||
if (!newline)
|
||||
break; /* got to end of file */
|
||||
|
||||
/*
|
||||
* Got a client - check if it's a match or a wildcard.
|
||||
*/
|
||||
got_flag = 0;
|
||||
if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) {
|
||||
newline = 0;
|
||||
continue;
|
||||
}
|
||||
if (!ISWILD(word))
|
||||
got_flag = NONWILD_CLIENT;
|
||||
|
||||
/*
|
||||
* Now get a server and check if it matches.
|
||||
*/
|
||||
if (!getword(f, word, &newline, filename))
|
||||
break;
|
||||
if (newline)
|
||||
continue;
|
||||
if (!ISWILD(word)) {
|
||||
if (server != NULL && strcmp(word, server) != 0)
|
||||
continue;
|
||||
got_flag |= NONWILD_SERVER;
|
||||
}
|
||||
|
||||
/*
|
||||
* Got some sort of a match - see if it's better than what
|
||||
* we have already.
|
||||
*/
|
||||
if (got_flag <= best_flag)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Get the cli_cert
|
||||
*/
|
||||
if (!getword(f, word, &newline, filename))
|
||||
break;
|
||||
if (newline)
|
||||
continue;
|
||||
if (strcmp(word, "-") != 0) {
|
||||
strlcpy(cli_cert, word, MAXWORDLEN);
|
||||
} else
|
||||
cli_cert[0] = 0;
|
||||
|
||||
/*
|
||||
* Get serv_cert
|
||||
*/
|
||||
if (!getword(f, word, &newline, filename))
|
||||
break;
|
||||
if (newline)
|
||||
continue;
|
||||
if (strcmp(word, "-") != 0) {
|
||||
strlcpy(serv_cert, word, MAXWORDLEN);
|
||||
} else
|
||||
serv_cert[0] = 0;
|
||||
|
||||
/*
|
||||
* Get ca_cert
|
||||
*/
|
||||
if (!getword(f, word, &newline, filename))
|
||||
break;
|
||||
if (newline)
|
||||
continue;
|
||||
strlcpy(ca_cert, word, MAXWORDLEN);
|
||||
|
||||
/*
|
||||
* Get pk
|
||||
*/
|
||||
if (!getword(f, word, &newline, filename))
|
||||
break;
|
||||
if (newline)
|
||||
continue;
|
||||
strlcpy(pk, word, MAXWORDLEN);
|
||||
|
||||
|
||||
/*
|
||||
* Now read address authorization info and make a wordlist.
|
||||
*/
|
||||
app = &alist;
|
||||
for (;;) {
|
||||
if (!getword(f, word, &newline, filename) || newline)
|
||||
break;
|
||||
ap = (struct wordlist *)
|
||||
malloc(sizeof(struct wordlist) + strlen(word) + 1);
|
||||
if (ap == NULL)
|
||||
novm("authorized addresses");
|
||||
ap->word = (char *) (ap + 1);
|
||||
strcpy(ap->word, word);
|
||||
*app = ap;
|
||||
app = &ap->next;
|
||||
}
|
||||
*app = NULL;
|
||||
/*
|
||||
* This is the best so far; remember it.
|
||||
*/
|
||||
best_flag = got_flag;
|
||||
if (addr_list)
|
||||
free_wordlist(addr_list);
|
||||
addr_list = alist;
|
||||
|
||||
if (!newline)
|
||||
break;
|
||||
}
|
||||
|
||||
/* scan for a -- word indicating the start of options */
|
||||
for (app = &addr_list; (ap = *app) != NULL; app = &ap->next)
|
||||
if (strcmp(ap->word, "--") == 0)
|
||||
break;
|
||||
/* ap = start of options */
|
||||
if (ap != NULL) {
|
||||
ap = ap->next; /* first option */
|
||||
free(*app); /* free the "--" word */
|
||||
*app = NULL; /* terminate addr list */
|
||||
}
|
||||
if (opts != NULL)
|
||||
*opts = ap;
|
||||
else if (ap != NULL)
|
||||
free_wordlist(ap);
|
||||
if (addrs != NULL)
|
||||
*addrs = addr_list;
|
||||
else if (addr_list != NULL)
|
||||
free_wordlist(addr_list);
|
||||
|
||||
return best_flag;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
get_eaptls_secret(unit, client, server, clicertfile, servcertfile,
|
||||
cacertfile, pkfile, am_server)
|
||||
int unit;
|
||||
char *client;
|
||||
char *server;
|
||||
char *clicertfile;
|
||||
char *servcertfile;
|
||||
char *cacertfile;
|
||||
char *pkfile;
|
||||
int am_server;
|
||||
{
|
||||
FILE *fp;
|
||||
int ret;
|
||||
char *filename = NULL;
|
||||
struct wordlist *addrs = NULL;
|
||||
struct wordlist *opts = NULL;
|
||||
|
||||
/* in client mode the ca+cert+privkey can also be specified as options */
|
||||
if (!am_server && cacert_file && cert_file && privkey_file )
|
||||
{
|
||||
strlcpy( clicertfile, cert_file, MAXWORDLEN );
|
||||
strlcpy( cacertfile, cacert_file, MAXWORDLEN );
|
||||
strlcpy( pkfile, privkey_file, MAXWORDLEN );
|
||||
servcertfile[0] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = (am_server ? _PATH_EAPTLSSERVFILE : _PATH_EAPTLSCLIFILE);
|
||||
addrs = NULL;
|
||||
|
||||
fp = fopen(filename, "r");
|
||||
if (fp == NULL)
|
||||
{
|
||||
error("Can't open eap-tls secret file %s: %m", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
check_access(fp, filename);
|
||||
|
||||
ret = scan_authfile_eaptls(fp, client, server, clicertfile, servcertfile,
|
||||
cacertfile, pkfile, &addrs, &opts, filename, 0);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
if (ret < 0) return 0;
|
||||
}
|
||||
|
||||
if (eaptls_passwd_hook)
|
||||
{
|
||||
dbglog( "Calling eaptls password hook" );
|
||||
if ( (*eaptls_passwd_hook)(pkfile, passwd) < 0)
|
||||
{
|
||||
error("Unable to obtain EAP-TLS password for %s (%s) from plugin",
|
||||
client, pkfile);
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
20
pppd/ccp.c
20
pppd/ccp.c
|
@ -540,6 +540,9 @@ ccp_resetci(f)
|
|||
if (go->mppe) {
|
||||
ccp_options *ao = &ccp_allowoptions[f->unit];
|
||||
int auth_mschap_bits = auth_done[f->unit];
|
||||
#ifdef USE_EAPTLS
|
||||
int auth_eap_bits = auth_done[f->unit];
|
||||
#endif
|
||||
int numbits;
|
||||
|
||||
/*
|
||||
|
@ -567,8 +570,23 @@ ccp_resetci(f)
|
|||
lcp_close(f->unit, "MPPE required but not available");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
/*
|
||||
* MPPE is also possible in combination with EAP-TLS.
|
||||
* It is not possible to detect if we're doing EAP or EAP-TLS
|
||||
* at this stage, hence we accept all forms of EAP. If TLS is
|
||||
* not used then the MPPE keys will not be derived anyway.
|
||||
*/
|
||||
/* Leave only the eap auth bits set */
|
||||
auth_eap_bits &= (EAP_WITHPEER | EAP_PEER );
|
||||
|
||||
if ((numbits == 0) && (auth_eap_bits == 0)) {
|
||||
error("MPPE required, but MS-CHAP[v2] nor EAP-TLS auth are performed.");
|
||||
#else
|
||||
if (!numbits) {
|
||||
error("MPPE required, but MS-CHAP[v2] auth not performed.");
|
||||
error("MPPE required, but MS-CHAP[v2] auth not performed.");
|
||||
#endif
|
||||
lcp_close(f->unit, "MPPE required but not available");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -36,7 +36,11 @@
|
|||
#include "chap-new.h"
|
||||
#include "chap-md5.h"
|
||||
#include "magic.h"
|
||||
#ifdef USE_EAPTLS
|
||||
#include "eap-tls.h"
|
||||
#else
|
||||
#include "md5.h"
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
#define MD5_HASH_SIZE 16
|
||||
#define MD5_MIN_CHALLENGE 16
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* eap-tls.h
|
||||
*
|
||||
* Copyright (c) Beniamino Galvani 2005 All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. The name(s) of the authors of this software must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission.
|
||||
*
|
||||
* THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
|
||||
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
* AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
|
||||
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __EAP_TLS_H__
|
||||
#define __EAP_TLS_H__
|
||||
|
||||
#include "eap.h"
|
||||
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/md5.h>
|
||||
|
||||
#define EAP_TLS_FLAGS_LI 128 /* length included flag */
|
||||
#define EAP_TLS_FLAGS_MF 64 /* more fragments flag */
|
||||
#define EAP_TLS_FLAGS_START 32 /* start flag */
|
||||
|
||||
#define EAP_TLS_MAX_LEN 65536 /* max eap tls packet size */
|
||||
|
||||
struct eaptls_session
|
||||
{
|
||||
u_char *data; /* buffered data */
|
||||
int datalen; /* buffered data len */
|
||||
int offset; /* from where to send */
|
||||
int tlslen; /* total length of tls data */
|
||||
bool frag; /* packet is fragmented */
|
||||
SSL_CTX *ctx;
|
||||
SSL *ssl; /* ssl connection */
|
||||
BIO *from_ssl;
|
||||
BIO *into_ssl;
|
||||
char peer[MAXWORDLEN]; /* peer name */
|
||||
char peercertfile[MAXWORDLEN];
|
||||
bool alert_sent;
|
||||
u_char alert_sent_desc;
|
||||
bool alert_recv;
|
||||
u_char alert_recv_desc;
|
||||
char rtx[65536]; /* retransmission buffer */
|
||||
int rtx_len;
|
||||
int mtu; /* unit mtu */
|
||||
};
|
||||
|
||||
typedef struct pw_cb_data
|
||||
{
|
||||
const void *password;
|
||||
const char *prompt_info;
|
||||
} PW_CB_DATA;
|
||||
|
||||
|
||||
int ssl_verify_callback(int, X509_STORE_CTX *);
|
||||
void ssl_msg_callback(int write_p, int version, int ct, const void *buf,
|
||||
size_t len, SSL * ssl, void *arg);
|
||||
|
||||
X509 *get_X509_from_file(char *filename);
|
||||
int ssl_cmp_certs(char *filename, X509 * a);
|
||||
|
||||
SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile,
|
||||
char *certfile, char *peer_certfile, char *privkeyfile);
|
||||
int eaptls_init_ssl_server(eap_state * esp);
|
||||
int eaptls_init_ssl_client(eap_state * esp);
|
||||
void eaptls_free_session(struct eaptls_session *ets);
|
||||
|
||||
int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len);
|
||||
int eaptls_send(struct eaptls_session *ets, u_char ** outp);
|
||||
void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp);
|
||||
|
||||
int get_eaptls_secret(int unit, char *client, char *server,
|
||||
char *clicertfile, char *servcertfile, char *cacertfile,
|
||||
char *pkfile, int am_server);
|
||||
|
||||
#ifdef MPPE
|
||||
#include "mppe.h" /* MPPE_MAX_KEY_LEN */
|
||||
extern u_char mppe_send_key[MPPE_MAX_KEY_LEN];
|
||||
extern u_char mppe_recv_key[MPPE_MAX_KEY_LEN];
|
||||
extern int mppe_keys_set;
|
||||
|
||||
void eaptls_gen_mppe_keys(struct eaptls_session *ets, const char *prf_label, int client);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
463
pppd/eap.c
463
pppd/eap.c
|
@ -43,6 +43,11 @@
|
|||
* Based on draft-ietf-pppext-eap-srp-03.txt.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modification by Beniamino Galvani, Mar 2005
|
||||
* Implemented EAP-TLS authentication
|
||||
*/
|
||||
|
||||
#define RCSID "$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $"
|
||||
|
||||
/*
|
||||
|
@ -62,8 +67,12 @@
|
|||
|
||||
#include "pppd.h"
|
||||
#include "pathnames.h"
|
||||
#include "md5.h"
|
||||
#include "eap.h"
|
||||
#ifdef USE_EAPTLS
|
||||
#include "eap-tls.h"
|
||||
#else
|
||||
#include "md5.h"
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
#ifdef USE_SRP
|
||||
#include <t_pwd.h>
|
||||
|
@ -209,6 +218,9 @@ int unit;
|
|||
esp->es_server.ea_id = (u_char)(drand48() * 0x100);
|
||||
esp->es_client.ea_timeout = EAP_DEFREQTIME;
|
||||
esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
|
||||
#ifdef USE_EAPTLS
|
||||
esp->es_client.ea_using_eaptls = 0;
|
||||
#endif /* USE_EAPTLS */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -436,8 +448,16 @@ int status;
|
|||
u_char vals[2];
|
||||
struct b64state bs;
|
||||
#endif /* USE_SRP */
|
||||
#ifdef USE_EAPTLS
|
||||
struct eaptls_session *ets;
|
||||
int secret_len;
|
||||
char secret[MAXWORDLEN];
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
esp->es_server.ea_timeout = esp->es_savedtime;
|
||||
#ifdef USE_EAPTLS
|
||||
esp->es_server.ea_prev_state = esp->es_server.ea_state;
|
||||
#endif /* USE_EAPTLS */
|
||||
switch (esp->es_server.ea_state) {
|
||||
case eapBadAuth:
|
||||
return;
|
||||
|
@ -562,9 +582,79 @@ int status;
|
|||
break;
|
||||
}
|
||||
#endif /* USE_SRP */
|
||||
#ifdef USE_EAPTLS
|
||||
if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
|
||||
esp->es_server.ea_name, secret, &secret_len, 1)) {
|
||||
|
||||
esp->es_server.ea_state = eapTlsStart;
|
||||
break;
|
||||
}
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
esp->es_server.ea_state = eapMD5Chall;
|
||||
break;
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
case eapTlsStart:
|
||||
/* Initialize ssl session */
|
||||
if(!eaptls_init_ssl_server(esp)) {
|
||||
esp->es_server.ea_state = eapBadAuth;
|
||||
break;
|
||||
}
|
||||
|
||||
esp->es_server.ea_state = eapTlsRecv;
|
||||
break;
|
||||
|
||||
case eapTlsRecv:
|
||||
ets = (struct eaptls_session *) esp->es_server.ea_session;
|
||||
|
||||
if(ets->alert_sent) {
|
||||
esp->es_server.ea_state = eapTlsSendAlert;
|
||||
break;
|
||||
}
|
||||
|
||||
if (status) {
|
||||
esp->es_server.ea_state = eapBadAuth;
|
||||
break;
|
||||
}
|
||||
ets = (struct eaptls_session *) esp->es_server.ea_session;
|
||||
|
||||
if(ets->frag)
|
||||
esp->es_server.ea_state = eapTlsSendAck;
|
||||
else
|
||||
esp->es_server.ea_state = eapTlsSend;
|
||||
break;
|
||||
|
||||
case eapTlsSend:
|
||||
ets = (struct eaptls_session *) esp->es_server.ea_session;
|
||||
|
||||
if(ets->frag)
|
||||
esp->es_server.ea_state = eapTlsRecvAck;
|
||||
else
|
||||
if(SSL_is_init_finished(ets->ssl))
|
||||
esp->es_server.ea_state = eapTlsRecvClient;
|
||||
else
|
||||
esp->es_server.ea_state = eapTlsRecv;
|
||||
break;
|
||||
|
||||
case eapTlsSendAck:
|
||||
esp->es_server.ea_state = eapTlsRecv;
|
||||
break;
|
||||
|
||||
case eapTlsRecvAck:
|
||||
if (status) {
|
||||
esp->es_server.ea_state = eapBadAuth;
|
||||
break;
|
||||
}
|
||||
|
||||
esp->es_server.ea_state = eapTlsSend;
|
||||
break;
|
||||
|
||||
case eapTlsSendAlert:
|
||||
esp->es_server.ea_state = eapTlsRecvAlertAck;
|
||||
break;
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
case eapSRP1:
|
||||
#ifdef USE_SRP
|
||||
ts = (struct t_server *)esp->es_server.ea_session;
|
||||
|
@ -718,6 +808,30 @@ eap_state *esp;
|
|||
INCPTR(esp->es_server.ea_namelen, outp);
|
||||
break;
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
case eapTlsStart:
|
||||
PUTCHAR(EAPT_TLS, outp);
|
||||
PUTCHAR(EAP_TLS_FLAGS_START, outp);
|
||||
eap_figure_next_state(esp, 0);
|
||||
break;
|
||||
|
||||
case eapTlsSend:
|
||||
eaptls_send(esp->es_server.ea_session, &outp);
|
||||
eap_figure_next_state(esp, 0);
|
||||
break;
|
||||
|
||||
case eapTlsSendAck:
|
||||
PUTCHAR(EAPT_TLS, outp);
|
||||
PUTCHAR(0, outp);
|
||||
eap_figure_next_state(esp, 0);
|
||||
break;
|
||||
|
||||
case eapTlsSendAlert:
|
||||
eaptls_send(esp->es_server.ea_session, &outp);
|
||||
eap_figure_next_state(esp, 0);
|
||||
break;
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
#ifdef USE_SRP
|
||||
case eapSRP1:
|
||||
PUTCHAR(EAPT_SRP, outp);
|
||||
|
@ -904,11 +1018,57 @@ static void
|
|||
eap_server_timeout(arg)
|
||||
void *arg;
|
||||
{
|
||||
#ifdef USE_EAPTLS
|
||||
u_char *outp;
|
||||
u_char *lenloc;
|
||||
int outlen;
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
eap_state *esp = (eap_state *) arg;
|
||||
|
||||
if (!eap_server_active(esp))
|
||||
return;
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
switch(esp->es_server.ea_prev_state) {
|
||||
|
||||
/*
|
||||
* In eap-tls the state changes after a request, so we return to
|
||||
* previous state ...
|
||||
*/
|
||||
case(eapTlsStart):
|
||||
case(eapTlsSendAck):
|
||||
esp->es_server.ea_state = esp->es_server.ea_prev_state;
|
||||
break;
|
||||
|
||||
/*
|
||||
* ... or resend the stored data
|
||||
*/
|
||||
case(eapTlsSend):
|
||||
case(eapTlsSendAlert):
|
||||
outp = outpacket_buf;
|
||||
MAKEHEADER(outp, PPP_EAP);
|
||||
PUTCHAR(EAP_REQUEST, outp);
|
||||
PUTCHAR(esp->es_server.ea_id, outp);
|
||||
lenloc = outp;
|
||||
INCPTR(2, outp);
|
||||
|
||||
eaptls_retransmit(esp->es_server.ea_session, &outp);
|
||||
|
||||
outlen = (outp - outpacket_buf) - PPP_HDRLEN;
|
||||
PUTSHORT(outlen, lenloc);
|
||||
output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
|
||||
esp->es_server.ea_requests++;
|
||||
|
||||
if (esp->es_server.ea_timeout > 0)
|
||||
TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
|
||||
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
/* EAP ID number must not change on timeout. */
|
||||
eap_send_request(esp);
|
||||
}
|
||||
|
@ -1166,6 +1326,81 @@ u_char *str;
|
|||
}
|
||||
#endif /* USE_SRP */
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
/*
|
||||
* Send an EAP-TLS response message with tls data
|
||||
*/
|
||||
static void
|
||||
eap_tls_response(esp, id)
|
||||
eap_state *esp;
|
||||
u_char id;
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen;
|
||||
u_char *lenloc;
|
||||
|
||||
outp = outpacket_buf;
|
||||
|
||||
MAKEHEADER(outp, PPP_EAP);
|
||||
|
||||
PUTCHAR(EAP_RESPONSE, outp);
|
||||
PUTCHAR(id, outp);
|
||||
|
||||
lenloc = outp;
|
||||
INCPTR(2, outp);
|
||||
|
||||
/*
|
||||
If the id in the request is unchanged, we must retransmit
|
||||
the old data
|
||||
*/
|
||||
if(id == esp->es_client.ea_id)
|
||||
eaptls_retransmit(esp->es_client.ea_session, &outp);
|
||||
else
|
||||
eaptls_send(esp->es_client.ea_session, &outp);
|
||||
|
||||
outlen = (outp - outpacket_buf) - PPP_HDRLEN;
|
||||
PUTSHORT(outlen, lenloc);
|
||||
|
||||
output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
|
||||
|
||||
esp->es_client.ea_id = id;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Send an EAP-TLS ack
|
||||
*/
|
||||
static void
|
||||
eap_tls_sendack(esp, id)
|
||||
eap_state *esp;
|
||||
u_char id;
|
||||
{
|
||||
u_char *outp;
|
||||
int outlen;
|
||||
u_char *lenloc;
|
||||
|
||||
outp = outpacket_buf;
|
||||
|
||||
MAKEHEADER(outp, PPP_EAP);
|
||||
|
||||
PUTCHAR(EAP_RESPONSE, outp);
|
||||
PUTCHAR(id, outp);
|
||||
esp->es_client.ea_id = id;
|
||||
|
||||
lenloc = outp;
|
||||
INCPTR(2, outp);
|
||||
|
||||
PUTCHAR(EAPT_TLS, outp);
|
||||
PUTCHAR(0, outp);
|
||||
|
||||
outlen = (outp - outpacket_buf) - PPP_HDRLEN;
|
||||
PUTSHORT(outlen, lenloc);
|
||||
|
||||
output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
|
||||
|
||||
}
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
static void
|
||||
eap_send_nak(esp, id, type)
|
||||
eap_state *esp;
|
||||
|
@ -1320,6 +1555,11 @@ int len;
|
|||
char rhostname[256];
|
||||
MD5_CTX mdContext;
|
||||
u_char hash[MD5_SIGNATURE_SIZE];
|
||||
#ifdef USE_EAPTLS
|
||||
u_char flags;
|
||||
struct eaptls_session *ets = esp->es_client.ea_session;
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
#ifdef USE_SRP
|
||||
struct t_client *tc;
|
||||
struct t_num sval, gval, Nval, *Ap, Bval;
|
||||
|
@ -1456,6 +1696,100 @@ int len;
|
|||
esp->es_client.ea_namelen);
|
||||
break;
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
case EAPT_TLS:
|
||||
|
||||
switch(esp->es_client.ea_state) {
|
||||
|
||||
case eapListen:
|
||||
|
||||
if (len < 1) {
|
||||
error("EAP: received EAP-TLS Listen packet with no data");
|
||||
/* Bogus request; wait for something real. */
|
||||
return;
|
||||
}
|
||||
GETCHAR(flags, inp);
|
||||
if(flags & EAP_TLS_FLAGS_START){
|
||||
|
||||
esp->es_client.ea_using_eaptls = 1;
|
||||
|
||||
if (explicit_remote){
|
||||
esp->es_client.ea_peer = strdup(remote_name);
|
||||
esp->es_client.ea_peerlen = strlen(remote_name);
|
||||
} else
|
||||
esp->es_client.ea_peer = NULL;
|
||||
|
||||
/* Init ssl session */
|
||||
if(!eaptls_init_ssl_client(esp)) {
|
||||
dbglog("cannot init ssl");
|
||||
eap_send_nak(esp, id, EAPT_TLS);
|
||||
esp->es_client.ea_using_eaptls = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ets = esp->es_client.ea_session;
|
||||
eap_tls_response(esp, id);
|
||||
esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck :
|
||||
eapTlsRecv);
|
||||
break;
|
||||
}
|
||||
|
||||
/* The server has sent a bad start packet. */
|
||||
eap_send_nak(esp, id, EAPT_TLS);
|
||||
break;
|
||||
|
||||
case eapTlsRecvAck:
|
||||
eap_tls_response(esp, id);
|
||||
esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck :
|
||||
eapTlsRecv);
|
||||
break;
|
||||
|
||||
case eapTlsRecv:
|
||||
if (len < 1) {
|
||||
error("EAP: discarding EAP-TLS Receive packet with no data");
|
||||
/* Bogus request; wait for something real. */
|
||||
return;
|
||||
}
|
||||
eaptls_receive(ets, inp, len);
|
||||
|
||||
if(ets->frag) {
|
||||
eap_tls_sendack(esp, id);
|
||||
esp->es_client.ea_state = eapTlsRecv;
|
||||
break;
|
||||
}
|
||||
|
||||
if(ets->alert_recv) {
|
||||
eap_tls_sendack(esp, id);
|
||||
esp->es_client.ea_state = eapTlsRecvFailure;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if TLS handshake is finished */
|
||||
if(SSL_is_init_finished(ets->ssl)){
|
||||
#ifdef MPPE
|
||||
eaptls_gen_mppe_keys( ets, "client EAP encryption", 1 );
|
||||
#endif
|
||||
eaptls_free_session(ets);
|
||||
eap_tls_sendack(esp, id);
|
||||
esp->es_client.ea_state = eapTlsRecvSuccess;
|
||||
break;
|
||||
}
|
||||
|
||||
eap_tls_response(esp,id);
|
||||
esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck :
|
||||
eapTlsRecv);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
eap_send_nak(esp, id, EAPT_TLS);
|
||||
esp->es_client.ea_using_eaptls = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
#ifdef USE_SRP
|
||||
case EAPT_SRP:
|
||||
if (len < 1) {
|
||||
|
@ -1737,6 +2071,11 @@ int len;
|
|||
u_char dig[SHA_DIGESTSIZE];
|
||||
#endif /* USE_SRP */
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
struct eaptls_session *ets;
|
||||
u_char flags;
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
if (esp->es_server.ea_id != id) {
|
||||
dbglog("EAP: discarding Response %d; expected ID %d", id,
|
||||
esp->es_server.ea_id);
|
||||
|
@ -1776,6 +2115,64 @@ int len;
|
|||
eap_figure_next_state(esp, 0);
|
||||
break;
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
case EAPT_TLS:
|
||||
switch(esp->es_server.ea_state) {
|
||||
|
||||
case eapTlsRecv:
|
||||
|
||||
ets = (struct eaptls_session *) esp->es_server.ea_session;
|
||||
eap_figure_next_state(esp,
|
||||
eaptls_receive(esp->es_server.ea_session, inp, len));
|
||||
|
||||
if(ets->alert_recv) {
|
||||
eap_send_failure(esp);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case eapTlsRecvAck:
|
||||
if(len > 1) {
|
||||
dbglog("EAP-TLS ACK with extra data");
|
||||
}
|
||||
eap_figure_next_state(esp, 0);
|
||||
break;
|
||||
|
||||
case eapTlsRecvClient:
|
||||
/* Receive authentication response from client */
|
||||
|
||||
if (len > 0) {
|
||||
GETCHAR(flags, inp);
|
||||
|
||||
if(len == 1 && !flags) { /* Ack = ok */
|
||||
#ifdef MPPE
|
||||
eaptls_gen_mppe_keys( esp->es_server.ea_session, "client EAP encryption", 0 );
|
||||
#endif
|
||||
eap_send_success(esp);
|
||||
}
|
||||
else { /* failure */
|
||||
warn("Server authentication failed");
|
||||
eap_send_failure(esp);
|
||||
}
|
||||
}
|
||||
else
|
||||
warn("Bogus EAP-TLS packet received from client");
|
||||
|
||||
eaptls_free_session(esp->es_server.ea_session);
|
||||
|
||||
break;
|
||||
|
||||
case eapTlsRecvAlertAck:
|
||||
eap_send_failure(esp);
|
||||
break;
|
||||
|
||||
default:
|
||||
eap_figure_next_state(esp, 1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
case EAPT_NOTIFICATION:
|
||||
dbglog("EAP unexpected Notification; response discarded");
|
||||
break;
|
||||
|
@ -1807,6 +2204,13 @@ int len;
|
|||
esp->es_server.ea_state = eapMD5Chall;
|
||||
break;
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
/* Send EAP-TLS start packet */
|
||||
case EAPT_TLS:
|
||||
esp->es_server.ea_state = eapTlsStart;
|
||||
break;
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
default:
|
||||
dbglog("EAP: peer requesting unknown Type %d", vallen);
|
||||
switch (esp->es_server.ea_state) {
|
||||
|
@ -2018,13 +2422,27 @@ u_char *inp;
|
|||
int id;
|
||||
int len;
|
||||
{
|
||||
if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)) {
|
||||
if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
|
||||
#ifdef USE_EAPTLS
|
||||
&& esp->es_client.ea_state != eapTlsRecvSuccess
|
||||
#endif /* USE_EAPTLS */
|
||||
) {
|
||||
dbglog("EAP unexpected success message in state %s (%d)",
|
||||
eap_state_name(esp->es_client.ea_state),
|
||||
esp->es_client.ea_state);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
|
||||
eapTlsRecvSuccess) {
|
||||
dbglog("EAP-TLS unexpected success message in state %s (%d)",
|
||||
eap_state_name(esp->es_client.ea_state),
|
||||
esp->es_client.ea_state);
|
||||
return;
|
||||
}
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
if (esp->es_client.ea_timeout > 0) {
|
||||
UNTIMEOUT(eap_client_timeout, (void *)esp);
|
||||
}
|
||||
|
@ -2150,6 +2568,9 @@ void *arg;
|
|||
int code, id, len, rtype, vallen;
|
||||
u_char *pstart;
|
||||
u_int32_t uval;
|
||||
#ifdef USE_EAPTLS
|
||||
u_char flags;
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
if (inlen < EAP_HEADERLEN)
|
||||
return (0);
|
||||
|
@ -2214,6 +2635,24 @@ void *arg;
|
|||
}
|
||||
break;
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
case EAPT_TLS:
|
||||
if (len < 1)
|
||||
break;
|
||||
GETCHAR(flags, inp);
|
||||
len--;
|
||||
|
||||
if(flags == 0 && len == 0){
|
||||
printer(arg, " Ack");
|
||||
break;
|
||||
}
|
||||
|
||||
printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
|
||||
printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
|
||||
printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
|
||||
break;
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
case EAPT_SRP:
|
||||
if (len < 3)
|
||||
goto truncated;
|
||||
|
@ -2325,6 +2764,25 @@ void *arg;
|
|||
}
|
||||
break;
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
case EAPT_TLS:
|
||||
if (len < 1)
|
||||
break;
|
||||
GETCHAR(flags, inp);
|
||||
len--;
|
||||
|
||||
if(flags == 0 && len == 0){
|
||||
printer(arg, " Ack");
|
||||
break;
|
||||
}
|
||||
|
||||
printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
|
||||
printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
|
||||
printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
|
||||
|
||||
break;
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
case EAPT_NAK:
|
||||
if (len <= 0) {
|
||||
printer(arg, " <missing hint>");
|
||||
|
@ -2426,3 +2884,4 @@ void *arg;
|
|||
|
||||
return (inp - pstart);
|
||||
}
|
||||
|
||||
|
|
32
pppd/eap.h
32
pppd/eap.h
|
@ -84,6 +84,16 @@ enum eap_state_code {
|
|||
eapClosed, /* Authentication not in use */
|
||||
eapListen, /* Client ready (and timer running) */
|
||||
eapIdentify, /* EAP Identify sent */
|
||||
eapTlsStart, /* Send EAP-TLS start packet */
|
||||
eapTlsRecv, /* Receive EAP-TLS tls data */
|
||||
eapTlsSendAck, /* Send EAP-TLS ack */
|
||||
eapTlsSend, /* Send EAP-TLS tls data */
|
||||
eapTlsRecvAck, /* Receive EAP-TLS ack */
|
||||
eapTlsRecvClient, /* Receive EAP-TLS auth response from client*/
|
||||
eapTlsSendAlert, /* Send EAP-TLS tls alert (server)*/
|
||||
eapTlsRecvAlertAck, /* Receive EAP-TLS ack after sending alert */
|
||||
eapTlsRecvSuccess, /* Receive EAP success */
|
||||
eapTlsRecvFailure, /* Receive EAP failure */
|
||||
eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */
|
||||
eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */
|
||||
eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */
|
||||
|
@ -95,9 +105,18 @@ enum eap_state_code {
|
|||
|
||||
#define EAP_STATES \
|
||||
"Initial", "Pending", "Closed", "Listen", "Identify", \
|
||||
"TlsStart", "TlsRecv", "TlsSendAck", "TlsSend", "TlsRecvAck", "TlsRecvClient",\
|
||||
"TlsSendAlert", "TlsRecvAlertAck" , "TlsRecvSuccess", "TlsRecvFailure", \
|
||||
"SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth"
|
||||
|
||||
#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen)
|
||||
#ifdef USE_EAPTLS
|
||||
#define eap_client_active(esp) ((esp)->es_client.ea_state != eapInitial &&\
|
||||
(esp)->es_client.ea_state != eapPending &&\
|
||||
(esp)->es_client.ea_state != eapClosed)
|
||||
#else
|
||||
#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen)
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
#define eap_server_active(esp) \
|
||||
((esp)->es_server.ea_state >= eapIdentify && \
|
||||
(esp)->es_server.ea_state <= eapMD5Chall)
|
||||
|
@ -112,11 +131,17 @@ struct eap_auth {
|
|||
u_short ea_namelen; /* Length of our name */
|
||||
u_short ea_peerlen; /* Length of peer's name */
|
||||
enum eap_state_code ea_state;
|
||||
#ifdef USE_EAPTLS
|
||||
enum eap_state_code ea_prev_state;
|
||||
#endif
|
||||
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 */
|
||||
#ifdef USE_EAPTLS
|
||||
bool ea_using_eaptls;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -139,7 +164,12 @@ typedef struct eap_state {
|
|||
* Timeouts.
|
||||
*/
|
||||
#define EAP_DEFTIMEOUT 3 /* Timeout (seconds) for rexmit */
|
||||
#ifdef USE_EAPTLS
|
||||
#define EAP_DEFTRANSMITS 30 /* max # times to transmit */
|
||||
/* certificates can be long ... */
|
||||
#else
|
||||
#define EAP_DEFTRANSMITS 10 /* max # times to transmit */
|
||||
#endif /* USE_EAPTLS */
|
||||
#define EAP_DEFREQTIME 20 /* Time to wait for peer request */
|
||||
#define EAP_DEFALLOWREQ 20 /* max # times to accept requests */
|
||||
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
***********************************************************************
|
||||
*/
|
||||
|
||||
#ifndef USE_EAPTLS
|
||||
|
||||
#include <string.h>
|
||||
#include "md5.h"
|
||||
|
||||
|
@ -305,3 +307,5 @@ UINT4 *in;
|
|||
** End of md5.c **
|
||||
******************************** (cut) ********************************
|
||||
*/
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
** documentation and/or software. **
|
||||
***********************************************************************
|
||||
*/
|
||||
#ifndef USE_EAPTLS
|
||||
|
||||
#ifndef __MD5_INCLUDE__
|
||||
|
||||
|
@ -63,3 +64,5 @@ void MD5_Final (unsigned char hash[], MD5_CTX *mdContext);
|
|||
|
||||
#define __MD5_INCLUDE__
|
||||
#endif /* __MD5_INCLUDE__ */
|
||||
|
||||
#endif /* USE_EAPTLS */
|
||||
|
|
|
@ -21,6 +21,13 @@
|
|||
#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"
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
#define _PATH_EAPTLSCLIFILE _ROOT_PATH "/etc/ppp/eaptls-client"
|
||||
#define _PATH_EAPTLSSERVFILE _ROOT_PATH "/etc/ppp/eaptls-server"
|
||||
#define _PATH_OPENSSLCONFFILE _ROOT_PATH "/etc/ppp/openssl.cnf"
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
#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"
|
||||
|
|
|
@ -4,6 +4,9 @@ CFLAGS = $(COPTS) -I.. -I../../include -fPIC
|
|||
LDFLAGS = $(LDOPTS)
|
||||
INSTALL = install
|
||||
|
||||
# EAP-TLS
|
||||
CFLAGS += -DUSE_EAPTLS=1
|
||||
|
||||
DESTDIR = $(INSTROOT)@DESTDIR@
|
||||
BINDIR = $(DESTDIR)/sbin
|
||||
MANDIR = $(DESTDIR)/share/man/man8
|
||||
|
|
|
@ -107,4 +107,7 @@ void plugin_init(void)
|
|||
{
|
||||
add_options(options);
|
||||
pap_passwd_hook = promptpass;
|
||||
#ifdef USE_EAPTLS
|
||||
eaptls_passwd_hook = promptpass;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -79,4 +79,8 @@ void plugin_init (void)
|
|||
|
||||
chap_check_hook = pwfd_check;
|
||||
chap_passwd_hook = pwfd_passwd;
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
eaptls_passwd_hook = pwfd_passwd;
|
||||
#endif
|
||||
}
|
||||
|
|
33
pppd/pppd.8
33
pppd/pppd.8
|
@ -253,6 +253,12 @@ Alternatively, a value of 0 for \fInr\fR or \fInt\fR disables
|
|||
compression in the corresponding direction. Use \fInobsdcomp\fR or
|
||||
\fIbsdcomp 0\fR to disable BSD-Compress compression entirely.
|
||||
.TP
|
||||
.B ca \fIca-file
|
||||
(EAP-TLS) Use the file \fIca-file\fR as the X.509 Certificate Authority
|
||||
(CA) file (in PEM format), needed for setting up an EAP-TLS connection.
|
||||
This option is used on the client-side in conjunction with the \fBcert\fR
|
||||
and \fBkey\fR options.
|
||||
.TP
|
||||
.B cdtrcts
|
||||
Use a non-standard hardware flow control (i.e. DTR/CTS) to control
|
||||
the flow of data on the serial port. If neither the \fIcrtscts\fR,
|
||||
|
@ -264,6 +270,12 @@ RTS output. Such serial ports use this mode to implement true
|
|||
bi-directional flow control. The sacrifice is that this flow
|
||||
control mode does not permit using DTR as a modem control line.
|
||||
.TP
|
||||
.B cert \fIcertfile
|
||||
(EAP-TLS) Use the file \fIcertfile\fR as the X.509 certificate (in PEM
|
||||
format), needed for setting up an EAP-TLS connection. This option is
|
||||
used on the client-side in conjunction with the \fBca\fR and
|
||||
\fBkey\fR options.
|
||||
.TP
|
||||
.B chap\-interval \fIn
|
||||
If this option is given, pppd will rechallenge the peer every \fIn\fR
|
||||
seconds.
|
||||
|
@ -292,6 +304,18 @@ negotiation by sending its first LCP packet. The default value is
|
|||
1000 (1 second). This wait period only applies if the \fBconnect\fR
|
||||
or \fBpty\fR option is used.
|
||||
.TP
|
||||
.B crl \fIfilename
|
||||
(EAP-TLS) Use the file \fIfilename\fR as the Certificate Revocation List
|
||||
to check for the validity of the peer's certificate. This option is not
|
||||
mandatory for setting up an EAP-TLS connection. Also see the \fBcrl-dir\fR
|
||||
option.
|
||||
.TP
|
||||
.B crl-dir \fIdirectory
|
||||
(EAP-TLS) Use the directory \fIdirectory\fR to scan for CRL files in
|
||||
has format ($hash.r0) to check for the validity of the peer's certificate.
|
||||
This option is not mandatory for setting up an EAP-TLS connection.
|
||||
Also see the \fBcrl\fR option.
|
||||
.TP
|
||||
.B debug
|
||||
Enables connection debugging facilities.
|
||||
If this option is given, pppd will log the contents of all
|
||||
|
@ -561,6 +585,12 @@ transmitted packets be printed. On most systems, messages printed by
|
|||
the kernel are logged by syslog(1) to a file as directed in the
|
||||
/etc/syslog.conf configuration file.
|
||||
.TP
|
||||
.B key \fIkeyfile
|
||||
(EAP-TLS) Use the file \fIkeyfile\fR as the private key file (in PEM
|
||||
format), needed for setting up an EAP-TLS connection. This option is
|
||||
used on the client-side in conjunction with the \fBca\fR and
|
||||
\fBcert\fR options.
|
||||
.TP
|
||||
.B ktune
|
||||
Enables pppd to alter kernel settings as appropriate. Under Linux,
|
||||
pppd will enable IP forwarding (i.e. set /proc/sys/net/ipv4/ip_forward
|
||||
|
@ -724,6 +754,9 @@ name to \fIname\fR.)
|
|||
Disable Address/Control compression in both directions (send and
|
||||
receive).
|
||||
.TP
|
||||
.B need-peer-eap
|
||||
(EAP-TLS) Require the peer to verify our authentication credentials.
|
||||
.TP
|
||||
.B noauth
|
||||
Do not require the peer to authenticate itself. This option is
|
||||
privileged.
|
||||
|
|
|
@ -338,6 +338,11 @@ extern bool dump_options; /* print out option values */
|
|||
extern bool dryrun; /* check everything, print options, exit */
|
||||
extern int child_wait; /* # seconds to wait for children at end */
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
extern char *crl_dir;
|
||||
extern char *crl_file;
|
||||
#endif /* USE_EAPTLS */
|
||||
|
||||
#ifdef MAXOCTETS
|
||||
extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */
|
||||
extern int maxoctets_dir; /* Direction :
|
||||
|
@ -758,6 +763,10 @@ extern int (*chap_check_hook) __P((void));
|
|||
extern int (*chap_passwd_hook) __P((char *user, char *passwd));
|
||||
extern void (*multilink_join_hook) __P((void));
|
||||
|
||||
#ifdef USE_EAPTLS
|
||||
extern int (*eaptls_passwd_hook) __P((char *user, char *passwd));
|
||||
#endif
|
||||
|
||||
/* Let a plugin snoop sent and received packets. Useful for L2TP */
|
||||
extern void (*snoop_recv_hook) __P((unsigned char *p, int len));
|
||||
extern void (*snoop_send_hook) __P((unsigned char *p, int len));
|
||||
|
|
Loading…
Reference in New Issue