From ad8f16ddb21258ec6aea87698cccb494898a9e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= Date: Mon, 11 Jun 2018 23:59:15 +0200 Subject: [PATCH] Updated EAP-TLS patch to v1.101 Resolves: CVE-2018-11574 --- 0017-pppd-rebase-EAP-TLS-patch-v0.994.patch | 3045 ---------------- ...ert-pppd-rebase-EAP-TLS-patch-v0.994.patch | 3046 ----------------- ...patch => ppp-2.4.7-eaptls-mppe-1.101.patch | 223 +- ppp.spec | 10 +- 4 files changed, 130 insertions(+), 6194 deletions(-) delete mode 100644 0017-pppd-rebase-EAP-TLS-patch-v0.994.patch delete mode 100644 0026-Revert-pppd-rebase-EAP-TLS-patch-v0.994.patch rename 0027-pppd-EAP-TLS-patch-v0.999.patch => ppp-2.4.7-eaptls-mppe-1.101.patch (93%) diff --git a/0017-pppd-rebase-EAP-TLS-patch-v0.994.patch b/0017-pppd-rebase-EAP-TLS-patch-v0.994.patch deleted file mode 100644 index 991355d..0000000 --- a/0017-pppd-rebase-EAP-TLS-patch-v0.994.patch +++ /dev/null @@ -1,3045 +0,0 @@ -From 044a5b1e5d878c519143b71a44b3d5b0ca91de3b Mon Sep 17 00:00:00 2001 -From: Michal Sekletar -Date: Mon, 7 Apr 2014 14:56:56 +0200 -Subject: [PATCH 17/27] pppd: rebase EAP-TLS patch v0.994 - ---- - README.eap-tls | 169 +++++++ - etc.ppp/eaptls-client | 10 + - etc.ppp/eaptls-server | 11 + - etc.ppp/openssl.cnf | 14 + - linux/Makefile.top | 6 +- - pppd/Makefile.linux | 12 + - pppd/auth.c | 414 ++++++++++++++- - pppd/ccp.c | 20 +- - pppd/chap-md5.c | 4 + - pppd/eap-tls.c | 1174 +++++++++++++++++++++++++++++++++++++++++++ - pppd/eap-tls.h | 107 ++++ - pppd/eap.c | 462 ++++++++++++++++- - pppd/eap.h | 32 +- - pppd/md5.c | 3 + - pppd/md5.h | 3 + - pppd/options.c | 10 + - pppd/pathnames.h | 7 + - pppd/plugins/Makefile.linux | 3 + - pppd/plugins/passprompt.c | 3 + - pppd/plugins/passwordfd.c | 4 + - pppd/pppd.h | 8 + - 21 files changed, 2461 insertions(+), 15 deletions(-) - create mode 100644 README.eap-tls - create mode 100644 etc.ppp/eaptls-client - create mode 100644 etc.ppp/eaptls-server - create mode 100644 etc.ppp/openssl.cnf - create mode 100644 pppd/eap-tls.c - create mode 100644 pppd/eap-tls.h - -diff --git a/README.eap-tls b/README.eap-tls -new file mode 100644 -index 0000000..0a4fee9 ---- /dev/null -+++ b/README.eap-tls -@@ -0,0 +1,169 @@ -+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 2246) 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: -+ : -+ 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: -+ : -+ 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 -+ Use the CA public certificate found in in PEM format -+ cert -+ Use the client public certificate found in in PEM format -+ or in engine:engine_id format -+ key -+ Use the client private key found in in PEM format -+ or in engine:engine_id format -+ crl-dir -+ Use CRL files from 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. Notes -+ -+ This is experimental code. -+ Send suggestions and comments to Jan Just Keijser -+ -diff --git a/etc.ppp/eaptls-client b/etc.ppp/eaptls-client -new file mode 100644 -index 0000000..7782f0e ---- /dev/null -+++ b/etc.ppp/eaptls-client -@@ -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 -diff --git a/etc.ppp/eaptls-server b/etc.ppp/eaptls-server -new file mode 100644 -index 0000000..fa53cbd ---- /dev/null -+++ b/etc.ppp/eaptls-server -@@ -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 -diff --git a/etc.ppp/openssl.cnf b/etc.ppp/openssl.cnf -new file mode 100644 -index 0000000..dd32f30 ---- /dev/null -+++ b/etc.ppp/openssl.cnf -@@ -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 -+ -diff --git a/linux/Makefile.top b/linux/Makefile.top -index f42efd5..9a8945a 100644 ---- a/linux/Makefile.top -+++ b/linux/Makefile.top -@@ -28,7 +28,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 -@@ -39,6 +39,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 $@ -diff --git a/pppd/Makefile.linux b/pppd/Makefile.linux -index 65700fa..53df4d2 100644 ---- a/pppd/Makefile.linux -+++ b/pppd/Makefile.linux -@@ -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 -@@ -115,6 +118,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) -diff --git a/pppd/auth.c b/pppd/auth.c -index 9e957fa..88cbdb6 100644 ---- a/pppd/auth.c -+++ b/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,13 @@ 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 */ -+bool need_peer_eap = 0; /* Require peer to authenticate us */ -+#endif - - static char *uafname; /* name of most recent +ua file */ - -@@ -254,6 +269,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 +429,14 @@ 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" }, -+ { "need-peer-eap", o_bool, &need_peer_eap, -+ "Require the peer to authenticate us", 1 }, -+#endif /* USE_EAPTLS */ - { NULL } - }; - -@@ -730,6 +766,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 +803,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) { -@@ -1117,7 +1172,7 @@ np_down(unit, proto) - UNTIMEOUT(connect_time_expired, NULL); - #ifdef MAXOCTETS - UNTIMEOUT(check_maxoctets, NULL); --#endif -+#endif - new_phase(PHASE_NETWORK); - } - } -@@ -1144,7 +1199,7 @@ check_maxoctets(arg) - - update_link_stats(ifunit); - link_stats_valid=0; -- -+ - switch(maxoctets_dir) { - case PPP_OCTETS_DIRECTION_IN: - used = link_stats.bytes_in; -@@ -1277,6 +1332,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 +1395,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 +1414,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; -+ - } - - -@@ -1707,6 +1781,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. -@@ -2359,3 +2434,334 @@ 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 -diff --git a/pppd/ccp.c b/pppd/ccp.c -index 5814f35..7dead23 100644 ---- a/pppd/ccp.c -+++ b/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; - } -diff --git a/pppd/chap-md5.c b/pppd/chap-md5.c -index 77dd4ec..269b52c 100644 ---- a/pppd/chap-md5.c -+++ b/pppd/chap-md5.c -@@ -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 -diff --git a/pppd/eap-tls.c b/pppd/eap-tls.c -new file mode 100644 -index 0000000..a3aea5a ---- /dev/null -+++ b/pppd/eap-tls.c -@@ -0,0 +1,1174 @@ -+/* -+ * eap-tls.c - EAP-TLS implementation for PPP -+ * -+ * 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. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "pppd.h" -+#include "eap.h" -+#include "eap-tls.h" -+#include "fsm.h" -+#include "lcp.h" -+#include "pathnames.h" -+ -+/* The openssl configuration file and engines can be loaded only once */ -+static CONF *ssl_config = NULL; -+static ENGINE *cert_engine = NULL; -+static ENGINE *pkey_engine = NULL; -+ -+#ifdef MPPE -+ -+/* -+ * TLS PRF from RFC 2246 -+ */ -+static void P_hash(const EVP_MD *evp_md, -+ const unsigned char *secret, unsigned int secret_len, -+ const unsigned char *seed, unsigned int seed_len, -+ unsigned char *out, unsigned int out_len) -+{ -+ HMAC_CTX ctx_a, ctx_out; -+ unsigned char a[HMAC_MAX_MD_CBLOCK]; -+ unsigned int size; -+ -+ HMAC_CTX_init(&ctx_a); -+ HMAC_CTX_init(&ctx_out); -+ HMAC_Init_ex(&ctx_a, secret, secret_len, evp_md, NULL); -+ HMAC_Init_ex(&ctx_out, secret, secret_len, evp_md, NULL); -+ -+ size = HMAC_size(&ctx_out); -+ -+ /* Calculate A(1) */ -+ HMAC_Update(&ctx_a, seed, seed_len); -+ HMAC_Final(&ctx_a, a, NULL); -+ -+ while (1) { -+ /* Calculate next part of output */ -+ HMAC_Update(&ctx_out, a, size); -+ HMAC_Update(&ctx_out, seed, seed_len); -+ -+ /* Check if last part */ -+ if (out_len < size) { -+ HMAC_Final(&ctx_out, a, NULL); -+ memcpy(out, a, out_len); -+ break; -+ } -+ -+ /* Place digest in output buffer */ -+ HMAC_Final(&ctx_out, out, NULL); -+ HMAC_Init_ex(&ctx_out, NULL, 0, NULL, NULL); -+ out += size; -+ out_len -= size; -+ -+ /* Calculate next A(i) */ -+ HMAC_Init_ex(&ctx_a, NULL, 0, NULL, NULL); -+ HMAC_Update(&ctx_a, a, size); -+ HMAC_Final(&ctx_a, a, NULL); -+ } -+ -+ HMAC_CTX_cleanup(&ctx_a); -+ HMAC_CTX_cleanup(&ctx_out); -+ memset(a, 0, sizeof(a)); -+} -+ -+static void PRF(const unsigned char *secret, unsigned int secret_len, -+ const unsigned char *seed, unsigned int seed_len, -+ unsigned char *out, unsigned char *buf, unsigned int out_len) -+{ -+ unsigned int i; -+ unsigned int len = (secret_len + 1) / 2; -+ const unsigned char *s1 = secret; -+ const unsigned char *s2 = secret + (secret_len - len); -+ -+ P_hash(EVP_md5(), s1, len, seed, seed_len, out, out_len); -+ P_hash(EVP_sha1(), s2, len, seed, seed_len, buf, out_len); -+ -+ for (i=0; i < out_len; i++) { -+ out[i] ^= buf[i]; -+ } -+} -+ -+#define EAPTLS_MPPE_KEY_LEN 32 -+ -+/* -+ * Generate keys according to RFC 2716 and add to reply -+ */ -+void eaptls_gen_mppe_keys(struct eaptls_session *ets, const char *prf_label, -+ int client) -+{ -+ unsigned char out[4*EAPTLS_MPPE_KEY_LEN], buf[4*EAPTLS_MPPE_KEY_LEN]; -+ unsigned char seed[64 + 2*SSL3_RANDOM_SIZE]; -+ unsigned char *p = seed; -+ SSL *s = ets->ssl; -+ size_t prf_size; -+ -+ prf_size = strlen(prf_label); -+ -+ memcpy(p, prf_label, prf_size); -+ p += prf_size; -+ -+ memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); -+ p += SSL3_RANDOM_SIZE; -+ prf_size += SSL3_RANDOM_SIZE; -+ -+ memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE); -+ prf_size += SSL3_RANDOM_SIZE; -+ -+ PRF(s->session->master_key, s->session->master_key_length, -+ seed, prf_size, out, buf, sizeof(out)); -+ -+ /* -+ * We now have the master send and receive keys. -+ * From these, generate the session send and receive keys. -+ * (see RFC3079 / draft-ietf-pppext-mppe-keys-03.txt for details) -+ */ -+ if (client) -+ { -+ p = out; -+ BCOPY( p, mppe_send_key, sizeof(mppe_send_key) ); -+ p += EAPTLS_MPPE_KEY_LEN; -+ BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) ); -+ } -+ else -+ { -+ p = out; -+ BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) ); -+ p += EAPTLS_MPPE_KEY_LEN; -+ BCOPY( p, mppe_send_key, sizeof(mppe_send_key) ); -+ } -+ -+ mppe_keys_set = 1; -+} -+ -+#endif -+ -+void log_ssl_errors( void ) -+{ -+ unsigned long ssl_err = ERR_get_error(); -+ -+ if (ssl_err != 0) -+ dbglog("EAP-TLS SSL error stack:"); -+ while (ssl_err != 0) { -+ dbglog( ERR_error_string( ssl_err, NULL ) ); -+ ssl_err = ERR_get_error(); -+ } -+} -+ -+ -+int password_callback (char *buf, int size, int rwflag, void *u) -+{ -+ if (buf) -+ { -+ strncpy (buf, passwd, size); -+ return strlen (buf); -+ } -+ return 0; -+} -+ -+ -+CONF *eaptls_ssl_load_config( void ) -+{ -+ CONF *config; -+ int ret_code; -+ long error_line = 33; -+ -+ config = NCONF_new( NULL ); -+ dbglog( "Loading OpenSSL config file" ); -+ ret_code = NCONF_load( config, _PATH_OPENSSLCONFFILE, &error_line ); -+ if (ret_code == 0) -+ { -+ warn( "EAP-TLS: Error in OpenSSL config file %s at line %d", _PATH_OPENSSLCONFFILE, error_line ); -+ NCONF_free( config ); -+ config = NULL; -+ ERR_clear_error(); -+ } -+ -+ dbglog( "Loading OpenSSL built-ins" ); -+ ENGINE_load_builtin_engines(); -+ OPENSSL_load_builtin_modules(); -+ -+ dbglog( "Loading OpenSSL configured modules" ); -+ if (CONF_modules_load( config, NULL, 0 ) <= 0 ) -+ { -+ warn( "EAP-TLS: Error loading OpenSSL modules" ); -+ log_ssl_errors(); -+ config = NULL; -+ } -+ -+ return config; -+} -+ -+ENGINE *eaptls_ssl_load_engine( char *engine_name ) -+{ -+ ENGINE *e = NULL; -+ -+ dbglog( "Enabling OpenSSL auto engines" ); -+ ENGINE_register_all_complete(); -+ -+ dbglog( "Loading OpenSSL '%s' engine support", engine_name ); -+ e = ENGINE_by_id( engine_name ); -+ if (!e) -+ { -+ dbglog( "EAP-TLS: Cannot load '%s' engine support, trying 'dynamic'", engine_name ); -+ e = ENGINE_by_id( "dynamic" ); -+ if (e) -+ { -+ if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine_name, 0) -+ || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) -+ { -+ warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name ); -+ log_ssl_errors(); -+ ENGINE_free(e); -+ e = NULL; -+ } -+ } -+ else -+ { -+ warn( "EAP-TLS: Cannot load dynamic engine support" ); -+ } -+ } -+ -+ if (e) -+ { -+ dbglog( "Initialising engine" ); -+ if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) -+ { -+ warn( "EAP-TLS: Cannot use that engine" ); -+ log_ssl_errors(); -+ ENGINE_free(e); -+ e = NULL; -+ } -+ } -+ -+ return e; -+} -+ -+/* -+ * Initialize the SSL stacks and tests if certificates, key and crl -+ * for client or server use can be loaded. -+ */ -+SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, -+ char *certfile, char *peer_certfile, char *privkeyfile) -+{ -+ char *cert_engine_name = NULL; -+ char *cert_identifier = NULL; -+ char *pkey_engine_name = NULL; -+ char *pkey_identifier = NULL; -+ SSL_CTX *ctx; -+ X509_STORE *certstore; -+ X509_LOOKUP *lookup; -+ X509 *tmp; -+ -+ /* -+ * Without these can't continue -+ */ -+ if (!cacertfile[0]) -+ { -+ error("EAP-TLS: CA certificate missing"); -+ return NULL; -+ } -+ -+ if (!certfile[0]) -+ { -+ error("EAP-TLS: User certificate missing"); -+ return NULL; -+ } -+ -+ if (!privkeyfile[0]) -+ { -+ error("EAP-TLS: User private key missing"); -+ return NULL; -+ } -+ -+ SSL_library_init(); -+ SSL_load_error_strings(); -+ -+ ctx = SSL_CTX_new(TLSv1_method()); -+ -+ if (!ctx) { -+ error("EAP-TLS: Cannot initialize SSL CTX context"); -+ goto fail; -+ } -+ -+ /* if the certificate filename is of the form engine:id. e.g. -+ pkcs11:12345 -+ then we try to load and use this engine. -+ If the certificate filename starts with a / or . then we -+ ALWAYS assume it is a file and not an engine/pkcs11 identifier -+ */ -+ if ( index( certfile, '/' ) == NULL && index( certfile, '.') == NULL ) -+ { -+ cert_identifier = index( certfile, ':' ); -+ -+ if (cert_identifier) -+ { -+ cert_engine_name = certfile; -+ *cert_identifier = '\0'; -+ cert_identifier++; -+ -+ dbglog( "Found certificate engine '%s'", cert_engine_name ); -+ dbglog( "Found certificate identifier '%s'", cert_identifier ); -+ } -+ } -+ -+ /* if the privatekey filename is of the form engine:id. e.g. -+ pkcs11:12345 -+ then we try to load and use this engine. -+ If the privatekey filename starts with a / or . then we -+ ALWAYS assume it is a file and not an engine/pkcs11 identifier -+ */ -+ if ( index( privkeyfile, '/' ) == NULL && index( privkeyfile, '.') == NULL ) -+ { -+ pkey_identifier = index( privkeyfile, ':' ); -+ -+ if (pkey_identifier) -+ { -+ pkey_engine_name = privkeyfile; -+ *pkey_identifier = '\0'; -+ pkey_identifier++; -+ -+ dbglog( "Found privatekey engine '%s'", pkey_engine_name ); -+ dbglog( "Found privatekey identifier '%s'", pkey_identifier ); -+ } -+ } -+ -+ if (cert_identifier && pkey_identifier) -+ { -+ if (strlen( cert_identifier ) == 0) -+ { -+ if (strlen( pkey_identifier ) == 0) -+ error( "EAP-TLS: both the certificate and privatekey identifiers are missing!" ); -+ else -+ { -+ dbglog( "Substituting privatekey identifier for certificate identifier" ); -+ cert_identifier = pkey_identifier; -+ } -+ } -+ else -+ { -+ if (strlen( pkey_identifier ) == 0) -+ { -+ dbglog( "Substituting certificate identifier for privatekey identifier" ); -+ pkey_identifier = cert_identifier; -+ } -+ } -+ -+ } -+ -+ /* load the openssl config file only once */ -+ if (!ssl_config) -+ { -+ if (cert_engine_name || pkey_engine_name) -+ ssl_config = eaptls_ssl_load_config(); -+ -+ if (ssl_config && cert_engine_name) -+ cert_engine = eaptls_ssl_load_engine( cert_engine_name ); -+ -+ if (ssl_config && pkey_engine_name) -+ { -+ /* don't load the same engine twice */ -+ if ( strcmp( cert_engine_name, pkey_engine_name) == 0 ) -+ pkey_engine = cert_engine; -+ else -+ pkey_engine = eaptls_ssl_load_engine( pkey_engine_name ); -+ } -+ } -+ -+ SSL_CTX_set_default_passwd_cb (ctx, password_callback); -+ -+ if (!SSL_CTX_load_verify_locations(ctx, cacertfile, NULL)) -+ { -+ error("EAP-TLS: Cannot load or verify CA file %s", cacertfile); -+ goto fail; -+ } -+ -+ if (init_server) -+ SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(cacertfile)); -+ -+ if (cert_engine) -+ { -+ struct -+ { -+ const char *s_slot_cert_id; -+ X509 *cert; -+ } cert_info; -+ -+ cert_info.s_slot_cert_id = cert_identifier; -+ cert_info.cert = NULL; -+ -+ if (!ENGINE_ctrl_cmd( cert_engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0 ) ) -+ { -+ error( "EAP-TLS: Error loading certificate with id '%s' from engine", cert_identifier ); -+ goto fail; -+ } -+ -+ if (cert_info.cert) -+ { -+ dbglog( "Got the certificate, adding it to SSL context" ); -+ dbglog( "subject = %s", X509_NAME_oneline( X509_get_subject_name( cert_info.cert ), NULL, 0 ) ); -+ if (SSL_CTX_use_certificate(ctx, cert_info.cert) <= 0) -+ { -+ error("EAP-TLS: Cannot use PKCS11 certificate %s", cert_identifier); -+ goto fail; -+ } -+ } -+ else -+ { -+ warn("EAP-TLS: Cannot load PKCS11 key %s", cert_identifier); -+ log_ssl_errors(); -+ } -+ } -+ else -+ { -+ if (!SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM)) -+ { -+ error( "EAP-TLS: Cannot use public certificate %s", certfile ); -+ goto fail; -+ } -+ } -+ -+ if (pkey_engine) -+ { -+ EVP_PKEY *pkey = NULL; -+ PW_CB_DATA cb_data; -+ -+ cb_data.password = passwd; -+ cb_data.prompt_info = pkey_identifier; -+ -+ dbglog( "Loading private key '%s' from engine", pkey_identifier ); -+ pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, NULL, &cb_data); -+ if (pkey) -+ { -+ dbglog( "Got the private key, adding it to SSL context" ); -+ if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0) -+ { -+ error("EAP-TLS: Cannot use PKCS11 key %s", pkey_identifier); -+ goto fail; -+ } -+ } -+ else -+ { -+ warn("EAP-TLS: Cannot load PKCS11 key %s", pkey_identifier); -+ log_ssl_errors(); -+ } -+ } -+ else -+ { -+ if (!SSL_CTX_use_PrivateKey_file(ctx, privkeyfile, SSL_FILETYPE_PEM)) -+ { -+ error("EAP-TLS: Cannot use private key %s", privkeyfile); -+ goto fail; -+ } -+ } -+ -+ if (SSL_CTX_check_private_key(ctx) != 1) { -+ error("EAP-TLS: Private key %s fails security check", privkeyfile); -+ goto fail; -+ } -+ -+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); -+ SSL_CTX_set_verify_depth(ctx, 5); -+ SSL_CTX_set_verify(ctx, -+ SSL_VERIFY_PEER | -+ SSL_VERIFY_FAIL_IF_NO_PEER_CERT, -+ &ssl_verify_callback); -+ -+ if (crl_dir) { -+ if (!(certstore = SSL_CTX_get_cert_store(ctx))) { -+ error("EAP-TLS: Failed to get certificate store"); -+ goto fail; -+ } -+ -+ if (!(lookup = -+ X509_STORE_add_lookup(certstore, X509_LOOKUP_hash_dir()))) { -+ error("EAP-TLS: Store lookup for CRL failed"); -+ -+ goto fail; -+ } -+ -+ X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM); -+ X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK); -+ } -+ -+ /* -+ * If a peer certificate file was specified, it must be valid, else fail -+ */ -+ if (peer_certfile[0]) { -+ if (!(tmp = get_X509_from_file(peer_certfile))) { -+ error("EAP-TLS: Error loading client certificate from file %s", -+ peer_certfile); -+ goto fail; -+ } -+ X509_free(tmp); -+ } -+ -+ return ctx; -+ -+fail: -+ log_ssl_errors(); -+ SSL_CTX_free(ctx); -+ return NULL; -+} -+ -+/* -+ * Determine the maximum packet size by looking at the LCP handshake -+ */ -+ -+int eaptls_get_mtu(int unit) -+{ -+ int mtu, mru; -+ -+ lcp_options *wo = &lcp_wantoptions[unit]; -+ lcp_options *go = &lcp_gotoptions[unit]; -+ lcp_options *ho = &lcp_hisoptions[unit]; -+ lcp_options *ao = &lcp_allowoptions[unit]; -+ -+ mtu = ho->neg_mru? ho->mru: PPP_MRU; -+ mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU; -+ mtu = MIN(MIN(mtu, mru), ao->mru)- PPP_HDRLEN - 10; -+ -+ dbglog("MTU = %d", mtu); -+ return mtu; -+} -+ -+ -+/* -+ * Init the ssl handshake (server mode) -+ */ -+int eaptls_init_ssl_server(eap_state * esp) -+{ -+ struct eaptls_session *ets; -+ char servcertfile[MAXWORDLEN]; -+ char clicertfile[MAXWORDLEN]; -+ char cacertfile[MAXWORDLEN]; -+ char pkfile[MAXWORDLEN]; -+ /* -+ * Allocate new eaptls session -+ */ -+ esp->es_server.ea_session = malloc(sizeof(struct eaptls_session)); -+ if (!esp->es_server.ea_session) -+ fatal("Allocation error"); -+ ets = esp->es_server.ea_session; -+ -+ if (!esp->es_server.ea_peer) { -+ error("EAP-TLS: Error: client name not set (BUG)"); -+ return 0; -+ } -+ -+ strncpy(ets->peer, esp->es_server.ea_peer, MAXWORDLEN); -+ -+ dbglog( "getting eaptls secret" ); -+ if (!get_eaptls_secret(esp->es_unit, esp->es_server.ea_peer, -+ esp->es_server.ea_name, clicertfile, -+ servcertfile, cacertfile, pkfile, 1)) { -+ error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"", -+ esp->es_server.ea_peer, esp->es_server.ea_name ); -+ return 0; -+ } -+ -+ ets->mtu = eaptls_get_mtu(esp->es_unit); -+ -+ ets->ctx = eaptls_init_ssl(1, cacertfile, servcertfile, clicertfile, pkfile); -+ if (!ets->ctx) -+ goto fail; -+ -+ if (!(ets->ssl = SSL_new(ets->ctx))) -+ goto fail; -+ -+ /* -+ * Set auto-retry to avoid timeouts on BIO_read -+ */ -+ SSL_set_mode(ets->ssl, SSL_MODE_AUTO_RETRY); -+ -+ /* -+ * Initialize the BIOs we use to read/write to ssl engine -+ */ -+ ets->into_ssl = BIO_new(BIO_s_mem()); -+ ets->from_ssl = BIO_new(BIO_s_mem()); -+ SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl); -+ -+ SSL_set_msg_callback(ets->ssl, ssl_msg_callback); -+ SSL_set_msg_callback_arg(ets->ssl, ets); -+ -+ /* -+ * Attach the session struct to the connection, so we can later -+ * retrieve it when doing certificate verification -+ */ -+ SSL_set_ex_data(ets->ssl, 0, ets); -+ -+ SSL_set_accept_state(ets->ssl); -+ -+ ets->data = NULL; -+ ets->datalen = 0; -+ ets->alert_sent = 0; -+ ets->alert_recv = 0; -+ -+ /* -+ * If we specified the client certificate file, store it in ets->peercertfile, -+ * so we can check it later in ssl_verify_callback() -+ */ -+ if (clicertfile[0]) -+ strncpy(&ets->peercertfile[0], clicertfile, MAXWORDLEN); -+ else -+ ets->peercertfile[0] = 0; -+ -+ return 1; -+ -+fail: -+ SSL_CTX_free(ets->ctx); -+ return 0; -+} -+ -+/* -+ * Init the ssl handshake (client mode) -+ */ -+int eaptls_init_ssl_client(eap_state * esp) -+{ -+ struct eaptls_session *ets; -+ char servcertfile[MAXWORDLEN]; -+ char clicertfile[MAXWORDLEN]; -+ char cacertfile[MAXWORDLEN]; -+ char pkfile[MAXWORDLEN]; -+ -+ /* -+ * Allocate new eaptls session -+ */ -+ esp->es_client.ea_session = malloc(sizeof(struct eaptls_session)); -+ if (!esp->es_client.ea_session) -+ fatal("Allocation error"); -+ ets = esp->es_client.ea_session; -+ -+ /* -+ * If available, copy server name in ets; it will be used in cert -+ * verify -+ */ -+ if (esp->es_client.ea_peer) -+ strncpy(ets->peer, esp->es_client.ea_peer, MAXWORDLEN); -+ else -+ ets->peer[0] = 0; -+ -+ ets->mtu = eaptls_get_mtu(esp->es_unit); -+ -+ dbglog( "calling get_eaptls_secret" ); -+ if (!get_eaptls_secret(esp->es_unit, esp->es_client.ea_name, -+ esp->es_client.ea_peer, clicertfile, -+ servcertfile, cacertfile, pkfile, 0)) { -+ error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"", -+ esp->es_client.ea_name, esp->es_client.ea_peer ); -+ return 0; -+ } -+ -+ dbglog( "calling eaptls_init_ssl" ); -+ ets->ctx = eaptls_init_ssl(0, cacertfile, clicertfile, servcertfile, pkfile); -+ if (!ets->ctx) -+ goto fail; -+ -+ ets->ssl = SSL_new(ets->ctx); -+ -+ if (!ets->ssl) -+ goto fail; -+ -+ /* -+ * Initialize the BIOs we use to read/write to ssl engine -+ */ -+ dbglog( "Initializing SSL BIOs" ); -+ ets->into_ssl = BIO_new(BIO_s_mem()); -+ ets->from_ssl = BIO_new(BIO_s_mem()); -+ SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl); -+ -+ SSL_set_msg_callback(ets->ssl, ssl_msg_callback); -+ SSL_set_msg_callback_arg(ets->ssl, ets); -+ -+ /* -+ * Attach the session struct to the connection, so we can later -+ * retrieve it when doing certificate verification -+ */ -+ SSL_set_ex_data(ets->ssl, 0, ets); -+ -+ SSL_set_connect_state(ets->ssl); -+ -+ ets->data = NULL; -+ ets->datalen = 0; -+ ets->alert_sent = 0; -+ ets->alert_recv = 0; -+ -+ /* -+ * If we specified the server certificate file, store it in -+ * ets->peercertfile, so we can check it later in -+ * ssl_verify_callback() -+ */ -+ if (servcertfile[0]) -+ strncpy(ets->peercertfile, servcertfile, MAXWORDLEN); -+ else -+ ets->peercertfile[0] = 0; -+ -+ return 1; -+ -+fail: -+ dbglog( "eaptls_init_ssl_client: fail" ); -+ SSL_CTX_free(ets->ctx); -+ return 0; -+ -+} -+ -+void eaptls_free_session(struct eaptls_session *ets) -+{ -+ if (ets->ssl) -+ SSL_free(ets->ssl); -+ -+ if (ets->ctx) -+ SSL_CTX_free(ets->ctx); -+ -+ free(ets); -+} -+ -+/* -+ * Handle a received packet, reassembling fragmented messages and -+ * passing them to the ssl engine -+ */ -+int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len) -+{ -+ u_char flags; -+ u_int tlslen; -+ u_char dummy[65536]; -+ -+ GETCHAR(flags, inp); -+ len--; -+ -+ if (flags & EAP_TLS_FLAGS_LI && !ets->data) { -+ -+ /* -+ * This is the first packet of a message -+ */ -+ -+ GETLONG(tlslen, inp); -+ len -= 4; -+ -+ if (tlslen > EAP_TLS_MAX_LEN) { -+ error("Error: tls message length > %d, truncated", -+ EAP_TLS_MAX_LEN); -+ tlslen = EAP_TLS_MAX_LEN; -+ } -+ -+ /* -+ * Allocate memory for the whole message -+ */ -+ ets->data = malloc(tlslen); -+ if (!ets->data) -+ fatal("EAP TLS: allocation error\n"); -+ -+ ets->datalen = 0; -+ ets->tlslen = tlslen; -+ -+ } -+ else if (flags & EAP_TLS_FLAGS_LI && ets->data) { -+ /* -+ * Non first with LI (strange...) -+ */ -+ -+ GETLONG(tlslen, inp); -+ len -= 4; -+ -+ } -+ else if (!ets->data) { -+ /* -+ * A non fragmented message without LI flag -+ */ -+ -+ ets->data = malloc(len); -+ if (!ets->data) -+ fatal("EAP TLS: allocation error\n"); -+ -+ ets->datalen = 0; -+ ets->tlslen = len; -+ } -+ -+ if (flags & EAP_TLS_FLAGS_MF) -+ ets->frag = 1; -+ else -+ ets->frag = 0; -+ -+ if (len + ets->datalen > ets->tlslen) { -+ warn("EAP TLS: received data > TLS message length"); -+ return 1; -+ } -+ -+ BCOPY(inp, ets->data + ets->datalen, len); -+ ets->datalen += len; -+ -+ if (!ets->frag) { -+ -+ /* -+ * If we have the whole message, pass it to ssl -+ */ -+ -+ if (ets->datalen != ets->tlslen) { -+ warn("EAP TLS: received data != TLS message length"); -+ return 1; -+ } -+ -+ if (BIO_write(ets->into_ssl, ets->data, ets->datalen) == -1) -+ log_ssl_errors(); -+ -+ SSL_read(ets->ssl, dummy, 65536); -+ -+ free(ets->data); -+ ets->data = NULL; -+ ets->datalen = 0; -+ } -+ -+ return 0; -+} -+ -+/* -+ * Return an eap-tls packet in outp. -+ * A TLS message read from the ssl engine is buffered in ets->data. -+ * At each call we control if there is buffered data and send a -+ * packet of mtu bytes. -+ */ -+int eaptls_send(struct eaptls_session *ets, u_char ** outp) -+{ -+ bool first = 0; -+ int size; -+ u_char fromtls[65536]; -+ int res; -+ u_char *start; -+ -+ start = *outp; -+ -+ if (!ets->data) { -+ -+ if(!ets->alert_sent) -+ SSL_read(ets->ssl, fromtls, 65536); -+ -+ /* -+ * Read from ssl -+ */ -+ if ((res = BIO_read(ets->from_ssl, fromtls, 65536)) == -1) -+ fatal("No data from BIO_read"); -+ -+ ets->datalen = res; -+ -+ ets->data = malloc(ets->datalen); -+ BCOPY(fromtls, ets->data, ets->datalen); -+ -+ ets->offset = 0; -+ first = 1; -+ -+ } -+ -+ size = ets->datalen - ets->offset; -+ -+ if (size > ets->mtu) { -+ size = ets->mtu; -+ ets->frag = 1; -+ } else -+ ets->frag = 0; -+ -+ PUTCHAR(EAPT_TLS, *outp); -+ -+ /* -+ * Set right flags and length if necessary -+ */ -+ if (ets->frag && first) { -+ PUTCHAR(EAP_TLS_FLAGS_LI | EAP_TLS_FLAGS_MF, *outp); -+ PUTLONG(ets->datalen, *outp); -+ } else if (ets->frag) { -+ PUTCHAR(EAP_TLS_FLAGS_MF, *outp); -+ } else -+ PUTCHAR(0, *outp); -+ -+ /* -+ * Copy the data in outp -+ */ -+ BCOPY(ets->data + ets->offset, *outp, size); -+ INCPTR(size, *outp); -+ -+ /* -+ * Copy the packet in retransmission buffer -+ */ -+ BCOPY(start, &ets->rtx[0], *outp - start); -+ ets->rtx_len = *outp - start; -+ -+ ets->offset += size; -+ -+ if (ets->offset >= ets->datalen) { -+ -+ /* -+ * The whole message has been sent -+ */ -+ -+ free(ets->data); -+ ets->data = NULL; -+ ets->datalen = 0; -+ ets->offset = 0; -+ } -+ -+ return 0; -+} -+ -+/* -+ * Get the sent packet from the retransmission buffer -+ */ -+void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp) -+{ -+ BCOPY(ets->rtx, *outp, ets->rtx_len); -+ INCPTR(ets->rtx_len, *outp); -+} -+ -+/* -+ * Verify a certificate. -+ * Most of the work (signatures and issuer attributes checking) -+ * is done by ssl; we check the CN in the peer certificate -+ * against the peer name. -+ */ -+int ssl_verify_callback(int preverify_ok, X509_STORE_CTX * ctx) -+{ -+ char subject[256]; -+ char cn_str[256]; -+ X509 *peer_cert; -+ int err, depth; -+ int ok = preverify_ok; -+ SSL *ssl; -+ struct eaptls_session *ets; -+ -+ peer_cert = X509_STORE_CTX_get_current_cert(ctx); -+ err = X509_STORE_CTX_get_error(ctx); -+ depth = X509_STORE_CTX_get_error_depth(ctx); -+ -+ dbglog("certificate verify depth: %d", depth); -+ -+ if (auth_required && !ok) { -+ X509_NAME_oneline(X509_get_subject_name(peer_cert), -+ subject, 256); -+ -+ X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert), -+ NID_commonName, cn_str, 256); -+ -+ dbglog("Certificate verification error:\n depth: %d CN: %s" -+ "\n err: %d (%s)\n", depth, cn_str, err, -+ X509_verify_cert_error_string(err)); -+ -+ return 0; -+ } -+ -+ ssl = X509_STORE_CTX_get_ex_data(ctx, -+ SSL_get_ex_data_X509_STORE_CTX_idx()); -+ -+ ets = (struct eaptls_session *)SSL_get_ex_data(ssl, 0); -+ -+ if (ets == NULL) { -+ error("Error: SSL_get_ex_data returned NULL"); -+ return 0; -+ } -+ -+ log_ssl_errors(); -+ -+ if (!depth) { /* This is the peer certificate */ -+ -+ X509_NAME_oneline(X509_get_subject_name(peer_cert), -+ subject, 256); -+ -+ X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert), -+ NID_commonName, cn_str, 256); -+ -+ /* -+ * If acting as client and the name of the server wasn't specified -+ * explicitely, we can't verify the server authenticity -+ */ -+ if (!ets->peer[0]) { -+ warn("Peer name not specified: no check"); -+ return 1; -+ } -+ -+ /* -+ * Check the CN -+ */ -+ if (strcmp(cn_str, ets->peer)) { -+ error -+ ("Certificate verification error: CN (%s) != peer_name (%s)", -+ cn_str, ets->peer); -+ return 0; -+ } -+ -+ warn("Certificate CN: %s , peer name %s", cn_str, ets->peer); -+ -+ /* -+ * If a peer certificate file was specified, here we check it -+ */ -+ if (ets->peercertfile[0]) { -+ if (ssl_cmp_certs(&ets->peercertfile[0], peer_cert) -+ != 0) { -+ error -+ ("Peer certificate doesn't match stored certificate"); -+ return 0; -+ } -+ } -+ } -+ -+ return 1; -+} -+ -+/* -+ * Compare a certificate with the one stored in a file -+ */ -+int ssl_cmp_certs(char *filename, X509 * a) -+{ -+ X509 *b; -+ int ret; -+ -+ if (!(b = get_X509_from_file(filename))) -+ return 1; -+ -+ ret = X509_cmp(a, b); -+ X509_free(b); -+ -+ return ret; -+ -+} -+ -+X509 *get_X509_from_file(char *filename) -+{ -+ FILE *fp; -+ X509 *ret; -+ -+ if (!(fp = fopen(filename, "r"))) -+ return NULL; -+ -+ ret = PEM_read_X509(fp, NULL, NULL, NULL); -+ -+ fclose(fp); -+ -+ return ret; -+} -+ -+/* -+ * Every sent & received message this callback function is invoked, -+ * so we know when alert messages have arrived or are sent and -+ * we can print debug information about TLS handshake. -+ */ -+void -+ssl_msg_callback(int write_p, int version, int content_type, -+ const void *buf, size_t len, SSL * ssl, void *arg) -+{ -+ char string[256]; -+ struct eaptls_session *ets = (struct eaptls_session *)arg; -+ unsigned char code; -+ -+ if(write_p) -+ strcpy(string, " -> "); -+ else -+ strcpy(string, " <- "); -+ -+ -+ switch(content_type) { -+ -+ case SSL3_RT_ALERT: -+ strcat(string, "Alert: "); -+ code = ((const unsigned char *)buf)[1]; -+ -+ if (write_p) { -+ ets->alert_sent = 1; -+ ets->alert_sent_desc = code; -+ } else { -+ ets->alert_recv = 1; -+ ets->alert_recv_desc = code; -+ } -+ -+ strcat(string, SSL_alert_desc_string_long(code)); -+ break; -+ -+ case SSL3_RT_CHANGE_CIPHER_SPEC: -+ strcat(string, "ChangeCipherSpec"); -+ break; -+ -+ case SSL3_RT_HANDSHAKE: -+ -+ strcat(string, "Handshake: "); -+ code = ((const unsigned char *)buf)[0]; -+ -+ switch(code) { -+ case SSL3_MT_HELLO_REQUEST: -+ strcat(string,"Hello Request"); -+ break; -+ case SSL3_MT_CLIENT_HELLO: -+ strcat(string,"Client Hello"); -+ break; -+ case SSL3_MT_SERVER_HELLO: -+ strcat(string,"Server Hello"); -+ break; -+ case SSL3_MT_CERTIFICATE: -+ strcat(string,"Certificate"); -+ break; -+ case SSL3_MT_SERVER_KEY_EXCHANGE: -+ strcat(string,"Server Key Exchange"); -+ break; -+ case SSL3_MT_CERTIFICATE_REQUEST: -+ strcat(string,"Certificate Request"); -+ break; -+ case SSL3_MT_SERVER_DONE: -+ strcat(string,"Server Hello Done"); -+ break; -+ case SSL3_MT_CERTIFICATE_VERIFY: -+ strcat(string,"Certificate Verify"); -+ break; -+ case SSL3_MT_CLIENT_KEY_EXCHANGE: -+ strcat(string,"Client Key Exchange"); -+ break; -+ case SSL3_MT_FINISHED: -+ strcat(string,"Finished"); -+ break; -+ -+ default: -+ sprintf( string, "Handshake: Unknown SSL3 code received: %d", code ); -+ } -+ break; -+ -+ default: -+ sprintf( string, "SSL message contains unknown content type: %d", content_type ); -+ -+ } -+ -+ /* Alert messages must always be displayed */ -+ if(content_type == SSL3_RT_ALERT) -+ error("%s", string); -+ else -+ dbglog("%s", string); -+} -+ -diff --git a/pppd/eap-tls.h b/pppd/eap-tls.h -new file mode 100644 -index 0000000..2d45a0b ---- /dev/null -+++ b/pppd/eap-tls.h -@@ -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 -+#include -+#include -+ -+#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 -diff --git a/pppd/eap.c b/pppd/eap.c -index faced53..e2270af 100644 ---- a/pppd/eap.c -+++ b/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 -@@ -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 */ - } - - /* -@@ -268,7 +280,7 @@ eap_state *esp; - u_char *outp; - - outp = outpacket_buf; -- -+ - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_FAILURE, outp); -@@ -293,7 +305,7 @@ eap_state *esp; - u_char *outp; - - outp = outpacket_buf; -- -+ - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_SUCCESS, outp); -@@ -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,81 @@ 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(SSL_is_init_finished(ets->ssl)) { -+ esp->es_server.ea_state = eapTlsRecvClient; -+ break; -+ } -+ -+ if(ets->frag) -+ esp->es_server.ea_state = eapTlsRecvAck; -+ 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; -@@ -681,7 +773,7 @@ eap_state *esp; - } - - outp = outpacket_buf; -- -+ - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_REQUEST, outp); -@@ -718,6 +810,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 +1020,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); - } -@@ -1081,7 +1243,7 @@ int namelen; - int msglen; - - outp = outpacket_buf; -- -+ - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); -@@ -1117,7 +1279,7 @@ int lenstr; - int msglen; - - outp = outpacket_buf; -- -+ - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); -@@ -1148,7 +1310,7 @@ u_char *str; - int msglen; - - outp = outpacket_buf; -- -+ - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); -@@ -1166,6 +1328,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 +1557,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 +1698,90 @@ int len; - esp->es_client.ea_namelen); - break; - -+#ifdef USE_EAPTLS -+ case EAPT_TLS: -+ -+ switch(esp->es_client.ea_state) { -+ -+ case eapListen: -+ -+ 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: -+ 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 +2063,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 +2107,60 @@ 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 */ -+ -+ 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 */ -+ eaptls_receive(esp->es_server.ea_session, inp, len); -+ warn("Server authentication failed"); -+ eap_send_failure(esp); -+ } -+ -+ 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 +2192,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 +2410,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 +2556,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 +2623,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 +2752,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, " "); -diff --git a/pppd/eap.h b/pppd/eap.h -index 199d184..3fa5391 100644 ---- a/pppd/eap.h -+++ b/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 */ - -diff --git a/pppd/md5.c b/pppd/md5.c -index f1291ce..2ee0c80 100644 ---- a/pppd/md5.c -+++ b/pppd/md5.c -@@ -33,6 +33,8 @@ - *********************************************************************** - */ - -+#ifndef USE_EAPTLS -+ - #include - #include "md5.h" - -@@ -305,3 +307,4 @@ UINT4 *in; - ** End of md5.c ** - ******************************** (cut) ******************************** - */ -+#endif /* USE_EAPTLS */ -diff --git a/pppd/md5.h b/pppd/md5.h -index 71e8b00..14d7121 100644 ---- a/pppd/md5.h -+++ b/pppd/md5.h -@@ -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 */ -diff --git a/pppd/options.c b/pppd/options.c -index 8e62635..6915b2d 100644 ---- a/pppd/options.c -+++ b/pppd/options.c -@@ -120,6 +120,10 @@ bool dump_options; /* print out option values */ - bool dryrun; /* print out option values and exit */ - char *domain; /* domain name set by domain option */ - int child_wait = 5; /* # seconds to wait for children at exit */ -+#ifdef USE_EAPTLS -+bool only_update_crl_server = 0; /* update server crl and exit */ -+bool only_update_crl_client = 0; /* update client crl and exit */ -+#endif /* USE_EAPTLS */ - struct userenv *userenv_list; /* user environment variables */ - - #ifdef MAXOCTETS -@@ -338,6 +342,12 @@ option_t general_options[] = { - { "mo-timeout", o_int, &maxoctets_timeout, - "Check for traffic limit every N seconds", OPT_PRIO | OPT_LLIMIT | 1 }, - #endif -+#ifdef USE_EAPTLS -+ { "only-update-crl-server", o_bool, &only_update_crl_server, -+ "Update server CA CRLs and exit", 1 }, -+ { "only-update-crl-client", o_bool, &only_update_crl_client, -+ "Update client CA CRLs and exit", 1 }, -+#endif /* USE_EAPTLS */ - - { NULL } - }; -diff --git a/pppd/pathnames.h b/pppd/pathnames.h -index 24e010c..6275df6 100644 ---- a/pppd/pathnames.h -+++ b/pppd/pathnames.h -@@ -22,6 +22,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" -diff --git a/pppd/plugins/Makefile.linux b/pppd/plugins/Makefile.linux -index b474a19..760cad4 100644 ---- a/pppd/plugins/Makefile.linux -+++ b/pppd/plugins/Makefile.linux -@@ -4,6 +4,9 @@ CFLAGS = $(COPTS) -I.. -I../../include -fPIC - LDFLAGS = -shared - INSTALL = install - -+# EAP-TLS -+CFLAGS += -DUSE_EAPTLS=1 -+ - DESTDIR = $(INSTROOT)@DESTDIR@ - BINDIR = $(DESTDIR)/sbin - MANDIR = $(DESTDIR)/share/man/man8 -diff --git a/pppd/plugins/passprompt.c b/pppd/plugins/passprompt.c -index babb6dc..6ba73ca 100644 ---- a/pppd/plugins/passprompt.c -+++ b/pppd/plugins/passprompt.c -@@ -107,4 +107,7 @@ void plugin_init(void) - { - add_options(options); - pap_passwd_hook = promptpass; -+#ifdef USE_EAPTLS -+ eaptls_passwd_hook = promptpass; -+#endif - } -diff --git a/pppd/plugins/passwordfd.c b/pppd/plugins/passwordfd.c -index d718f3b..c3f9793 100644 ---- a/pppd/plugins/passwordfd.c -+++ b/pppd/plugins/passwordfd.c -@@ -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 - } -diff --git a/pppd/pppd.h b/pppd/pppd.h -index 47e4d9a..de271c1 100644 ---- a/pppd/pppd.h -+++ b/pppd/pppd.h -@@ -324,6 +324,10 @@ 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; -+#endif /* USE_EAPTLS */ -+ - #ifdef MAXOCTETS - extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ - extern int maxoctets_dir; /* Direction : -@@ -738,6 +742,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)); --- -1.8.3.1 - diff --git a/0026-Revert-pppd-rebase-EAP-TLS-patch-v0.994.patch b/0026-Revert-pppd-rebase-EAP-TLS-patch-v0.994.patch deleted file mode 100644 index 515a5f4..0000000 --- a/0026-Revert-pppd-rebase-EAP-TLS-patch-v0.994.patch +++ /dev/null @@ -1,3046 +0,0 @@ -From 1c5d747dac840a633aebd3eef882b11321993009 Mon Sep 17 00:00:00 2001 -From: Michal Sekletar -Date: Fri, 20 Jun 2014 10:26:32 +0200 -Subject: [PATCH 26/27] Revert "pppd: rebase EAP-TLS patch v0.994" - -This reverts commit 044a5b1e5d878c519143b71a44b3d5b0ca91de3b. ---- - README.eap-tls | 169 ------- - etc.ppp/eaptls-client | 10 - - etc.ppp/eaptls-server | 11 - - etc.ppp/openssl.cnf | 14 - - linux/Makefile.top | 6 +- - pppd/Makefile.linux | 12 - - pppd/auth.c | 414 +-------------- - pppd/ccp.c | 20 +- - pppd/chap-md5.c | 4 - - pppd/eap-tls.c | 1174 ------------------------------------------- - pppd/eap-tls.h | 107 ---- - pppd/eap.c | 462 +---------------- - pppd/eap.h | 32 +- - pppd/md5.c | 3 - - pppd/md5.h | 3 - - pppd/options.c | 10 - - pppd/pathnames.h | 7 - - pppd/plugins/Makefile.linux | 3 - - pppd/plugins/passprompt.c | 3 - - pppd/plugins/passwordfd.c | 4 - - pppd/pppd.h | 8 - - 21 files changed, 15 insertions(+), 2461 deletions(-) - delete mode 100644 README.eap-tls - delete mode 100644 etc.ppp/eaptls-client - delete mode 100644 etc.ppp/eaptls-server - delete mode 100644 etc.ppp/openssl.cnf - delete mode 100644 pppd/eap-tls.c - delete mode 100644 pppd/eap-tls.h - -diff --git a/README.eap-tls b/README.eap-tls -deleted file mode 100644 -index 0a4fee9..0000000 ---- a/README.eap-tls -+++ /dev/null -@@ -1,169 +0,0 @@ --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 2246) 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: -- : -- 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: -- : -- 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 -- Use the CA public certificate found in in PEM format -- cert -- Use the client public certificate found in in PEM format -- or in engine:engine_id format -- key -- Use the client private key found in in PEM format -- or in engine:engine_id format -- crl-dir -- Use CRL files from 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. Notes -- -- This is experimental code. -- Send suggestions and comments to Jan Just Keijser -- -diff --git a/etc.ppp/eaptls-client b/etc.ppp/eaptls-client -deleted file mode 100644 -index 7782f0e..0000000 ---- a/etc.ppp/eaptls-client -+++ /dev/null -@@ -1,10 +0,0 @@ --# 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 -diff --git a/etc.ppp/eaptls-server b/etc.ppp/eaptls-server -deleted file mode 100644 -index fa53cbd..0000000 ---- a/etc.ppp/eaptls-server -+++ /dev/null -@@ -1,11 +0,0 @@ --# 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 -diff --git a/etc.ppp/openssl.cnf b/etc.ppp/openssl.cnf -deleted file mode 100644 -index dd32f30..0000000 ---- a/etc.ppp/openssl.cnf -+++ /dev/null -@@ -1,14 +0,0 @@ --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 -- -diff --git a/linux/Makefile.top b/linux/Makefile.top -index 9a8945a..f42efd5 100644 ---- a/linux/Makefile.top -+++ b/linux/Makefile.top -@@ -28,7 +28,7 @@ install-progs: - cd pppdump; $(MAKE) $(MFLAGS) install - - install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \ -- $(ETCDIR)/chap-secrets $(ETCDIR)/eaptls-server $(ETCDIR)/eaptls-client -+ $(ETCDIR)/chap-secrets - - install-devel: - cd pppd; $(MAKE) $(MFLAGS) install-devel -@@ -39,10 +39,6 @@ $(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 $@ -diff --git a/pppd/Makefile.linux b/pppd/Makefile.linux -index 534ccc2..943cf83 100644 ---- a/pppd/Makefile.linux -+++ b/pppd/Makefile.linux -@@ -79,9 +79,6 @@ CBCP=y - # Use libutil - USE_LIBUTIL=y - --# Enable EAP-TLS authentication (requires libssl and libcrypto) --USE_EAPTLS=y -- - MAXOCTETS=y - - INCLUDE_DIRS= -I../include -@@ -121,15 +118,6 @@ 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) -diff --git a/pppd/auth.c b/pppd/auth.c -index 88cbdb6..9e957fa 100644 ---- a/pppd/auth.c -+++ b/pppd/auth.c -@@ -109,9 +109,6 @@ - #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 -@@ -186,11 +183,6 @@ 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, -@@ -246,13 +238,6 @@ 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 */ --bool need_peer_eap = 0; /* Require peer to authenticate us */ --#endif - - static char *uafname; /* name of most recent +ua file */ - -@@ -269,19 +254,6 @@ 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 **, -@@ -429,14 +401,6 @@ 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" }, -- { "need-peer-eap", o_bool, &need_peer_eap, -- "Require the peer to authenticate us", 1 }, --#endif /* USE_EAPTLS */ - { NULL } - }; - -@@ -766,9 +730,6 @@ 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; - -@@ -803,22 +764,6 @@ 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) { -@@ -1172,7 +1117,7 @@ np_down(unit, proto) - UNTIMEOUT(connect_time_expired, NULL); - #ifdef MAXOCTETS - UNTIMEOUT(check_maxoctets, NULL); --#endif -+#endif - new_phase(PHASE_NETWORK); - } - } -@@ -1199,7 +1144,7 @@ check_maxoctets(arg) - - update_link_stats(ifunit); - link_stats_valid=0; -- -+ - switch(maxoctets_dir) { - case PPP_OCTETS_DIRECTION_IN: - used = link_stats.bytes_in; -@@ -1332,15 +1277,6 @@ 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( -@@ -1395,11 +1331,7 @@ 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) --#ifdef USE_EAPTLS -- || have_eaptls_secret_client(user, (explicit_remote? remote_name: NULL)) --#endif -- ); -+ have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)); - - hadchap = -1; - if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) -@@ -1414,14 +1346,8 @@ 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) --#ifdef USE_EAPTLS -- && !have_eaptls_secret_server((explicit_remote? remote_name: NULL), -- our_name, 1, NULL) --#endif -- ) -+ NULL)) - go->neg_eap = 0; -- - } - - -@@ -1781,7 +1707,6 @@ 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. -@@ -2434,334 +2359,3 @@ 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 -diff --git a/pppd/ccp.c b/pppd/ccp.c -index 7dead23..5814f35 100644 ---- a/pppd/ccp.c -+++ b/pppd/ccp.c -@@ -540,9 +540,6 @@ 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; - - /* -@@ -570,23 +567,8 @@ 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."); --#endif -+ error("MPPE required, but MS-CHAP[v2] auth not performed."); - lcp_close(f->unit, "MPPE required but not available"); - return; - } -diff --git a/pppd/chap-md5.c b/pppd/chap-md5.c -index 269b52c..77dd4ec 100644 ---- a/pppd/chap-md5.c -+++ b/pppd/chap-md5.c -@@ -36,11 +36,7 @@ - #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 -diff --git a/pppd/eap-tls.c b/pppd/eap-tls.c -deleted file mode 100644 -index a3aea5a..0000000 ---- a/pppd/eap-tls.c -+++ /dev/null -@@ -1,1174 +0,0 @@ --/* -- * eap-tls.c - EAP-TLS implementation for PPP -- * -- * 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. -- * -- */ -- --#include --#include --#include --#include --#include -- --#include --#include --#include --#include --#include -- --#include "pppd.h" --#include "eap.h" --#include "eap-tls.h" --#include "fsm.h" --#include "lcp.h" --#include "pathnames.h" -- --/* The openssl configuration file and engines can be loaded only once */ --static CONF *ssl_config = NULL; --static ENGINE *cert_engine = NULL; --static ENGINE *pkey_engine = NULL; -- --#ifdef MPPE -- --/* -- * TLS PRF from RFC 2246 -- */ --static void P_hash(const EVP_MD *evp_md, -- const unsigned char *secret, unsigned int secret_len, -- const unsigned char *seed, unsigned int seed_len, -- unsigned char *out, unsigned int out_len) --{ -- HMAC_CTX ctx_a, ctx_out; -- unsigned char a[HMAC_MAX_MD_CBLOCK]; -- unsigned int size; -- -- HMAC_CTX_init(&ctx_a); -- HMAC_CTX_init(&ctx_out); -- HMAC_Init_ex(&ctx_a, secret, secret_len, evp_md, NULL); -- HMAC_Init_ex(&ctx_out, secret, secret_len, evp_md, NULL); -- -- size = HMAC_size(&ctx_out); -- -- /* Calculate A(1) */ -- HMAC_Update(&ctx_a, seed, seed_len); -- HMAC_Final(&ctx_a, a, NULL); -- -- while (1) { -- /* Calculate next part of output */ -- HMAC_Update(&ctx_out, a, size); -- HMAC_Update(&ctx_out, seed, seed_len); -- -- /* Check if last part */ -- if (out_len < size) { -- HMAC_Final(&ctx_out, a, NULL); -- memcpy(out, a, out_len); -- break; -- } -- -- /* Place digest in output buffer */ -- HMAC_Final(&ctx_out, out, NULL); -- HMAC_Init_ex(&ctx_out, NULL, 0, NULL, NULL); -- out += size; -- out_len -= size; -- -- /* Calculate next A(i) */ -- HMAC_Init_ex(&ctx_a, NULL, 0, NULL, NULL); -- HMAC_Update(&ctx_a, a, size); -- HMAC_Final(&ctx_a, a, NULL); -- } -- -- HMAC_CTX_cleanup(&ctx_a); -- HMAC_CTX_cleanup(&ctx_out); -- memset(a, 0, sizeof(a)); --} -- --static void PRF(const unsigned char *secret, unsigned int secret_len, -- const unsigned char *seed, unsigned int seed_len, -- unsigned char *out, unsigned char *buf, unsigned int out_len) --{ -- unsigned int i; -- unsigned int len = (secret_len + 1) / 2; -- const unsigned char *s1 = secret; -- const unsigned char *s2 = secret + (secret_len - len); -- -- P_hash(EVP_md5(), s1, len, seed, seed_len, out, out_len); -- P_hash(EVP_sha1(), s2, len, seed, seed_len, buf, out_len); -- -- for (i=0; i < out_len; i++) { -- out[i] ^= buf[i]; -- } --} -- --#define EAPTLS_MPPE_KEY_LEN 32 -- --/* -- * Generate keys according to RFC 2716 and add to reply -- */ --void eaptls_gen_mppe_keys(struct eaptls_session *ets, const char *prf_label, -- int client) --{ -- unsigned char out[4*EAPTLS_MPPE_KEY_LEN], buf[4*EAPTLS_MPPE_KEY_LEN]; -- unsigned char seed[64 + 2*SSL3_RANDOM_SIZE]; -- unsigned char *p = seed; -- SSL *s = ets->ssl; -- size_t prf_size; -- -- prf_size = strlen(prf_label); -- -- memcpy(p, prf_label, prf_size); -- p += prf_size; -- -- memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); -- p += SSL3_RANDOM_SIZE; -- prf_size += SSL3_RANDOM_SIZE; -- -- memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE); -- prf_size += SSL3_RANDOM_SIZE; -- -- PRF(s->session->master_key, s->session->master_key_length, -- seed, prf_size, out, buf, sizeof(out)); -- -- /* -- * We now have the master send and receive keys. -- * From these, generate the session send and receive keys. -- * (see RFC3079 / draft-ietf-pppext-mppe-keys-03.txt for details) -- */ -- if (client) -- { -- p = out; -- BCOPY( p, mppe_send_key, sizeof(mppe_send_key) ); -- p += EAPTLS_MPPE_KEY_LEN; -- BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) ); -- } -- else -- { -- p = out; -- BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) ); -- p += EAPTLS_MPPE_KEY_LEN; -- BCOPY( p, mppe_send_key, sizeof(mppe_send_key) ); -- } -- -- mppe_keys_set = 1; --} -- --#endif -- --void log_ssl_errors( void ) --{ -- unsigned long ssl_err = ERR_get_error(); -- -- if (ssl_err != 0) -- dbglog("EAP-TLS SSL error stack:"); -- while (ssl_err != 0) { -- dbglog( ERR_error_string( ssl_err, NULL ) ); -- ssl_err = ERR_get_error(); -- } --} -- -- --int password_callback (char *buf, int size, int rwflag, void *u) --{ -- if (buf) -- { -- strncpy (buf, passwd, size); -- return strlen (buf); -- } -- return 0; --} -- -- --CONF *eaptls_ssl_load_config( void ) --{ -- CONF *config; -- int ret_code; -- long error_line = 33; -- -- config = NCONF_new( NULL ); -- dbglog( "Loading OpenSSL config file" ); -- ret_code = NCONF_load( config, _PATH_OPENSSLCONFFILE, &error_line ); -- if (ret_code == 0) -- { -- warn( "EAP-TLS: Error in OpenSSL config file %s at line %d", _PATH_OPENSSLCONFFILE, error_line ); -- NCONF_free( config ); -- config = NULL; -- ERR_clear_error(); -- } -- -- dbglog( "Loading OpenSSL built-ins" ); -- ENGINE_load_builtin_engines(); -- OPENSSL_load_builtin_modules(); -- -- dbglog( "Loading OpenSSL configured modules" ); -- if (CONF_modules_load( config, NULL, 0 ) <= 0 ) -- { -- warn( "EAP-TLS: Error loading OpenSSL modules" ); -- log_ssl_errors(); -- config = NULL; -- } -- -- return config; --} -- --ENGINE *eaptls_ssl_load_engine( char *engine_name ) --{ -- ENGINE *e = NULL; -- -- dbglog( "Enabling OpenSSL auto engines" ); -- ENGINE_register_all_complete(); -- -- dbglog( "Loading OpenSSL '%s' engine support", engine_name ); -- e = ENGINE_by_id( engine_name ); -- if (!e) -- { -- dbglog( "EAP-TLS: Cannot load '%s' engine support, trying 'dynamic'", engine_name ); -- e = ENGINE_by_id( "dynamic" ); -- if (e) -- { -- if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine_name, 0) -- || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) -- { -- warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name ); -- log_ssl_errors(); -- ENGINE_free(e); -- e = NULL; -- } -- } -- else -- { -- warn( "EAP-TLS: Cannot load dynamic engine support" ); -- } -- } -- -- if (e) -- { -- dbglog( "Initialising engine" ); -- if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) -- { -- warn( "EAP-TLS: Cannot use that engine" ); -- log_ssl_errors(); -- ENGINE_free(e); -- e = NULL; -- } -- } -- -- return e; --} -- --/* -- * Initialize the SSL stacks and tests if certificates, key and crl -- * for client or server use can be loaded. -- */ --SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, -- char *certfile, char *peer_certfile, char *privkeyfile) --{ -- char *cert_engine_name = NULL; -- char *cert_identifier = NULL; -- char *pkey_engine_name = NULL; -- char *pkey_identifier = NULL; -- SSL_CTX *ctx; -- X509_STORE *certstore; -- X509_LOOKUP *lookup; -- X509 *tmp; -- -- /* -- * Without these can't continue -- */ -- if (!cacertfile[0]) -- { -- error("EAP-TLS: CA certificate missing"); -- return NULL; -- } -- -- if (!certfile[0]) -- { -- error("EAP-TLS: User certificate missing"); -- return NULL; -- } -- -- if (!privkeyfile[0]) -- { -- error("EAP-TLS: User private key missing"); -- return NULL; -- } -- -- SSL_library_init(); -- SSL_load_error_strings(); -- -- ctx = SSL_CTX_new(TLSv1_method()); -- -- if (!ctx) { -- error("EAP-TLS: Cannot initialize SSL CTX context"); -- goto fail; -- } -- -- /* if the certificate filename is of the form engine:id. e.g. -- pkcs11:12345 -- then we try to load and use this engine. -- If the certificate filename starts with a / or . then we -- ALWAYS assume it is a file and not an engine/pkcs11 identifier -- */ -- if ( index( certfile, '/' ) == NULL && index( certfile, '.') == NULL ) -- { -- cert_identifier = index( certfile, ':' ); -- -- if (cert_identifier) -- { -- cert_engine_name = certfile; -- *cert_identifier = '\0'; -- cert_identifier++; -- -- dbglog( "Found certificate engine '%s'", cert_engine_name ); -- dbglog( "Found certificate identifier '%s'", cert_identifier ); -- } -- } -- -- /* if the privatekey filename is of the form engine:id. e.g. -- pkcs11:12345 -- then we try to load and use this engine. -- If the privatekey filename starts with a / or . then we -- ALWAYS assume it is a file and not an engine/pkcs11 identifier -- */ -- if ( index( privkeyfile, '/' ) == NULL && index( privkeyfile, '.') == NULL ) -- { -- pkey_identifier = index( privkeyfile, ':' ); -- -- if (pkey_identifier) -- { -- pkey_engine_name = privkeyfile; -- *pkey_identifier = '\0'; -- pkey_identifier++; -- -- dbglog( "Found privatekey engine '%s'", pkey_engine_name ); -- dbglog( "Found privatekey identifier '%s'", pkey_identifier ); -- } -- } -- -- if (cert_identifier && pkey_identifier) -- { -- if (strlen( cert_identifier ) == 0) -- { -- if (strlen( pkey_identifier ) == 0) -- error( "EAP-TLS: both the certificate and privatekey identifiers are missing!" ); -- else -- { -- dbglog( "Substituting privatekey identifier for certificate identifier" ); -- cert_identifier = pkey_identifier; -- } -- } -- else -- { -- if (strlen( pkey_identifier ) == 0) -- { -- dbglog( "Substituting certificate identifier for privatekey identifier" ); -- pkey_identifier = cert_identifier; -- } -- } -- -- } -- -- /* load the openssl config file only once */ -- if (!ssl_config) -- { -- if (cert_engine_name || pkey_engine_name) -- ssl_config = eaptls_ssl_load_config(); -- -- if (ssl_config && cert_engine_name) -- cert_engine = eaptls_ssl_load_engine( cert_engine_name ); -- -- if (ssl_config && pkey_engine_name) -- { -- /* don't load the same engine twice */ -- if ( strcmp( cert_engine_name, pkey_engine_name) == 0 ) -- pkey_engine = cert_engine; -- else -- pkey_engine = eaptls_ssl_load_engine( pkey_engine_name ); -- } -- } -- -- SSL_CTX_set_default_passwd_cb (ctx, password_callback); -- -- if (!SSL_CTX_load_verify_locations(ctx, cacertfile, NULL)) -- { -- error("EAP-TLS: Cannot load or verify CA file %s", cacertfile); -- goto fail; -- } -- -- if (init_server) -- SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(cacertfile)); -- -- if (cert_engine) -- { -- struct -- { -- const char *s_slot_cert_id; -- X509 *cert; -- } cert_info; -- -- cert_info.s_slot_cert_id = cert_identifier; -- cert_info.cert = NULL; -- -- if (!ENGINE_ctrl_cmd( cert_engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0 ) ) -- { -- error( "EAP-TLS: Error loading certificate with id '%s' from engine", cert_identifier ); -- goto fail; -- } -- -- if (cert_info.cert) -- { -- dbglog( "Got the certificate, adding it to SSL context" ); -- dbglog( "subject = %s", X509_NAME_oneline( X509_get_subject_name( cert_info.cert ), NULL, 0 ) ); -- if (SSL_CTX_use_certificate(ctx, cert_info.cert) <= 0) -- { -- error("EAP-TLS: Cannot use PKCS11 certificate %s", cert_identifier); -- goto fail; -- } -- } -- else -- { -- warn("EAP-TLS: Cannot load PKCS11 key %s", cert_identifier); -- log_ssl_errors(); -- } -- } -- else -- { -- if (!SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM)) -- { -- error( "EAP-TLS: Cannot use public certificate %s", certfile ); -- goto fail; -- } -- } -- -- if (pkey_engine) -- { -- EVP_PKEY *pkey = NULL; -- PW_CB_DATA cb_data; -- -- cb_data.password = passwd; -- cb_data.prompt_info = pkey_identifier; -- -- dbglog( "Loading private key '%s' from engine", pkey_identifier ); -- pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, NULL, &cb_data); -- if (pkey) -- { -- dbglog( "Got the private key, adding it to SSL context" ); -- if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0) -- { -- error("EAP-TLS: Cannot use PKCS11 key %s", pkey_identifier); -- goto fail; -- } -- } -- else -- { -- warn("EAP-TLS: Cannot load PKCS11 key %s", pkey_identifier); -- log_ssl_errors(); -- } -- } -- else -- { -- if (!SSL_CTX_use_PrivateKey_file(ctx, privkeyfile, SSL_FILETYPE_PEM)) -- { -- error("EAP-TLS: Cannot use private key %s", privkeyfile); -- goto fail; -- } -- } -- -- if (SSL_CTX_check_private_key(ctx) != 1) { -- error("EAP-TLS: Private key %s fails security check", privkeyfile); -- goto fail; -- } -- -- SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); -- SSL_CTX_set_verify_depth(ctx, 5); -- SSL_CTX_set_verify(ctx, -- SSL_VERIFY_PEER | -- SSL_VERIFY_FAIL_IF_NO_PEER_CERT, -- &ssl_verify_callback); -- -- if (crl_dir) { -- if (!(certstore = SSL_CTX_get_cert_store(ctx))) { -- error("EAP-TLS: Failed to get certificate store"); -- goto fail; -- } -- -- if (!(lookup = -- X509_STORE_add_lookup(certstore, X509_LOOKUP_hash_dir()))) { -- error("EAP-TLS: Store lookup for CRL failed"); -- -- goto fail; -- } -- -- X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM); -- X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK); -- } -- -- /* -- * If a peer certificate file was specified, it must be valid, else fail -- */ -- if (peer_certfile[0]) { -- if (!(tmp = get_X509_from_file(peer_certfile))) { -- error("EAP-TLS: Error loading client certificate from file %s", -- peer_certfile); -- goto fail; -- } -- X509_free(tmp); -- } -- -- return ctx; -- --fail: -- log_ssl_errors(); -- SSL_CTX_free(ctx); -- return NULL; --} -- --/* -- * Determine the maximum packet size by looking at the LCP handshake -- */ -- --int eaptls_get_mtu(int unit) --{ -- int mtu, mru; -- -- lcp_options *wo = &lcp_wantoptions[unit]; -- lcp_options *go = &lcp_gotoptions[unit]; -- lcp_options *ho = &lcp_hisoptions[unit]; -- lcp_options *ao = &lcp_allowoptions[unit]; -- -- mtu = ho->neg_mru? ho->mru: PPP_MRU; -- mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU; -- mtu = MIN(MIN(mtu, mru), ao->mru)- PPP_HDRLEN - 10; -- -- dbglog("MTU = %d", mtu); -- return mtu; --} -- -- --/* -- * Init the ssl handshake (server mode) -- */ --int eaptls_init_ssl_server(eap_state * esp) --{ -- struct eaptls_session *ets; -- char servcertfile[MAXWORDLEN]; -- char clicertfile[MAXWORDLEN]; -- char cacertfile[MAXWORDLEN]; -- char pkfile[MAXWORDLEN]; -- /* -- * Allocate new eaptls session -- */ -- esp->es_server.ea_session = malloc(sizeof(struct eaptls_session)); -- if (!esp->es_server.ea_session) -- fatal("Allocation error"); -- ets = esp->es_server.ea_session; -- -- if (!esp->es_server.ea_peer) { -- error("EAP-TLS: Error: client name not set (BUG)"); -- return 0; -- } -- -- strncpy(ets->peer, esp->es_server.ea_peer, MAXWORDLEN); -- -- dbglog( "getting eaptls secret" ); -- if (!get_eaptls_secret(esp->es_unit, esp->es_server.ea_peer, -- esp->es_server.ea_name, clicertfile, -- servcertfile, cacertfile, pkfile, 1)) { -- error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"", -- esp->es_server.ea_peer, esp->es_server.ea_name ); -- return 0; -- } -- -- ets->mtu = eaptls_get_mtu(esp->es_unit); -- -- ets->ctx = eaptls_init_ssl(1, cacertfile, servcertfile, clicertfile, pkfile); -- if (!ets->ctx) -- goto fail; -- -- if (!(ets->ssl = SSL_new(ets->ctx))) -- goto fail; -- -- /* -- * Set auto-retry to avoid timeouts on BIO_read -- */ -- SSL_set_mode(ets->ssl, SSL_MODE_AUTO_RETRY); -- -- /* -- * Initialize the BIOs we use to read/write to ssl engine -- */ -- ets->into_ssl = BIO_new(BIO_s_mem()); -- ets->from_ssl = BIO_new(BIO_s_mem()); -- SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl); -- -- SSL_set_msg_callback(ets->ssl, ssl_msg_callback); -- SSL_set_msg_callback_arg(ets->ssl, ets); -- -- /* -- * Attach the session struct to the connection, so we can later -- * retrieve it when doing certificate verification -- */ -- SSL_set_ex_data(ets->ssl, 0, ets); -- -- SSL_set_accept_state(ets->ssl); -- -- ets->data = NULL; -- ets->datalen = 0; -- ets->alert_sent = 0; -- ets->alert_recv = 0; -- -- /* -- * If we specified the client certificate file, store it in ets->peercertfile, -- * so we can check it later in ssl_verify_callback() -- */ -- if (clicertfile[0]) -- strncpy(&ets->peercertfile[0], clicertfile, MAXWORDLEN); -- else -- ets->peercertfile[0] = 0; -- -- return 1; -- --fail: -- SSL_CTX_free(ets->ctx); -- return 0; --} -- --/* -- * Init the ssl handshake (client mode) -- */ --int eaptls_init_ssl_client(eap_state * esp) --{ -- struct eaptls_session *ets; -- char servcertfile[MAXWORDLEN]; -- char clicertfile[MAXWORDLEN]; -- char cacertfile[MAXWORDLEN]; -- char pkfile[MAXWORDLEN]; -- -- /* -- * Allocate new eaptls session -- */ -- esp->es_client.ea_session = malloc(sizeof(struct eaptls_session)); -- if (!esp->es_client.ea_session) -- fatal("Allocation error"); -- ets = esp->es_client.ea_session; -- -- /* -- * If available, copy server name in ets; it will be used in cert -- * verify -- */ -- if (esp->es_client.ea_peer) -- strncpy(ets->peer, esp->es_client.ea_peer, MAXWORDLEN); -- else -- ets->peer[0] = 0; -- -- ets->mtu = eaptls_get_mtu(esp->es_unit); -- -- dbglog( "calling get_eaptls_secret" ); -- if (!get_eaptls_secret(esp->es_unit, esp->es_client.ea_name, -- esp->es_client.ea_peer, clicertfile, -- servcertfile, cacertfile, pkfile, 0)) { -- error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"", -- esp->es_client.ea_name, esp->es_client.ea_peer ); -- return 0; -- } -- -- dbglog( "calling eaptls_init_ssl" ); -- ets->ctx = eaptls_init_ssl(0, cacertfile, clicertfile, servcertfile, pkfile); -- if (!ets->ctx) -- goto fail; -- -- ets->ssl = SSL_new(ets->ctx); -- -- if (!ets->ssl) -- goto fail; -- -- /* -- * Initialize the BIOs we use to read/write to ssl engine -- */ -- dbglog( "Initializing SSL BIOs" ); -- ets->into_ssl = BIO_new(BIO_s_mem()); -- ets->from_ssl = BIO_new(BIO_s_mem()); -- SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl); -- -- SSL_set_msg_callback(ets->ssl, ssl_msg_callback); -- SSL_set_msg_callback_arg(ets->ssl, ets); -- -- /* -- * Attach the session struct to the connection, so we can later -- * retrieve it when doing certificate verification -- */ -- SSL_set_ex_data(ets->ssl, 0, ets); -- -- SSL_set_connect_state(ets->ssl); -- -- ets->data = NULL; -- ets->datalen = 0; -- ets->alert_sent = 0; -- ets->alert_recv = 0; -- -- /* -- * If we specified the server certificate file, store it in -- * ets->peercertfile, so we can check it later in -- * ssl_verify_callback() -- */ -- if (servcertfile[0]) -- strncpy(ets->peercertfile, servcertfile, MAXWORDLEN); -- else -- ets->peercertfile[0] = 0; -- -- return 1; -- --fail: -- dbglog( "eaptls_init_ssl_client: fail" ); -- SSL_CTX_free(ets->ctx); -- return 0; -- --} -- --void eaptls_free_session(struct eaptls_session *ets) --{ -- if (ets->ssl) -- SSL_free(ets->ssl); -- -- if (ets->ctx) -- SSL_CTX_free(ets->ctx); -- -- free(ets); --} -- --/* -- * Handle a received packet, reassembling fragmented messages and -- * passing them to the ssl engine -- */ --int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len) --{ -- u_char flags; -- u_int tlslen; -- u_char dummy[65536]; -- -- GETCHAR(flags, inp); -- len--; -- -- if (flags & EAP_TLS_FLAGS_LI && !ets->data) { -- -- /* -- * This is the first packet of a message -- */ -- -- GETLONG(tlslen, inp); -- len -= 4; -- -- if (tlslen > EAP_TLS_MAX_LEN) { -- error("Error: tls message length > %d, truncated", -- EAP_TLS_MAX_LEN); -- tlslen = EAP_TLS_MAX_LEN; -- } -- -- /* -- * Allocate memory for the whole message -- */ -- ets->data = malloc(tlslen); -- if (!ets->data) -- fatal("EAP TLS: allocation error\n"); -- -- ets->datalen = 0; -- ets->tlslen = tlslen; -- -- } -- else if (flags & EAP_TLS_FLAGS_LI && ets->data) { -- /* -- * Non first with LI (strange...) -- */ -- -- GETLONG(tlslen, inp); -- len -= 4; -- -- } -- else if (!ets->data) { -- /* -- * A non fragmented message without LI flag -- */ -- -- ets->data = malloc(len); -- if (!ets->data) -- fatal("EAP TLS: allocation error\n"); -- -- ets->datalen = 0; -- ets->tlslen = len; -- } -- -- if (flags & EAP_TLS_FLAGS_MF) -- ets->frag = 1; -- else -- ets->frag = 0; -- -- if (len + ets->datalen > ets->tlslen) { -- warn("EAP TLS: received data > TLS message length"); -- return 1; -- } -- -- BCOPY(inp, ets->data + ets->datalen, len); -- ets->datalen += len; -- -- if (!ets->frag) { -- -- /* -- * If we have the whole message, pass it to ssl -- */ -- -- if (ets->datalen != ets->tlslen) { -- warn("EAP TLS: received data != TLS message length"); -- return 1; -- } -- -- if (BIO_write(ets->into_ssl, ets->data, ets->datalen) == -1) -- log_ssl_errors(); -- -- SSL_read(ets->ssl, dummy, 65536); -- -- free(ets->data); -- ets->data = NULL; -- ets->datalen = 0; -- } -- -- return 0; --} -- --/* -- * Return an eap-tls packet in outp. -- * A TLS message read from the ssl engine is buffered in ets->data. -- * At each call we control if there is buffered data and send a -- * packet of mtu bytes. -- */ --int eaptls_send(struct eaptls_session *ets, u_char ** outp) --{ -- bool first = 0; -- int size; -- u_char fromtls[65536]; -- int res; -- u_char *start; -- -- start = *outp; -- -- if (!ets->data) { -- -- if(!ets->alert_sent) -- SSL_read(ets->ssl, fromtls, 65536); -- -- /* -- * Read from ssl -- */ -- if ((res = BIO_read(ets->from_ssl, fromtls, 65536)) == -1) -- fatal("No data from BIO_read"); -- -- ets->datalen = res; -- -- ets->data = malloc(ets->datalen); -- BCOPY(fromtls, ets->data, ets->datalen); -- -- ets->offset = 0; -- first = 1; -- -- } -- -- size = ets->datalen - ets->offset; -- -- if (size > ets->mtu) { -- size = ets->mtu; -- ets->frag = 1; -- } else -- ets->frag = 0; -- -- PUTCHAR(EAPT_TLS, *outp); -- -- /* -- * Set right flags and length if necessary -- */ -- if (ets->frag && first) { -- PUTCHAR(EAP_TLS_FLAGS_LI | EAP_TLS_FLAGS_MF, *outp); -- PUTLONG(ets->datalen, *outp); -- } else if (ets->frag) { -- PUTCHAR(EAP_TLS_FLAGS_MF, *outp); -- } else -- PUTCHAR(0, *outp); -- -- /* -- * Copy the data in outp -- */ -- BCOPY(ets->data + ets->offset, *outp, size); -- INCPTR(size, *outp); -- -- /* -- * Copy the packet in retransmission buffer -- */ -- BCOPY(start, &ets->rtx[0], *outp - start); -- ets->rtx_len = *outp - start; -- -- ets->offset += size; -- -- if (ets->offset >= ets->datalen) { -- -- /* -- * The whole message has been sent -- */ -- -- free(ets->data); -- ets->data = NULL; -- ets->datalen = 0; -- ets->offset = 0; -- } -- -- return 0; --} -- --/* -- * Get the sent packet from the retransmission buffer -- */ --void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp) --{ -- BCOPY(ets->rtx, *outp, ets->rtx_len); -- INCPTR(ets->rtx_len, *outp); --} -- --/* -- * Verify a certificate. -- * Most of the work (signatures and issuer attributes checking) -- * is done by ssl; we check the CN in the peer certificate -- * against the peer name. -- */ --int ssl_verify_callback(int preverify_ok, X509_STORE_CTX * ctx) --{ -- char subject[256]; -- char cn_str[256]; -- X509 *peer_cert; -- int err, depth; -- int ok = preverify_ok; -- SSL *ssl; -- struct eaptls_session *ets; -- -- peer_cert = X509_STORE_CTX_get_current_cert(ctx); -- err = X509_STORE_CTX_get_error(ctx); -- depth = X509_STORE_CTX_get_error_depth(ctx); -- -- dbglog("certificate verify depth: %d", depth); -- -- if (auth_required && !ok) { -- X509_NAME_oneline(X509_get_subject_name(peer_cert), -- subject, 256); -- -- X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert), -- NID_commonName, cn_str, 256); -- -- dbglog("Certificate verification error:\n depth: %d CN: %s" -- "\n err: %d (%s)\n", depth, cn_str, err, -- X509_verify_cert_error_string(err)); -- -- return 0; -- } -- -- ssl = X509_STORE_CTX_get_ex_data(ctx, -- SSL_get_ex_data_X509_STORE_CTX_idx()); -- -- ets = (struct eaptls_session *)SSL_get_ex_data(ssl, 0); -- -- if (ets == NULL) { -- error("Error: SSL_get_ex_data returned NULL"); -- return 0; -- } -- -- log_ssl_errors(); -- -- if (!depth) { /* This is the peer certificate */ -- -- X509_NAME_oneline(X509_get_subject_name(peer_cert), -- subject, 256); -- -- X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert), -- NID_commonName, cn_str, 256); -- -- /* -- * If acting as client and the name of the server wasn't specified -- * explicitely, we can't verify the server authenticity -- */ -- if (!ets->peer[0]) { -- warn("Peer name not specified: no check"); -- return 1; -- } -- -- /* -- * Check the CN -- */ -- if (strcmp(cn_str, ets->peer)) { -- error -- ("Certificate verification error: CN (%s) != peer_name (%s)", -- cn_str, ets->peer); -- return 0; -- } -- -- warn("Certificate CN: %s , peer name %s", cn_str, ets->peer); -- -- /* -- * If a peer certificate file was specified, here we check it -- */ -- if (ets->peercertfile[0]) { -- if (ssl_cmp_certs(&ets->peercertfile[0], peer_cert) -- != 0) { -- error -- ("Peer certificate doesn't match stored certificate"); -- return 0; -- } -- } -- } -- -- return 1; --} -- --/* -- * Compare a certificate with the one stored in a file -- */ --int ssl_cmp_certs(char *filename, X509 * a) --{ -- X509 *b; -- int ret; -- -- if (!(b = get_X509_from_file(filename))) -- return 1; -- -- ret = X509_cmp(a, b); -- X509_free(b); -- -- return ret; -- --} -- --X509 *get_X509_from_file(char *filename) --{ -- FILE *fp; -- X509 *ret; -- -- if (!(fp = fopen(filename, "r"))) -- return NULL; -- -- ret = PEM_read_X509(fp, NULL, NULL, NULL); -- -- fclose(fp); -- -- return ret; --} -- --/* -- * Every sent & received message this callback function is invoked, -- * so we know when alert messages have arrived or are sent and -- * we can print debug information about TLS handshake. -- */ --void --ssl_msg_callback(int write_p, int version, int content_type, -- const void *buf, size_t len, SSL * ssl, void *arg) --{ -- char string[256]; -- struct eaptls_session *ets = (struct eaptls_session *)arg; -- unsigned char code; -- -- if(write_p) -- strcpy(string, " -> "); -- else -- strcpy(string, " <- "); -- -- -- switch(content_type) { -- -- case SSL3_RT_ALERT: -- strcat(string, "Alert: "); -- code = ((const unsigned char *)buf)[1]; -- -- if (write_p) { -- ets->alert_sent = 1; -- ets->alert_sent_desc = code; -- } else { -- ets->alert_recv = 1; -- ets->alert_recv_desc = code; -- } -- -- strcat(string, SSL_alert_desc_string_long(code)); -- break; -- -- case SSL3_RT_CHANGE_CIPHER_SPEC: -- strcat(string, "ChangeCipherSpec"); -- break; -- -- case SSL3_RT_HANDSHAKE: -- -- strcat(string, "Handshake: "); -- code = ((const unsigned char *)buf)[0]; -- -- switch(code) { -- case SSL3_MT_HELLO_REQUEST: -- strcat(string,"Hello Request"); -- break; -- case SSL3_MT_CLIENT_HELLO: -- strcat(string,"Client Hello"); -- break; -- case SSL3_MT_SERVER_HELLO: -- strcat(string,"Server Hello"); -- break; -- case SSL3_MT_CERTIFICATE: -- strcat(string,"Certificate"); -- break; -- case SSL3_MT_SERVER_KEY_EXCHANGE: -- strcat(string,"Server Key Exchange"); -- break; -- case SSL3_MT_CERTIFICATE_REQUEST: -- strcat(string,"Certificate Request"); -- break; -- case SSL3_MT_SERVER_DONE: -- strcat(string,"Server Hello Done"); -- break; -- case SSL3_MT_CERTIFICATE_VERIFY: -- strcat(string,"Certificate Verify"); -- break; -- case SSL3_MT_CLIENT_KEY_EXCHANGE: -- strcat(string,"Client Key Exchange"); -- break; -- case SSL3_MT_FINISHED: -- strcat(string,"Finished"); -- break; -- -- default: -- sprintf( string, "Handshake: Unknown SSL3 code received: %d", code ); -- } -- break; -- -- default: -- sprintf( string, "SSL message contains unknown content type: %d", content_type ); -- -- } -- -- /* Alert messages must always be displayed */ -- if(content_type == SSL3_RT_ALERT) -- error("%s", string); -- else -- dbglog("%s", string); --} -- -diff --git a/pppd/eap-tls.h b/pppd/eap-tls.h -deleted file mode 100644 -index 2d45a0b..0000000 ---- a/pppd/eap-tls.h -+++ /dev/null -@@ -1,107 +0,0 @@ --/* -- * 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 --#include --#include -- --#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 -diff --git a/pppd/eap.c b/pppd/eap.c -index e2270af..faced53 100644 ---- a/pppd/eap.c -+++ b/pppd/eap.c -@@ -43,11 +43,6 @@ - * 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 $" - - /* -@@ -67,12 +62,8 @@ - - #include "pppd.h" - #include "pathnames.h" --#include "eap.h" --#ifdef USE_EAPTLS --#include "eap-tls.h" --#else - #include "md5.h" --#endif /* USE_EAPTLS */ -+#include "eap.h" - - #ifdef USE_SRP - #include -@@ -218,9 +209,6 @@ 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 */ - } - - /* -@@ -280,7 +268,7 @@ eap_state *esp; - u_char *outp; - - outp = outpacket_buf; -- -+ - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_FAILURE, outp); -@@ -305,7 +293,7 @@ eap_state *esp; - u_char *outp; - - outp = outpacket_buf; -- -+ - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_SUCCESS, outp); -@@ -448,16 +436,8 @@ 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; -@@ -582,81 +562,9 @@ 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(SSL_is_init_finished(ets->ssl)) { -- esp->es_server.ea_state = eapTlsRecvClient; -- break; -- } -- -- if(ets->frag) -- esp->es_server.ea_state = eapTlsRecvAck; -- 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; -@@ -773,7 +681,7 @@ eap_state *esp; - } - - outp = outpacket_buf; -- -+ - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_REQUEST, outp); -@@ -810,30 +718,6 @@ 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); -@@ -1020,57 +904,11 @@ 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); - } -@@ -1243,7 +1081,7 @@ int namelen; - int msglen; - - outp = outpacket_buf; -- -+ - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); -@@ -1279,7 +1117,7 @@ int lenstr; - int msglen; - - outp = outpacket_buf; -- -+ - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); -@@ -1310,7 +1148,7 @@ u_char *str; - int msglen; - - outp = outpacket_buf; -- -+ - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); -@@ -1328,81 +1166,6 @@ 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; -@@ -1557,11 +1320,6 @@ 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; -@@ -1698,90 +1456,6 @@ int len; - esp->es_client.ea_namelen); - break; - --#ifdef USE_EAPTLS -- case EAPT_TLS: -- -- switch(esp->es_client.ea_state) { -- -- case eapListen: -- -- 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: -- 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) { -@@ -2063,11 +1737,6 @@ 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); -@@ -2107,60 +1776,6 @@ 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 */ -- -- 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 */ -- eaptls_receive(esp->es_server.ea_session, inp, len); -- warn("Server authentication failed"); -- eap_send_failure(esp); -- } -- -- 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; -@@ -2192,13 +1807,6 @@ 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) { -@@ -2410,27 +2018,13 @@ u_char *inp; - int id; - int len; - { -- if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp) --#ifdef USE_EAPTLS -- && esp->es_client.ea_state != eapTlsRecvSuccess --#endif /* USE_EAPTLS */ -- ) { -+ if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)) { - 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); - } -@@ -2556,9 +2150,6 @@ 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); -@@ -2623,24 +2214,6 @@ 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; -@@ -2752,25 +2325,6 @@ 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, " "); -diff --git a/pppd/eap.h b/pppd/eap.h -index 3fa5391..199d184 100644 ---- a/pppd/eap.h -+++ b/pppd/eap.h -@@ -84,16 +84,6 @@ 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 */ -@@ -105,18 +95,9 @@ 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" - --#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_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) -@@ -131,17 +112,11 @@ 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 - }; - - /* -@@ -164,12 +139,7 @@ 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 */ - -diff --git a/pppd/md5.c b/pppd/md5.c -index 2ee0c80..f1291ce 100644 ---- a/pppd/md5.c -+++ b/pppd/md5.c -@@ -33,8 +33,6 @@ - *********************************************************************** - */ - --#ifndef USE_EAPTLS -- - #include - #include "md5.h" - -@@ -307,4 +305,3 @@ UINT4 *in; - ** End of md5.c ** - ******************************** (cut) ******************************** - */ --#endif /* USE_EAPTLS */ -diff --git a/pppd/md5.h b/pppd/md5.h -index 14d7121..71e8b00 100644 ---- a/pppd/md5.h -+++ b/pppd/md5.h -@@ -36,7 +36,6 @@ - ** documentation and/or software. ** - *********************************************************************** - */ --#ifndef USE_EAPTLS - - #ifndef __MD5_INCLUDE__ - -@@ -64,5 +63,3 @@ void MD5_Final (unsigned char hash[], MD5_CTX *mdContext); - - #define __MD5_INCLUDE__ - #endif /* __MD5_INCLUDE__ */ -- --#endif /* USE_EAPTLS */ -diff --git a/pppd/options.c b/pppd/options.c -index 6915b2d..8e62635 100644 ---- a/pppd/options.c -+++ b/pppd/options.c -@@ -120,10 +120,6 @@ bool dump_options; /* print out option values */ - bool dryrun; /* print out option values and exit */ - char *domain; /* domain name set by domain option */ - int child_wait = 5; /* # seconds to wait for children at exit */ --#ifdef USE_EAPTLS --bool only_update_crl_server = 0; /* update server crl and exit */ --bool only_update_crl_client = 0; /* update client crl and exit */ --#endif /* USE_EAPTLS */ - struct userenv *userenv_list; /* user environment variables */ - - #ifdef MAXOCTETS -@@ -342,12 +338,6 @@ option_t general_options[] = { - { "mo-timeout", o_int, &maxoctets_timeout, - "Check for traffic limit every N seconds", OPT_PRIO | OPT_LLIMIT | 1 }, - #endif --#ifdef USE_EAPTLS -- { "only-update-crl-server", o_bool, &only_update_crl_server, -- "Update server CA CRLs and exit", 1 }, -- { "only-update-crl-client", o_bool, &only_update_crl_client, -- "Update client CA CRLs and exit", 1 }, --#endif /* USE_EAPTLS */ - - { NULL } - }; -diff --git a/pppd/pathnames.h b/pppd/pathnames.h -index 6275df6..24e010c 100644 ---- a/pppd/pathnames.h -+++ b/pppd/pathnames.h -@@ -22,13 +22,6 @@ - #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" -diff --git a/pppd/plugins/Makefile.linux b/pppd/plugins/Makefile.linux -index 760cad4..b474a19 100644 ---- a/pppd/plugins/Makefile.linux -+++ b/pppd/plugins/Makefile.linux -@@ -4,9 +4,6 @@ CFLAGS = $(COPTS) -I.. -I../../include -fPIC - LDFLAGS = -shared - INSTALL = install - --# EAP-TLS --CFLAGS += -DUSE_EAPTLS=1 -- - DESTDIR = $(INSTROOT)@DESTDIR@ - BINDIR = $(DESTDIR)/sbin - MANDIR = $(DESTDIR)/share/man/man8 -diff --git a/pppd/plugins/passprompt.c b/pppd/plugins/passprompt.c -index 6ba73ca..babb6dc 100644 ---- a/pppd/plugins/passprompt.c -+++ b/pppd/plugins/passprompt.c -@@ -107,7 +107,4 @@ void plugin_init(void) - { - add_options(options); - pap_passwd_hook = promptpass; --#ifdef USE_EAPTLS -- eaptls_passwd_hook = promptpass; --#endif - } -diff --git a/pppd/plugins/passwordfd.c b/pppd/plugins/passwordfd.c -index c3f9793..d718f3b 100644 ---- a/pppd/plugins/passwordfd.c -+++ b/pppd/plugins/passwordfd.c -@@ -79,8 +79,4 @@ void plugin_init (void) - - chap_check_hook = pwfd_check; - chap_passwd_hook = pwfd_passwd; -- --#ifdef USE_EAPTLS -- eaptls_passwd_hook = pwfd_passwd; --#endif - } -diff --git a/pppd/pppd.h b/pppd/pppd.h -index aaddba1..5f72f72 100644 ---- a/pppd/pppd.h -+++ b/pppd/pppd.h -@@ -324,10 +324,6 @@ 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; --#endif /* USE_EAPTLS */ -- - #ifdef MAXOCTETS - extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ - extern int maxoctets_dir; /* Direction : -@@ -742,10 +738,6 @@ 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)); --- -1.8.3.1 - diff --git a/0027-pppd-EAP-TLS-patch-v0.999.patch b/ppp-2.4.7-eaptls-mppe-1.101.patch similarity index 93% rename from 0027-pppd-EAP-TLS-patch-v0.999.patch rename to ppp-2.4.7-eaptls-mppe-1.101.patch index 2f71a8e..127fcf8 100644 --- a/0027-pppd-EAP-TLS-patch-v0.999.patch +++ b/ppp-2.4.7-eaptls-mppe-1.101.patch @@ -1,7 +1,7 @@ -diff -Naur ppp-2.4.7/README.eap-tls ppp-2.4.7-eaptls-mppe-0.999/README.eap-tls +diff -Naur ppp-2.4.7/README.eap-tls ppp-2.4.7-eaptls-mppe-1.101b/README.eap-tls --- ppp-2.4.7/README.eap-tls 1970-01-01 01:00:00.000000000 +0100 -+++ ppp-2.4.7-eaptls-mppe-0.999/README.eap-tls 2017-05-09 14:38:55.129084488 +0200 -@@ -0,0 +1,280 @@ ++++ ppp-2.4.7-eaptls-mppe-1.101b/README.eap-tls 2018-06-02 01:42:04.021165440 +0200 +@@ -0,0 +1,286 @@ +EAP-TLS authentication support for PPP +====================================== + @@ -277,14 +277,20 @@ diff -Naur ppp-2.4.7/README.eap-tls ppp-2.4.7-eaptls-mppe-0.999/README.eap-tls +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 option and provide an example. ++ - 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. ++ - Change SSL_OP_NO_TICKETS to SSL_OP_NO_TICKET ++ - Fix bug in initialisation code with fragmented packets. ++v0.998 (13-Mar-2015) ++ - Added fix for https://bugzilla.redhat.com/show_bug.cgi?id=1023620 ++v0.999 (11-May-2017) ++ - Added 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. + -diff -Naur ppp-2.4.7/etc.ppp/eaptls-client ppp-2.4.7-eaptls-mppe-0.999/etc.ppp/eaptls-client +diff -Naur ppp-2.4.7/etc.ppp/eaptls-client ppp-2.4.7-eaptls-mppe-1.101b/etc.ppp/eaptls-client --- ppp-2.4.7/etc.ppp/eaptls-client 1970-01-01 01:00:00.000000000 +0100 -+++ ppp-2.4.7-eaptls-mppe-0.999/etc.ppp/eaptls-client 2017-05-09 14:38:55.129084488 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/etc.ppp/eaptls-client 2018-06-02 01:42:04.021165440 +0200 @@ -0,0 +1,10 @@ +# Parameters for authentication using EAP-TLS (client) + @@ -296,9 +302,9 @@ diff -Naur ppp-2.4.7/etc.ppp/eaptls-client ppp-2.4.7-eaptls-mppe-0.999/etc.ppp/e +# client private key file (required) + +#client server /root/cert/client.crt - /root/cert/ca.crt /root/cert/client.key -diff -Naur ppp-2.4.7/etc.ppp/eaptls-server ppp-2.4.7-eaptls-mppe-0.999/etc.ppp/eaptls-server +diff -Naur ppp-2.4.7/etc.ppp/eaptls-server ppp-2.4.7-eaptls-mppe-1.101b/etc.ppp/eaptls-server --- ppp-2.4.7/etc.ppp/eaptls-server 1970-01-01 01:00:00.000000000 +0100 -+++ ppp-2.4.7-eaptls-mppe-0.999/etc.ppp/eaptls-server 2017-05-09 14:38:55.137084099 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/etc.ppp/eaptls-server 2018-06-02 01:42:04.021165440 +0200 @@ -0,0 +1,11 @@ +# Parameters for authentication using EAP-TLS (server) + @@ -311,9 +317,9 @@ diff -Naur ppp-2.4.7/etc.ppp/eaptls-server ppp-2.4.7-eaptls-mppe-0.999/etc.ppp/e +# allowed addresses (required, can be *) + +#client server - /root/cert/server.crt /root/cert/ca.crt /root/cert/server.key 192.168.1.0/24 -diff -Naur ppp-2.4.7/etc.ppp/openssl.cnf ppp-2.4.7-eaptls-mppe-0.999/etc.ppp/openssl.cnf +diff -Naur ppp-2.4.7/etc.ppp/openssl.cnf ppp-2.4.7-eaptls-mppe-1.101b/etc.ppp/openssl.cnf --- ppp-2.4.7/etc.ppp/openssl.cnf 1970-01-01 01:00:00.000000000 +0100 -+++ ppp-2.4.7-eaptls-mppe-0.999/etc.ppp/openssl.cnf 2017-05-09 14:38:55.137084099 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/etc.ppp/openssl.cnf 2018-06-02 01:42:04.021165440 +0200 @@ -0,0 +1,14 @@ +openssl_conf = openssl_def + @@ -329,9 +335,9 @@ diff -Naur ppp-2.4.7/etc.ppp/openssl.cnf ppp-2.4.7-eaptls-mppe-0.999/etc.ppp/ope +MODULE_PATH = /usr/lib64/libeTPkcs11.so +init = 0 + -diff -Naur ppp-2.4.7/linux/Makefile.top ppp-2.4.7-eaptls-mppe-0.999/linux/Makefile.top +diff -Naur ppp-2.4.7/linux/Makefile.top ppp-2.4.7-eaptls-mppe-1.101b/linux/Makefile.top --- ppp-2.4.7/linux/Makefile.top 2014-08-09 14:31:39.000000000 +0200 -+++ ppp-2.4.7-eaptls-mppe-0.999/linux/Makefile.top 2017-05-09 14:38:55.138084052 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/linux/Makefile.top 2018-06-02 01:42:04.021165440 +0200 @@ -26,7 +26,7 @@ cd pppdump; $(MAKE) $(MFLAGS) install @@ -352,9 +358,9 @@ diff -Naur ppp-2.4.7/linux/Makefile.top ppp-2.4.7-eaptls-mppe-0.999/linux/Makefi $(BINDIR): $(INSTALL) -d -m 755 $@ -diff -Naur ppp-2.4.7/pppd/Makefile.linux ppp-2.4.7-eaptls-mppe-0.999/pppd/Makefile.linux +diff -Naur ppp-2.4.7/pppd/Makefile.linux ppp-2.4.7-eaptls-mppe-1.101b/pppd/Makefile.linux --- ppp-2.4.7/pppd/Makefile.linux 2014-08-09 14:31:39.000000000 +0200 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/Makefile.linux 2017-05-09 14:38:55.138084052 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/Makefile.linux 2018-06-02 01:42:04.021165440 +0200 @@ -76,6 +76,9 @@ # Use libutil USE_LIBUTIL=y @@ -381,9 +387,9 @@ diff -Naur ppp-2.4.7/pppd/Makefile.linux ppp-2.4.7-eaptls-mppe-0.999/pppd/Makefi ifdef HAS_SHADOW CFLAGS += -DHAS_SHADOW #LIBS += -lshadow $(LIBS) -diff -Naur ppp-2.4.7/pppd/auth.c ppp-2.4.7-eaptls-mppe-0.999/pppd/auth.c +diff -Naur ppp-2.4.7/pppd/auth.c ppp-2.4.7-eaptls-mppe-1.101b/pppd/auth.c --- ppp-2.4.7/pppd/auth.c 2014-08-09 14:31:39.000000000 +0200 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/auth.c 2017-05-09 14:38:55.139084004 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/auth.c 2018-06-02 01:42:04.022165436 +0200 @@ -109,6 +109,9 @@ #include "upap.h" #include "chap-new.h" @@ -879,9 +885,9 @@ diff -Naur ppp-2.4.7/pppd/auth.c ppp-2.4.7-eaptls-mppe-0.999/pppd/auth.c +} +#endif + -diff -Naur ppp-2.4.7/pppd/ccp.c ppp-2.4.7-eaptls-mppe-0.999/pppd/ccp.c +diff -Naur ppp-2.4.7/pppd/ccp.c ppp-2.4.7-eaptls-mppe-1.101b/pppd/ccp.c --- ppp-2.4.7/pppd/ccp.c 2014-08-09 14:31:39.000000000 +0200 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/ccp.c 2017-05-09 14:38:55.148083482 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/ccp.c 2018-06-02 01:42:04.022165436 +0200 @@ -540,6 +540,9 @@ if (go->mppe) { ccp_options *ao = &ccp_allowoptions[f->unit]; @@ -917,9 +923,9 @@ diff -Naur ppp-2.4.7/pppd/ccp.c ppp-2.4.7-eaptls-mppe-0.999/pppd/ccp.c lcp_close(f->unit, "MPPE required but not available"); return; } -diff -Naur ppp-2.4.7/pppd/chap-md5.c ppp-2.4.7-eaptls-mppe-0.999/pppd/chap-md5.c +diff -Naur ppp-2.4.7/pppd/chap-md5.c ppp-2.4.7-eaptls-mppe-1.101b/pppd/chap-md5.c --- ppp-2.4.7/pppd/chap-md5.c 2014-08-09 14:31:39.000000000 +0200 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/chap-md5.c 2017-05-09 14:38:55.148083482 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/chap-md5.c 2018-06-02 01:42:04.022165436 +0200 @@ -36,7 +36,11 @@ #include "chap-new.h" #include "chap-md5.h" @@ -932,10 +938,10 @@ diff -Naur ppp-2.4.7/pppd/chap-md5.c ppp-2.4.7-eaptls-mppe-0.999/pppd/chap-md5.c #define MD5_HASH_SIZE 16 #define MD5_MIN_CHALLENGE 16 -diff -Naur ppp-2.4.7/pppd/eap-tls.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.c +diff -Naur ppp-2.4.7/pppd/eap-tls.c ppp-2.4.7-eaptls-mppe-1.101b/pppd/eap-tls.c --- ppp-2.4.7/pppd/eap-tls.c 1970-01-01 01:00:00.000000000 +0100 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.c 2017-05-11 10:43:00.345739124 +0200 -@@ -0,0 +1,1308 @@ ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/eap-tls.c 2018-06-02 01:42:16.790124406 +0200 +@@ -0,0 +1,1313 @@ +/* + * eap-tls.c - EAP-TLS implementation for PPP + * @@ -1000,6 +1006,7 @@ diff -Naur ppp-2.4.7/pppd/eap-tls.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.c + * tries to provide some guidance but ultimately falls short. + */ + ++ +static void HMAC_CTX_free(HMAC_CTX *ctx) +{ + if (ctx != NULL) { @@ -1803,46 +1810,47 @@ diff -Naur ppp-2.4.7/pppd/eap-tls.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.c +int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len) +{ + u_char flags; -+ u_int tlslen; ++ u_int tlslen = 0; + u_char dummy[65536]; + ++ if (len < 1) { ++ warn("EAP-TLS: received no or invalid data"); ++ return 1; ++ } ++ + GETCHAR(flags, inp); + len--; + -+ if (flags & EAP_TLS_FLAGS_LI && !ets->data) { -+ ++ if (flags & EAP_TLS_FLAGS_LI && len >= 4) { + /* -+ * This is the first packet of a message ++ * LenghtIncluded flag set -> this is the first packet of a message + */ -+ ++ ++ /* ++ * the first 4 octets are the length of the EAP-TLS message ++ */ + GETLONG(tlslen, inp); + len -= 4; + -+ if (tlslen > EAP_TLS_MAX_LEN) { -+ error("Error: tls message length > %d, truncated", -+ EAP_TLS_MAX_LEN); -+ tlslen = EAP_TLS_MAX_LEN; ++ if (!ets->data) { ++ ++ if (tlslen > EAP_TLS_MAX_LEN) { ++ error("EAP-TLS: TLS message length > %d, truncated", EAP_TLS_MAX_LEN); ++ tlslen = EAP_TLS_MAX_LEN; ++ } ++ ++ /* ++ * Allocate memory for the whole message ++ */ ++ ets->data = malloc(tlslen); ++ if (!ets->data) ++ fatal("EAP-TLS: allocation error\n"); ++ ++ ets->datalen = 0; ++ ets->tlslen = tlslen; + } -+ -+ /* -+ * Allocate memory for the whole message -+ */ -+ ets->data = malloc(tlslen); -+ if (!ets->data) -+ fatal("EAP TLS: allocation error\n"); -+ -+ ets->datalen = 0; -+ ets->tlslen = tlslen; -+ -+ } -+ else if (flags & EAP_TLS_FLAGS_LI && ets->data) { -+ /* -+ * Non first with LI (strange...) -+ */ -+ -+ GETLONG(tlslen, inp); -+ len -= 4; -+ ++ else ++ warn("EAP-TLS: non-first LI packet? that's odd..."); + } + else if (!ets->data) { + /* @@ -1851,7 +1859,7 @@ diff -Naur ppp-2.4.7/pppd/eap-tls.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.c + + ets->data = malloc(len); + if (!ets->data) -+ fatal("EAP TLS: allocation error\n"); ++ fatal("EAP-TLS: allocation error\n"); + + ets->datalen = 0; + ets->tlslen = len; @@ -1862,8 +1870,13 @@ diff -Naur ppp-2.4.7/pppd/eap-tls.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.c + else + ets->frag = 0; + ++ if (len < 0) { ++ warn("EAP-TLS: received malformed data"); ++ return 1; ++ } ++ + if (len + ets->datalen > ets->tlslen) { -+ warn("EAP TLS: received data > TLS message length"); ++ warn("EAP-TLS: received data > TLS message length"); + return 1; + } + @@ -1877,7 +1890,7 @@ diff -Naur ppp-2.4.7/pppd/eap-tls.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.c + */ + + if (ets->datalen != ets->tlslen) { -+ warn("EAP TLS: received data != TLS message length"); ++ warn("EAP-TLS: received data != TLS message length"); + return 1; + } + @@ -2138,7 +2151,6 @@ diff -Naur ppp-2.4.7/pppd/eap-tls.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.c + + switch(content_type) { + -+#if OPENSSL_VERSION_NUMBER >= 0x10100000L + case SSL3_RT_HEADER: + strcat(string, "SSL/TLS Header: "); + switch(hvers) { @@ -2164,7 +2176,6 @@ diff -Naur ppp-2.4.7/pppd/eap-tls.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.c + strcat(string, "Unknown version"); + } + break; -+#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ + + case SSL3_RT_ALERT: + strcat(string, "Alert: "); @@ -2244,9 +2255,9 @@ diff -Naur ppp-2.4.7/pppd/eap-tls.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.c + dbglog("%s", string); +} + -diff -Naur ppp-2.4.7/pppd/eap-tls.h ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.h +diff -Naur ppp-2.4.7/pppd/eap-tls.h ppp-2.4.7-eaptls-mppe-1.101b/pppd/eap-tls.h --- ppp-2.4.7/pppd/eap-tls.h 1970-01-01 01:00:00.000000000 +0100 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.h 2017-05-09 14:38:55.150083347 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/eap-tls.h 2018-06-02 01:42:04.023165433 +0200 @@ -0,0 +1,107 @@ +/* + * eap-tls.h @@ -2355,9 +2366,9 @@ diff -Naur ppp-2.4.7/pppd/eap-tls.h ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.h +#endif + +#endif -diff -Naur ppp-2.4.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c +diff -Naur ppp-2.4.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-1.101b/pppd/eap.c --- ppp-2.4.7/pppd/eap.c 2014-08-09 14:31:39.000000000 +0200 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c 2017-05-09 14:38:55.151083274 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/eap.c 2018-06-02 01:42:04.023165433 +0200 @@ -43,6 +43,11 @@ * Based on draft-ietf-pppext-eap-srp-03.txt. */ @@ -2674,7 +2685,7 @@ diff -Naur ppp-2.4.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c #ifdef USE_SRP struct t_client *tc; struct t_num sval, gval, Nval, *Ap, Bval; -@@ -1456,6 +1696,90 @@ +@@ -1456,6 +1696,100 @@ esp->es_client.ea_namelen); break; @@ -2685,6 +2696,11 @@ diff -Naur ppp-2.4.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c + + 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){ + @@ -2722,6 +2738,11 @@ diff -Naur ppp-2.4.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c + 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) { @@ -2765,7 +2786,7 @@ diff -Naur ppp-2.4.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c #ifdef USE_SRP case EAPT_SRP: if (len < 1) { -@@ -1737,6 +2061,11 @@ +@@ -1737,6 +2071,11 @@ u_char dig[SHA_DIGESTSIZE]; #endif /* USE_SRP */ @@ -2777,7 +2798,7 @@ diff -Naur ppp-2.4.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c if (esp->es_server.ea_id != id) { dbglog("EAP: discarding Response %d; expected ID %d", id, esp->es_server.ea_id); -@@ -1776,6 +2105,60 @@ +@@ -1776,6 +2115,64 @@ eap_figure_next_state(esp, 0); break; @@ -2786,6 +2807,7 @@ diff -Naur ppp-2.4.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c + 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)); @@ -2806,19 +2828,22 @@ diff -Naur ppp-2.4.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c + case eapTlsRecvClient: + /* Receive authentication response from client */ + -+ GETCHAR(flags, inp); ++ if (len > 0) { ++ GETCHAR(flags, inp); + -+ if(len == 1 && !flags) { /* Ack = ok */ ++ if(len == 1 && !flags) { /* Ack = ok */ +#ifdef MPPE -+ eaptls_gen_mppe_keys( esp->es_server.ea_session, "client EAP encryption", 0 ); ++ eaptls_gen_mppe_keys( esp->es_server.ea_session, "client EAP encryption", 0 ); +#endif -+ eap_send_success(esp); -+ } -+ else { /* failure */ -+ eaptls_receive(esp->es_server.ea_session, inp, len); -+ warn("Server authentication failed"); -+ eap_send_failure(esp); ++ 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); + @@ -2838,7 +2863,7 @@ diff -Naur ppp-2.4.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c case EAPT_NOTIFICATION: dbglog("EAP unexpected Notification; response discarded"); break; -@@ -1807,6 +2190,13 @@ +@@ -1807,6 +2204,13 @@ esp->es_server.ea_state = eapMD5Chall; break; @@ -2852,7 +2877,7 @@ diff -Naur ppp-2.4.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c default: dbglog("EAP: peer requesting unknown Type %d", vallen); switch (esp->es_server.ea_state) { -@@ -2018,13 +2408,27 @@ +@@ -2018,13 +2422,27 @@ int id; int len; { @@ -2881,7 +2906,7 @@ diff -Naur ppp-2.4.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c if (esp->es_client.ea_timeout > 0) { UNTIMEOUT(eap_client_timeout, (void *)esp); } -@@ -2150,6 +2554,9 @@ +@@ -2150,6 +2568,9 @@ int code, id, len, rtype, vallen; u_char *pstart; u_int32_t uval; @@ -2891,7 +2916,7 @@ diff -Naur ppp-2.4.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c if (inlen < EAP_HEADERLEN) return (0); -@@ -2214,6 +2621,24 @@ +@@ -2214,6 +2635,24 @@ } break; @@ -2916,7 +2941,7 @@ diff -Naur ppp-2.4.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c case EAPT_SRP: if (len < 3) goto truncated; -@@ -2325,6 +2750,25 @@ +@@ -2325,6 +2764,25 @@ } break; @@ -2942,14 +2967,14 @@ diff -Naur ppp-2.4.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c case EAPT_NAK: if (len <= 0) { printer(arg, " "); -@@ -2426,3 +2870,4 @@ +@@ -2426,3 +2884,4 @@ return (inp - pstart); } + -diff -Naur ppp-2.4.7/pppd/eap.h ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.h +diff -Naur ppp-2.4.7/pppd/eap.h ppp-2.4.7-eaptls-mppe-1.101b/pppd/eap.h --- ppp-2.4.7/pppd/eap.h 2014-08-09 14:31:39.000000000 +0200 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.h 2017-05-09 14:38:55.152083200 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/eap.h 2018-06-02 01:42:04.023165433 +0200 @@ -84,6 +84,16 @@ eapClosed, /* Authentication not in use */ eapListen, /* Client ready (and timer running) */ @@ -3018,9 +3043,9 @@ diff -Naur ppp-2.4.7/pppd/eap.h ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.h #define EAP_DEFREQTIME 20 /* Time to wait for peer request */ #define EAP_DEFALLOWREQ 20 /* max # times to accept requests */ -diff -Naur ppp-2.4.7/pppd/md5.c ppp-2.4.7-eaptls-mppe-0.999/pppd/md5.c +diff -Naur ppp-2.4.7/pppd/md5.c ppp-2.4.7-eaptls-mppe-1.101b/pppd/md5.c --- ppp-2.4.7/pppd/md5.c 2014-08-09 14:31:39.000000000 +0200 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/md5.c 2017-05-09 14:38:55.152083200 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/md5.c 2018-06-02 01:42:04.023165433 +0200 @@ -33,6 +33,8 @@ *********************************************************************** */ @@ -3036,9 +3061,9 @@ diff -Naur ppp-2.4.7/pppd/md5.c ppp-2.4.7-eaptls-mppe-0.999/pppd/md5.c */ +#endif /* USE_EAPTLS */ + -diff -Naur ppp-2.4.7/pppd/md5.h ppp-2.4.7-eaptls-mppe-0.999/pppd/md5.h +diff -Naur ppp-2.4.7/pppd/md5.h ppp-2.4.7-eaptls-mppe-1.101b/pppd/md5.h --- ppp-2.4.7/pppd/md5.h 2014-08-09 14:31:39.000000000 +0200 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/md5.h 2017-05-09 14:38:55.152083200 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/md5.h 2018-06-02 01:42:04.024165430 +0200 @@ -36,6 +36,7 @@ ** documentation and/or software. ** *********************************************************************** @@ -3053,9 +3078,9 @@ diff -Naur ppp-2.4.7/pppd/md5.h ppp-2.4.7-eaptls-mppe-0.999/pppd/md5.h #endif /* __MD5_INCLUDE__ */ + +#endif /* USE_EAPTLS */ -diff -Naur ppp-2.4.7/pppd/pathnames.h ppp-2.4.7-eaptls-mppe-0.999/pppd/pathnames.h +diff -Naur ppp-2.4.7/pppd/pathnames.h ppp-2.4.7-eaptls-mppe-1.101b/pppd/pathnames.h --- ppp-2.4.7/pppd/pathnames.h 2014-08-09 14:31:39.000000000 +0200 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/pathnames.h 2017-05-09 14:38:55.153083126 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/pathnames.h 2018-06-02 01:42:04.024165430 +0200 @@ -21,6 +21,13 @@ #define _PATH_UPAPFILE _ROOT_PATH "/etc/ppp/pap-secrets" #define _PATH_CHAPFILE _ROOT_PATH "/etc/ppp/chap-secrets" @@ -3070,9 +3095,9 @@ diff -Naur ppp-2.4.7/pppd/pathnames.h ppp-2.4.7-eaptls-mppe-0.999/pppd/pathnames #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" -diff -Naur ppp-2.4.7/pppd/plugins/Makefile.linux ppp-2.4.7-eaptls-mppe-0.999/pppd/plugins/Makefile.linux +diff -Naur ppp-2.4.7/pppd/plugins/Makefile.linux ppp-2.4.7-eaptls-mppe-1.101b/pppd/plugins/Makefile.linux --- ppp-2.4.7/pppd/plugins/Makefile.linux 2014-08-09 14:31:39.000000000 +0200 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/plugins/Makefile.linux 2017-05-09 14:38:55.153083126 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/plugins/Makefile.linux 2018-06-02 01:42:04.024165430 +0200 @@ -4,6 +4,9 @@ LDFLAGS = -shared INSTALL = install @@ -3083,9 +3108,9 @@ diff -Naur ppp-2.4.7/pppd/plugins/Makefile.linux ppp-2.4.7-eaptls-mppe-0.999/ppp DESTDIR = $(INSTROOT)@DESTDIR@ BINDIR = $(DESTDIR)/sbin MANDIR = $(DESTDIR)/share/man/man8 -diff -Naur ppp-2.4.7/pppd/plugins/passprompt.c ppp-2.4.7-eaptls-mppe-0.999/pppd/plugins/passprompt.c +diff -Naur ppp-2.4.7/pppd/plugins/passprompt.c ppp-2.4.7-eaptls-mppe-1.101b/pppd/plugins/passprompt.c --- ppp-2.4.7/pppd/plugins/passprompt.c 2014-08-09 14:31:39.000000000 +0200 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/plugins/passprompt.c 2017-05-09 14:38:55.153083126 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/plugins/passprompt.c 2018-06-02 01:42:04.024165430 +0200 @@ -107,4 +107,7 @@ { add_options(options); @@ -3094,9 +3119,9 @@ diff -Naur ppp-2.4.7/pppd/plugins/passprompt.c ppp-2.4.7-eaptls-mppe-0.999/pppd/ + eaptls_passwd_hook = promptpass; +#endif } -diff -Naur ppp-2.4.7/pppd/plugins/passwordfd.c ppp-2.4.7-eaptls-mppe-0.999/pppd/plugins/passwordfd.c +diff -Naur ppp-2.4.7/pppd/plugins/passwordfd.c ppp-2.4.7-eaptls-mppe-1.101b/pppd/plugins/passwordfd.c --- ppp-2.4.7/pppd/plugins/passwordfd.c 2014-08-09 14:31:39.000000000 +0200 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/plugins/passwordfd.c 2017-05-09 14:38:55.154083052 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/plugins/passwordfd.c 2018-06-02 01:42:04.024165430 +0200 @@ -79,4 +79,8 @@ chap_check_hook = pwfd_check; @@ -3106,9 +3131,9 @@ diff -Naur ppp-2.4.7/pppd/plugins/passwordfd.c ppp-2.4.7-eaptls-mppe-0.999/pppd/ + eaptls_passwd_hook = pwfd_passwd; +#endif } -diff -Naur ppp-2.4.7/pppd/pppd.8 ppp-2.4.7-eaptls-mppe-0.999/pppd/pppd.8 +diff -Naur ppp-2.4.7/pppd/pppd.8 ppp-2.4.7-eaptls-mppe-1.101b/pppd/pppd.8 --- ppp-2.4.7/pppd/pppd.8 2014-08-09 14:31:39.000000000 +0200 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/pppd.8 2017-05-09 14:38:55.155082978 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/pppd.8 2018-06-02 01:42:04.025165427 +0200 @@ -248,6 +248,12 @@ compression in the corresponding direction. Use \fInobsdcomp\fR or \fIbsdcomp 0\fR to disable BSD-Compress compression entirely. @@ -3177,9 +3202,9 @@ diff -Naur ppp-2.4.7/pppd/pppd.8 ppp-2.4.7-eaptls-mppe-0.999/pppd/pppd.8 .B noauth Do not require the peer to authenticate itself. This option is privileged. -diff -Naur ppp-2.4.7/pppd/pppd.h ppp-2.4.7-eaptls-mppe-0.999/pppd/pppd.h +diff -Naur ppp-2.4.7/pppd/pppd.h ppp-2.4.7-eaptls-mppe-1.101b/pppd/pppd.h --- ppp-2.4.7/pppd/pppd.h 2014-08-09 14:31:39.000000000 +0200 -+++ ppp-2.4.7-eaptls-mppe-0.999/pppd/pppd.h 2017-05-09 14:38:55.156082905 +0200 ++++ ppp-2.4.7-eaptls-mppe-1.101b/pppd/pppd.h 2018-06-02 01:42:04.025165427 +0200 @@ -325,6 +325,11 @@ extern bool dryrun; /* check everything, print options, exit */ extern int child_wait; /* # seconds to wait for children at end */ diff --git a/ppp.spec b/ppp.spec index 12d2add..c5b7aa6 100644 --- a/ppp.spec +++ b/ppp.spec @@ -3,7 +3,7 @@ Summary: The Point-to-Point Protocol daemon Name: ppp Version: 2.4.7 -Release: 21%{?dist} +Release: 22%{?dist} License: BSD and LGPLv2+ and GPLv2+ and Public Domain Group: System Environment/Daemons URL: http://www.samba.org/ppp @@ -38,7 +38,6 @@ Patch0013: 0013-everywhere-O_CLOEXEC-harder.patch Patch0014: 0014-everywhere-use-SOCK_CLOEXEC-when-creating-socket.patch Patch0015: 0015-pppd-move-pppd-database-to-var-run-ppp.patch Patch0016: 0016-rp-pppoe-add-manpage-for-pppoe-discovery.patch -Patch0017: 0017-pppd-rebase-EAP-TLS-patch-v0.994.patch Patch0018: 0018-scritps-fix-ip-up.local-sample.patch Patch0019: 0019-sys-linux-rework-get_first_ethernet.patch Patch0020: 0020-pppd-put-lock-files-in-var-lock-ppp.patch @@ -47,8 +46,7 @@ Patch0022: 0022-build-sys-compile-pppol2tp-with-multilink-support.patch Patch0023: 0023-build-sys-install-rp-pppoe-plugin-files-with-standar.patch Patch0024: 0024-build-sys-install-pppoatm-plugin-files-with-standard.patch Patch0025: 0025-pppd-install-pppd-binary-using-standard-perms-755.patch -Patch0026: 0026-Revert-pppd-rebase-EAP-TLS-patch-v0.994.patch -Patch0027: 0027-pppd-EAP-TLS-patch-v0.999.patch +Patch0026: ppp-2.4.7-eaptls-mppe-1.101.patch Patch0028: 0028-pppoe-include-netinet-in.h-before-linux-in.h.patch # rhbz#1556132 @@ -175,6 +173,10 @@ install -p %{SOURCE11} %{buildroot}%{_sysconfdir}/sysconfig/network-scripts/ifdo %doc PLUGINS %changelog +* Tue Jun 5 2018 Jaroslav Škarvada - 2.4.7-22 +- Updated EAP-TLS patch to v1.101 + Resolves: CVE-2018-11574 + * Mon Apr 9 2018 Jaroslav Škarvada - 2.4.7-21 - Link with -E not to break plugins Resolves: rhbz#1564459