/[smeserver]/rpms/ppp/sme10/ppp-2.4.5-eaptls-mppe-0.99.patch
ViewVC logotype

Contents of /rpms/ppp/sme10/ppp-2.4.5-eaptls-mppe-0.99.patch

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download)
Thu Feb 4 13:23:45 2016 UTC (8 years, 3 months ago) by vip-ire
Branch: MAIN
CVS Tags: ppp-2_4_5-24_el7_sme, HEAD
sme10 branch

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

admin@koozali.org
ViewVC Help
Powered by ViewVC 1.2.1 RSS 2.0 feed