~ubuntu-branches/ubuntu/trusty/ppp/trusty

« back to all changes in this revision

Viewing changes to debian/patches/ppp-2.4.5-eaptls-mppe-0.994.patch

  • Committer: Jamie Strandboge
  • Author(s): Pavel Plesov
  • Date: 2013-01-22 22:09:03 UTC
  • mfrom: (27.1.1 ppp)
  • Revision ID: jamie@canonical.com-20130122220903-5r8pmz68jquzmn08
Tags: 2.4.5-5.1ubuntu2
add  EAPTLS-MPPE 0.994 patch from http://www.nikhef.nl/~janjust/ppp/

Show diffs side-by-side

added added

removed removed

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