Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 299059 Details for
Bug 399065
net-dialup/ppp-2.4.5 EAP-TLS patch update
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
Newest patch from Jan Just Keijser
ppp-2.4.5-eaptls-mppe-0.992.patch (text/plain), 76.75 KB, created by
Ladislav Zitka
on 2012-01-16 12:11:04 UTC
(
hide
)
Description:
Newest patch from Jan Just Keijser
Filename:
MIME Type:
Creator:
Ladislav Zitka
Created:
2012-01-16 12:11:04 UTC
Size:
76.75 KB
patch
obsolete
>diff -Naur ppp-2.4.5/README.eap-tls ppp-2.4.5-eaptls-mppe-0.992/README.eap-tls >--- ppp-2.4.5/README.eap-tls 1970-01-01 01:00:00.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/README.eap-tls 2011-12-01 15:14:39.020344767 +0100 >@@ -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: >+ <engine>:<identifier> >+ e.g. >+ pkcs11:123456 >+ >+ - The certificate can also be loaded from the 'pkcs11' engine using >+ a special client certificate filename in the /etc/ppp/eaptls-client file: >+ <engine>:<identifier> >+ e.g. >+ pkcs11:123456 >+ >+ - Create an /etc/ppp/openssl.cnf file to load the right OpenSSL engine prior >+ to starting 'pppd'. A sample openssl.cnf file is >+ >+ openssl_conf = openssl_def >+ >+ [ openssl_def ] >+ engines = engine_section >+ >+ [ engine_section ] >+ pkcs11 = pkcs11_section >+ >+ [ pkcs11_section ] >+ engine_id = pkcs11 >+ dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so >+ MODULE_PATH = /usr/lib64/libeTPkcs11.so >+ init = 0 >+ >+ - There are two ways to specify a password/PIN for the PKCS11 engine: >+ - inside the openssl.cnf file using >+ PIN = your-secret-pin >+ Note The keyword 'PIN' is case sensitive! >+ - Using the 'password' in the ppp options file. >+ From v0.97 of the eap-tls patch the password can also be supplied >+ using the appropriate 'eaptls_passwd_hook' (see plugins/passprompt.c >+ for an example). >+ >+ >+4. Options >+ >+ These pppd options are available: >+ >+ ca <ca-file> >+ Use the CA public certificate found in <ca-file> in PEM format >+ cert <cert-file> >+ Use the client public certificate found in <cert-file> in PEM format >+ or in engine:engine_id format >+ key <key-file> >+ Use the client private key found in <key-file> in PEM format >+ or in engine:engine_id format >+ crl-dir <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 <janjust@nikhef.nl> >+ >diff -Naur ppp-2.4.5/etc.ppp/eaptls-client ppp-2.4.5-eaptls-mppe-0.992/etc.ppp/eaptls-client >--- ppp-2.4.5/etc.ppp/eaptls-client 1970-01-01 01:00:00.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/etc.ppp/eaptls-client 2011-12-01 15:14:39.030346052 +0100 >@@ -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 -Naur ppp-2.4.5/etc.ppp/eaptls-server ppp-2.4.5-eaptls-mppe-0.992/etc.ppp/eaptls-server >--- ppp-2.4.5/etc.ppp/eaptls-server 1970-01-01 01:00:00.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/etc.ppp/eaptls-server 2011-12-01 15:14:39.038347081 +0100 >@@ -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 -Naur ppp-2.4.5/etc.ppp/openssl.cnf ppp-2.4.5-eaptls-mppe-0.992/etc.ppp/openssl.cnf >--- ppp-2.4.5/etc.ppp/openssl.cnf 1970-01-01 01:00:00.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/etc.ppp/openssl.cnf 2011-12-01 15:14:39.038347081 +0100 >@@ -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 -Naur ppp-2.4.5/linux/Makefile.top ppp-2.4.5-eaptls-mppe-0.992/linux/Makefile.top >--- ppp-2.4.5/linux/Makefile.top 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/linux/Makefile.top 2011-12-01 15:14:39.046348110 +0100 >@@ -26,7 +26,7 @@ > cd pppdump; $(MAKE) $(MFLAGS) install > > install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \ >- $(ETCDIR)/chap-secrets >+ $(ETCDIR)/chap-secrets $(ETCDIR)/eaptls-server $(ETCDIR)/eaptls-client > > install-devel: > cd pppd; $(MAKE) $(MFLAGS) install-devel >@@ -37,6 +37,10 @@ > $(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 -Naur ppp-2.4.5/pppd/Makefile.linux ppp-2.4.5-eaptls-mppe-0.992/pppd/Makefile.linux >--- ppp-2.4.5/pppd/Makefile.linux 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/Makefile.linux 2011-12-01 15:14:39.060349910 +0100 >@@ -33,7 +33,7 @@ > # CC = gcc > # > COPTS = -O2 -pipe -Wall -g >-LIBS = >+LIBS = > > # Uncomment the next 2 lines to include support for Microsoft's > # MS-CHAP authentication protocol. Also, edit plugins/radius/Makefile.linux. >@@ -73,6 +73,9 @@ > # Enable EAP SRP-SHA1 authentication (requires libsrp) > #USE_SRP=y > >+# Enable EAP-TLS authentication (requires libssl and libcrypto) >+USE_EAPTLS=y >+ > MAXOCTETS=y > > INCLUDE_DIRS= -I../include >@@ -112,6 +115,15 @@ > 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 -Naur ppp-2.4.5/pppd/auth.c ppp-2.4.5-eaptls-mppe-0.992/pppd/auth.c >--- ppp-2.4.5/pppd/auth.c 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/auth.c 2011-12-01 15:14:39.069351068 +0100 >@@ -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 @@ > /* 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_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_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 @@ > "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 } > }; > >@@ -731,6 +767,9 @@ > 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; > >@@ -765,6 +804,22 @@ > } > } > >+#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) { >@@ -1278,6 +1333,15 @@ > 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( >@@ -1332,7 +1396,11 @@ > 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)) >@@ -1347,8 +1415,14 @@ > !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; >+ > } > > >@@ -1706,6 +1780,7 @@ > } > > >+ > /* > * get_secret - open the CHAP secret file and return the secret > * for authenticating the given client on the given server. >@@ -2358,3 +2433,335 @@ > > 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 -Naur ppp-2.4.5/pppd/ccp.c ppp-2.4.5-eaptls-mppe-0.992/pppd/ccp.c >--- ppp-2.4.5/pppd/ccp.c 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/ccp.c 2011-12-01 15:14:39.078352226 +0100 >@@ -540,6 +540,9 @@ > 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 @@ > 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 -Naur ppp-2.4.5/pppd/chap-md5.c ppp-2.4.5-eaptls-mppe-0.992/pppd/chap-md5.c >--- ppp-2.4.5/pppd/chap-md5.c 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/chap-md5.c 2011-12-01 15:14:39.079352354 +0100 >@@ -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 -Naur ppp-2.4.5/pppd/eap-tls.c ppp-2.4.5-eaptls-mppe-0.992/pppd/eap-tls.c >--- ppp-2.4.5/pppd/eap-tls.c 1970-01-01 01:00:00.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/eap-tls.c 2011-12-01 15:14:39.080352482 +0100 >@@ -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 <string.h> >+#include <unistd.h> >+#include <sys/types.h> >+#include <sys/stat.h> >+#include <fcntl.h> >+ >+#include <openssl/conf.h> >+#include <openssl/engine.h> >+#include <openssl/hmac.h> >+#include <openssl/err.h> >+#include <openssl/x509v3.h> >+ >+#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 -Naur ppp-2.4.5/pppd/eap-tls.h ppp-2.4.5-eaptls-mppe-0.992/pppd/eap-tls.h >--- ppp-2.4.5/pppd/eap-tls.h 1970-01-01 01:00:00.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/eap-tls.h 2011-12-01 15:14:39.081352611 +0100 >@@ -0,0 +1,107 @@ >+/* >+ * eap-tls.h >+ * >+ * Copyright (c) Beniamino Galvani 2005 All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in >+ * the documentation and/or other materials provided with the >+ * distribution. >+ * >+ * 3. The name(s) of the authors of this software must not be used to >+ * endorse or promote products derived from this software without >+ * prior written permission. >+ * >+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO >+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY >+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY >+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES >+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN >+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING >+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. >+ * >+ */ >+ >+#ifndef __EAP_TLS_H__ >+#define __EAP_TLS_H__ >+ >+#include "eap.h" >+ >+#include <openssl/ssl.h> >+#include <openssl/bio.h> >+#include <openssl/md5.h> >+ >+#define EAP_TLS_FLAGS_LI 128 /* length included flag */ >+#define EAP_TLS_FLAGS_MF 64 /* more fragments flag */ >+#define EAP_TLS_FLAGS_START 32 /* start flag */ >+ >+#define EAP_TLS_MAX_LEN 65536 /* max eap tls packet size */ >+ >+struct eaptls_session >+{ >+ u_char *data; /* buffered data */ >+ int datalen; /* buffered data len */ >+ int offset; /* from where to send */ >+ int tlslen; /* total length of tls data */ >+ bool frag; /* packet is fragmented */ >+ SSL_CTX *ctx; >+ SSL *ssl; /* ssl connection */ >+ BIO *from_ssl; >+ BIO *into_ssl; >+ char peer[MAXWORDLEN]; /* peer name */ >+ char peercertfile[MAXWORDLEN]; >+ bool alert_sent; >+ u_char alert_sent_desc; >+ bool alert_recv; >+ u_char alert_recv_desc; >+ char rtx[65536]; /* retransmission buffer */ >+ int rtx_len; >+ int mtu; /* unit mtu */ >+}; >+ >+typedef struct pw_cb_data >+{ >+ const void *password; >+ const char *prompt_info; >+} PW_CB_DATA; >+ >+ >+int ssl_verify_callback(int, X509_STORE_CTX *); >+void ssl_msg_callback(int write_p, int version, int ct, const void *buf, >+ size_t len, SSL * ssl, void *arg); >+ >+X509 *get_X509_from_file(char *filename); >+int ssl_cmp_certs(char *filename, X509 * a); >+ >+SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, >+ char *certfile, char *peer_certfile, char *privkeyfile); >+int eaptls_init_ssl_server(eap_state * esp); >+int eaptls_init_ssl_client(eap_state * esp); >+void eaptls_free_session(struct eaptls_session *ets); >+ >+int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len); >+int eaptls_send(struct eaptls_session *ets, u_char ** outp); >+void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp); >+ >+int get_eaptls_secret(int unit, char *client, char *server, >+ char *clicertfile, char *servcertfile, char *cacertfile, >+ char *pkfile, int am_server); >+ >+#ifdef MPPE >+#include "mppe.h" /* MPPE_MAX_KEY_LEN */ >+extern u_char mppe_send_key[MPPE_MAX_KEY_LEN]; >+extern u_char mppe_recv_key[MPPE_MAX_KEY_LEN]; >+extern int mppe_keys_set; >+ >+void eaptls_gen_mppe_keys(struct eaptls_session *ets, const char *prf_label, int client); >+ >+#endif >+ >+#endif >diff -Naur ppp-2.4.5/pppd/eap.c ppp-2.4.5-eaptls-mppe-0.992/pppd/eap.c >--- ppp-2.4.5/pppd/eap.c 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/eap.c 2011-12-01 15:14:39.083352869 +0100 >@@ -43,6 +43,11 @@ > * Based on draft-ietf-pppext-eap-srp-03.txt. > */ > >+/* >+ * Modification by Beniamino Galvani, Mar 2005 >+ * Implemented EAP-TLS authentication >+ */ >+ > #define RCSID "$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $" > > /* >@@ -62,8 +67,12 @@ > > #include "pppd.h" > #include "pathnames.h" >-#include "md5.h" > #include "eap.h" >+#ifdef USE_EAPTLS >+#include "eap-tls.h" >+#else >+#include "md5.h" >+#endif /* USE_EAPTLS */ > > #ifdef USE_SRP > #include <t_pwd.h> >@@ -209,6 +218,9 @@ > esp->es_server.ea_id = (u_char)(drand48() * 0x100); > esp->es_client.ea_timeout = EAP_DEFREQTIME; > esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ; >+#ifdef USE_EAPTLS >+ esp->es_client.ea_using_eaptls = 0; >+#endif /* USE_EAPTLS */ > } > > /* >@@ -436,8 +448,16 @@ > 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 @@ > 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; >@@ -718,6 +810,30 @@ > 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 @@ > eap_server_timeout(arg) > void *arg; > { >+#ifdef USE_EAPTLS >+ u_char *outp; >+ u_char *lenloc; >+ int outlen; >+#endif /* USE_EAPTLS */ >+ > eap_state *esp = (eap_state *) arg; > > if (!eap_server_active(esp)) > return; > >+#ifdef USE_EAPTLS >+ switch(esp->es_server.ea_prev_state) { >+ >+ /* >+ * In eap-tls the state changes after a request, so we return to >+ * previous state ... >+ */ >+ case(eapTlsStart): >+ case(eapTlsSendAck): >+ esp->es_server.ea_state = esp->es_server.ea_prev_state; >+ break; >+ >+ /* >+ * ... or resend the stored data >+ */ >+ case(eapTlsSend): >+ case(eapTlsSendAlert): >+ outp = outpacket_buf; >+ MAKEHEADER(outp, PPP_EAP); >+ PUTCHAR(EAP_REQUEST, outp); >+ PUTCHAR(esp->es_server.ea_id, outp); >+ lenloc = outp; >+ INCPTR(2, outp); >+ >+ eaptls_retransmit(esp->es_server.ea_session, &outp); >+ >+ outlen = (outp - outpacket_buf) - PPP_HDRLEN; >+ PUTSHORT(outlen, lenloc); >+ output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN); >+ esp->es_server.ea_requests++; >+ >+ if (esp->es_server.ea_timeout > 0) >+ TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout); >+ >+ return; >+ default: >+ break; >+ } >+#endif /* USE_EAPTLS */ >+ > /* EAP ID number must not change on timeout. */ > eap_send_request(esp); > } >@@ -1166,6 +1328,81 @@ > } > #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 @@ > 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 @@ > 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 @@ > 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 @@ > 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 @@ > 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 @@ > 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 @@ > 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 @@ > } > 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 @@ > } > break; > >+#ifdef USE_EAPTLS >+ case EAPT_TLS: >+ if (len < 1) >+ break; >+ GETCHAR(flags, inp); >+ len--; >+ >+ if(flags == 0 && len == 0){ >+ printer(arg, " Ack"); >+ break; >+ } >+ >+ printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -"); >+ printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-"); >+ printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- "); >+ >+ break; >+#endif /* USE_EAPTLS */ >+ > case EAPT_NAK: > if (len <= 0) { > printer(arg, " <missing hint>"); >@@ -2426,3 +2872,4 @@ > > return (inp - pstart); > } >+ >diff -Naur ppp-2.4.5/pppd/eap.h ppp-2.4.5-eaptls-mppe-0.992/pppd/eap.h >--- ppp-2.4.5/pppd/eap.h 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/eap.h 2011-12-01 15:14:39.085353125 +0100 >@@ -84,6 +84,16 @@ > 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 @@ > > #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 @@ > 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 @@ > * 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 -Naur ppp-2.4.5/pppd/md5.c ppp-2.4.5-eaptls-mppe-0.992/pppd/md5.c >--- ppp-2.4.5/pppd/md5.c 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/md5.c 2011-12-01 15:14:39.086353254 +0100 >@@ -33,6 +33,8 @@ > *********************************************************************** > */ > >+#ifndef USE_EAPTLS >+ > #include <string.h> > #include "md5.h" > >@@ -305,3 +307,5 @@ > ** End of md5.c ** > ******************************** (cut) ******************************** > */ >+#endif /* USE_EAPTLS */ >+ >diff -Naur ppp-2.4.5/pppd/md5.h ppp-2.4.5-eaptls-mppe-0.992/pppd/md5.h >--- ppp-2.4.5/pppd/md5.h 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/md5.h 2011-12-01 15:14:39.086353254 +0100 >@@ -36,6 +36,7 @@ > ** documentation and/or software. ** > *********************************************************************** > */ >+#ifndef USE_EAPTLS > > #ifndef __MD5_INCLUDE__ > >@@ -63,3 +64,5 @@ > > #define __MD5_INCLUDE__ > #endif /* __MD5_INCLUDE__ */ >+ >+#endif /* USE_EAPTLS */ >diff -Naur ppp-2.4.5/pppd/options.c ppp-2.4.5-eaptls-mppe-0.992/pppd/options.c >--- ppp-2.4.5/pppd/options.c 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/options.c 2011-12-01 15:14:39.087353383 +0100 >@@ -119,6 +119,10 @@ > 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 */ > > #ifdef MAXOCTETS > unsigned int maxoctets = 0; /* default - no limit */ >@@ -320,6 +324,12 @@ > { "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 -Naur ppp-2.4.5/pppd/pathnames.h ppp-2.4.5-eaptls-mppe-0.992/pppd/pathnames.h >--- ppp-2.4.5/pppd/pathnames.h 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/pathnames.h 2011-12-01 15:14:39.088353512 +0100 >@@ -21,6 +21,13 @@ > #define _PATH_UPAPFILE _ROOT_PATH "/etc/ppp/pap-secrets" > #define _PATH_CHAPFILE _ROOT_PATH "/etc/ppp/chap-secrets" > #define _PATH_SRPFILE _ROOT_PATH "/etc/ppp/srp-secrets" >+ >+#ifdef USE_EAPTLS >+#define _PATH_EAPTLSCLIFILE _ROOT_PATH "/etc/ppp/eaptls-client" >+#define _PATH_EAPTLSSERVFILE _ROOT_PATH "/etc/ppp/eaptls-server" >+#define _PATH_OPENSSLCONFFILE _ROOT_PATH "/etc/ppp/openssl.cnf" >+#endif /* USE_EAPTLS */ >+ > #define _PATH_SYSOPTIONS _ROOT_PATH "/etc/ppp/options" > #define _PATH_IPUP _ROOT_PATH "/etc/ppp/ip-up" > #define _PATH_IPDOWN _ROOT_PATH "/etc/ppp/ip-down" >diff -Naur ppp-2.4.5/pppd/plugins/Makefile.linux ppp-2.4.5-eaptls-mppe-0.992/pppd/plugins/Makefile.linux >--- ppp-2.4.5/pppd/plugins/Makefile.linux 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/plugins/Makefile.linux 2011-12-01 15:14:39.089353640 +0100 >@@ -4,6 +4,9 @@ > LDFLAGS = -shared > INSTALL = install > >+# EAP-TLS >+CFLAGS += -DUSE_EAPTLS=1 >+ > DESTDIR = $(INSTROOT)@DESTDIR@ > BINDIR = $(DESTDIR)/sbin > MANDIR = $(DESTDIR)/share/man/man8 >diff -Naur ppp-2.4.5/pppd/plugins/passprompt.c ppp-2.4.5-eaptls-mppe-0.992/pppd/plugins/passprompt.c >--- ppp-2.4.5/pppd/plugins/passprompt.c 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/plugins/passprompt.c 2011-12-01 15:14:39.090353769 +0100 >@@ -107,4 +107,7 @@ > { > add_options(options); > pap_passwd_hook = promptpass; >+#ifdef USE_EAPTLS >+ eaptls_passwd_hook = promptpass; >+#endif > } >diff -Naur ppp-2.4.5/pppd/plugins/passwordfd.c ppp-2.4.5-eaptls-mppe-0.992/pppd/plugins/passwordfd.c >--- ppp-2.4.5/pppd/plugins/passwordfd.c 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/plugins/passwordfd.c 2011-12-01 15:16:39.158794111 +0100 >@@ -79,4 +79,8 @@ > > chap_check_hook = pwfd_check; > chap_passwd_hook = pwfd_passwd; >+ >+#ifdef USE_EAPTLS >+ eaptls_passwd_hook = pwfd_passwd; >+#endif > } >diff -Naur ppp-2.4.5/pppd/pppd.h ppp-2.4.5-eaptls-mppe-0.992/pppd/pppd.h >--- ppp-2.4.5/pppd/pppd.h 2009-11-16 23:26:07.000000000 +0100 >+++ ppp-2.4.5-eaptls-mppe-0.992/pppd/pppd.h 2011-12-01 15:16:25.296011439 +0100 >@@ -320,6 +320,10 @@ > 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 : >@@ -717,6 +721,10 @@ > 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));
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 399065
: 299059