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

Annotation 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 - (hide 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 vip-ire 1.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