]> git.ipfire.org Git - people/amarx/ipfire-3.x.git/blob - 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
1 diff -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 +
174 diff -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
188 diff -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
203 diff -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 +
221 diff -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 $@
244 diff -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)
273 diff -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 +
769 diff -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 }
807 diff -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
822 diff -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 +
2000 diff -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
2111 diff -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 +
2705 diff -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
2776 diff -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 +
2794 diff -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 */
2811 diff -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 };
2838 diff -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"
2855 diff -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
2868 diff -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 }
2879 diff -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 }
2892 diff -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));