]> git.ipfire.org Git - people/amarx/ipfire-3.x.git/blame - ppp/patches/ppp-2.4.5-eaptls-mppe-0.99.patch
Move all packages to root.
[people/amarx/ipfire-3.x.git] / ppp / patches / ppp-2.4.5-eaptls-mppe-0.99.patch
CommitLineData
0bc5d371
MT
1diff -Naur ppp-2.4.5/README.eap-tls ppp-2.4.5-eaptls-mppe-0.99/README.eap-tls
2--- ppp-2.4.5/README.eap-tls 1970-01-01 01:00:00.000000000 +0100
3+++ ppp-2.4.5-eaptls-mppe-0.99/README.eap-tls 2010-10-01 15:17:54.205272328 +0200
4@@ -0,0 +1,169 @@
5+EAP-TLS authentication support for PPP
6+======================================
7+
8+1. Intro
9+
10+ The Extensible Authentication Protocol (EAP; RFC 3748) is a
11+ security protocol that can be used with PPP. It provides a means
12+ to plug in multiple optional authentication methods.
13+
14+ Transport Level Security (TLS; RFC 2246) provides for mutual
15+ authentication, integrity-protected ciphersuite negotiation and
16+ key exchange between two endpoints. It also provides for optional
17+ MPPE encryption.
18+
19+ EAP-TLS (RFC 2716) incapsulates the TLS messages in EAP packets,
20+ allowing TLS mutual authentication to be used as a generic EAP
21+ mechanism. It also provides optional encryption using the MPPE
22+ protocol.
23+
24+ This patch provide EAP-TLS support to pppd.
25+ This authentication method can be used in both client or server
26+ mode.
27+
28+2. Building
29+
30+ To build pppd with EAP-TLS support, OpenSSL (http://www.openssl.org)
31+ is required. Any version from 0.9.7 should work.
32+
33+ Configure, compile, and install as usual.
34+
35+3. Configuration
36+
37+ On the client side there are two ways to configure EAP-TLS:
38+
39+ 1. supply the appropriate 'ca', 'cert' and 'key' command-line parameters
40+
41+ 2. edit the /etc/ppp/eaptls-client file.
42+ Insert a line for each system with which you use EAP-TLS.
43+ The line is composed of this fields separated by tab:
44+
45+ - Client name
46+ The name used by the client for authentication, can be *
47+ - Server name
48+ The name of the server, can be *
49+ - Client certificate file
50+ The file containing the certificate chain for the
51+ client in PEM format
52+ - Server certificate file
53+ If you want to specify the certificate that the
54+ server is allowed to use, put the certificate file name.
55+ Else put a dash '-'.
56+ - CA certificate file
57+ The file containing the trusted CA certificates in PEM
58+ format.
59+ - Client private key file
60+ The file containing the client private key in PEM format.
61+
62+
63+ On the server side edit the /etc/ppp/eaptls-server file.
64+ Insert a line for each system with which you use EAP-TLS.
65+ The line is composed of this fields separated by tab:
66+
67+ - Client name
68+ The name used by the client for authentication, can be *
69+ - Server name
70+ The name of the server, can be *
71+ - Client certificate file
72+ If you want to specify the certificate that the
73+ client is allowed to use, put the certificate file name.
74+ Else put a dash '-'.
75+ - Server certificate file
76+ The file containing the certificate chain for the
77+ server in PEM format
78+ - CA certificate file
79+ The file containing the trusted CA certificates in PEM
80+ format.
81+ - Client private key file
82+ The file containing the server private key in PEM format.
83+ - addresses
84+ A list of IP addresses the client is allowed to use.
85+
86+
87+ OpenSSL engine support is included starting with v0.95 of this patch.
88+ Currently the only engine tested is the 'pkcs11' engine (hardware token
89+ support). To use the 'pksc11' engine:
90+ - Use a special private key fileiname in the /etc/ppp/eaptls-client file:
91+ <engine>:<identifier>
92+ e.g.
93+ pkcs11:123456
94+
95+ - The certificate can also be loaded from the 'pkcs11' engine using
96+ a special client certificate filename in the /etc/ppp/eaptls-client file:
97+ <engine>:<identifier>
98+ e.g.
99+ pkcs11:123456
100+
101+ - Create an /etc/ppp/openssl.cnf file to load the right OpenSSL engine prior
102+ to starting 'pppd'. A sample openssl.cnf file is
103+
104+ openssl_conf = openssl_def
105+
106+ [ openssl_def ]
107+ engines = engine_section
108+
109+ [ engine_section ]
110+ pkcs11 = pkcs11_section
111+
112+ [ pkcs11_section ]
113+ engine_id = pkcs11
114+ dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so
115+ MODULE_PATH = /usr/lib64/libeTPkcs11.so
116+ init = 0
117+
118+ - There are two ways to specify a password/PIN for the PKCS11 engine:
119+ - inside the openssl.cnf file using
120+ PIN = your-secret-pin
121+ Note The keyword 'PIN' is case sensitive!
122+ - Using the 'password' in the ppp options file.
123+ From v0.97 of the eap-tls patch the password can also be supplied
124+ using the appropriate 'eaptls_passwd_hook' (see plugins/passprompt.c
125+ for an example).
126+
127+
128+4. Options
129+
130+ These pppd options are available:
131+
132+ ca <ca-file>
133+ Use the CA public certificate found in <ca-file> in PEM format
134+ cert <cert-file>
135+ Use the client public certificate found in <cert-file> in PEM format
136+ or in engine:engine_id format
137+ key <key-file>
138+ Use the client private key found in <key-file> in PEM format
139+ or in engine:engine_id format
140+ crl-dir <dir>
141+ Use CRL files from dir. It contains CRL files in PEM
142+ format and each file contains a CRL. The files are looked up
143+ by the issuer name hash value. Use the c_rehash utility
144+ to create necessary links.
145+ need-peer-eap
146+ If the peer doesn't ask us to authenticate or doesn't use eap
147+ to authenticate us, disconnect.
148+
149+ Note:
150+ password-encrypted certificates can be used as of v0.94 of this
151+ patch. The password for the eap-tls.key file is specified using
152+ the regular
153+ password ....
154+ statement in the ppp options file, or by using the appropriate
155+ plugin which supplies a 'eaptls_passwd_hook' routine.
156+
157+5. Connecting
158+
159+ If you're setting up a pppd server, edit the EAP-TLS configuration file
160+ as written above and then run pppd with the 'auth' option to authenticate
161+ the client. The EAP-TLS method will be used if the other eap methods can't
162+ be used (no secrets).
163+
164+ If you're setting up a client, edit the configuration file and then run
165+ pppd with 'remotename' option to specify the server name. Add the
166+ 'need-peer-eap' option if you want to be sure the peer ask you to
167+ authenticate (and to use eap) and to disconnect if it doesn't.
168+
169+6. Notes
170+
171+ This is experimental code.
172+ Send suggestions and comments to Jan Just Keijser <janjust@nikhef.nl>
173+
174diff -Naur ppp-2.4.5/etc.ppp/eaptls-client ppp-2.4.5-eaptls-mppe-0.99/etc.ppp/eaptls-client
175--- ppp-2.4.5/etc.ppp/eaptls-client 1970-01-01 01:00:00.000000000 +0100
176+++ ppp-2.4.5-eaptls-mppe-0.99/etc.ppp/eaptls-client 2010-10-01 15:17:54.205272328 +0200
177@@ -0,0 +1,10 @@
178+# Parameters for authentication using EAP-TLS (client)
179+
180+# client name (can be *)
181+# server name (can be *)
182+# client certificate file (required)
183+# server certificate file (optional, if unused put '-')
184+# CA certificate file (required)
185+# client private key file (required)
186+
187+#client server /root/cert/client.crt - /root/cert/ca.crt /root/cert/client.key
188diff -Naur ppp-2.4.5/etc.ppp/eaptls-server ppp-2.4.5-eaptls-mppe-0.99/etc.ppp/eaptls-server
189--- ppp-2.4.5/etc.ppp/eaptls-server 1970-01-01 01:00:00.000000000 +0100
190+++ ppp-2.4.5-eaptls-mppe-0.99/etc.ppp/eaptls-server 2010-10-01 15:17:54.205272328 +0200
191@@ -0,0 +1,11 @@
192+# Parameters for authentication using EAP-TLS (server)
193+
194+# client name (can be *)
195+# server name (can be *)
196+# client certificate file (optional, if unused put '-')
197+# server certificate file (required)
198+# CA certificate file (required)
199+# server private key file (required)
200+# allowed addresses (required, can be *)
201+
202+#client server - /root/cert/server.crt /root/cert/ca.crt /root/cert/server.key 192.168.1.0/24
203diff -Naur ppp-2.4.5/etc.ppp/openssl.cnf ppp-2.4.5-eaptls-mppe-0.99/etc.ppp/openssl.cnf
204--- ppp-2.4.5/etc.ppp/openssl.cnf 1970-01-01 01:00:00.000000000 +0100
205+++ ppp-2.4.5-eaptls-mppe-0.99/etc.ppp/openssl.cnf 2010-10-01 15:17:54.206272162 +0200
206@@ -0,0 +1,14 @@
207+openssl_conf = openssl_def
208+
209+[ openssl_def ]
210+engines = engine_section
211+
212+[ engine_section ]
213+pkcs11 = pkcs11_section
214+
215+[ pkcs11_section ]
216+engine_id = pkcs11
217+dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so
218+MODULE_PATH = /usr/lib64/libeTPkcs11.so
219+init = 0
220+
221diff -Naur ppp-2.4.5/linux/Makefile.top ppp-2.4.5-eaptls-mppe-0.99/linux/Makefile.top
222--- ppp-2.4.5/linux/Makefile.top 2009-11-16 23:26:07.000000000 +0100
223+++ ppp-2.4.5-eaptls-mppe-0.99/linux/Makefile.top 2010-10-01 15:17:54.206272162 +0200
224@@ -26,7 +26,7 @@
225 cd pppdump; $(MAKE) $(MFLAGS) install
226
227 install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \
228- $(ETCDIR)/chap-secrets
229+ $(ETCDIR)/chap-secrets $(ETCDIR)/eaptls-server $(ETCDIR)/eaptls-client
230
231 install-devel:
232 cd pppd; $(MAKE) $(MFLAGS) install-devel
233@@ -37,6 +37,10 @@
234 $(INSTALL) -c -m 600 etc.ppp/pap-secrets $@
235 $(ETCDIR)/chap-secrets:
236 $(INSTALL) -c -m 600 etc.ppp/chap-secrets $@
237+$(ETCDIR)/eaptls-server:
238+ $(INSTALL) -c -m 600 etc.ppp/eaptls-server $@
239+$(ETCDIR)/eaptls-client:
240+ $(INSTALL) -c -m 600 etc.ppp/eaptls-client $@
241
242 $(BINDIR):
243 $(INSTALL) -d -m 755 $@
244diff -Naur ppp-2.4.5/pppd/Makefile.linux ppp-2.4.5-eaptls-mppe-0.99/pppd/Makefile.linux
245--- ppp-2.4.5/pppd/Makefile.linux 2009-11-16 23:26:07.000000000 +0100
246+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/Makefile.linux 2010-10-01 15:17:54.207272272 +0200
247@@ -73,6 +73,9 @@
248 # Enable EAP SRP-SHA1 authentication (requires libsrp)
249 #USE_SRP=y
250
251+# Enable EAP-TLS authentication (requires libssl and libcurl)
252+USE_EAPTLS=y
253+
254 MAXOCTETS=y
255
256 INCLUDE_DIRS= -I../include
257@@ -112,6 +115,15 @@
258 PPPDOBJS += sha1.o
259 endif
260
261+# EAP-TLS
262+ifdef USE_EAPTLS
263+CFLAGS += -DUSE_EAPTLS=1 -I/usr/kerberos/include
264+LIBS += -lssl -lcrypto
265+PPPDSRC += eap-tls.c
266+HEADERS += eap-tls.h
267+PPPDOBJS += eap-tls.o
268+endif
269+
270 ifdef HAS_SHADOW
271 CFLAGS += -DHAS_SHADOW
272 #LIBS += -lshadow $(LIBS)
273diff -Naur ppp-2.4.5/pppd/auth.c ppp-2.4.5-eaptls-mppe-0.99/pppd/auth.c
274--- ppp-2.4.5/pppd/auth.c 2009-11-16 23:26:07.000000000 +0100
275+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/auth.c 2010-10-01 15:17:54.210272021 +0200
276@@ -109,6 +109,9 @@
277 #include "upap.h"
278 #include "chap-new.h"
279 #include "eap.h"
280+#ifdef USE_EAPTLS
281+#include "eap-tls.h"
282+#endif
283 #ifdef CBCP_SUPPORT
284 #include "cbcp.h"
285 #endif
286@@ -183,6 +186,11 @@
287 /* Hook for a plugin to get the CHAP password for authenticating us */
288 int (*chap_passwd_hook) __P((char *user, char *passwd)) = NULL;
289
290+#ifdef USE_EAPTLS
291+/* Hook for a plugin to get the EAP-TLS password for authenticating us */
292+int (*eaptls_passwd_hook) __P((char *user, char *passwd)) = NULL;
293+#endif
294+
295 /* Hook for a plugin to say whether it is OK if the peer
296 refuses to authenticate. */
297 int (*null_auth_hook) __P((struct wordlist **paddrs,
298@@ -238,6 +246,13 @@
299 bool explicit_user = 0; /* Set if "user" option supplied */
300 bool explicit_passwd = 0; /* Set if "password" option supplied */
301 char remote_name[MAXNAMELEN]; /* Peer's name for authentication */
302+#ifdef USE_EAPTLS
303+char *cacert_file = NULL; /* CA certificate file (pem format) */
304+char *cert_file = NULL; /* client certificate file (pem format) */
305+char *privkey_file = NULL; /* client private key file (pem format) */
306+char *crl_dir = NULL; /* directory containing CRL files */
307+bool need_peer_eap = 0; /* Require peer to authenticate us */
308+#endif
309
310 static char *uafname; /* name of most recent +ua file */
311
312@@ -254,6 +269,19 @@
313 static int have_chap_secret __P((char *, char *, int, int *));
314 static int have_srp_secret __P((char *client, char *server, int need_ip,
315 int *lacks_ipp));
316+
317+#ifdef USE_EAPTLS
318+static int have_eaptls_secret_server
319+__P((char *client, char *server, int need_ip, int *lacks_ipp));
320+static int have_eaptls_secret_client __P((char *client, char *server));
321+static int scan_authfile_eaptls __P((FILE * f, char *client, char *server,
322+ char *cli_cert, char *serv_cert,
323+ char *ca_cert, char *pk,
324+ struct wordlist ** addrs,
325+ struct wordlist ** opts,
326+ char *filename, int flags));
327+#endif
328+
329 static int ip_addr_check __P((u_int32_t, struct permitted_ip *));
330 static int scan_authfile __P((FILE *, char *, char *, char *,
331 struct wordlist **, struct wordlist **,
332@@ -401,6 +429,14 @@
333 "Set telephone number(s) which are allowed to connect",
334 OPT_PRIV | OPT_A2LIST },
335
336+#ifdef USE_EAPTLS
337+ { "ca", o_string, &cacert_file, "EAP-TLS CA certificate in PEM format" },
338+ { "cert", o_string, &cert_file, "EAP-TLS client certificate in PEM format" },
339+ { "key", o_string, &privkey_file, "EAP-TLS client private key in PEM format" },
340+ { "crl-dir", o_string, &crl_dir, "Use CRLs in directory" },
341+ { "need-peer-eap", o_bool, &need_peer_eap,
342+ "Require the peer to authenticate us", 1 },
343+#endif /* USE_EAPTLS */
344 { NULL }
345 };
346
347@@ -731,6 +767,9 @@
348 lcp_options *wo = &lcp_wantoptions[unit];
349 lcp_options *go = &lcp_gotoptions[unit];
350 lcp_options *ho = &lcp_hisoptions[unit];
351+#ifdef USE_EAPTLS
352+ lcp_options *ao = &lcp_allowoptions[unit];
353+#endif
354 int i;
355 struct protent *protp;
356
357@@ -765,6 +804,22 @@
358 }
359 }
360
361+#ifdef USE_EAPTLS
362+ if (need_peer_eap && !ao->neg_eap) {
363+ warn("eap required to authenticate us but no suitable secrets");
364+ lcp_close(unit, "couldn't negotiate eap");
365+ status = EXIT_AUTH_TOPEER_FAILED;
366+ return;
367+ }
368+
369+ if (need_peer_eap && !ho->neg_eap) {
370+ warn("peer doesn't want to authenticate us with eap");
371+ lcp_close(unit, "couldn't negotiate eap");
372+ status = EXIT_PEER_AUTH_FAILED;
373+ return;
374+ }
375+#endif
376+
377 new_phase(PHASE_AUTHENTICATE);
378 auth = 0;
379 if (go->neg_eap) {
380@@ -1278,6 +1333,15 @@
381 our_name, 1, &lacks_ip);
382 }
383
384+#ifdef USE_EAPTLS
385+ if (!can_auth && wo->neg_eap) {
386+ can_auth =
387+ have_eaptls_secret_server((explicit_remote ? remote_name :
388+ NULL), our_name, 1, &lacks_ip);
389+
390+ }
391+#endif
392+
393 if (auth_required && !can_auth && noauth_addrs == NULL) {
394 if (default_auth) {
395 option_error(
396@@ -1332,7 +1396,11 @@
397 passwd[0] != 0 ||
398 (hadchap == 1 || (hadchap == -1 && have_chap_secret(user,
399 (explicit_remote? remote_name: NULL), 0, NULL))) ||
400- have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL));
401+ have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)
402+#ifdef USE_EAPTLS
403+ || have_eaptls_secret_client(user, (explicit_remote? remote_name: NULL)))
404+#endif
405+ ;
406
407 hadchap = -1;
408 if (go->neg_upap && !uselogin && !have_pap_secret(NULL))
409@@ -1347,8 +1415,14 @@
410 !have_chap_secret((explicit_remote? remote_name: NULL), our_name,
411 1, NULL))) &&
412 !have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1,
413- NULL))
414+ NULL)
415+#ifdef USE_EAPTLS
416+ && !have_eaptls_secret_server((explicit_remote? remote_name: NULL),
417+ our_name, 1, NULL)
418+#endif
419+ )
420 go->neg_eap = 0;
421+
422 }
423
424
425@@ -1706,6 +1780,7 @@
426 }
427
428
429+
430 /*
431 * get_secret - open the CHAP secret file and return the secret
432 * for authenticating the given client on the given server.
433@@ -2358,3 +2433,335 @@
434
435 auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL, 0);
436 }
437+
438+
439+#ifdef USE_EAPTLS
440+static int
441+have_eaptls_secret_server(client, server, need_ip, lacks_ipp)
442+ char *client;
443+ char *server;
444+ int need_ip;
445+ int *lacks_ipp;
446+{
447+ FILE *f;
448+ int ret;
449+ char *filename;
450+ struct wordlist *addrs;
451+ char servcertfile[MAXWORDLEN];
452+ char clicertfile[MAXWORDLEN];
453+ char cacertfile[MAXWORDLEN];
454+ char pkfile[MAXWORDLEN];
455+
456+ filename = _PATH_EAPTLSSERVFILE;
457+ f = fopen(filename, "r");
458+ if (f == NULL)
459+ return 0;
460+
461+ if (client != NULL && client[0] == 0)
462+ client = NULL;
463+ else if (server != NULL && server[0] == 0)
464+ server = NULL;
465+
466+ ret =
467+ scan_authfile_eaptls(f, client, server, clicertfile, servcertfile,
468+ cacertfile, pkfile, &addrs, NULL, filename,
469+ 0);
470+
471+ fclose(f);
472+
473+/*
474+ if (ret >= 0 && !eaptls_init_ssl(1, cacertfile, servcertfile,
475+ clicertfile, pkfile))
476+ ret = -1;
477+*/
478+
479+ if (ret >= 0 && need_ip && !some_ip_ok(addrs)) {
480+ if (lacks_ipp != 0)
481+ *lacks_ipp = 1;
482+ ret = -1;
483+ }
484+ if (addrs != 0)
485+ free_wordlist(addrs);
486+
487+ return ret >= 0;
488+}
489+
490+
491+static int
492+have_eaptls_secret_client(client, server)
493+ char *client;
494+ char *server;
495+{
496+ FILE *f;
497+ int ret;
498+ char *filename;
499+ struct wordlist *addrs = NULL;
500+ char servcertfile[MAXWORDLEN];
501+ char clicertfile[MAXWORDLEN];
502+ char cacertfile[MAXWORDLEN];
503+ char pkfile[MAXWORDLEN];
504+
505+ if (client != NULL && client[0] == 0)
506+ client = NULL;
507+ else if (server != NULL && server[0] == 0)
508+ server = NULL;
509+
510+ if (cacert_file && cert_file && privkey_file)
511+ return 1;
512+
513+ filename = _PATH_EAPTLSCLIFILE;
514+ f = fopen(filename, "r");
515+ if (f == NULL)
516+ return 0;
517+
518+ ret =
519+ scan_authfile_eaptls(f, client, server, clicertfile, servcertfile,
520+ cacertfile, pkfile, &addrs, NULL, filename,
521+ 0);
522+ fclose(f);
523+
524+/*
525+ if (ret >= 0 && !eaptls_init_ssl(0, cacertfile, clicertfile,
526+ servcertfile, pkfile))
527+ ret = -1;
528+*/
529+
530+ if (addrs != 0)
531+ free_wordlist(addrs);
532+
533+ return ret >= 0;
534+}
535+
536+
537+static int
538+scan_authfile_eaptls(f, client, server, cli_cert, serv_cert, ca_cert, pk,
539+ addrs, opts, filename, flags)
540+ FILE *f;
541+ char *client;
542+ char *server;
543+ char *cli_cert;
544+ char *serv_cert;
545+ char *ca_cert;
546+ char *pk;
547+ struct wordlist **addrs;
548+ struct wordlist **opts;
549+ char *filename;
550+ int flags;
551+{
552+ int newline;
553+ int got_flag, best_flag;
554+ struct wordlist *ap, *addr_list, *alist, **app;
555+ char word[MAXWORDLEN];
556+
557+ if (addrs != NULL)
558+ *addrs = NULL;
559+ if (opts != NULL)
560+ *opts = NULL;
561+ addr_list = NULL;
562+ if (!getword(f, word, &newline, filename))
563+ return -1; /* file is empty??? */
564+ newline = 1;
565+ best_flag = -1;
566+ for (;;) {
567+ /*
568+ * Skip until we find a word at the start of a line.
569+ */
570+ while (!newline && getword(f, word, &newline, filename));
571+ if (!newline)
572+ break; /* got to end of file */
573+
574+ /*
575+ * Got a client - check if it's a match or a wildcard.
576+ */
577+ got_flag = 0;
578+ if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) {
579+ newline = 0;
580+ continue;
581+ }
582+ if (!ISWILD(word))
583+ got_flag = NONWILD_CLIENT;
584+
585+ /*
586+ * Now get a server and check if it matches.
587+ */
588+ if (!getword(f, word, &newline, filename))
589+ break;
590+ if (newline)
591+ continue;
592+ if (!ISWILD(word)) {
593+ if (server != NULL && strcmp(word, server) != 0)
594+ continue;
595+ got_flag |= NONWILD_SERVER;
596+ }
597+
598+ /*
599+ * Got some sort of a match - see if it's better than what
600+ * we have already.
601+ */
602+ if (got_flag <= best_flag)
603+ continue;
604+
605+ /*
606+ * Get the cli_cert
607+ */
608+ if (!getword(f, word, &newline, filename))
609+ break;
610+ if (newline)
611+ continue;
612+ if (strcmp(word, "-") != 0) {
613+ strlcpy(cli_cert, word, MAXWORDLEN);
614+ } else
615+ cli_cert[0] = 0;
616+
617+ /*
618+ * Get serv_cert
619+ */
620+ if (!getword(f, word, &newline, filename))
621+ break;
622+ if (newline)
623+ continue;
624+ if (strcmp(word, "-") != 0) {
625+ strlcpy(serv_cert, word, MAXWORDLEN);
626+ } else
627+ serv_cert[0] = 0;
628+
629+ /*
630+ * Get ca_cert
631+ */
632+ if (!getword(f, word, &newline, filename))
633+ break;
634+ if (newline)
635+ continue;
636+ strlcpy(ca_cert, word, MAXWORDLEN);
637+
638+ /*
639+ * Get pk
640+ */
641+ if (!getword(f, word, &newline, filename))
642+ break;
643+ if (newline)
644+ continue;
645+ strlcpy(pk, word, MAXWORDLEN);
646+
647+
648+ /*
649+ * Now read address authorization info and make a wordlist.
650+ */
651+ app = &alist;
652+ for (;;) {
653+ if (!getword(f, word, &newline, filename) || newline)
654+ break;
655+ ap = (struct wordlist *)
656+ malloc(sizeof(struct wordlist) + strlen(word) + 1);
657+ if (ap == NULL)
658+ novm("authorized addresses");
659+ ap->word = (char *) (ap + 1);
660+ strcpy(ap->word, word);
661+ *app = ap;
662+ app = &ap->next;
663+ }
664+ *app = NULL;
665+ /*
666+ * This is the best so far; remember it.
667+ */
668+ best_flag = got_flag;
669+ if (addr_list)
670+ free_wordlist(addr_list);
671+ addr_list = alist;
672+
673+ if (!newline)
674+ break;
675+ }
676+
677+ /* scan for a -- word indicating the start of options */
678+ for (app = &addr_list; (ap = *app) != NULL; app = &ap->next)
679+ if (strcmp(ap->word, "--") == 0)
680+ break;
681+ /* ap = start of options */
682+ if (ap != NULL) {
683+ ap = ap->next; /* first option */
684+ free(*app); /* free the "--" word */
685+ *app = NULL; /* terminate addr list */
686+ }
687+ if (opts != NULL)
688+ *opts = ap;
689+ else if (ap != NULL)
690+ free_wordlist(ap);
691+ if (addrs != NULL)
692+ *addrs = addr_list;
693+ else if (addr_list != NULL)
694+ free_wordlist(addr_list);
695+
696+ return best_flag;
697+}
698+
699+
700+int
701+get_eaptls_secret(unit, client, server, clicertfile, servcertfile,
702+ cacertfile, pkfile, am_server)
703+ int unit;
704+ char *client;
705+ char *server;
706+ char *clicertfile;
707+ char *servcertfile;
708+ char *cacertfile;
709+ char *pkfile;
710+ int am_server;
711+{
712+ FILE *fp;
713+ int ret;
714+ char *filename = NULL;
715+ struct wordlist *addrs = NULL;
716+ struct wordlist *opts = NULL;
717+
718+ /* in client mode the ca+cert+privkey can also be specified as options */
719+ if (!am_server && cacert_file && cert_file && privkey_file )
720+ {
721+ strlcpy( clicertfile, cert_file, MAXWORDLEN );
722+ strlcpy( cacertfile, cacert_file, MAXWORDLEN );
723+ strlcpy( pkfile, privkey_file, MAXWORDLEN );
724+ servcertfile[0] = '\0';
725+ }
726+ else
727+ {
728+ filename = (am_server ? _PATH_EAPTLSSERVFILE : _PATH_EAPTLSCLIFILE);
729+ addrs = NULL;
730+
731+ fp = fopen(filename, "r");
732+ if (fp == NULL)
733+ {
734+ error("Can't open eap-tls secret file %s: %m", filename);
735+ return 0;
736+ }
737+
738+ check_access(fp, filename);
739+
740+ ret = scan_authfile_eaptls(fp, client, server, clicertfile, servcertfile,
741+ cacertfile, pkfile, &addrs, &opts, filename, 0);
742+
743+ fclose(fp);
744+
745+ if (ret < 0) return 0;
746+ }
747+
748+ if (eaptls_passwd_hook)
749+ {
750+ dbglog( "Calling eaptls password hook" );
751+ if ( (*eaptls_passwd_hook)(pkfile, passwd) < 0)
752+ {
753+ error("Unable to obtain EAP-TLS password for %s (%s) from plugin",
754+ client, pkfile);
755+ return 0;
756+ }
757+ }
758+ if (am_server)
759+ set_allowed_addrs(unit, addrs, opts);
760+ else if (opts != NULL)
761+ free_wordlist(opts);
762+ if (addrs != NULL)
763+ free_wordlist(addrs);
764+
765+ return 1;
766+}
767+#endif
768+
769diff -Naur ppp-2.4.5/pppd/ccp.c ppp-2.4.5-eaptls-mppe-0.99/pppd/ccp.c
770--- ppp-2.4.5/pppd/ccp.c 2009-11-16 23:26:07.000000000 +0100
771+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/ccp.c 2010-10-01 15:17:54.211272258 +0200
772@@ -540,6 +540,9 @@
773 if (go->mppe) {
774 ccp_options *ao = &ccp_allowoptions[f->unit];
775 int auth_mschap_bits = auth_done[f->unit];
776+#ifdef USE_EAPTLS
777+ int auth_eap_bits = auth_done[f->unit];
778+#endif
779 int numbits;
780
781 /*
782@@ -567,8 +570,23 @@
783 lcp_close(f->unit, "MPPE required but not available");
784 return;
785 }
786+
787+#ifdef USE_EAPTLS
788+ /*
789+ * MPPE is also possible in combination with EAP-TLS.
790+ * It is not possible to detect if we're doing EAP or EAP-TLS
791+ * at this stage, hence we accept all forms of EAP. If TLS is
792+ * not used then the MPPE keys will not be derived anyway.
793+ */
794+ /* Leave only the eap auth bits set */
795+ auth_eap_bits &= (EAP_WITHPEER | EAP_PEER );
796+
797+ if ((numbits == 0) && (auth_eap_bits == 0)) {
798+ error("MPPE required, but MS-CHAP[v2] nor EAP-TLS auth are performed.");
799+#else
800 if (!numbits) {
801- error("MPPE required, but MS-CHAP[v2] auth not performed.");
802+ error("MPPE required, but MS-CHAP[v2] auth not performed.");
803+#endif
804 lcp_close(f->unit, "MPPE required but not available");
805 return;
806 }
807diff -Naur ppp-2.4.5/pppd/chap-md5.c ppp-2.4.5-eaptls-mppe-0.99/pppd/chap-md5.c
808--- ppp-2.4.5/pppd/chap-md5.c 2009-11-16 23:26:07.000000000 +0100
809+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/chap-md5.c 2010-10-01 15:17:54.212272142 +0200
810@@ -36,7 +36,11 @@
811 #include "chap-new.h"
812 #include "chap-md5.h"
813 #include "magic.h"
814+#ifdef USE_EAPTLS
815+#include "eap-tls.h"
816+#else
817 #include "md5.h"
818+#endif /* USE_EAPTLS */
819
820 #define MD5_HASH_SIZE 16
821 #define MD5_MIN_CHALLENGE 16
822diff -Naur ppp-2.4.5/pppd/eap-tls.c ppp-2.4.5-eaptls-mppe-0.99/pppd/eap-tls.c
823--- ppp-2.4.5/pppd/eap-tls.c 1970-01-01 01:00:00.000000000 +0100
824+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/eap-tls.c 2010-10-05 15:12:45.881615580 +0200
825@@ -0,0 +1,1174 @@
826+/*
827+ * eap-tls.c - EAP-TLS implementation for PPP
828+ *
829+ * Copyright (c) Beniamino Galvani 2005 All rights reserved.
830+ *
831+ * Redistribution and use in source and binary forms, with or without
832+ * modification, are permitted provided that the following conditions
833+ * are met:
834+ *
835+ * 1. Redistributions of source code must retain the above copyright
836+ * notice, this list of conditions and the following disclaimer.
837+ *
838+ * 2. Redistributions in binary form must reproduce the above copyright
839+ * notice, this list of conditions and the following disclaimer in
840+ * the documentation and/or other materials provided with the
841+ * distribution.
842+ *
843+ * 3. The name(s) of the authors of this software must not be used to
844+ * endorse or promote products derived from this software without
845+ * prior written permission.
846+ *
847+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
848+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
849+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
850+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
851+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
852+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
853+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
854+ *
855+ */
856+
857+#include <string.h>
858+#include <unistd.h>
859+#include <sys/types.h>
860+#include <sys/stat.h>
861+#include <fcntl.h>
862+
863+#include <openssl/conf.h>
864+#include <openssl/engine.h>
865+#include <openssl/hmac.h>
866+#include <openssl/err.h>
867+#include <openssl/x509v3.h>
868+
869+#include "pppd.h"
870+#include "eap.h"
871+#include "eap-tls.h"
872+#include "fsm.h"
873+#include "lcp.h"
874+#include "pathnames.h"
875+
876+/* The openssl configuration file and engines can be loaded only once */
877+static CONF *ssl_config = NULL;
878+static ENGINE *cert_engine = NULL;
879+static ENGINE *pkey_engine = NULL;
880+
881+#ifdef MPPE
882+
883+/*
884+ * TLS PRF from RFC 2246
885+ */
886+static void P_hash(const EVP_MD *evp_md,
887+ const unsigned char *secret, unsigned int secret_len,
888+ const unsigned char *seed, unsigned int seed_len,
889+ unsigned char *out, unsigned int out_len)
890+{
891+ HMAC_CTX ctx_a, ctx_out;
892+ unsigned char a[HMAC_MAX_MD_CBLOCK];
893+ unsigned int size;
894+
895+ HMAC_CTX_init(&ctx_a);
896+ HMAC_CTX_init(&ctx_out);
897+ HMAC_Init_ex(&ctx_a, secret, secret_len, evp_md, NULL);
898+ HMAC_Init_ex(&ctx_out, secret, secret_len, evp_md, NULL);
899+
900+ size = HMAC_size(&ctx_out);
901+
902+ /* Calculate A(1) */
903+ HMAC_Update(&ctx_a, seed, seed_len);
904+ HMAC_Final(&ctx_a, a, NULL);
905+
906+ while (1) {
907+ /* Calculate next part of output */
908+ HMAC_Update(&ctx_out, a, size);
909+ HMAC_Update(&ctx_out, seed, seed_len);
910+
911+ /* Check if last part */
912+ if (out_len < size) {
913+ HMAC_Final(&ctx_out, a, NULL);
914+ memcpy(out, a, out_len);
915+ break;
916+ }
917+
918+ /* Place digest in output buffer */
919+ HMAC_Final(&ctx_out, out, NULL);
920+ HMAC_Init_ex(&ctx_out, NULL, 0, NULL, NULL);
921+ out += size;
922+ out_len -= size;
923+
924+ /* Calculate next A(i) */
925+ HMAC_Init_ex(&ctx_a, NULL, 0, NULL, NULL);
926+ HMAC_Update(&ctx_a, a, size);
927+ HMAC_Final(&ctx_a, a, NULL);
928+ }
929+
930+ HMAC_CTX_cleanup(&ctx_a);
931+ HMAC_CTX_cleanup(&ctx_out);
932+ memset(a, 0, sizeof(a));
933+}
934+
935+static void PRF(const unsigned char *secret, unsigned int secret_len,
936+ const unsigned char *seed, unsigned int seed_len,
937+ unsigned char *out, unsigned char *buf, unsigned int out_len)
938+{
939+ unsigned int i;
940+ unsigned int len = (secret_len + 1) / 2;
941+ const unsigned char *s1 = secret;
942+ const unsigned char *s2 = secret + (secret_len - len);
943+
944+ P_hash(EVP_md5(), s1, len, seed, seed_len, out, out_len);
945+ P_hash(EVP_sha1(), s2, len, seed, seed_len, buf, out_len);
946+
947+ for (i=0; i < out_len; i++) {
948+ out[i] ^= buf[i];
949+ }
950+}
951+
952+#define EAPTLS_MPPE_KEY_LEN 32
953+
954+/*
955+ * Generate keys according to RFC 2716 and add to reply
956+ */
957+void eaptls_gen_mppe_keys(struct eaptls_session *ets, const char *prf_label,
958+ int client)
959+{
960+ unsigned char out[4*EAPTLS_MPPE_KEY_LEN], buf[4*EAPTLS_MPPE_KEY_LEN];
961+ unsigned char seed[64 + 2*SSL3_RANDOM_SIZE];
962+ unsigned char *p = seed;
963+ SSL *s = ets->ssl;
964+ size_t prf_size;
965+
966+ prf_size = strlen(prf_label);
967+
968+ memcpy(p, prf_label, prf_size);
969+ p += prf_size;
970+
971+ memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
972+ p += SSL3_RANDOM_SIZE;
973+ prf_size += SSL3_RANDOM_SIZE;
974+
975+ memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE);
976+ prf_size += SSL3_RANDOM_SIZE;
977+
978+ PRF(s->session->master_key, s->session->master_key_length,
979+ seed, prf_size, out, buf, sizeof(out));
980+
981+ /*
982+ * We now have the master send and receive keys.
983+ * From these, generate the session send and receive keys.
984+ * (see RFC3079 / draft-ietf-pppext-mppe-keys-03.txt for details)
985+ */
986+ if (client)
987+ {
988+ p = out;
989+ BCOPY( p, mppe_send_key, sizeof(mppe_send_key) );
990+ p += EAPTLS_MPPE_KEY_LEN;
991+ BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) );
992+ }
993+ else
994+ {
995+ p = out;
996+ BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) );
997+ p += EAPTLS_MPPE_KEY_LEN;
998+ BCOPY( p, mppe_send_key, sizeof(mppe_send_key) );
999+ }
1000+
1001+ mppe_keys_set = 1;
1002+}
1003+
1004+#endif
1005+
1006+void log_ssl_errors( void )
1007+{
1008+ unsigned long ssl_err = ERR_get_error();
1009+
1010+ if (ssl_err != 0)
1011+ dbglog("EAP-TLS SSL error stack:");
1012+ while (ssl_err != 0) {
1013+ dbglog( ERR_error_string( ssl_err, NULL ) );
1014+ ssl_err = ERR_get_error();
1015+ }
1016+}
1017+
1018+
1019+int password_callback (char *buf, int size, int rwflag, void *u)
1020+{
1021+ if (buf)
1022+ {
1023+ strncpy (buf, passwd, size);
1024+ return strlen (buf);
1025+ }
1026+ return 0;
1027+}
1028+
1029+
1030+CONF *eaptls_ssl_load_config( void )
1031+{
1032+ CONF *config;
1033+ int ret_code;
1034+ long error_line = 33;
1035+
1036+ config = NCONF_new( NULL );
1037+ dbglog( "Loading OpenSSL config file" );
1038+ ret_code = NCONF_load( config, _PATH_OPENSSLCONFFILE, &error_line );
1039+ if (ret_code == 0)
1040+ {
1041+ warn( "EAP-TLS: Error in OpenSSL config file %s at line %d", _PATH_OPENSSLCONFFILE, error_line );
1042+ NCONF_free( config );
1043+ config = NULL;
1044+ ERR_clear_error();
1045+ }
1046+
1047+ dbglog( "Loading OpenSSL built-ins" );
1048+ ENGINE_load_builtin_engines();
1049+ OPENSSL_load_builtin_modules();
1050+
1051+ dbglog( "Loading OpenSSL configured modules" );
1052+ if (CONF_modules_load( config, NULL, 0 ) <= 0 )
1053+ {
1054+ warn( "EAP-TLS: Error loading OpenSSL modules" );
1055+ log_ssl_errors();
1056+ config = NULL;
1057+ }
1058+
1059+ return config;
1060+}
1061+
1062+ENGINE *eaptls_ssl_load_engine( char *engine_name )
1063+{
1064+ ENGINE *e = NULL;
1065+
1066+ dbglog( "Enabling OpenSSL auto engines" );
1067+ ENGINE_register_all_complete();
1068+
1069+ dbglog( "Loading OpenSSL '%s' engine support", engine_name );
1070+ e = ENGINE_by_id( engine_name );
1071+ if (!e)
1072+ {
1073+ dbglog( "EAP-TLS: Cannot load '%s' engine support, trying 'dynamic'", engine_name );
1074+ e = ENGINE_by_id( "dynamic" );
1075+ if (e)
1076+ {
1077+ if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine_name, 0)
1078+ || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
1079+ {
1080+ warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name );
1081+ log_ssl_errors();
1082+ ENGINE_free(e);
1083+ e = NULL;
1084+ }
1085+ }
1086+ else
1087+ {
1088+ warn( "EAP-TLS: Cannot load dynamic engine support" );
1089+ }
1090+ }
1091+
1092+ if (e)
1093+ {
1094+ dbglog( "Initialising engine" );
1095+ if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
1096+ {
1097+ warn( "EAP-TLS: Cannot use that engine" );
1098+ log_ssl_errors();
1099+ ENGINE_free(e);
1100+ e = NULL;
1101+ }
1102+ }
1103+
1104+ return e;
1105+}
1106+
1107+/*
1108+ * Initialize the SSL stacks and tests if certificates, key and crl
1109+ * for client or server use can be loaded.
1110+ */
1111+SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile,
1112+ char *certfile, char *peer_certfile, char *privkeyfile)
1113+{
1114+ char *cert_engine_name = NULL;
1115+ char *cert_identifier = NULL;
1116+ char *pkey_engine_name = NULL;
1117+ char *pkey_identifier = NULL;
1118+ SSL_CTX *ctx;
1119+ X509_STORE *certstore;
1120+ X509_LOOKUP *lookup;
1121+ X509 *tmp;
1122+
1123+ /*
1124+ * Without these can't continue
1125+ */
1126+ if (!cacertfile[0])
1127+ {
1128+ error("EAP-TLS: CA certificate missing");
1129+ return NULL;
1130+ }
1131+
1132+ if (!certfile[0])
1133+ {
1134+ error("EAP-TLS: User certificate missing");
1135+ return NULL;
1136+ }
1137+
1138+ if (!privkeyfile[0])
1139+ {
1140+ error("EAP-TLS: User private key missing");
1141+ return NULL;
1142+ }
1143+
1144+ SSL_library_init();
1145+ SSL_load_error_strings();
1146+
1147+ ctx = SSL_CTX_new(TLSv1_method());
1148+
1149+ if (!ctx) {
1150+ error("EAP-TLS: Cannot initialize SSL CTX context");
1151+ goto fail;
1152+ }
1153+
1154+ /* if the certificate filename is of the form engine:id. e.g.
1155+ pkcs11:12345
1156+ then we try to load and use this engine.
1157+ If the certificate filename starts with a / or . then we
1158+ ALWAYS assume it is a file and not an engine/pkcs11 identifier
1159+ */
1160+ if ( index( certfile, '/' ) == NULL && index( certfile, '.') == NULL )
1161+ {
1162+ cert_identifier = index( certfile, ':' );
1163+
1164+ if (cert_identifier)
1165+ {
1166+ cert_engine_name = certfile;
1167+ *cert_identifier = '\0';
1168+ cert_identifier++;
1169+
1170+ dbglog( "Found certificate engine '%s'", cert_engine_name );
1171+ dbglog( "Found certificate identifier '%s'", cert_identifier );
1172+ }
1173+ }
1174+
1175+ /* if the privatekey filename is of the form engine:id. e.g.
1176+ pkcs11:12345
1177+ then we try to load and use this engine.
1178+ If the privatekey filename starts with a / or . then we
1179+ ALWAYS assume it is a file and not an engine/pkcs11 identifier
1180+ */
1181+ if ( index( privkeyfile, '/' ) == NULL && index( privkeyfile, '.') == NULL )
1182+ {
1183+ pkey_identifier = index( privkeyfile, ':' );
1184+
1185+ if (pkey_identifier)
1186+ {
1187+ pkey_engine_name = privkeyfile;
1188+ *pkey_identifier = '\0';
1189+ pkey_identifier++;
1190+
1191+ dbglog( "Found privatekey engine '%s'", pkey_engine_name );
1192+ dbglog( "Found privatekey identifier '%s'", pkey_identifier );
1193+ }
1194+ }
1195+
1196+ if (cert_identifier && pkey_identifier)
1197+ {
1198+ if (strlen( cert_identifier ) == 0)
1199+ {
1200+ if (strlen( pkey_identifier ) == 0)
1201+ error( "EAP-TLS: both the certificate and privatekey identifiers are missing!" );
1202+ else
1203+ {
1204+ dbglog( "Substituting privatekey identifier for certificate identifier" );
1205+ cert_identifier = pkey_identifier;
1206+ }
1207+ }
1208+ else
1209+ {
1210+ if (strlen( pkey_identifier ) == 0)
1211+ {
1212+ dbglog( "Substituting certificate identifier for privatekey identifier" );
1213+ pkey_identifier = cert_identifier;
1214+ }
1215+ }
1216+
1217+ }
1218+
1219+ /* load the openssl config file only once */
1220+ if (!ssl_config)
1221+ {
1222+ if (cert_engine_name || pkey_engine_name)
1223+ ssl_config = eaptls_ssl_load_config();
1224+
1225+ if (ssl_config && cert_engine_name)
1226+ cert_engine = eaptls_ssl_load_engine( cert_engine_name );
1227+
1228+ if (ssl_config && pkey_engine_name)
1229+ {
1230+ /* don't load the same engine twice */
1231+ if ( strcmp( cert_engine_name, pkey_engine_name) == 0 )
1232+ pkey_engine = cert_engine;
1233+ else
1234+ pkey_engine = eaptls_ssl_load_engine( pkey_engine_name );
1235+ }
1236+ }
1237+
1238+ SSL_CTX_set_default_passwd_cb (ctx, password_callback);
1239+
1240+ if (!SSL_CTX_load_verify_locations(ctx, cacertfile, NULL))
1241+ {
1242+ error("EAP-TLS: Cannot load or verify CA file %s", cacertfile);
1243+ goto fail;
1244+ }
1245+
1246+ if (init_server)
1247+ SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(cacertfile));
1248+
1249+ if (cert_engine)
1250+ {
1251+ struct
1252+ {
1253+ const char *s_slot_cert_id;
1254+ X509 *cert;
1255+ } cert_info;
1256+
1257+ cert_info.s_slot_cert_id = cert_identifier;
1258+ cert_info.cert = NULL;
1259+
1260+ if (!ENGINE_ctrl_cmd( cert_engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0 ) )
1261+ {
1262+ error( "EAP-TLS: Error loading certificate with id '%s' from engine", cert_identifier );
1263+ goto fail;
1264+ }
1265+
1266+ if (cert_info.cert)
1267+ {
1268+ dbglog( "Got the certificate, adding it to SSL context" );
1269+ dbglog( "subject = %s", X509_NAME_oneline( X509_get_subject_name( cert_info.cert ), NULL, 0 ) );
1270+ if (SSL_CTX_use_certificate(ctx, cert_info.cert) <= 0)
1271+ {
1272+ error("EAP-TLS: Cannot use PKCS11 certificate %s", cert_identifier);
1273+ goto fail;
1274+ }
1275+ }
1276+ else
1277+ {
1278+ warn("EAP-TLS: Cannot load PKCS11 key %s", cert_identifier);
1279+ log_ssl_errors();
1280+ }
1281+ }
1282+ else
1283+ {
1284+ if (!SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM))
1285+ {
1286+ error( "EAP-TLS: Cannot use public certificate %s", certfile );
1287+ goto fail;
1288+ }
1289+ }
1290+
1291+ if (pkey_engine)
1292+ {
1293+ EVP_PKEY *pkey = NULL;
1294+ PW_CB_DATA cb_data;
1295+
1296+ cb_data.password = passwd;
1297+ cb_data.prompt_info = pkey_identifier;
1298+
1299+ dbglog( "Loading private key '%s' from engine", pkey_identifier );
1300+ pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, NULL, &cb_data);
1301+ if (pkey)
1302+ {
1303+ dbglog( "Got the private key, adding it to SSL context" );
1304+ if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0)
1305+ {
1306+ error("EAP-TLS: Cannot use PKCS11 key %s", pkey_identifier);
1307+ goto fail;
1308+ }
1309+ }
1310+ else
1311+ {
1312+ warn("EAP-TLS: Cannot load PKCS11 key %s", pkey_identifier);
1313+ log_ssl_errors();
1314+ }
1315+ }
1316+ else
1317+ {
1318+ if (!SSL_CTX_use_PrivateKey_file(ctx, privkeyfile, SSL_FILETYPE_PEM))
1319+ {
1320+ error("EAP-TLS: Cannot use private key %s", privkeyfile);
1321+ goto fail;
1322+ }
1323+ }
1324+
1325+ if (SSL_CTX_check_private_key(ctx) != 1) {
1326+ error("EAP-TLS: Private key %s fails security check", privkeyfile);
1327+ goto fail;
1328+ }
1329+
1330+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
1331+ SSL_CTX_set_verify_depth(ctx, 5);
1332+ SSL_CTX_set_verify(ctx,
1333+ SSL_VERIFY_PEER |
1334+ SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
1335+ &ssl_verify_callback);
1336+
1337+ if (crl_dir) {
1338+ if (!(certstore = SSL_CTX_get_cert_store(ctx))) {
1339+ error("EAP-TLS: Failed to get certificate store");
1340+ goto fail;
1341+ }
1342+
1343+ if (!(lookup =
1344+ X509_STORE_add_lookup(certstore, X509_LOOKUP_hash_dir()))) {
1345+ error("EAP-TLS: Store lookup for CRL failed");
1346+
1347+ goto fail;
1348+ }
1349+
1350+ X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM);
1351+ X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
1352+ }
1353+
1354+ /*
1355+ * If a peer certificate file was specified, it must be valid, else fail
1356+ */
1357+ if (peer_certfile[0]) {
1358+ if (!(tmp = get_X509_from_file(peer_certfile))) {
1359+ error("EAP-TLS: Error loading client certificate from file %s",
1360+ peer_certfile);
1361+ goto fail;
1362+ }
1363+ X509_free(tmp);
1364+ }
1365+
1366+ return ctx;
1367+
1368+fail:
1369+ log_ssl_errors();
1370+ SSL_CTX_free(ctx);
1371+ return NULL;
1372+}
1373+
1374+/*
1375+ * Determine the maximum packet size by looking at the LCP handshake
1376+ */
1377+
1378+int eaptls_get_mtu(int unit)
1379+{
1380+ int mtu, mru;
1381+
1382+ lcp_options *wo = &lcp_wantoptions[unit];
1383+ lcp_options *go = &lcp_gotoptions[unit];
1384+ lcp_options *ho = &lcp_hisoptions[unit];
1385+ lcp_options *ao = &lcp_allowoptions[unit];
1386+
1387+ mtu = ho->neg_mru? ho->mru: PPP_MRU;
1388+ mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU;
1389+ mtu = MIN(MIN(mtu, mru), ao->mru)- PPP_HDRLEN - 10;
1390+
1391+ dbglog("MTU = %d", mtu);
1392+ return mtu;
1393+}
1394+
1395+
1396+/*
1397+ * Init the ssl handshake (server mode)
1398+ */
1399+int eaptls_init_ssl_server(eap_state * esp)
1400+{
1401+ struct eaptls_session *ets;
1402+ char servcertfile[MAXWORDLEN];
1403+ char clicertfile[MAXWORDLEN];
1404+ char cacertfile[MAXWORDLEN];
1405+ char pkfile[MAXWORDLEN];
1406+ /*
1407+ * Allocate new eaptls session
1408+ */
1409+ esp->es_server.ea_session = malloc(sizeof(struct eaptls_session));
1410+ if (!esp->es_server.ea_session)
1411+ fatal("Allocation error");
1412+ ets = esp->es_server.ea_session;
1413+
1414+ if (!esp->es_server.ea_peer) {
1415+ error("EAP-TLS: Error: client name not set (BUG)");
1416+ return 0;
1417+ }
1418+
1419+ strncpy(ets->peer, esp->es_server.ea_peer, MAXWORDLEN);
1420+
1421+ dbglog( "getting eaptls secret" );
1422+ if (!get_eaptls_secret(esp->es_unit, esp->es_server.ea_peer,
1423+ esp->es_server.ea_name, clicertfile,
1424+ servcertfile, cacertfile, pkfile, 1)) {
1425+ error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"",
1426+ esp->es_server.ea_peer, esp->es_server.ea_name );
1427+ return 0;
1428+ }
1429+
1430+ ets->mtu = eaptls_get_mtu(esp->es_unit);
1431+
1432+ ets->ctx = eaptls_init_ssl(1, cacertfile, servcertfile, clicertfile, pkfile);
1433+ if (!ets->ctx)
1434+ goto fail;
1435+
1436+ if (!(ets->ssl = SSL_new(ets->ctx)))
1437+ goto fail;
1438+
1439+ /*
1440+ * Set auto-retry to avoid timeouts on BIO_read
1441+ */
1442+ SSL_set_mode(ets->ssl, SSL_MODE_AUTO_RETRY);
1443+
1444+ /*
1445+ * Initialize the BIOs we use to read/write to ssl engine
1446+ */
1447+ ets->into_ssl = BIO_new(BIO_s_mem());
1448+ ets->from_ssl = BIO_new(BIO_s_mem());
1449+ SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl);
1450+
1451+ SSL_set_msg_callback(ets->ssl, ssl_msg_callback);
1452+ SSL_set_msg_callback_arg(ets->ssl, ets);
1453+
1454+ /*
1455+ * Attach the session struct to the connection, so we can later
1456+ * retrieve it when doing certificate verification
1457+ */
1458+ SSL_set_ex_data(ets->ssl, 0, ets);
1459+
1460+ SSL_set_accept_state(ets->ssl);
1461+
1462+ ets->data = NULL;
1463+ ets->datalen = 0;
1464+ ets->alert_sent = 0;
1465+ ets->alert_recv = 0;
1466+
1467+ /*
1468+ * If we specified the client certificate file, store it in ets->peercertfile,
1469+ * so we can check it later in ssl_verify_callback()
1470+ */
1471+ if (clicertfile[0])
1472+ strncpy(&ets->peercertfile[0], clicertfile, MAXWORDLEN);
1473+ else
1474+ ets->peercertfile[0] = 0;
1475+
1476+ return 1;
1477+
1478+fail:
1479+ SSL_CTX_free(ets->ctx);
1480+ return 0;
1481+}
1482+
1483+/*
1484+ * Init the ssl handshake (client mode)
1485+ */
1486+int eaptls_init_ssl_client(eap_state * esp)
1487+{
1488+ struct eaptls_session *ets;
1489+ char servcertfile[MAXWORDLEN];
1490+ char clicertfile[MAXWORDLEN];
1491+ char cacertfile[MAXWORDLEN];
1492+ char pkfile[MAXWORDLEN];
1493+
1494+ /*
1495+ * Allocate new eaptls session
1496+ */
1497+ esp->es_client.ea_session = malloc(sizeof(struct eaptls_session));
1498+ if (!esp->es_client.ea_session)
1499+ fatal("Allocation error");
1500+ ets = esp->es_client.ea_session;
1501+
1502+ /*
1503+ * If available, copy server name in ets; it will be used in cert
1504+ * verify
1505+ */
1506+ if (esp->es_client.ea_peer)
1507+ strncpy(ets->peer, esp->es_client.ea_peer, MAXWORDLEN);
1508+ else
1509+ ets->peer[0] = 0;
1510+
1511+ ets->mtu = eaptls_get_mtu(esp->es_unit);
1512+
1513+ dbglog( "calling get_eaptls_secret" );
1514+ if (!get_eaptls_secret(esp->es_unit, esp->es_client.ea_name,
1515+ esp->es_client.ea_peer, clicertfile,
1516+ servcertfile, cacertfile, pkfile, 0)) {
1517+ error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"",
1518+ esp->es_client.ea_name, esp->es_client.ea_peer );
1519+ return 0;
1520+ }
1521+
1522+ dbglog( "calling eaptls_init_ssl" );
1523+ ets->ctx = eaptls_init_ssl(0, cacertfile, clicertfile, servcertfile, pkfile);
1524+ if (!ets->ctx)
1525+ goto fail;
1526+
1527+ ets->ssl = SSL_new(ets->ctx);
1528+
1529+ if (!ets->ssl)
1530+ goto fail;
1531+
1532+ /*
1533+ * Initialize the BIOs we use to read/write to ssl engine
1534+ */
1535+ dbglog( "Initializing SSL BIOs" );
1536+ ets->into_ssl = BIO_new(BIO_s_mem());
1537+ ets->from_ssl = BIO_new(BIO_s_mem());
1538+ SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl);
1539+
1540+ SSL_set_msg_callback(ets->ssl, ssl_msg_callback);
1541+ SSL_set_msg_callback_arg(ets->ssl, ets);
1542+
1543+ /*
1544+ * Attach the session struct to the connection, so we can later
1545+ * retrieve it when doing certificate verification
1546+ */
1547+ SSL_set_ex_data(ets->ssl, 0, ets);
1548+
1549+ SSL_set_connect_state(ets->ssl);
1550+
1551+ ets->data = NULL;
1552+ ets->datalen = 0;
1553+ ets->alert_sent = 0;
1554+ ets->alert_recv = 0;
1555+
1556+ /*
1557+ * If we specified the server certificate file, store it in
1558+ * ets->peercertfile, so we can check it later in
1559+ * ssl_verify_callback()
1560+ */
1561+ if (servcertfile[0])
1562+ strncpy(ets->peercertfile, servcertfile, MAXWORDLEN);
1563+ else
1564+ ets->peercertfile[0] = 0;
1565+
1566+ return 1;
1567+
1568+fail:
1569+ dbglog( "eaptls_init_ssl_client: fail" );
1570+ SSL_CTX_free(ets->ctx);
1571+ return 0;
1572+
1573+}
1574+
1575+void eaptls_free_session(struct eaptls_session *ets)
1576+{
1577+ if (ets->ssl)
1578+ SSL_free(ets->ssl);
1579+
1580+ if (ets->ctx)
1581+ SSL_CTX_free(ets->ctx);
1582+
1583+ free(ets);
1584+}
1585+
1586+/*
1587+ * Handle a received packet, reassembling fragmented messages and
1588+ * passing them to the ssl engine
1589+ */
1590+int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len)
1591+{
1592+ u_char flags;
1593+ u_int tlslen;
1594+ u_char dummy[65536];
1595+
1596+ GETCHAR(flags, inp);
1597+ len--;
1598+
1599+ if (flags & EAP_TLS_FLAGS_LI && !ets->data) {
1600+
1601+ /*
1602+ * This is the first packet of a message
1603+ */
1604+
1605+ GETLONG(tlslen, inp);
1606+ len -= 4;
1607+
1608+ if (tlslen > EAP_TLS_MAX_LEN) {
1609+ error("Error: tls message length > %d, truncated",
1610+ EAP_TLS_MAX_LEN);
1611+ tlslen = EAP_TLS_MAX_LEN;
1612+ }
1613+
1614+ /*
1615+ * Allocate memory for the whole message
1616+ */
1617+ ets->data = malloc(tlslen);
1618+ if (!ets->data)
1619+ fatal("EAP TLS: allocation error\n");
1620+
1621+ ets->datalen = 0;
1622+ ets->tlslen = tlslen;
1623+
1624+ }
1625+ else if (flags & EAP_TLS_FLAGS_LI && ets->data) {
1626+ /*
1627+ * Non first with LI (strange...)
1628+ */
1629+
1630+ GETLONG(tlslen, inp);
1631+ len -= 4;
1632+
1633+ }
1634+ else if (!ets->data) {
1635+ /*
1636+ * A non fragmented message without LI flag
1637+ */
1638+
1639+ ets->data = malloc(len);
1640+ if (!ets->data)
1641+ fatal("EAP TLS: allocation error\n");
1642+
1643+ ets->datalen = 0;
1644+ ets->tlslen = len;
1645+ }
1646+
1647+ if (flags & EAP_TLS_FLAGS_MF)
1648+ ets->frag = 1;
1649+ else
1650+ ets->frag = 0;
1651+
1652+ if (len + ets->datalen > ets->tlslen) {
1653+ warn("EAP TLS: received data > TLS message length");
1654+ return 1;
1655+ }
1656+
1657+ BCOPY(inp, ets->data + ets->datalen, len);
1658+ ets->datalen += len;
1659+
1660+ if (!ets->frag) {
1661+
1662+ /*
1663+ * If we have the whole message, pass it to ssl
1664+ */
1665+
1666+ if (ets->datalen != ets->tlslen) {
1667+ warn("EAP TLS: received data != TLS message length");
1668+ return 1;
1669+ }
1670+
1671+ if (BIO_write(ets->into_ssl, ets->data, ets->datalen) == -1)
1672+ log_ssl_errors();
1673+
1674+ SSL_read(ets->ssl, dummy, 65536);
1675+
1676+ free(ets->data);
1677+ ets->data = NULL;
1678+ ets->datalen = 0;
1679+ }
1680+
1681+ return 0;
1682+}
1683+
1684+/*
1685+ * Return an eap-tls packet in outp.
1686+ * A TLS message read from the ssl engine is buffered in ets->data.
1687+ * At each call we control if there is buffered data and send a
1688+ * packet of mtu bytes.
1689+ */
1690+int eaptls_send(struct eaptls_session *ets, u_char ** outp)
1691+{
1692+ bool first = 0;
1693+ int size;
1694+ u_char fromtls[65536];
1695+ int res;
1696+ u_char *start;
1697+
1698+ start = *outp;
1699+
1700+ if (!ets->data) {
1701+
1702+ if(!ets->alert_sent)
1703+ SSL_read(ets->ssl, fromtls, 65536);
1704+
1705+ /*
1706+ * Read from ssl
1707+ */
1708+ if ((res = BIO_read(ets->from_ssl, fromtls, 65536)) == -1)
1709+ fatal("No data from BIO_read");
1710+
1711+ ets->datalen = res;
1712+
1713+ ets->data = malloc(ets->datalen);
1714+ BCOPY(fromtls, ets->data, ets->datalen);
1715+
1716+ ets->offset = 0;
1717+ first = 1;
1718+
1719+ }
1720+
1721+ size = ets->datalen - ets->offset;
1722+
1723+ if (size > ets->mtu) {
1724+ size = ets->mtu;
1725+ ets->frag = 1;
1726+ } else
1727+ ets->frag = 0;
1728+
1729+ PUTCHAR(EAPT_TLS, *outp);
1730+
1731+ /*
1732+ * Set right flags and length if necessary
1733+ */
1734+ if (ets->frag && first) {
1735+ PUTCHAR(EAP_TLS_FLAGS_LI | EAP_TLS_FLAGS_MF, *outp);
1736+ PUTLONG(ets->datalen, *outp);
1737+ } else if (ets->frag) {
1738+ PUTCHAR(EAP_TLS_FLAGS_MF, *outp);
1739+ } else
1740+ PUTCHAR(0, *outp);
1741+
1742+ /*
1743+ * Copy the data in outp
1744+ */
1745+ BCOPY(ets->data + ets->offset, *outp, size);
1746+ INCPTR(size, *outp);
1747+
1748+ /*
1749+ * Copy the packet in retransmission buffer
1750+ */
1751+ BCOPY(start, &ets->rtx[0], *outp - start);
1752+ ets->rtx_len = *outp - start;
1753+
1754+ ets->offset += size;
1755+
1756+ if (ets->offset >= ets->datalen) {
1757+
1758+ /*
1759+ * The whole message has been sent
1760+ */
1761+
1762+ free(ets->data);
1763+ ets->data = NULL;
1764+ ets->datalen = 0;
1765+ ets->offset = 0;
1766+ }
1767+
1768+ return 0;
1769+}
1770+
1771+/*
1772+ * Get the sent packet from the retransmission buffer
1773+ */
1774+void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp)
1775+{
1776+ BCOPY(ets->rtx, *outp, ets->rtx_len);
1777+ INCPTR(ets->rtx_len, *outp);
1778+}
1779+
1780+/*
1781+ * Verify a certificate.
1782+ * Most of the work (signatures and issuer attributes checking)
1783+ * is done by ssl; we check the CN in the peer certificate
1784+ * against the peer name.
1785+ */
1786+int ssl_verify_callback(int preverify_ok, X509_STORE_CTX * ctx)
1787+{
1788+ char subject[256];
1789+ char cn_str[256];
1790+ X509 *peer_cert;
1791+ int err, depth;
1792+ int ok = preverify_ok;
1793+ SSL *ssl;
1794+ struct eaptls_session *ets;
1795+
1796+ peer_cert = X509_STORE_CTX_get_current_cert(ctx);
1797+ err = X509_STORE_CTX_get_error(ctx);
1798+ depth = X509_STORE_CTX_get_error_depth(ctx);
1799+
1800+ dbglog("certificate verify depth: %d", depth);
1801+
1802+ if (auth_required && !ok) {
1803+ X509_NAME_oneline(X509_get_subject_name(peer_cert),
1804+ subject, 256);
1805+
1806+ X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
1807+ NID_commonName, cn_str, 256);
1808+
1809+ dbglog("Certificate verification error:\n depth: %d CN: %s"
1810+ "\n err: %d (%s)\n", depth, cn_str, err,
1811+ X509_verify_cert_error_string(err));
1812+
1813+ return 0;
1814+ }
1815+
1816+ ssl = X509_STORE_CTX_get_ex_data(ctx,
1817+ SSL_get_ex_data_X509_STORE_CTX_idx());
1818+
1819+ ets = (struct eaptls_session *)SSL_get_ex_data(ssl, 0);
1820+
1821+ if (ets == NULL) {
1822+ error("Error: SSL_get_ex_data returned NULL");
1823+ return 0;
1824+ }
1825+
1826+ log_ssl_errors();
1827+
1828+ if (!depth) { /* This is the peer certificate */
1829+
1830+ X509_NAME_oneline(X509_get_subject_name(peer_cert),
1831+ subject, 256);
1832+
1833+ X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
1834+ NID_commonName, cn_str, 256);
1835+
1836+ /*
1837+ * If acting as client and the name of the server wasn't specified
1838+ * explicitely, we can't verify the server authenticity
1839+ */
1840+ if (!ets->peer[0]) {
1841+ warn("Peer name not specified: no check");
1842+ return 1;
1843+ }
1844+
1845+ /*
1846+ * Check the CN
1847+ */
1848+ if (strcmp(cn_str, ets->peer)) {
1849+ error
1850+ ("Certificate verification error: CN (%s) != peer_name (%s)",
1851+ cn_str, ets->peer);
1852+ return 0;
1853+ }
1854+
1855+ warn("Certificate CN: %s , peer name %s", cn_str, ets->peer);
1856+
1857+ /*
1858+ * If a peer certificate file was specified, here we check it
1859+ */
1860+ if (ets->peercertfile[0]) {
1861+ if (ssl_cmp_certs(&ets->peercertfile[0], peer_cert)
1862+ != 0) {
1863+ error
1864+ ("Peer certificate doesn't match stored certificate");
1865+ return 0;
1866+ }
1867+ }
1868+ }
1869+
1870+ return 1;
1871+}
1872+
1873+/*
1874+ * Compare a certificate with the one stored in a file
1875+ */
1876+int ssl_cmp_certs(char *filename, X509 * a)
1877+{
1878+ X509 *b;
1879+ int ret;
1880+
1881+ if (!(b = get_X509_from_file(filename)))
1882+ return 1;
1883+
1884+ ret = X509_cmp(a, b);
1885+ X509_free(b);
1886+
1887+ return ret;
1888+
1889+}
1890+
1891+X509 *get_X509_from_file(char *filename)
1892+{
1893+ FILE *fp;
1894+ X509 *ret;
1895+
1896+ if (!(fp = fopen(filename, "r")))
1897+ return NULL;
1898+
1899+ ret = PEM_read_X509(fp, NULL, NULL, NULL);
1900+
1901+ fclose(fp);
1902+
1903+ return ret;
1904+}
1905+
1906+/*
1907+ * Every sent & received message this callback function is invoked,
1908+ * so we know when alert messages have arrived or are sent and
1909+ * we can print debug information about TLS handshake.
1910+ */
1911+void
1912+ssl_msg_callback(int write_p, int version, int content_type,
1913+ const void *buf, size_t len, SSL * ssl, void *arg)
1914+{
1915+ char string[256];
1916+ struct eaptls_session *ets = (struct eaptls_session *)arg;
1917+ unsigned char code;
1918+
1919+ if(write_p)
1920+ strcpy(string, " -> ");
1921+ else
1922+ strcpy(string, " <- ");
1923+
1924+
1925+ switch(content_type) {
1926+
1927+ case SSL3_RT_ALERT:
1928+ strcat(string, "Alert: ");
1929+ code = ((const unsigned char *)buf)[1];
1930+
1931+ if (write_p) {
1932+ ets->alert_sent = 1;
1933+ ets->alert_sent_desc = code;
1934+ } else {
1935+ ets->alert_recv = 1;
1936+ ets->alert_recv_desc = code;
1937+ }
1938+
1939+ strcat(string, SSL_alert_desc_string_long(code));
1940+ break;
1941+
1942+ case SSL3_RT_CHANGE_CIPHER_SPEC:
1943+ strcat(string, "ChangeCipherSpec");
1944+ break;
1945+
1946+ case SSL3_RT_HANDSHAKE:
1947+
1948+ strcat(string, "Handshake: ");
1949+ code = ((const unsigned char *)buf)[0];
1950+
1951+ switch(code) {
1952+ case SSL3_MT_HELLO_REQUEST:
1953+ strcat(string,"Hello Request");
1954+ break;
1955+ case SSL3_MT_CLIENT_HELLO:
1956+ strcat(string,"Client Hello");
1957+ break;
1958+ case SSL3_MT_SERVER_HELLO:
1959+ strcat(string,"Server Hello");
1960+ break;
1961+ case SSL3_MT_CERTIFICATE:
1962+ strcat(string,"Certificate");
1963+ break;
1964+ case SSL3_MT_SERVER_KEY_EXCHANGE:
1965+ strcat(string,"Server Key Exchange");
1966+ break;
1967+ case SSL3_MT_CERTIFICATE_REQUEST:
1968+ strcat(string,"Certificate Request");
1969+ break;
1970+ case SSL3_MT_SERVER_DONE:
1971+ strcat(string,"Server Hello Done");
1972+ break;
1973+ case SSL3_MT_CERTIFICATE_VERIFY:
1974+ strcat(string,"Certificate Verify");
1975+ break;
1976+ case SSL3_MT_CLIENT_KEY_EXCHANGE:
1977+ strcat(string,"Client Key Exchange");
1978+ break;
1979+ case SSL3_MT_FINISHED:
1980+ strcat(string,"Finished");
1981+ break;
1982+
1983+ default:
1984+ sprintf( string, "Handshake: Unknown SSL3 code received: %d", code );
1985+ }
1986+ break;
1987+
1988+ default:
1989+ sprintf( string, "SSL message contains unknown content type: %d", content_type );
1990+
1991+ }
1992+
1993+ /* Alert messages must always be displayed */
1994+ if(content_type == SSL3_RT_ALERT)
1995+ error("%s", string);
1996+ else
1997+ dbglog("%s", string);
1998+}
1999+
2000diff -Naur ppp-2.4.5/pppd/eap-tls.h ppp-2.4.5-eaptls-mppe-0.99/pppd/eap-tls.h
2001--- ppp-2.4.5/pppd/eap-tls.h 1970-01-01 01:00:00.000000000 +0100
2002+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/eap-tls.h 2010-10-01 15:17:54.213271816 +0200
2003@@ -0,0 +1,107 @@
2004+/*
2005+ * eap-tls.h
2006+ *
2007+ * Copyright (c) Beniamino Galvani 2005 All rights reserved.
2008+ *
2009+ * Redistribution and use in source and binary forms, with or without
2010+ * modification, are permitted provided that the following conditions
2011+ * are met:
2012+ *
2013+ * 1. Redistributions of source code must retain the above copyright
2014+ * notice, this list of conditions and the following disclaimer.
2015+ *
2016+ * 2. Redistributions in binary form must reproduce the above copyright
2017+ * notice, this list of conditions and the following disclaimer in
2018+ * the documentation and/or other materials provided with the
2019+ * distribution.
2020+ *
2021+ * 3. The name(s) of the authors of this software must not be used to
2022+ * endorse or promote products derived from this software without
2023+ * prior written permission.
2024+ *
2025+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
2026+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
2027+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
2028+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
2029+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
2030+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
2031+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2032+ *
2033+ */
2034+
2035+#ifndef __EAP_TLS_H__
2036+#define __EAP_TLS_H__
2037+
2038+#include "eap.h"
2039+
2040+#include <openssl/ssl.h>
2041+#include <openssl/bio.h>
2042+#include <openssl/md5.h>
2043+
2044+#define EAP_TLS_FLAGS_LI 128 /* length included flag */
2045+#define EAP_TLS_FLAGS_MF 64 /* more fragments flag */
2046+#define EAP_TLS_FLAGS_START 32 /* start flag */
2047+
2048+#define EAP_TLS_MAX_LEN 65536 /* max eap tls packet size */
2049+
2050+struct eaptls_session
2051+{
2052+ u_char *data; /* buffered data */
2053+ int datalen; /* buffered data len */
2054+ int offset; /* from where to send */
2055+ int tlslen; /* total length of tls data */
2056+ bool frag; /* packet is fragmented */
2057+ SSL_CTX *ctx;
2058+ SSL *ssl; /* ssl connection */
2059+ BIO *from_ssl;
2060+ BIO *into_ssl;
2061+ char peer[MAXWORDLEN]; /* peer name */
2062+ char peercertfile[MAXWORDLEN];
2063+ bool alert_sent;
2064+ u_char alert_sent_desc;
2065+ bool alert_recv;
2066+ u_char alert_recv_desc;
2067+ char rtx[65536]; /* retransmission buffer */
2068+ int rtx_len;
2069+ int mtu; /* unit mtu */
2070+};
2071+
2072+typedef struct pw_cb_data
2073+{
2074+ const void *password;
2075+ const char *prompt_info;
2076+} PW_CB_DATA;
2077+
2078+
2079+int ssl_verify_callback(int, X509_STORE_CTX *);
2080+void ssl_msg_callback(int write_p, int version, int ct, const void *buf,
2081+ size_t len, SSL * ssl, void *arg);
2082+
2083+X509 *get_X509_from_file(char *filename);
2084+int ssl_cmp_certs(char *filename, X509 * a);
2085+
2086+SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile,
2087+ char *certfile, char *peer_certfile, char *privkeyfile);
2088+int eaptls_init_ssl_server(eap_state * esp);
2089+int eaptls_init_ssl_client(eap_state * esp);
2090+void eaptls_free_session(struct eaptls_session *ets);
2091+
2092+int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len);
2093+int eaptls_send(struct eaptls_session *ets, u_char ** outp);
2094+void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp);
2095+
2096+int get_eaptls_secret(int unit, char *client, char *server,
2097+ char *clicertfile, char *servcertfile, char *cacertfile,
2098+ char *pkfile, int am_server);
2099+
2100+#ifdef MPPE
2101+#include "mppe.h" /* MPPE_MAX_KEY_LEN */
2102+extern u_char mppe_send_key[MPPE_MAX_KEY_LEN];
2103+extern u_char mppe_recv_key[MPPE_MAX_KEY_LEN];
2104+extern int mppe_keys_set;
2105+
2106+void eaptls_gen_mppe_keys(struct eaptls_session *ets, const char *prf_label, int client);
2107+
2108+#endif
2109+
2110+#endif
2111diff -Naur ppp-2.4.5/pppd/eap.c ppp-2.4.5-eaptls-mppe-0.99/pppd/eap.c
2112--- ppp-2.4.5/pppd/eap.c 2009-11-16 23:26:07.000000000 +0100
2113+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/eap.c 2010-01-29 16:31:29.000000000 +0100
2114@@ -43,6 +43,11 @@
2115 * Based on draft-ietf-pppext-eap-srp-03.txt.
2116 */
2117
2118+/*
2119+ * Modification by Beniamino Galvani, Mar 2005
2120+ * Implemented EAP-TLS authentication
2121+ */
2122+
2123 #define RCSID "$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $"
2124
2125 /*
2126@@ -62,8 +67,12 @@
2127
2128 #include "pppd.h"
2129 #include "pathnames.h"
2130-#include "md5.h"
2131 #include "eap.h"
2132+#ifdef USE_EAPTLS
2133+#include "eap-tls.h"
2134+#else
2135+#include "md5.h"
2136+#endif /* USE_EAPTLS */
2137
2138 #ifdef USE_SRP
2139 #include <t_pwd.h>
2140@@ -209,6 +218,9 @@
2141 esp->es_server.ea_id = (u_char)(drand48() * 0x100);
2142 esp->es_client.ea_timeout = EAP_DEFREQTIME;
2143 esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
2144+#ifdef USE_EAPTLS
2145+ esp->es_client.ea_using_eaptls = 0;
2146+#endif /* USE_EAPTLS */
2147 }
2148
2149 /*
2150@@ -436,8 +448,16 @@
2151 u_char vals[2];
2152 struct b64state bs;
2153 #endif /* USE_SRP */
2154+#ifdef USE_EAPTLS
2155+ struct eaptls_session *ets;
2156+ int secret_len;
2157+ char secret[MAXWORDLEN];
2158+#endif /* USE_EAPTLS */
2159
2160 esp->es_server.ea_timeout = esp->es_savedtime;
2161+#ifdef USE_EAPTLS
2162+ esp->es_server.ea_prev_state = esp->es_server.ea_state;
2163+#endif /* USE_EAPTLS */
2164 switch (esp->es_server.ea_state) {
2165 case eapBadAuth:
2166 return;
2167@@ -562,9 +582,81 @@
2168 break;
2169 }
2170 #endif /* USE_SRP */
2171+#ifdef USE_EAPTLS
2172+ if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
2173+ esp->es_server.ea_name, secret, &secret_len, 1)) {
2174+
2175+ esp->es_server.ea_state = eapTlsStart;
2176+ break;
2177+ }
2178+#endif /* USE_EAPTLS */
2179+
2180 esp->es_server.ea_state = eapMD5Chall;
2181 break;
2182
2183+#ifdef USE_EAPTLS
2184+ case eapTlsStart:
2185+ /* Initialize ssl session */
2186+ if(!eaptls_init_ssl_server(esp)) {
2187+ esp->es_server.ea_state = eapBadAuth;
2188+ break;
2189+ }
2190+
2191+ esp->es_server.ea_state = eapTlsRecv;
2192+ break;
2193+
2194+ case eapTlsRecv:
2195+ ets = (struct eaptls_session *) esp->es_server.ea_session;
2196+
2197+ if(ets->alert_sent) {
2198+ esp->es_server.ea_state = eapTlsSendAlert;
2199+ break;
2200+ }
2201+
2202+ if (status) {
2203+ esp->es_server.ea_state = eapBadAuth;
2204+ break;
2205+ }
2206+ ets = (struct eaptls_session *) esp->es_server.ea_session;
2207+
2208+ if(ets->frag)
2209+ esp->es_server.ea_state = eapTlsSendAck;
2210+ else
2211+ esp->es_server.ea_state = eapTlsSend;
2212+ break;
2213+
2214+ case eapTlsSend:
2215+ ets = (struct eaptls_session *) esp->es_server.ea_session;
2216+
2217+ if(SSL_is_init_finished(ets->ssl)) {
2218+ esp->es_server.ea_state = eapTlsRecvClient;
2219+ break;
2220+ }
2221+
2222+ if(ets->frag)
2223+ esp->es_server.ea_state = eapTlsRecvAck;
2224+ else
2225+ esp->es_server.ea_state = eapTlsRecv;
2226+ break;
2227+
2228+ case eapTlsSendAck:
2229+ esp->es_server.ea_state = eapTlsRecv;
2230+ break;
2231+
2232+ case eapTlsRecvAck:
2233+ if (status) {
2234+ esp->es_server.ea_state = eapBadAuth;
2235+ break;
2236+ }
2237+
2238+ esp->es_server.ea_state = eapTlsSend;
2239+ break;
2240+
2241+ case eapTlsSendAlert:
2242+ esp->es_server.ea_state = eapTlsRecvAlertAck;
2243+ break;
2244+#endif /* USE_EAPTLS */
2245+
2246 case eapSRP1:
2247 #ifdef USE_SRP
2248 ts = (struct t_server *)esp->es_server.ea_session;
2249@@ -718,6 +810,30 @@
2250 INCPTR(esp->es_server.ea_namelen, outp);
2251 break;
2252
2253+#ifdef USE_EAPTLS
2254+ case eapTlsStart:
2255+ PUTCHAR(EAPT_TLS, outp);
2256+ PUTCHAR(EAP_TLS_FLAGS_START, outp);
2257+ eap_figure_next_state(esp, 0);
2258+ break;
2259+
2260+ case eapTlsSend:
2261+ eaptls_send(esp->es_server.ea_session, &outp);
2262+ eap_figure_next_state(esp, 0);
2263+ break;
2264+
2265+ case eapTlsSendAck:
2266+ PUTCHAR(EAPT_TLS, outp);
2267+ PUTCHAR(0, outp);
2268+ eap_figure_next_state(esp, 0);
2269+ break;
2270+
2271+ case eapTlsSendAlert:
2272+ eaptls_send(esp->es_server.ea_session, &outp);
2273+ eap_figure_next_state(esp, 0);
2274+ break;
2275+#endif /* USE_EAPTLS */
2276+
2277 #ifdef USE_SRP
2278 case eapSRP1:
2279 PUTCHAR(EAPT_SRP, outp);
2280@@ -904,11 +1020,57 @@
2281 eap_server_timeout(arg)
2282 void *arg;
2283 {
2284+#ifdef USE_EAPTLS
2285+ u_char *outp;
2286+ u_char *lenloc;
2287+ int outlen;
2288+#endif /* USE_EAPTLS */
2289+
2290 eap_state *esp = (eap_state *) arg;
2291
2292 if (!eap_server_active(esp))
2293 return;
2294
2295+#ifdef USE_EAPTLS
2296+ switch(esp->es_server.ea_prev_state) {
2297+
2298+ /*
2299+ * In eap-tls the state changes after a request, so we return to
2300+ * previous state ...
2301+ */
2302+ case(eapTlsStart):
2303+ case(eapTlsSendAck):
2304+ esp->es_server.ea_state = esp->es_server.ea_prev_state;
2305+ break;
2306+
2307+ /*
2308+ * ... or resend the stored data
2309+ */
2310+ case(eapTlsSend):
2311+ case(eapTlsSendAlert):
2312+ outp = outpacket_buf;
2313+ MAKEHEADER(outp, PPP_EAP);
2314+ PUTCHAR(EAP_REQUEST, outp);
2315+ PUTCHAR(esp->es_server.ea_id, outp);
2316+ lenloc = outp;
2317+ INCPTR(2, outp);
2318+
2319+ eaptls_retransmit(esp->es_server.ea_session, &outp);
2320+
2321+ outlen = (outp - outpacket_buf) - PPP_HDRLEN;
2322+ PUTSHORT(outlen, lenloc);
2323+ output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
2324+ esp->es_server.ea_requests++;
2325+
2326+ if (esp->es_server.ea_timeout > 0)
2327+ TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
2328+
2329+ return;
2330+ default:
2331+ break;
2332+ }
2333+#endif /* USE_EAPTLS */
2334+
2335 /* EAP ID number must not change on timeout. */
2336 eap_send_request(esp);
2337 }
2338@@ -1166,6 +1328,81 @@
2339 }
2340 #endif /* USE_SRP */
2341
2342+#ifdef USE_EAPTLS
2343+/*
2344+ * Send an EAP-TLS response message with tls data
2345+ */
2346+static void
2347+eap_tls_response(esp, id)
2348+eap_state *esp;
2349+u_char id;
2350+{
2351+ u_char *outp;
2352+ int outlen;
2353+ u_char *lenloc;
2354+
2355+ outp = outpacket_buf;
2356+
2357+ MAKEHEADER(outp, PPP_EAP);
2358+
2359+ PUTCHAR(EAP_RESPONSE, outp);
2360+ PUTCHAR(id, outp);
2361+
2362+ lenloc = outp;
2363+ INCPTR(2, outp);
2364+
2365+ /*
2366+ If the id in the request is unchanged, we must retransmit
2367+ the old data
2368+ */
2369+ if(id == esp->es_client.ea_id)
2370+ eaptls_retransmit(esp->es_client.ea_session, &outp);
2371+ else
2372+ eaptls_send(esp->es_client.ea_session, &outp);
2373+
2374+ outlen = (outp - outpacket_buf) - PPP_HDRLEN;
2375+ PUTSHORT(outlen, lenloc);
2376+
2377+ output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
2378+
2379+ esp->es_client.ea_id = id;
2380+
2381+}
2382+
2383+/*
2384+ * Send an EAP-TLS ack
2385+ */
2386+static void
2387+eap_tls_sendack(esp, id)
2388+eap_state *esp;
2389+u_char id;
2390+{
2391+ u_char *outp;
2392+ int outlen;
2393+ u_char *lenloc;
2394+
2395+ outp = outpacket_buf;
2396+
2397+ MAKEHEADER(outp, PPP_EAP);
2398+
2399+ PUTCHAR(EAP_RESPONSE, outp);
2400+ PUTCHAR(id, outp);
2401+ esp->es_client.ea_id = id;
2402+
2403+ lenloc = outp;
2404+ INCPTR(2, outp);
2405+
2406+ PUTCHAR(EAPT_TLS, outp);
2407+ PUTCHAR(0, outp);
2408+
2409+ outlen = (outp - outpacket_buf) - PPP_HDRLEN;
2410+ PUTSHORT(outlen, lenloc);
2411+
2412+ output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
2413+
2414+}
2415+#endif /* USE_EAPTLS */
2416+
2417 static void
2418 eap_send_nak(esp, id, type)
2419 eap_state *esp;
2420@@ -1320,6 +1557,11 @@
2421 char rhostname[256];
2422 MD5_CTX mdContext;
2423 u_char hash[MD5_SIGNATURE_SIZE];
2424+#ifdef USE_EAPTLS
2425+ u_char flags;
2426+ struct eaptls_session *ets = esp->es_client.ea_session;
2427+#endif /* USE_EAPTLS */
2428+
2429 #ifdef USE_SRP
2430 struct t_client *tc;
2431 struct t_num sval, gval, Nval, *Ap, Bval;
2432@@ -1456,6 +1698,90 @@
2433 esp->es_client.ea_namelen);
2434 break;
2435
2436+#ifdef USE_EAPTLS
2437+ case EAPT_TLS:
2438+
2439+ switch(esp->es_client.ea_state) {
2440+
2441+ case eapListen:
2442+
2443+ GETCHAR(flags, inp);
2444+ if(flags & EAP_TLS_FLAGS_START){
2445+
2446+ esp->es_client.ea_using_eaptls = 1;
2447+
2448+ if (explicit_remote){
2449+ esp->es_client.ea_peer = strdup(remote_name);
2450+ esp->es_client.ea_peerlen = strlen(remote_name);
2451+ } else
2452+ esp->es_client.ea_peer = NULL;
2453+
2454+ /* Init ssl session */
2455+ if(!eaptls_init_ssl_client(esp)) {
2456+ dbglog("cannot init ssl");
2457+ eap_send_nak(esp, id, EAPT_TLS);
2458+ esp->es_client.ea_using_eaptls = 0;
2459+ break;
2460+ }
2461+
2462+ ets = esp->es_client.ea_session;
2463+ eap_tls_response(esp, id);
2464+ esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck :
2465+ eapTlsRecv);
2466+ break;
2467+ }
2468+
2469+ /* The server has sent a bad start packet. */
2470+ eap_send_nak(esp, id, EAPT_TLS);
2471+ break;
2472+
2473+ case eapTlsRecvAck:
2474+ eap_tls_response(esp, id);
2475+ esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck :
2476+ eapTlsRecv);
2477+ break;
2478+
2479+ case eapTlsRecv:
2480+ eaptls_receive(ets, inp, len);
2481+
2482+ if(ets->frag) {
2483+ eap_tls_sendack(esp, id);
2484+ esp->es_client.ea_state = eapTlsRecv;
2485+ break;
2486+ }
2487+
2488+ if(ets->alert_recv) {
2489+ eap_tls_sendack(esp, id);
2490+ esp->es_client.ea_state = eapTlsRecvFailure;
2491+ break;
2492+ }
2493+
2494+ /* Check if TLS handshake is finished */
2495+ if(SSL_is_init_finished(ets->ssl)){
2496+#ifdef MPPE
2497+ eaptls_gen_mppe_keys( ets, "client EAP encryption", 1 );
2498+#endif
2499+ eaptls_free_session(ets);
2500+ eap_tls_sendack(esp, id);
2501+ esp->es_client.ea_state = eapTlsRecvSuccess;
2502+ break;
2503+ }
2504+
2505+ eap_tls_response(esp,id);
2506+ esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck :
2507+ eapTlsRecv);
2508+
2509+ break;
2510+
2511+ default:
2512+ eap_send_nak(esp, id, EAPT_TLS);
2513+ esp->es_client.ea_using_eaptls = 0;
2514+ break;
2515+ }
2516+
2517+ break;
2518+#endif /* USE_EAPTLS */
2519+
2520 #ifdef USE_SRP
2521 case EAPT_SRP:
2522 if (len < 1) {
2523@@ -1737,6 +2063,11 @@
2524 u_char dig[SHA_DIGESTSIZE];
2525 #endif /* USE_SRP */
2526
2527+#ifdef USE_EAPTLS
2528+ struct eaptls_session *ets;
2529+ u_char flags;
2530+#endif /* USE_EAPTLS */
2531+
2532 if (esp->es_server.ea_id != id) {
2533 dbglog("EAP: discarding Response %d; expected ID %d", id,
2534 esp->es_server.ea_id);
2535@@ -1776,6 +2107,60 @@
2536 eap_figure_next_state(esp, 0);
2537 break;
2538
2539+#ifdef USE_EAPTLS
2540+ case EAPT_TLS:
2541+ switch(esp->es_server.ea_state) {
2542+
2543+ case eapTlsRecv:
2544+ ets = (struct eaptls_session *) esp->es_server.ea_session;
2545+ eap_figure_next_state(esp,
2546+ eaptls_receive(esp->es_server.ea_session, inp, len));
2547+
2548+ if(ets->alert_recv) {
2549+ eap_send_failure(esp);
2550+ break;
2551+ }
2552+ break;
2553+
2554+ case eapTlsRecvAck:
2555+ if(len > 1) {
2556+ dbglog("EAP-TLS ACK with extra data");
2557+ }
2558+ eap_figure_next_state(esp, 0);
2559+ break;
2560+
2561+ case eapTlsRecvClient:
2562+ /* Receive authentication response from client */
2563+
2564+ GETCHAR(flags, inp);
2565+
2566+ if(len == 1 && !flags) { /* Ack = ok */
2567+#ifdef MPPE
2568+ eaptls_gen_mppe_keys( esp->es_server.ea_session, "client EAP encryption", 0 );
2569+#endif
2570+ eap_send_success(esp);
2571+ }
2572+ else { /* failure */
2573+ eaptls_receive(esp->es_server.ea_session, inp, len);
2574+ warn("Server authentication failed");
2575+ eap_send_failure(esp);
2576+ }
2577+
2578+ eaptls_free_session(esp->es_server.ea_session);
2579+
2580+ break;
2581+
2582+ case eapTlsRecvAlertAck:
2583+ eap_send_failure(esp);
2584+ break;
2585+
2586+ default:
2587+ eap_figure_next_state(esp, 1);
2588+ break;
2589+ }
2590+ break;
2591+#endif /* USE_EAPTLS */
2592+
2593 case EAPT_NOTIFICATION:
2594 dbglog("EAP unexpected Notification; response discarded");
2595 break;
2596@@ -1807,6 +2192,13 @@
2597 esp->es_server.ea_state = eapMD5Chall;
2598 break;
2599
2600+#ifdef USE_EAPTLS
2601+ /* Send EAP-TLS start packet */
2602+ case EAPT_TLS:
2603+ esp->es_server.ea_state = eapTlsStart;
2604+ break;
2605+#endif /* USE_EAPTLS */
2606+
2607 default:
2608 dbglog("EAP: peer requesting unknown Type %d", vallen);
2609 switch (esp->es_server.ea_state) {
2610@@ -2018,13 +2410,27 @@
2611 int id;
2612 int len;
2613 {
2614- if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)) {
2615+ if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
2616+#ifdef USE_EAPTLS
2617+ && esp->es_client.ea_state != eapTlsRecvSuccess
2618+#endif /* USE_EAPTLS */
2619+ ) {
2620 dbglog("EAP unexpected success message in state %s (%d)",
2621 eap_state_name(esp->es_client.ea_state),
2622 esp->es_client.ea_state);
2623 return;
2624 }
2625
2626+#ifdef USE_EAPTLS
2627+ if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state !=
2628+ eapTlsRecvSuccess) {
2629+ dbglog("EAP-TLS unexpected success message in state %s (%d)",
2630+ eap_state_name(esp->es_client.ea_state),
2631+ esp->es_client.ea_state);
2632+ return;
2633+ }
2634+#endif /* USE_EAPTLS */
2635+
2636 if (esp->es_client.ea_timeout > 0) {
2637 UNTIMEOUT(eap_client_timeout, (void *)esp);
2638 }
2639@@ -2150,6 +2556,9 @@
2640 int code, id, len, rtype, vallen;
2641 u_char *pstart;
2642 u_int32_t uval;
2643+#ifdef USE_EAPTLS
2644+ u_char flags;
2645+#endif /* USE_EAPTLS */
2646
2647 if (inlen < EAP_HEADERLEN)
2648 return (0);
2649@@ -2214,6 +2623,24 @@
2650 }
2651 break;
2652
2653+#ifdef USE_EAPTLS
2654+ case EAPT_TLS:
2655+ if (len < 1)
2656+ break;
2657+ GETCHAR(flags, inp);
2658+ len--;
2659+
2660+ if(flags == 0 && len == 0){
2661+ printer(arg, " Ack");
2662+ break;
2663+ }
2664+
2665+ printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
2666+ printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
2667+ printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
2668+ break;
2669+#endif /* USE_EAPTLS */
2670+
2671 case EAPT_SRP:
2672 if (len < 3)
2673 goto truncated;
2674@@ -2325,6 +2752,25 @@
2675 }
2676 break;
2677
2678+#ifdef USE_EAPTLS
2679+ case EAPT_TLS:
2680+ if (len < 1)
2681+ break;
2682+ GETCHAR(flags, inp);
2683+ len--;
2684+
2685+ if(flags == 0 && len == 0){
2686+ printer(arg, " Ack");
2687+ break;
2688+ }
2689+
2690+ printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
2691+ printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
2692+ printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
2693+
2694+ break;
2695+#endif /* USE_EAPTLS */
2696+
2697 case EAPT_NAK:
2698 if (len <= 0) {
2699 printer(arg, " <missing hint>");
2700@@ -2426,3 +2872,4 @@
2701
2702 return (inp - pstart);
2703 }
2704+
2705diff -Naur ppp-2.4.5/pppd/eap.h ppp-2.4.5-eaptls-mppe-0.99/pppd/eap.h
2706--- ppp-2.4.5/pppd/eap.h 2009-11-16 23:26:07.000000000 +0100
2707+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/eap.h 2010-10-01 15:17:54.214270927 +0200
2708@@ -84,6 +84,16 @@
2709 eapClosed, /* Authentication not in use */
2710 eapListen, /* Client ready (and timer running) */
2711 eapIdentify, /* EAP Identify sent */
2712+ eapTlsStart, /* Send EAP-TLS start packet */
2713+ eapTlsRecv, /* Receive EAP-TLS tls data */
2714+ eapTlsSendAck, /* Send EAP-TLS ack */
2715+ eapTlsSend, /* Send EAP-TLS tls data */
2716+ eapTlsRecvAck, /* Receive EAP-TLS ack */
2717+ eapTlsRecvClient, /* Receive EAP-TLS auth response from client*/
2718+ eapTlsSendAlert, /* Send EAP-TLS tls alert (server)*/
2719+ eapTlsRecvAlertAck, /* Receive EAP-TLS ack after sending alert */
2720+ eapTlsRecvSuccess, /* Receive EAP success */
2721+ eapTlsRecvFailure, /* Receive EAP failure */
2722 eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */
2723 eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */
2724 eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */
2725@@ -95,9 +105,18 @@
2726
2727 #define EAP_STATES \
2728 "Initial", "Pending", "Closed", "Listen", "Identify", \
2729+ "TlsStart", "TlsRecv", "TlsSendAck", "TlsSend", "TlsRecvAck", "TlsRecvClient",\
2730+ "TlsSendAlert", "TlsRecvAlertAck" , "TlsRecvSuccess", "TlsRecvFailure", \
2731 "SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth"
2732
2733-#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen)
2734+#ifdef USE_EAPTLS
2735+#define eap_client_active(esp) ((esp)->es_client.ea_state != eapInitial ||\
2736+ (esp)->es_client.ea_state != eapPending ||\
2737+ (esp)->es_client.ea_state != eapClosed)
2738+#else
2739+#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen)
2740+#endif /* USE_EAPTLS */
2741+
2742 #define eap_server_active(esp) \
2743 ((esp)->es_server.ea_state >= eapIdentify && \
2744 (esp)->es_server.ea_state <= eapMD5Chall)
2745@@ -112,11 +131,17 @@
2746 u_short ea_namelen; /* Length of our name */
2747 u_short ea_peerlen; /* Length of peer's name */
2748 enum eap_state_code ea_state;
2749+#ifdef USE_EAPTLS
2750+ enum eap_state_code ea_prev_state;
2751+#endif
2752 u_char ea_id; /* Current id */
2753 u_char ea_requests; /* Number of Requests sent/received */
2754 u_char ea_responses; /* Number of Responses */
2755 u_char ea_type; /* One of EAPT_* */
2756 u_int32_t ea_keyflags; /* SRP shared key usage flags */
2757+#ifdef USE_EAPTLS
2758+ bool ea_using_eaptls;
2759+#endif
2760 };
2761
2762 /*
2763@@ -139,7 +164,12 @@
2764 * Timeouts.
2765 */
2766 #define EAP_DEFTIMEOUT 3 /* Timeout (seconds) for rexmit */
2767+#ifdef USE_EAPTLS
2768+#define EAP_DEFTRANSMITS 30 /* max # times to transmit */
2769+ /* certificates can be long ... */
2770+#else
2771 #define EAP_DEFTRANSMITS 10 /* max # times to transmit */
2772+#endif /* USE_EAPTLS */
2773 #define EAP_DEFREQTIME 20 /* Time to wait for peer request */
2774 #define EAP_DEFALLOWREQ 20 /* max # times to accept requests */
2775
2776diff -Naur ppp-2.4.5/pppd/md5.c ppp-2.4.5-eaptls-mppe-0.99/pppd/md5.c
2777--- ppp-2.4.5/pppd/md5.c 2009-11-16 23:26:07.000000000 +0100
2778+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/md5.c 2010-10-01 15:17:54.214270927 +0200
2779@@ -33,6 +33,8 @@
2780 ***********************************************************************
2781 */
2782
2783+#ifndef USE_EAPTLS
2784+
2785 #include <string.h>
2786 #include "md5.h"
2787
2788@@ -305,3 +307,5 @@
2789 ** End of md5.c **
2790 ******************************** (cut) ********************************
2791 */
2792+#endif /* USE_EAPTLS */
2793+
2794diff -Naur ppp-2.4.5/pppd/md5.h ppp-2.4.5-eaptls-mppe-0.99/pppd/md5.h
2795--- ppp-2.4.5/pppd/md5.h 2009-11-16 23:26:07.000000000 +0100
2796+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/md5.h 2010-10-01 15:17:54.215271014 +0200
2797@@ -36,6 +36,7 @@
2798 ** documentation and/or software. **
2799 ***********************************************************************
2800 */
2801+#ifndef USE_EAPTLS
2802
2803 #ifndef __MD5_INCLUDE__
2804
2805@@ -63,3 +64,5 @@
2806
2807 #define __MD5_INCLUDE__
2808 #endif /* __MD5_INCLUDE__ */
2809+
2810+#endif /* USE_EAPTLS */
2811diff -Naur ppp-2.4.5/pppd/options.c ppp-2.4.5-eaptls-mppe-0.99/pppd/options.c
2812--- ppp-2.4.5/pppd/options.c 2009-11-16 23:26:07.000000000 +0100
2813+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/options.c 2010-10-01 15:17:54.215271014 +0200
2814@@ -119,6 +119,10 @@
2815 bool dryrun; /* print out option values and exit */
2816 char *domain; /* domain name set by domain option */
2817 int child_wait = 5; /* # seconds to wait for children at exit */
2818+#ifdef USE_EAPTLS
2819+bool only_update_crl_server = 0; /* update server crl and exit */
2820+bool only_update_crl_client = 0; /* update client crl and exit */
2821+#endif /* USE_EAPTLS */
2822
2823 #ifdef MAXOCTETS
2824 unsigned int maxoctets = 0; /* default - no limit */
2825@@ -320,6 +324,12 @@
2826 { "mo-timeout", o_int, &maxoctets_timeout,
2827 "Check for traffic limit every N seconds", OPT_PRIO | OPT_LLIMIT | 1 },
2828 #endif
2829+#ifdef USE_EAPTLS
2830+ { "only-update-crl-server", o_bool, &only_update_crl_server,
2831+ "Update server CA CRLs and exit", 1 },
2832+ { "only-update-crl-client", o_bool, &only_update_crl_client,
2833+ "Update client CA CRLs and exit", 1 },
2834+#endif /* USE_EAPTLS */
2835
2836 { NULL }
2837 };
2838diff -Naur ppp-2.4.5/pppd/pathnames.h ppp-2.4.5-eaptls-mppe-0.99/pppd/pathnames.h
2839--- ppp-2.4.5/pppd/pathnames.h 2009-11-16 23:26:07.000000000 +0100
2840+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/pathnames.h 2010-10-01 15:17:54.215271014 +0200
2841@@ -21,6 +21,13 @@
2842 #define _PATH_UPAPFILE _ROOT_PATH "/etc/ppp/pap-secrets"
2843 #define _PATH_CHAPFILE _ROOT_PATH "/etc/ppp/chap-secrets"
2844 #define _PATH_SRPFILE _ROOT_PATH "/etc/ppp/srp-secrets"
2845+
2846+#ifdef USE_EAPTLS
2847+#define _PATH_EAPTLSCLIFILE _ROOT_PATH "/etc/ppp/eaptls-client"
2848+#define _PATH_EAPTLSSERVFILE _ROOT_PATH "/etc/ppp/eaptls-server"
2849+#define _PATH_OPENSSLCONFFILE _ROOT_PATH "/etc/ppp/openssl.cnf"
2850+#endif /* USE_EAPTLS */
2851+
2852 #define _PATH_SYSOPTIONS _ROOT_PATH "/etc/ppp/options"
2853 #define _PATH_IPUP _ROOT_PATH "/etc/ppp/ip-up"
2854 #define _PATH_IPDOWN _ROOT_PATH "/etc/ppp/ip-down"
2855diff -Naur ppp-2.4.5/pppd/plugins/Makefile.linux ppp-2.4.5-eaptls-mppe-0.99/pppd/plugins/Makefile.linux
2856--- ppp-2.4.5/pppd/plugins/Makefile.linux 2009-11-16 23:26:07.000000000 +0100
2857+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/plugins/Makefile.linux 2010-10-01 15:17:54.215271014 +0200
2858@@ -4,6 +4,9 @@
2859 LDFLAGS = -shared
2860 INSTALL = install
2861
2862+# EAP-TLS
2863+CFLAGS += -DUSE_EAPTLS=1
2864+
2865 DESTDIR = $(INSTROOT)@DESTDIR@
2866 BINDIR = $(DESTDIR)/sbin
2867 MANDIR = $(DESTDIR)/share/man/man8
2868diff -Naur ppp-2.4.5/pppd/plugins/passprompt.c ppp-2.4.5-eaptls-mppe-0.99/pppd/plugins/passprompt.c
2869--- ppp-2.4.5/pppd/plugins/passprompt.c 2009-11-16 23:26:07.000000000 +0100
2870+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/plugins/passprompt.c 2010-10-01 15:17:54.215271014 +0200
2871@@ -107,4 +107,7 @@
2872 {
2873 add_options(options);
2874 pap_passwd_hook = promptpass;
2875+#ifdef USE_EAPTLS
2876+ eaptls_passwd_hook = promptpass;
2877+#endif
2878 }
2879diff -Naur ppp-2.4.5/pppd/plugins/passwordfd.c ppp-2.4.5-eaptls-mppe-0.99/pppd/plugins/passwordfd.c
2880--- ppp-2.4.5/pppd/plugins/passwordfd.c 2009-11-16 23:26:07.000000000 +0100
2881+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/plugins/passwordfd.c 2010-10-01 15:17:54.216270820 +0200
2882@@ -79,4 +79,9 @@
2883
2884 chap_check_hook = pwfd_check;
2885 chap_passwd_hook = pwfd_passwd;
2886+
2887+#ifdef USE_EAPTLS
2888+ eaptls_check_hook = pwfd_check;
2889+ eaptls_passwd_hook = pwfd_passwd;
2890+#endif
2891 }
2892diff -Naur ppp-2.4.5/pppd/pppd.h ppp-2.4.5-eaptls-mppe-0.99/pppd/pppd.h
2893--- ppp-2.4.5/pppd/pppd.h 2009-11-16 23:26:07.000000000 +0100
2894+++ ppp-2.4.5-eaptls-mppe-0.99/pppd/pppd.h 2010-10-01 15:17:54.216270820 +0200
2895@@ -320,6 +320,10 @@
2896 extern bool dryrun; /* check everything, print options, exit */
2897 extern int child_wait; /* # seconds to wait for children at end */
2898
2899+#ifdef USE_EAPTLS
2900+extern char *crl_dir;
2901+#endif /* USE_EAPTLS */
2902+
2903 #ifdef MAXOCTETS
2904 extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */
2905 extern int maxoctets_dir; /* Direction :
2906@@ -717,6 +721,11 @@
2907 extern int (*chap_passwd_hook) __P((char *user, char *passwd));
2908 extern void (*multilink_join_hook) __P((void));
2909
2910+#ifdef USE_EAPTLS
2911+extern int (*eaptls_check_hook) __P((void));
2912+extern int (*eaptls_passwd_hook) __P((char *user, char *passwd));
2913+#endif
2914+
2915 /* Let a plugin snoop sent and received packets. Useful for L2TP */
2916 extern void (*snoop_recv_hook) __P((unsigned char *p, int len));
2917 extern void (*snoop_send_hook) __P((unsigned char *p, int len));