Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 436122
Collapse All | Expand All

(-)ppp-2.4.5.orig/README.eap-tls (+169 lines)
Line 0 Link Here
1
EAP-TLS authentication support for PPP
2
======================================
3
4
1. Intro
5
6
    The Extensible Authentication Protocol (EAP; RFC 3748) is a
7
    security protocol that can be used with PPP.  It provides a means
8
    to plug in multiple optional authentication methods.
9
10
    Transport Level Security (TLS; RFC 2246) provides for mutual 
11
    authentication, integrity-protected ciphersuite negotiation and 
12
    key exchange between two endpoints.  It also provides for optional
13
    MPPE encryption.
14
15
    EAP-TLS (RFC 2716) incapsulates the TLS messages in EAP packets,
16
    allowing TLS mutual authentication to be used as a generic EAP
17
    mechanism. It also provides optional encryption using the MPPE
18
    protocol.
19
20
    This patch provide EAP-TLS support to pppd.
21
    This authentication method can be used in both client or server
22
    mode.
23
24
2. Building
25
26
    To build pppd with EAP-TLS support, OpenSSL (http://www.openssl.org)
27
    is required. Any version from 0.9.7 should work.
28
    
29
    Configure, compile, and install as usual. 
30
31
3. Configuration
32
33
    On the client side there are two ways to configure EAP-TLS:
34
35
	1. supply the appropriate 'ca', 'cert' and 'key' command-line parameters
36
37
	2. edit the /etc/ppp/eaptls-client file.
38
    Insert a line for each system with which you use EAP-TLS.
39
    The line is composed of this fields separated by tab:
40
41
      - Client name 
42
		The name used by the client for authentication, can be *
43
      - Server name
44
		The name of the server, can be *
45
      - Client certificate file 
46
		The file containing the certificate chain for the 
47
		client in PEM format
48
      - Server certificate file
49
		If you want to specify the certificate that the 
50
		server is allowed to use, put the certificate file name.
51
		Else put a dash '-'.
52
      - CA certificate file
53
		The file containing the trusted CA certificates in PEM
54
		format.
55
      - Client private key file
56
		The file containing the client private key in PEM format.
57
58
59
    On the server side edit the /etc/ppp/eaptls-server file.
60
    Insert a line for each system with which you use EAP-TLS.
61
    The line is composed of this fields separated by tab:
62
63
      - Client name
64
                The name used by the client for authentication, can be *
65
      - Server name
66
                The name of the server, can be *
67
      - Client certificate file
68
                If you want to specify the certificate that the
69
                client is allowed to use, put the certificate file name.
70
                Else put a dash '-'.
71
      - Server certificate file
72
		The file containing the certificate chain for the
73
                server in PEM format
74
      - CA certificate file
75
                The file containing the trusted CA certificates in PEM
76
                format.
77
      - Client private key file
78
                The file containing the server private key in PEM format.
79
      - addresses
80
		A list of IP addresses the client is allowed to use.
81
82
83
    OpenSSL engine support is included starting with v0.95 of this patch. 
84
    Currently the only engine tested is the 'pkcs11' engine (hardware token
85
    support). To use the 'pksc11' engine:
86
      - Use a special private key fileiname in the /etc/ppp/eaptls-client file:
87
          <engine>:<identifier>
88
        e.g.
89
          pkcs11:123456
90
91
      - The certificate can also be loaded from the 'pkcs11' engine using
92
        a special client certificate filename in the /etc/ppp/eaptls-client file:
93
          <engine>:<identifier>
94
        e.g.
95
          pkcs11:123456
96
97
      - Create an /etc/ppp/openssl.cnf file to load the right OpenSSL engine prior
98
        to starting 'pppd'. A sample openssl.cnf file is
99
100
        openssl_conf = openssl_def
101
102
        [ openssl_def ]
103
        engines = engine_section
104
105
        [ engine_section ]
106
        pkcs11 = pkcs11_section
107
108
        [ pkcs11_section ]
109
        engine_id = pkcs11
110
        dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so
111
        MODULE_PATH = /usr/lib64/libeTPkcs11.so
112
        init = 0
113
114
      - There are two ways to specify a password/PIN for the PKCS11 engine:
115
          - inside the openssl.cnf file using
116
              PIN = your-secret-pin
117
            Note The keyword 'PIN' is case sensitive!
118
          - Using the 'password' in the ppp options file.
119
        From v0.97 of the eap-tls patch the password can also be supplied
120
        using the appropriate 'eaptls_passwd_hook' (see plugins/passprompt.c
121
        for an example).
122
123
124
4. Options
125
126
      These pppd options are available:
127
128
	  ca <ca-file>
129
			Use the CA public certificate found in <ca-file> in PEM format
130
	  cert <cert-file>
131
			Use the client public certificate found in <cert-file> in PEM format
132
			or in engine:engine_id format
133
	  key <key-file>
134
			Use the client private key found in <key-file> in PEM format
135
			or in engine:engine_id format
136
      crl-dir <dir>
137
        	Use CRL files from dir. It contains CRL files in PEM
138
		format and each file contains a CRL. The files are looked up 
139
		by the issuer name hash value. Use the c_rehash utility 
140
		to create necessary links.
141
      need-peer-eap
142
		If the peer doesn't ask us to authenticate or doesn't use eap
143
		to authenticate us, disconnect.
144
145
      Note: 
146
        password-encrypted certificates can be used as of v0.94 of this 
147
        patch. The password for the eap-tls.key file is specified using 
148
        the regular
149
          password ....
150
        statement in the ppp options file, or by using the appropriate
151
        plugin which supplies a 'eaptls_passwd_hook' routine.
152
153
5. Connecting
154
155
    If you're setting up a pppd server, edit the EAP-TLS configuration file 
156
    as written above and then run pppd with the 'auth' option to authenticate
157
    the client. The EAP-TLS method will be used if the other eap methods can't
158
    be used (no secrets).
159
160
    If you're setting up a client, edit the configuration file and then run
161
    pppd with 'remotename' option to specify the server name. Add the 
162
    'need-peer-eap' option if you want to be sure the peer ask you to
163
    authenticate (and to use eap) and to disconnect if it doesn't.
164
165
6. Notes
166
167
   This is experimental code.
168
   Send suggestions and comments to Jan Just Keijser <janjust@nikhef.nl>
169
(-)ppp-2.4.5.orig/etc.ppp/eaptls-client (+10 lines)
Line 0 Link Here
1
# Parameters for authentication using EAP-TLS (client)
2
3
# client name (can be *)
4
# server name (can be *)
5
# client certificate file (required)
6
# server certificate file (optional, if unused put '-')
7
# CA certificate file (required)
8
# client private key file (required)
9
10
#client	server	/root/cert/client.crt	-	/root/cert/ca.crt	/root/cert/client.key
(-)ppp-2.4.5.orig/etc.ppp/eaptls-server (+11 lines)
Line 0 Link Here
1
# Parameters for authentication using EAP-TLS (server)
2
3
# client name (can be *)
4
# server name (can be *)
5
# client certificate file (optional, if unused put '-')
6
# server certificate file (required)
7
# CA certificate file (required)
8
# server private key file (required)
9
# allowed addresses (required, can be *)
10
11
#client	server	-	/root/cert/server.crt	/root/cert/ca.crt	/root/cert/server.key	192.168.1.0/24
(-)ppp-2.4.5.orig/etc.ppp/openssl.cnf (+14 lines)
Line 0 Link Here
1
openssl_conf = openssl_def
2
3
[ openssl_def ]
4
engines = engine_section
5
6
[ engine_section ]
7
pkcs11 = pkcs11_section
8
9
[ pkcs11_section ]
10
engine_id = pkcs11
11
dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so
12
MODULE_PATH = /usr/lib64/libeTPkcs11.so
13
init = 0
14
(-)ppp-2.4.5.orig/linux/Makefile.top (-1 / +5 lines)
Lines 26-32 Link Here
26
	cd pppdump; $(MAKE) $(MFLAGS) install
26
	cd pppdump; $(MAKE) $(MFLAGS) install
27
27
28
install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \
28
install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \
29
	$(ETCDIR)/chap-secrets
29
	$(ETCDIR)/chap-secrets $(ETCDIR)/eaptls-server $(ETCDIR)/eaptls-client
30
30
31
install-devel:
31
install-devel:
32
	cd pppd; $(MAKE) $(MFLAGS) install-devel
32
	cd pppd; $(MAKE) $(MFLAGS) install-devel
Lines 37-42 Link Here
37
	$(INSTALL) -c -m 600 etc.ppp/pap-secrets $@
37
	$(INSTALL) -c -m 600 etc.ppp/pap-secrets $@
38
$(ETCDIR)/chap-secrets:
38
$(ETCDIR)/chap-secrets:
39
	$(INSTALL) -c -m 600 etc.ppp/chap-secrets $@
39
	$(INSTALL) -c -m 600 etc.ppp/chap-secrets $@
40
$(ETCDIR)/eaptls-server:
41
	$(INSTALL) -c -m 600 etc.ppp/eaptls-server $@
42
$(ETCDIR)/eaptls-client:
43
	$(INSTALL) -c -m 600 etc.ppp/eaptls-client $@
40
44
41
$(BINDIR):
45
$(BINDIR):
42
	$(INSTALL) -d -m 755 $@
46
	$(INSTALL) -d -m 755 $@
(-)ppp-2.4.5.orig/pppd/Makefile.linux (+12 lines)
Lines 73-78 Link Here
73
# Enable EAP SRP-SHA1 authentication (requires libsrp)
73
# Enable EAP SRP-SHA1 authentication (requires libsrp)
74
#USE_SRP=y
74
#USE_SRP=y
75
75
76
# Enable EAP-TLS authentication (requires libssl and libcrypto)
77
USE_EAPTLS=y
78
76
MAXOCTETS=y
79
MAXOCTETS=y
77
80
78
INCLUDE_DIRS= -I../include
81
INCLUDE_DIRS= -I../include
Lines 112-117 Link Here
112
PPPDOBJS += sha1.o
115
PPPDOBJS += sha1.o
113
endif
116
endif
114
117
118
# EAP-TLS
119
ifdef USE_EAPTLS
120
CFLAGS += -DUSE_EAPTLS=1 -I/usr/kerberos/include
121
LIBS += -lssl -lcrypto
122
PPPDSRC += eap-tls.c
123
HEADERS += eap-tls.h
124
PPPDOBJS += eap-tls.o
125
endif
126
115
ifdef HAS_SHADOW
127
ifdef HAS_SHADOW
116
CFLAGS   += -DHAS_SHADOW
128
CFLAGS   += -DHAS_SHADOW
117
#LIBS     += -lshadow $(LIBS)
129
#LIBS     += -lshadow $(LIBS)
(-)ppp-2.4.5.orig/pppd/auth.c (-2 / +409 lines)
Lines 109-114 Link Here
109
#include "upap.h"
109
#include "upap.h"
110
#include "chap-new.h"
110
#include "chap-new.h"
111
#include "eap.h"
111
#include "eap.h"
112
#ifdef USE_EAPTLS
113
#include "eap-tls.h"
114
#endif
112
#ifdef CBCP_SUPPORT
115
#ifdef CBCP_SUPPORT
113
#include "cbcp.h"
116
#include "cbcp.h"
114
#endif
117
#endif
Lines 183-188 Link Here
183
/* Hook for a plugin to get the CHAP password for authenticating us */
186
/* Hook for a plugin to get the CHAP password for authenticating us */
184
int (*chap_passwd_hook) __P((char *user, char *passwd)) = NULL;
187
int (*chap_passwd_hook) __P((char *user, char *passwd)) = NULL;
185
188
189
#ifdef USE_EAPTLS
190
/* Hook for a plugin to get the EAP-TLS password for authenticating us */
191
int (*eaptls_passwd_hook) __P((char *user, char *passwd)) = NULL;
192
#endif
193
186
/* Hook for a plugin to say whether it is OK if the peer
194
/* Hook for a plugin to say whether it is OK if the peer
187
   refuses to authenticate. */
195
   refuses to authenticate. */
188
int (*null_auth_hook) __P((struct wordlist **paddrs,
196
int (*null_auth_hook) __P((struct wordlist **paddrs,
Lines 238-243 Link Here
238
bool explicit_user = 0;		/* Set if "user" option supplied */
246
bool explicit_user = 0;		/* Set if "user" option supplied */
239
bool explicit_passwd = 0;	/* Set if "password" option supplied */
247
bool explicit_passwd = 0;	/* Set if "password" option supplied */
240
char remote_name[MAXNAMELEN];	/* Peer's name for authentication */
248
char remote_name[MAXNAMELEN];	/* Peer's name for authentication */
249
#ifdef USE_EAPTLS
250
char *cacert_file  = NULL;	/* CA certificate file (pem format) */
251
char *cert_file    = NULL;	/* client certificate file (pem format) */
252
char *privkey_file = NULL;	/* client private key file (pem format) */
253
char *crl_dir      = NULL;	/* directory containing CRL files */
254
bool need_peer_eap = 0;			/* Require peer to authenticate us */
255
#endif
241
256
242
static char *uafname;		/* name of most recent +ua file */
257
static char *uafname;		/* name of most recent +ua file */
243
258
Lines 254-259 Link Here
254
static int  have_chap_secret __P((char *, char *, int, int *));
269
static int  have_chap_secret __P((char *, char *, int, int *));
255
static int  have_srp_secret __P((char *client, char *server, int need_ip,
270
static int  have_srp_secret __P((char *client, char *server, int need_ip,
256
    int *lacks_ipp));
271
    int *lacks_ipp));
272
273
#ifdef USE_EAPTLS
274
static int  have_eaptls_secret_server
275
__P((char *client, char *server, int need_ip, int *lacks_ipp));
276
static int  have_eaptls_secret_client __P((char *client, char *server));
277
static int  scan_authfile_eaptls __P((FILE * f, char *client, char *server,
278
			       char *cli_cert, char *serv_cert,
279
			       char *ca_cert, char *pk,
280
			       struct wordlist ** addrs,
281
			       struct wordlist ** opts,
282
			       char *filename, int flags));
283
#endif
284
257
static int  ip_addr_check __P((u_int32_t, struct permitted_ip *));
285
static int  ip_addr_check __P((u_int32_t, struct permitted_ip *));
258
static int  scan_authfile __P((FILE *, char *, char *, char *,
286
static int  scan_authfile __P((FILE *, char *, char *, char *,
259
			       struct wordlist **, struct wordlist **,
287
			       struct wordlist **, struct wordlist **,
Lines 401-406 Link Here
401
      "Set telephone number(s) which are allowed to connect",
429
      "Set telephone number(s) which are allowed to connect",
402
      OPT_PRIV | OPT_A2LIST },
430
      OPT_PRIV | OPT_A2LIST },
403
431
432
#ifdef USE_EAPTLS
433
    { "ca", o_string, &cacert_file,   "EAP-TLS CA certificate in PEM format" },
434
    { "cert", o_string, &cert_file,   "EAP-TLS client certificate in PEM format" },
435
    { "key", o_string, &privkey_file, "EAP-TLS client private key in PEM format" },
436
    { "crl-dir", o_string, &crl_dir,  "Use CRLs in directory" },
437
    { "need-peer-eap", o_bool, &need_peer_eap,
438
      "Require the peer to authenticate us", 1 },
439
#endif /* USE_EAPTLS */
404
    { NULL }
440
    { NULL }
405
};
441
};
406
442
Lines 731-736 Link Here
731
    lcp_options *wo = &lcp_wantoptions[unit];
767
    lcp_options *wo = &lcp_wantoptions[unit];
732
    lcp_options *go = &lcp_gotoptions[unit];
768
    lcp_options *go = &lcp_gotoptions[unit];
733
    lcp_options *ho = &lcp_hisoptions[unit];
769
    lcp_options *ho = &lcp_hisoptions[unit];
770
#ifdef USE_EAPTLS
771
    lcp_options *ao = &lcp_allowoptions[unit];
772
#endif
734
    int i;
773
    int i;
735
    struct protent *protp;
774
    struct protent *protp;
736
775
Lines 765-770 Link Here
765
	}
804
	}
766
    }
805
    }
767
806
807
#ifdef USE_EAPTLS
808
    if (need_peer_eap && !ao->neg_eap) {
809
	warn("eap required to authenticate us but no suitable secrets");
810
	lcp_close(unit, "couldn't negotiate eap");
811
	status = EXIT_AUTH_TOPEER_FAILED;
812
	return;
813
    }
814
815
    if (need_peer_eap && !ho->neg_eap) {
816
	warn("peer doesn't want to authenticate us with eap");
817
	lcp_close(unit, "couldn't negotiate eap");
818
	status = EXIT_PEER_AUTH_FAILED;
819
	return;
820
    }
821
#endif
822
768
    new_phase(PHASE_AUTHENTICATE);
823
    new_phase(PHASE_AUTHENTICATE);
769
    auth = 0;
824
    auth = 0;
770
    if (go->neg_eap) {
825
    if (go->neg_eap) {
Lines 1282-1287 Link Here
1282
				    our_name, 1, &lacks_ip);
1337
				    our_name, 1, &lacks_ip);
1283
    }
1338
    }
1284
1339
1340
#ifdef USE_EAPTLS
1341
    if (!can_auth && wo->neg_eap) {
1342
	can_auth =
1343
	    have_eaptls_secret_server((explicit_remote ? remote_name :
1344
				       NULL), our_name, 1, &lacks_ip);
1345
1346
    }
1347
#endif
1348
1285
    if (auth_required && !can_auth && noauth_addrs == NULL) {
1349
    if (auth_required && !can_auth && noauth_addrs == NULL) {
1286
	if (default_auth) {
1350
	if (default_auth) {
1287
	    option_error(
1351
	    option_error(
Lines 1336-1342 Link Here
1336
	passwd[0] != 0 ||
1400
	passwd[0] != 0 ||
1337
	(hadchap == 1 || (hadchap == -1 && have_chap_secret(user,
1401
	(hadchap == 1 || (hadchap == -1 && have_chap_secret(user,
1338
	    (explicit_remote? remote_name: NULL), 0, NULL))) ||
1402
	    (explicit_remote? remote_name: NULL), 0, NULL))) ||
1339
	have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL));
1403
	have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)
1404
#ifdef USE_EAPTLS
1405
		|| have_eaptls_secret_client(user, (explicit_remote? remote_name: NULL)))
1406
#endif
1407
	;
1340
1408
1341
    hadchap = -1;
1409
    hadchap = -1;
1342
    if (go->neg_upap && !uselogin && !have_pap_secret(NULL))
1410
    if (go->neg_upap && !uselogin && !have_pap_secret(NULL))
Lines 1351-1358 Link Here
1351
	    !have_chap_secret((explicit_remote? remote_name: NULL), our_name,
1419
	    !have_chap_secret((explicit_remote? remote_name: NULL), our_name,
1352
		1, NULL))) &&
1420
		1, NULL))) &&
1353
	!have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1,
1421
	!have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1,
1354
	    NULL))
1422
	    NULL)
1423
#ifdef USE_EAPTLS
1424
	 && !have_eaptls_secret_server((explicit_remote? remote_name: NULL),
1425
				   our_name, 1, NULL)
1426
#endif
1427
		)
1355
	go->neg_eap = 0;
1428
	go->neg_eap = 0;
1429
1356
}
1430
}
1357
1431
1358
1432
Lines 1710-1715 Link Here
1710
}
1784
}
1711
1785
1712
1786
1787
1713
/*
1788
/*
1714
 * get_secret - open the CHAP secret file and return the secret
1789
 * get_secret - open the CHAP secret file and return the secret
1715
 * for authenticating the given client on the given server.
1790
 * for authenticating the given client on the given server.
Lines 2366-2368 Link Here
2366
    else
2441
    else
2367
	auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL, 0);
2442
	auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL, 0);
2368
}
2443
}
2444
2445
2446
#ifdef USE_EAPTLS
2447
static int
2448
have_eaptls_secret_server(client, server, need_ip, lacks_ipp)
2449
    char *client;
2450
    char *server;
2451
    int need_ip;
2452
    int *lacks_ipp;
2453
{
2454
    FILE *f;
2455
    int ret;
2456
    char *filename;
2457
    struct wordlist *addrs;
2458
    char servcertfile[MAXWORDLEN];
2459
    char clicertfile[MAXWORDLEN];
2460
    char cacertfile[MAXWORDLEN];
2461
    char pkfile[MAXWORDLEN];
2462
2463
    filename = _PATH_EAPTLSSERVFILE;
2464
    f = fopen(filename, "r");
2465
    if (f == NULL)
2466
		return 0;
2467
2468
    if (client != NULL && client[0] == 0)
2469
		client = NULL;
2470
    else if (server != NULL && server[0] == 0)
2471
		server = NULL;
2472
2473
    ret =
2474
	scan_authfile_eaptls(f, client, server, clicertfile, servcertfile,
2475
			     cacertfile, pkfile, &addrs, NULL, filename,
2476
			     0);
2477
2478
    fclose(f);
2479
2480
/*
2481
    if (ret >= 0 && !eaptls_init_ssl(1, cacertfile, servcertfile,
2482
				clicertfile, pkfile))
2483
		ret = -1;
2484
*/
2485
2486
	if (ret >= 0 && need_ip && !some_ip_ok(addrs)) {
2487
		if (lacks_ipp != 0)
2488
			*lacks_ipp = 1;
2489
		ret = -1;
2490
    }
2491
    if (addrs != 0)
2492
		free_wordlist(addrs);
2493
2494
    return ret >= 0;
2495
}
2496
2497
2498
static int
2499
have_eaptls_secret_client(client, server)
2500
    char *client;
2501
    char *server;
2502
{
2503
    FILE *f;
2504
    int ret;
2505
    char *filename;
2506
    struct wordlist *addrs = NULL;
2507
    char servcertfile[MAXWORDLEN];
2508
    char clicertfile[MAXWORDLEN];
2509
    char cacertfile[MAXWORDLEN];
2510
    char pkfile[MAXWORDLEN];
2511
2512
    if (client != NULL && client[0] == 0)
2513
		client = NULL;
2514
    else if (server != NULL && server[0] == 0)
2515
		server = NULL;
2516
2517
	if (cacert_file && cert_file && privkey_file)
2518
		return 1;
2519
2520
    filename = _PATH_EAPTLSCLIFILE;
2521
    f = fopen(filename, "r");
2522
    if (f == NULL)
2523
		return 0;
2524
2525
    ret =
2526
	scan_authfile_eaptls(f, client, server, clicertfile, servcertfile,
2527
			     cacertfile, pkfile, &addrs, NULL, filename,
2528
			     0);
2529
    fclose(f);
2530
2531
/*
2532
    if (ret >= 0 && !eaptls_init_ssl(0, cacertfile, clicertfile,
2533
				servcertfile, pkfile))
2534
		ret = -1;
2535
*/
2536
2537
    if (addrs != 0)
2538
		free_wordlist(addrs);
2539
2540
    return ret >= 0;
2541
}
2542
2543
2544
static int
2545
scan_authfile_eaptls(f, client, server, cli_cert, serv_cert, ca_cert, pk,
2546
		     addrs, opts, filename, flags)
2547
    FILE *f;
2548
    char *client;
2549
    char *server;
2550
    char *cli_cert;
2551
    char *serv_cert;
2552
    char *ca_cert;
2553
    char *pk;
2554
    struct wordlist **addrs;
2555
    struct wordlist **opts;
2556
    char *filename;
2557
    int flags;
2558
{
2559
    int newline;
2560
    int got_flag, best_flag;
2561
    struct wordlist *ap, *addr_list, *alist, **app;
2562
    char word[MAXWORDLEN];
2563
2564
    if (addrs != NULL)
2565
	*addrs = NULL;
2566
    if (opts != NULL)
2567
	*opts = NULL;
2568
    addr_list = NULL;
2569
    if (!getword(f, word, &newline, filename))
2570
	return -1;		/* file is empty??? */
2571
    newline = 1;
2572
    best_flag = -1;
2573
    for (;;) {
2574
	/*
2575
	 * Skip until we find a word at the start of a line.
2576
	 */
2577
	while (!newline && getword(f, word, &newline, filename));
2578
	if (!newline)
2579
	    break;		/* got to end of file */
2580
2581
	/*
2582
	 * Got a client - check if it's a match or a wildcard.
2583
	 */
2584
	got_flag = 0;
2585
	if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) {
2586
	    newline = 0;
2587
	    continue;
2588
	}
2589
	if (!ISWILD(word))
2590
	    got_flag = NONWILD_CLIENT;
2591
2592
	/*
2593
	 * Now get a server and check if it matches.
2594
	 */
2595
	if (!getword(f, word, &newline, filename))
2596
	    break;
2597
	if (newline)
2598
	    continue;
2599
	if (!ISWILD(word)) {
2600
	    if (server != NULL && strcmp(word, server) != 0)
2601
		continue;
2602
	    got_flag |= NONWILD_SERVER;
2603
	}
2604
2605
	/*
2606
	 * Got some sort of a match - see if it's better than what
2607
	 * we have already.
2608
	 */
2609
	if (got_flag <= best_flag)
2610
	    continue;
2611
2612
	/*
2613
	 * Get the cli_cert
2614
	 */
2615
	if (!getword(f, word, &newline, filename))
2616
	    break;
2617
	if (newline)
2618
	    continue;
2619
	if (strcmp(word, "-") != 0) {
2620
	    strlcpy(cli_cert, word, MAXWORDLEN);
2621
	} else
2622
	    cli_cert[0] = 0;
2623
2624
	/*
2625
	 * Get serv_cert
2626
	 */
2627
	if (!getword(f, word, &newline, filename))
2628
	    break;
2629
	if (newline)
2630
	    continue;
2631
	if (strcmp(word, "-") != 0) {
2632
	    strlcpy(serv_cert, word, MAXWORDLEN);
2633
	} else
2634
	    serv_cert[0] = 0;
2635
2636
	/*
2637
	 * Get ca_cert
2638
	 */
2639
	if (!getword(f, word, &newline, filename))
2640
	    break;
2641
	if (newline)
2642
	    continue;
2643
	strlcpy(ca_cert, word, MAXWORDLEN);
2644
2645
	/*
2646
	 * Get pk
2647
	 */
2648
	if (!getword(f, word, &newline, filename))
2649
	    break;
2650
	if (newline)
2651
	    continue;
2652
	strlcpy(pk, word, MAXWORDLEN);
2653
2654
2655
	/*
2656
	 * Now read address authorization info and make a wordlist.
2657
	 */
2658
	app = &alist;
2659
	for (;;) {
2660
	    if (!getword(f, word, &newline, filename) || newline)
2661
		break;
2662
	    ap = (struct wordlist *)
2663
		malloc(sizeof(struct wordlist) + strlen(word) + 1);
2664
	    if (ap == NULL)
2665
		novm("authorized addresses");
2666
	    ap->word = (char *) (ap + 1);
2667
	    strcpy(ap->word, word);
2668
	    *app = ap;
2669
	    app = &ap->next;
2670
	}
2671
	*app = NULL;
2672
	/*
2673
	 * This is the best so far; remember it.
2674
	 */
2675
	best_flag = got_flag;
2676
	if (addr_list)
2677
	    free_wordlist(addr_list);
2678
	addr_list = alist;
2679
2680
	if (!newline)
2681
	    break;
2682
    }
2683
2684
    /* scan for a -- word indicating the start of options */
2685
    for (app = &addr_list; (ap = *app) != NULL; app = &ap->next)
2686
	if (strcmp(ap->word, "--") == 0)
2687
	    break;
2688
    /* ap = start of options */
2689
    if (ap != NULL) {
2690
	ap = ap->next;		/* first option */
2691
	free(*app);		/* free the "--" word */
2692
	*app = NULL;		/* terminate addr list */
2693
    }
2694
    if (opts != NULL)
2695
	*opts = ap;
2696
    else if (ap != NULL)
2697
	free_wordlist(ap);
2698
    if (addrs != NULL)
2699
	*addrs = addr_list;
2700
    else if (addr_list != NULL)
2701
	free_wordlist(addr_list);
2702
2703
    return best_flag;
2704
}
2705
2706
2707
int
2708
get_eaptls_secret(unit, client, server, clicertfile, servcertfile,
2709
		  cacertfile, pkfile, am_server)
2710
    int unit;
2711
    char *client;
2712
    char *server;
2713
    char *clicertfile;
2714
    char *servcertfile;
2715
    char *cacertfile;
2716
    char *pkfile;
2717
    int am_server;
2718
{
2719
    FILE *fp;
2720
    int ret;
2721
    char *filename         = NULL;
2722
    struct wordlist *addrs = NULL;
2723
    struct wordlist *opts  = NULL;
2724
2725
	/* in client mode the ca+cert+privkey can also be specified as options */
2726
	if (!am_server && cacert_file && cert_file && privkey_file )
2727
	{
2728
		strlcpy( clicertfile, cert_file, MAXWORDLEN );
2729
		strlcpy( cacertfile, cacert_file, MAXWORDLEN );
2730
		strlcpy( pkfile, privkey_file, MAXWORDLEN );
2731
		servcertfile[0] = '\0';
2732
	}
2733
	else
2734
	{
2735
		filename = (am_server ? _PATH_EAPTLSSERVFILE : _PATH_EAPTLSCLIFILE);
2736
		addrs = NULL;
2737
2738
		fp = fopen(filename, "r");
2739
		if (fp == NULL)
2740
		{
2741
			error("Can't open eap-tls secret file %s: %m", filename);
2742
			return 0;
2743
   	 	}
2744
2745
		check_access(fp, filename);
2746
2747
		ret = scan_authfile_eaptls(fp, client, server, clicertfile, servcertfile,
2748
				cacertfile, pkfile, &addrs, &opts, filename, 0);
2749
2750
		fclose(fp);
2751
2752
		if (ret < 0) return 0;
2753
	}
2754
2755
    if (eaptls_passwd_hook)
2756
    {
2757
		dbglog( "Calling eaptls password hook" );
2758
		if ( (*eaptls_passwd_hook)(pkfile, passwd) < 0)
2759
		{
2760
	   		 error("Unable to obtain EAP-TLS password for %s (%s) from plugin", 
2761
				client, pkfile);
2762
		    return 0;
2763
		}
2764
	}
2765
    if (am_server)
2766
		set_allowed_addrs(unit, addrs, opts);
2767
    else if (opts != NULL)
2768
		free_wordlist(opts);
2769
    if (addrs != NULL)
2770
		free_wordlist(addrs);
2771
2772
    return 1;
2773
}
2774
#endif
2775
(-)ppp-2.4.5.orig/pppd/ccp.c (-1 / +19 lines)
Lines 540-545 Link Here
540
    if (go->mppe) {
540
    if (go->mppe) {
541
	ccp_options *ao = &ccp_allowoptions[f->unit];
541
	ccp_options *ao = &ccp_allowoptions[f->unit];
542
	int auth_mschap_bits = auth_done[f->unit];
542
	int auth_mschap_bits = auth_done[f->unit];
543
#ifdef USE_EAPTLS
544
	int auth_eap_bits = auth_done[f->unit];
545
#endif
543
	int numbits;
546
	int numbits;
544
547
545
	/*
548
	/*
Lines 567-574 Link Here
567
	    lcp_close(f->unit, "MPPE required but not available");
570
	    lcp_close(f->unit, "MPPE required but not available");
568
	    return;
571
	    return;
569
	}
572
	}
573
574
#ifdef USE_EAPTLS
575
    /*
576
     * MPPE is also possible in combination with EAP-TLS.
577
     * It is not possible to detect if we're doing EAP or EAP-TLS
578
     * at this stage, hence we accept all forms of EAP. If TLS is
579
     * not used then the MPPE keys will not be derived anyway.
580
     */
581
	/* Leave only the eap auth bits set */
582
	auth_eap_bits &= (EAP_WITHPEER | EAP_PEER );
583
584
	if ((numbits == 0) && (auth_eap_bits == 0)) {
585
	    error("MPPE required, but MS-CHAP[v2] nor EAP-TLS auth are performed.");
586
#else
570
	if (!numbits) {
587
	if (!numbits) {
571
	    error("MPPE required, but MS-CHAP[v2] auth not performed.");
588
		error("MPPE required, but MS-CHAP[v2] auth not performed.");
589
#endif
572
	    lcp_close(f->unit, "MPPE required but not available");
590
	    lcp_close(f->unit, "MPPE required but not available");
573
	    return;
591
	    return;
574
	}
592
	}
(-)ppp-2.4.5.orig/pppd/chap-md5.c (+4 lines)
Lines 36-42 Link Here
36
#include "chap-new.h"
36
#include "chap-new.h"
37
#include "chap-md5.h"
37
#include "chap-md5.h"
38
#include "magic.h"
38
#include "magic.h"
39
#ifdef USE_EAPTLS
40
#include "eap-tls.h"
41
#else
39
#include "md5.h"
42
#include "md5.h"
43
#endif /* USE_EAPTLS */
40
44
41
#define MD5_HASH_SIZE		16
45
#define MD5_HASH_SIZE		16
42
#define MD5_MIN_CHALLENGE	16
46
#define MD5_MIN_CHALLENGE	16
(-)ppp-2.4.5.orig/pppd/eap-tls.c (+1174 lines)
Line 0 Link Here
1
/*
2
 * eap-tls.c - EAP-TLS implementation for PPP
3
 *
4
 * Copyright (c) Beniamino Galvani 2005 All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 *
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 *
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in
15
 *    the documentation and/or other materials provided with the
16
 *    distribution.
17
 *
18
 * 3. The name(s) of the authors of this software must not be used to
19
 *    endorse or promote products derived from this software without
20
 *    prior written permission.
21
 *
22
 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
23
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
24
 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25
 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
26
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
27
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
28
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29
 *
30
 */
31
32
#include <string.h>
33
#include <unistd.h>
34
#include <sys/types.h>
35
#include <sys/stat.h>
36
#include <fcntl.h>
37
38
#include <openssl/conf.h>
39
#include <openssl/engine.h>
40
#include <openssl/hmac.h>
41
#include <openssl/err.h>
42
#include <openssl/x509v3.h>
43
44
#include "pppd.h"
45
#include "eap.h"
46
#include "eap-tls.h"
47
#include "fsm.h"
48
#include "lcp.h"
49
#include "pathnames.h"
50
51
/* The openssl configuration file and engines can be loaded only once */
52
static CONF   *ssl_config  = NULL;
53
static ENGINE *cert_engine = NULL;
54
static ENGINE *pkey_engine = NULL;
55
56
#ifdef MPPE
57
58
/*
59
 * TLS PRF from RFC 2246
60
 */
61
static void P_hash(const EVP_MD *evp_md,
62
		   const unsigned char *secret, unsigned int secret_len,
63
		   const unsigned char *seed,   unsigned int seed_len,
64
		   unsigned char *out, unsigned int out_len)
65
{
66
	HMAC_CTX ctx_a, ctx_out;
67
	unsigned char a[HMAC_MAX_MD_CBLOCK];
68
	unsigned int size;
69
70
	HMAC_CTX_init(&ctx_a);
71
	HMAC_CTX_init(&ctx_out);
72
	HMAC_Init_ex(&ctx_a, secret, secret_len, evp_md, NULL);
73
	HMAC_Init_ex(&ctx_out, secret, secret_len, evp_md, NULL);
74
75
	size = HMAC_size(&ctx_out);
76
77
	/* Calculate A(1) */
78
	HMAC_Update(&ctx_a, seed, seed_len);
79
	HMAC_Final(&ctx_a, a, NULL);
80
81
	while (1) {
82
		/* Calculate next part of output */
83
		HMAC_Update(&ctx_out, a, size);
84
		HMAC_Update(&ctx_out, seed, seed_len);
85
86
		/* Check if last part */
87
		if (out_len < size) {
88
			HMAC_Final(&ctx_out, a, NULL);
89
			memcpy(out, a, out_len);
90
			break;
91
		}
92
93
		/* Place digest in output buffer */
94
		HMAC_Final(&ctx_out, out, NULL);
95
		HMAC_Init_ex(&ctx_out, NULL, 0, NULL, NULL);
96
		out += size;
97
		out_len -= size;
98
99
		/* Calculate next A(i) */
100
		HMAC_Init_ex(&ctx_a, NULL, 0, NULL, NULL);
101
		HMAC_Update(&ctx_a, a, size);
102
		HMAC_Final(&ctx_a, a, NULL);
103
	}
104
105
	HMAC_CTX_cleanup(&ctx_a);
106
	HMAC_CTX_cleanup(&ctx_out);
107
	memset(a, 0, sizeof(a));
108
}
109
110
static void PRF(const unsigned char *secret, unsigned int secret_len,
111
		const unsigned char *seed,   unsigned int seed_len,
112
		unsigned char *out, unsigned char *buf, unsigned int out_len)
113
{
114
        unsigned int i;
115
        unsigned int len = (secret_len + 1) / 2;
116
	const unsigned char *s1 = secret;
117
	const unsigned char *s2 = secret + (secret_len - len);
118
119
	P_hash(EVP_md5(),  s1, len, seed, seed_len, out, out_len);
120
	P_hash(EVP_sha1(), s2, len, seed, seed_len, buf, out_len);
121
122
	for (i=0; i < out_len; i++) {
123
	        out[i] ^= buf[i];
124
	}
125
}
126
127
#define EAPTLS_MPPE_KEY_LEN     32
128
129
/*
130
 *  Generate keys according to RFC 2716 and add to reply
131
 */
132
void eaptls_gen_mppe_keys(struct eaptls_session *ets, const char *prf_label,
133
                          int client)
134
{
135
    unsigned char out[4*EAPTLS_MPPE_KEY_LEN], buf[4*EAPTLS_MPPE_KEY_LEN];
136
    unsigned char seed[64 + 2*SSL3_RANDOM_SIZE];
137
    unsigned char *p = seed;
138
	SSL			  *s = ets->ssl;
139
    size_t prf_size;
140
141
    prf_size = strlen(prf_label);
142
143
    memcpy(p, prf_label, prf_size);
144
    p += prf_size;
145
146
    memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE);
147
    p += SSL3_RANDOM_SIZE;
148
    prf_size += SSL3_RANDOM_SIZE;
149
150
    memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE);
151
    prf_size += SSL3_RANDOM_SIZE;
152
153
    PRF(s->session->master_key, s->session->master_key_length,
154
        seed, prf_size, out, buf, sizeof(out));
155
156
    /* 
157
     * We now have the master send and receive keys.
158
     * From these, generate the session send and receive keys.
159
     * (see RFC3079 / draft-ietf-pppext-mppe-keys-03.txt for details)
160
     */
161
    if (client)
162
    {
163
	    p = out;
164
		BCOPY( p, mppe_send_key, sizeof(mppe_send_key) );
165
		p += EAPTLS_MPPE_KEY_LEN;
166
    	BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) );
167
    }
168
    else
169
    {
170
	    p = out;
171
    	BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) );
172
		p += EAPTLS_MPPE_KEY_LEN;
173
		BCOPY( p, mppe_send_key, sizeof(mppe_send_key) );
174
    }
175
176
    mppe_keys_set = 1;
177
}
178
179
#endif
180
181
void log_ssl_errors( void )
182
{
183
	unsigned long ssl_err = ERR_get_error();
184
185
    if (ssl_err != 0)
186
		dbglog("EAP-TLS SSL error stack:");
187
	while (ssl_err != 0) {
188
		dbglog( ERR_error_string( ssl_err, NULL ) );
189
		ssl_err = ERR_get_error();
190
	}
191
}
192
193
194
int password_callback (char *buf, int size, int rwflag, void *u)
195
{
196
	if (buf)
197
	{
198
		strncpy (buf, passwd, size);
199
		return strlen (buf);
200
	}
201
	return 0;
202
}
203
204
205
CONF *eaptls_ssl_load_config( void )
206
{
207
    CONF        *config;
208
    int          ret_code;
209
    long         error_line = 33;
210
211
    config = NCONF_new( NULL );
212
	dbglog( "Loading OpenSSL config file" );
213
    ret_code = NCONF_load( config, _PATH_OPENSSLCONFFILE, &error_line );
214
    if (ret_code == 0)
215
    {
216
        warn( "EAP-TLS: Error in OpenSSL config file %s at line %d", _PATH_OPENSSLCONFFILE, error_line );
217
        NCONF_free( config );
218
        config = NULL;
219
        ERR_clear_error();
220
    }
221
222
	dbglog( "Loading OpenSSL built-ins" );
223
    ENGINE_load_builtin_engines();
224
    OPENSSL_load_builtin_modules();
225
   
226
	dbglog( "Loading OpenSSL configured modules" );
227
    if (CONF_modules_load( config, NULL, 0 ) <= 0 )
228
    {
229
        warn( "EAP-TLS: Error loading OpenSSL modules" );
230
	    log_ssl_errors();
231
        config = NULL;
232
    }
233
234
    return config;
235
}
236
237
ENGINE *eaptls_ssl_load_engine( char *engine_name )
238
{
239
	ENGINE      *e = NULL;
240
241
	dbglog( "Enabling OpenSSL auto engines" );
242
	ENGINE_register_all_complete();
243
244
	dbglog( "Loading OpenSSL '%s' engine support", engine_name );
245
	e = ENGINE_by_id( engine_name );
246
    if (!e) 
247
	{
248
		dbglog( "EAP-TLS: Cannot load '%s' engine support, trying 'dynamic'", engine_name );
249
		e = ENGINE_by_id( "dynamic" );
250
		if (e)
251
		{
252
			if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine_name, 0)
253
   	         || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
254
			{
255
				warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name );
256
		        log_ssl_errors();
257
				ENGINE_free(e);
258
				e = NULL;
259
			}
260
		}
261
		else
262
		{
263
			warn( "EAP-TLS: Cannot load dynamic engine support" );
264
		}
265
	}
266
267
    if (e)
268
	{
269
		dbglog( "Initialising engine" );
270
		if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
271
		{
272
			warn( "EAP-TLS: Cannot use that engine" );
273
			log_ssl_errors();
274
			ENGINE_free(e);
275
			e = NULL;
276
		}
277
	}
278
279
    return e;
280
}
281
282
/*
283
 * Initialize the SSL stacks and tests if certificates, key and crl
284
 * for client or server use can be loaded.
285
 */
286
SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile,
287
			char *certfile, char *peer_certfile, char *privkeyfile)
288
{
289
	char		*cert_engine_name = NULL;
290
	char		*cert_identifier = NULL;
291
	char		*pkey_engine_name = NULL;
292
	char		*pkey_identifier = NULL;
293
	SSL_CTX		*ctx;
294
	X509_STORE	*certstore;
295
	X509_LOOKUP	*lookup;
296
	X509		*tmp;
297
298
	/*
299
	 * Without these can't continue 
300
	 */
301
	if (!cacertfile[0])
302
    {
303
		error("EAP-TLS: CA certificate missing");
304
		return NULL;
305
    }
306
307
	if (!certfile[0])
308
    {
309
		error("EAP-TLS: User certificate missing");
310
		return NULL;
311
    }
312
313
	if (!privkeyfile[0])
314
    {
315
		error("EAP-TLS: User private key missing");
316
		return NULL;
317
    }
318
319
	SSL_library_init();
320
	SSL_load_error_strings();
321
322
	ctx = SSL_CTX_new(TLSv1_method());
323
324
	if (!ctx) {
325
		error("EAP-TLS: Cannot initialize SSL CTX context");
326
		goto fail;
327
	}
328
329
	/* if the certificate filename is of the form engine:id. e.g.
330
		pkcs11:12345
331
	   then we try to load and use this engine.
332
	   If the certificate filename starts with a / or . then we
333
	   ALWAYS assume it is a file and not an engine/pkcs11 identifier
334
	 */
335
	if ( index( certfile, '/' ) == NULL && index( certfile, '.') == NULL )
336
	{
337
		cert_identifier = index( certfile, ':' );
338
339
		if (cert_identifier)
340
		{
341
			cert_engine_name = certfile;
342
			*cert_identifier = '\0';
343
			cert_identifier++;
344
345
			dbglog( "Found certificate engine '%s'", cert_engine_name );
346
			dbglog( "Found certificate identifier '%s'", cert_identifier );
347
		}
348
	}
349
350
	/* if the privatekey filename is of the form engine:id. e.g.
351
		pkcs11:12345
352
	   then we try to load and use this engine.
353
	   If the privatekey filename starts with a / or . then we
354
	   ALWAYS assume it is a file and not an engine/pkcs11 identifier
355
	 */
356
	if ( index( privkeyfile, '/' ) == NULL && index( privkeyfile, '.') == NULL )
357
	{
358
		pkey_identifier = index( privkeyfile, ':' );
359
360
		if (pkey_identifier)
361
		{
362
			pkey_engine_name = privkeyfile;
363
			*pkey_identifier = '\0';
364
			pkey_identifier++;
365
366
			dbglog( "Found privatekey engine '%s'", pkey_engine_name );
367
			dbglog( "Found privatekey identifier '%s'", pkey_identifier );
368
		}
369
	}
370
371
	if (cert_identifier && pkey_identifier)
372
	{
373
		if (strlen( cert_identifier ) == 0)
374
		{
375
			if (strlen( pkey_identifier ) == 0)
376
				error( "EAP-TLS: both the certificate and privatekey identifiers are missing!" );
377
			else
378
			{
379
				dbglog( "Substituting privatekey identifier for certificate identifier" );
380
				cert_identifier = pkey_identifier;
381
			}
382
		}
383
		else
384
		{
385
			if (strlen( pkey_identifier ) == 0)
386
			{
387
				dbglog( "Substituting certificate identifier for privatekey identifier" );
388
				pkey_identifier = cert_identifier;
389
			}
390
		}
391
392
	}
393
394
	/* load the openssl config file only once */
395
	if (!ssl_config)
396
	{
397
		if (cert_engine_name || pkey_engine_name)
398
			ssl_config = eaptls_ssl_load_config();
399
400
		if (ssl_config && cert_engine_name)
401
			cert_engine = eaptls_ssl_load_engine( cert_engine_name );
402
403
		if (ssl_config && pkey_engine_name)
404
		{
405
			/* don't load the same engine twice */
406
			if ( strcmp( cert_engine_name, pkey_engine_name) == 0 )
407
				pkey_engine = cert_engine;
408
			else
409
				pkey_engine = eaptls_ssl_load_engine( pkey_engine_name );
410
		}
411
	}
412
413
    SSL_CTX_set_default_passwd_cb (ctx, password_callback);
414
415
	if (!SSL_CTX_load_verify_locations(ctx, cacertfile, NULL))
416
	{
417
		error("EAP-TLS: Cannot load or verify CA file %s", cacertfile);
418
		goto fail;
419
	}
420
421
    if (init_server)
422
		SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(cacertfile));
423
424
	if (cert_engine)
425
	{
426
		struct
427
		{
428
			const char *s_slot_cert_id;
429
			X509 *cert;
430
		} cert_info;
431
432
		cert_info.s_slot_cert_id = cert_identifier;
433
		cert_info.cert = NULL;
434
		
435
		if (!ENGINE_ctrl_cmd( cert_engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0 ) )
436
		{
437
			error( "EAP-TLS: Error loading certificate with id '%s' from engine", cert_identifier );
438
			goto fail;
439
		}
440
441
		if (cert_info.cert)
442
		{
443
		    dbglog( "Got the certificate, adding it to SSL context" );
444
			dbglog( "subject = %s", X509_NAME_oneline( X509_get_subject_name( cert_info.cert ), NULL, 0 ) );
445
			if (SSL_CTX_use_certificate(ctx, cert_info.cert) <= 0)
446
			{
447
				error("EAP-TLS: Cannot use PKCS11 certificate %s", cert_identifier);
448
				goto fail;
449
			}
450
		}
451
		else
452
		{
453
			warn("EAP-TLS: Cannot load PKCS11 key %s", cert_identifier);
454
			log_ssl_errors();
455
		}
456
	}
457
	else
458
	{
459
		if (!SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM))
460
		{
461
			error( "EAP-TLS: Cannot use public certificate %s", certfile );
462
			goto fail;
463
		}
464
	}
465
466
	if (pkey_engine)
467
	{
468
		EVP_PKEY   *pkey = NULL;
469
		PW_CB_DATA  cb_data;
470
471
		cb_data.password = passwd;
472
		cb_data.prompt_info = pkey_identifier;
473
474
		dbglog( "Loading private key '%s' from engine", pkey_identifier );
475
		pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, NULL, &cb_data);
476
		if (pkey)
477
		{
478
		    dbglog( "Got the private key, adding it to SSL context" );
479
			if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0)
480
			{
481
				error("EAP-TLS: Cannot use PKCS11 key %s", pkey_identifier);
482
				goto fail;
483
			}
484
		}
485
		else
486
		{
487
			warn("EAP-TLS: Cannot load PKCS11 key %s", pkey_identifier);
488
			log_ssl_errors();
489
		}
490
	}
491
	else
492
	{
493
		if (!SSL_CTX_use_PrivateKey_file(ctx, privkeyfile, SSL_FILETYPE_PEM))
494
		{ 
495
			error("EAP-TLS: Cannot use private key %s", privkeyfile);
496
			goto fail;
497
		}
498
	}
499
500
	if (SSL_CTX_check_private_key(ctx) != 1) {
501
		error("EAP-TLS: Private key %s fails security check", privkeyfile);
502
		goto fail;
503
	}
504
505
	SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
506
	SSL_CTX_set_verify_depth(ctx, 5);
507
	SSL_CTX_set_verify(ctx,
508
			   SSL_VERIFY_PEER |
509
			   SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
510
			   &ssl_verify_callback);
511
512
	if (crl_dir) {
513
		if (!(certstore = SSL_CTX_get_cert_store(ctx))) {
514
			error("EAP-TLS: Failed to get certificate store");
515
			goto fail;
516
		}
517
518
		if (!(lookup =
519
		     X509_STORE_add_lookup(certstore, X509_LOOKUP_hash_dir()))) {
520
			error("EAP-TLS: Store lookup for CRL failed");
521
522
			goto fail;
523
		}
524
525
		X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM);
526
		X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
527
	}
528
529
	/*
530
	 * If a peer certificate file was specified, it must be valid, else fail 
531
	 */
532
	if (peer_certfile[0]) {
533
		if (!(tmp = get_X509_from_file(peer_certfile))) {
534
			error("EAP-TLS: Error loading client certificate from file %s",
535
			     peer_certfile);
536
			goto fail;
537
		}
538
		X509_free(tmp);
539
	}
540
541
	return ctx;
542
543
fail:
544
	log_ssl_errors();
545
	SSL_CTX_free(ctx);
546
	return NULL;
547
}
548
549
/*
550
 * Determine the maximum packet size by looking at the LCP handshake
551
 */
552
553
int eaptls_get_mtu(int unit)
554
{
555
	int mtu, mru;
556
557
	lcp_options *wo = &lcp_wantoptions[unit];
558
	lcp_options *go = &lcp_gotoptions[unit];
559
	lcp_options *ho = &lcp_hisoptions[unit];
560
	lcp_options *ao = &lcp_allowoptions[unit];
561
562
	mtu = ho->neg_mru? ho->mru: PPP_MRU;
563
	mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU;
564
    mtu = MIN(MIN(mtu, mru), ao->mru)- PPP_HDRLEN - 10;
565
566
	dbglog("MTU = %d", mtu);
567
 	return mtu;
568
}
569
570
571
/*
572
 * Init the ssl handshake (server mode)
573
 */
574
int eaptls_init_ssl_server(eap_state * esp)
575
{
576
	struct eaptls_session *ets;
577
	char servcertfile[MAXWORDLEN];
578
	char clicertfile[MAXWORDLEN];
579
	char cacertfile[MAXWORDLEN];
580
	char pkfile[MAXWORDLEN];
581
	/*
582
	 * Allocate new eaptls session 
583
	 */
584
	esp->es_server.ea_session = malloc(sizeof(struct eaptls_session));
585
	if (!esp->es_server.ea_session)
586
		fatal("Allocation error");
587
	ets = esp->es_server.ea_session;
588
589
	if (!esp->es_server.ea_peer) {
590
		error("EAP-TLS: Error: client name not set (BUG)");
591
		return 0;
592
	}
593
594
	strncpy(ets->peer, esp->es_server.ea_peer, MAXWORDLEN);
595
596
	dbglog( "getting eaptls secret" );
597
	if (!get_eaptls_secret(esp->es_unit, esp->es_server.ea_peer,
598
			       esp->es_server.ea_name, clicertfile,
599
			       servcertfile, cacertfile, pkfile, 1)) {
600
		error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"",
601
				esp->es_server.ea_peer, esp->es_server.ea_name );
602
		return 0;
603
	}
604
605
	ets->mtu = eaptls_get_mtu(esp->es_unit);
606
607
	ets->ctx = eaptls_init_ssl(1, cacertfile, servcertfile, clicertfile, pkfile);
608
	if (!ets->ctx)
609
		goto fail;
610
611
	if (!(ets->ssl = SSL_new(ets->ctx)))
612
		goto fail;
613
614
	/*
615
	 * Set auto-retry to avoid timeouts on BIO_read
616
	 */
617
	SSL_set_mode(ets->ssl, SSL_MODE_AUTO_RETRY);
618
619
	/*
620
	 * Initialize the BIOs we use to read/write to ssl engine 
621
	 */
622
	ets->into_ssl = BIO_new(BIO_s_mem());
623
	ets->from_ssl = BIO_new(BIO_s_mem());
624
	SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl);
625
626
	SSL_set_msg_callback(ets->ssl, ssl_msg_callback);
627
	SSL_set_msg_callback_arg(ets->ssl, ets);
628
629
	/*
630
	 * Attach the session struct to the connection, so we can later
631
	 * retrieve it when doing certificate verification
632
	 */
633
	SSL_set_ex_data(ets->ssl, 0, ets);
634
635
	SSL_set_accept_state(ets->ssl);
636
637
	ets->data = NULL;
638
	ets->datalen = 0;
639
	ets->alert_sent = 0;
640
	ets->alert_recv = 0;
641
642
	/*
643
	 * If we specified the client certificate file, store it in ets->peercertfile,
644
	 * so we can check it later in ssl_verify_callback()
645
	 */
646
	if (clicertfile[0])
647
		strncpy(&ets->peercertfile[0], clicertfile, MAXWORDLEN);
648
	else
649
		ets->peercertfile[0] = 0;
650
651
	return 1;
652
653
fail:
654
	SSL_CTX_free(ets->ctx);
655
	return 0;
656
}
657
658
/*
659
 * Init the ssl handshake (client mode)
660
 */
661
int eaptls_init_ssl_client(eap_state * esp)
662
{
663
	struct eaptls_session *ets;
664
	char servcertfile[MAXWORDLEN];
665
	char clicertfile[MAXWORDLEN];
666
	char cacertfile[MAXWORDLEN];
667
	char pkfile[MAXWORDLEN];
668
669
	/*
670
	 * Allocate new eaptls session 
671
	 */
672
	esp->es_client.ea_session = malloc(sizeof(struct eaptls_session));
673
	if (!esp->es_client.ea_session)
674
		fatal("Allocation error");
675
	ets = esp->es_client.ea_session;
676
677
	/*
678
	 * If available, copy server name in ets; it will be used in cert
679
	 * verify 
680
	 */
681
	if (esp->es_client.ea_peer)
682
		strncpy(ets->peer, esp->es_client.ea_peer, MAXWORDLEN);
683
	else
684
		ets->peer[0] = 0;
685
	
686
	ets->mtu = eaptls_get_mtu(esp->es_unit);
687
688
	dbglog( "calling get_eaptls_secret" );
689
	if (!get_eaptls_secret(esp->es_unit, esp->es_client.ea_name,
690
			       esp->es_client.ea_peer, clicertfile,
691
			       servcertfile, cacertfile, pkfile, 0)) {
692
		error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"",
693
				esp->es_client.ea_name, esp->es_client.ea_peer );
694
		return 0;
695
	}
696
697
	dbglog( "calling eaptls_init_ssl" );
698
	ets->ctx = eaptls_init_ssl(0, cacertfile, clicertfile, servcertfile, pkfile);
699
	if (!ets->ctx)
700
		goto fail;
701
702
	ets->ssl = SSL_new(ets->ctx);
703
704
	if (!ets->ssl)
705
		goto fail;
706
707
	/*
708
	 * Initialize the BIOs we use to read/write to ssl engine 
709
	 */
710
	dbglog( "Initializing SSL BIOs" );
711
	ets->into_ssl = BIO_new(BIO_s_mem());
712
	ets->from_ssl = BIO_new(BIO_s_mem());
713
	SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl);
714
715
	SSL_set_msg_callback(ets->ssl, ssl_msg_callback);
716
	SSL_set_msg_callback_arg(ets->ssl, ets);
717
718
	/*
719
	 * Attach the session struct to the connection, so we can later
720
	 * retrieve it when doing certificate verification
721
	 */
722
	SSL_set_ex_data(ets->ssl, 0, ets);
723
724
	SSL_set_connect_state(ets->ssl);
725
726
	ets->data = NULL;
727
	ets->datalen = 0;
728
	ets->alert_sent = 0;
729
	ets->alert_recv = 0;
730
731
	/*
732
	 * If we specified the server certificate file, store it in
733
	 * ets->peercertfile, so we can check it later in
734
	 * ssl_verify_callback() 
735
	 */
736
	if (servcertfile[0])
737
		strncpy(ets->peercertfile, servcertfile, MAXWORDLEN);
738
	else
739
		ets->peercertfile[0] = 0;
740
741
	return 1;
742
743
fail:
744
	dbglog( "eaptls_init_ssl_client: fail" );
745
	SSL_CTX_free(ets->ctx);
746
	return 0;
747
748
}
749
750
void eaptls_free_session(struct eaptls_session *ets)
751
{
752
	if (ets->ssl)
753
		SSL_free(ets->ssl);
754
755
	if (ets->ctx)
756
		SSL_CTX_free(ets->ctx);
757
758
	free(ets);
759
}
760
761
/*
762
 * Handle a received packet, reassembling fragmented messages and
763
 * passing them to the ssl engine
764
 */
765
int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len)
766
{
767
	u_char flags;
768
	u_int tlslen;
769
	u_char dummy[65536];
770
771
	GETCHAR(flags, inp);
772
	len--;
773
774
    if (flags & EAP_TLS_FLAGS_LI && !ets->data) {
775
 
776
		/*
777
		 * This is the first packet of a message
778
		*/
779
 
780
		GETLONG(tlslen, inp);
781
		len -= 4;
782
783
		if (tlslen > EAP_TLS_MAX_LEN) {
784
			error("Error: tls message length > %d, truncated",
785
				EAP_TLS_MAX_LEN);
786
			tlslen = EAP_TLS_MAX_LEN;
787
		}
788
789
		/*
790
		 * Allocate memory for the whole message
791
		*/
792
		ets->data = malloc(tlslen);
793
		if (!ets->data)
794
			fatal("EAP TLS: allocation error\n");
795
796
		ets->datalen = 0;
797
		ets->tlslen = tlslen;
798
799
	}
800
	else if (flags & EAP_TLS_FLAGS_LI && ets->data) {
801
		/*
802
		 * Non first with LI (strange...)
803
		*/
804
 
805
		GETLONG(tlslen, inp);
806
		len -= 4;
807
 
808
	}
809
	else if (!ets->data) {
810
		/*
811
		 * A non fragmented message without LI flag
812
		*/
813
 
814
		ets->data = malloc(len);
815
		if (!ets->data)
816
			fatal("EAP TLS: allocation error\n");
817
 
818
		ets->datalen = 0;
819
		ets->tlslen = len;
820
	}
821
822
	if (flags & EAP_TLS_FLAGS_MF)
823
		ets->frag = 1;
824
	else
825
		ets->frag = 0;
826
827
	if (len + ets->datalen > ets->tlslen) {
828
		warn("EAP TLS: received data > TLS message length");
829
		return 1;
830
	}
831
832
	BCOPY(inp, ets->data + ets->datalen, len);
833
	ets->datalen += len;
834
835
	if (!ets->frag) {
836
837
		/*
838
		 * If we have the whole message, pass it to ssl 
839
		 */
840
841
		if (ets->datalen != ets->tlslen) {
842
			warn("EAP TLS: received data != TLS message length");
843
			return 1;
844
		}
845
846
		if (BIO_write(ets->into_ssl, ets->data, ets->datalen) == -1)
847
			log_ssl_errors();
848
849
		SSL_read(ets->ssl, dummy, 65536);
850
851
		free(ets->data);
852
		ets->data = NULL;
853
		ets->datalen = 0;
854
	}
855
856
	return 0;
857
}
858
859
/*
860
 * Return an eap-tls packet in outp.
861
 * A TLS message read from the ssl engine is buffered in ets->data.
862
 * At each call we control if there is buffered data and send a 
863
 * packet of mtu bytes.
864
 */
865
int eaptls_send(struct eaptls_session *ets, u_char ** outp)
866
{
867
	bool first = 0;
868
	int size;
869
	u_char fromtls[65536];
870
	int res;
871
	u_char *start;
872
873
	start = *outp;
874
875
	if (!ets->data) {
876
877
		if(!ets->alert_sent)
878
			SSL_read(ets->ssl, fromtls, 65536);
879
880
		/*
881
		 * Read from ssl 
882
		 */
883
		if ((res = BIO_read(ets->from_ssl, fromtls, 65536)) == -1)
884
			fatal("No data from BIO_read");
885
886
		ets->datalen = res;
887
888
		ets->data = malloc(ets->datalen);
889
		BCOPY(fromtls, ets->data, ets->datalen);
890
891
		ets->offset = 0;
892
		first = 1;
893
894
	}
895
896
	size = ets->datalen - ets->offset;
897
    
898
	if (size > ets->mtu) {
899
		size = ets->mtu;
900
		ets->frag = 1;
901
	} else
902
		ets->frag = 0;
903
904
	PUTCHAR(EAPT_TLS, *outp);
905
906
	/*
907
	 * Set right flags and length if necessary 
908
	 */
909
	if (ets->frag && first) {
910
		PUTCHAR(EAP_TLS_FLAGS_LI | EAP_TLS_FLAGS_MF, *outp);
911
		PUTLONG(ets->datalen, *outp);
912
	} else if (ets->frag) {
913
		PUTCHAR(EAP_TLS_FLAGS_MF, *outp);
914
	} else
915
		PUTCHAR(0, *outp);
916
917
	/*
918
	 * Copy the data in outp 
919
	 */
920
	BCOPY(ets->data + ets->offset, *outp, size);
921
	INCPTR(size, *outp);
922
923
	/*
924
	 * Copy the packet in retransmission buffer 
925
	 */
926
	BCOPY(start, &ets->rtx[0], *outp - start);
927
	ets->rtx_len = *outp - start;
928
929
	ets->offset += size;
930
931
	if (ets->offset >= ets->datalen) {
932
933
		/*
934
		 * The whole message has been sent 
935
		 */
936
937
		free(ets->data);
938
		ets->data = NULL;
939
		ets->datalen = 0;
940
		ets->offset = 0;
941
	}
942
943
	return 0;
944
}
945
946
/*
947
 * Get the sent packet from the retransmission buffer
948
 */
949
void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp)
950
{
951
	BCOPY(ets->rtx, *outp, ets->rtx_len);
952
	INCPTR(ets->rtx_len, *outp);
953
}
954
955
/*
956
 * Verify a certificate.
957
 * Most of the work (signatures and issuer attributes checking)
958
 * is done by ssl; we check the CN in the peer certificate 
959
 * against the peer name.
960
 */
961
int ssl_verify_callback(int preverify_ok, X509_STORE_CTX * ctx)
962
{
963
	char subject[256];
964
	char cn_str[256];
965
	X509 *peer_cert;
966
	int err, depth;
967
	int ok = preverify_ok;
968
	SSL *ssl;
969
	struct eaptls_session *ets;
970
971
	peer_cert = X509_STORE_CTX_get_current_cert(ctx);
972
	err = X509_STORE_CTX_get_error(ctx);
973
	depth = X509_STORE_CTX_get_error_depth(ctx);
974
975
	dbglog("certificate verify depth: %d", depth);
976
977
    if (auth_required && !ok) {
978
		X509_NAME_oneline(X509_get_subject_name(peer_cert),
979
				  subject, 256);
980
981
		X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
982
					  NID_commonName, cn_str, 256);
983
984
		dbglog("Certificate verification error:\n depth: %d CN: %s"
985
		       "\n err: %d (%s)\n", depth, cn_str, err,
986
		       X509_verify_cert_error_string(err));
987
988
		return 0;
989
	}
990
991
	ssl = X509_STORE_CTX_get_ex_data(ctx,
992
				       SSL_get_ex_data_X509_STORE_CTX_idx());
993
994
	ets = (struct eaptls_session *)SSL_get_ex_data(ssl, 0);
995
996
	if (ets == NULL) {
997
		error("Error: SSL_get_ex_data returned NULL");
998
		return 0;
999
	}
1000
1001
	log_ssl_errors();
1002
1003
	if (!depth) {		/* This is the peer certificate */
1004
1005
		X509_NAME_oneline(X509_get_subject_name(peer_cert),
1006
				  subject, 256);
1007
1008
		X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert),
1009
					  NID_commonName, cn_str, 256);
1010
1011
		/*
1012
		 * If acting as client and the name of the server wasn't specified
1013
		 * explicitely, we can't verify the server authenticity 
1014
		 */
1015
		if (!ets->peer[0]) {
1016
			warn("Peer name not specified: no check");
1017
			return 1;
1018
		}
1019
1020
		/*
1021
		 * Check the CN 
1022
		 */
1023
		if (strcmp(cn_str, ets->peer)) {
1024
			error
1025
			    ("Certificate verification error: CN (%s) != peer_name (%s)",
1026
			     cn_str, ets->peer);
1027
			return 0;
1028
		}
1029
1030
		warn("Certificate CN: %s , peer name %s", cn_str, ets->peer);
1031
1032
		/*
1033
		 * If a peer certificate file was specified, here we check it 
1034
		 */
1035
		if (ets->peercertfile[0]) {
1036
			if (ssl_cmp_certs(&ets->peercertfile[0], peer_cert)
1037
			    != 0) {
1038
				error
1039
				    ("Peer certificate doesn't match stored certificate");
1040
				return 0;
1041
			}
1042
		}
1043
	}
1044
1045
	return 1;
1046
}
1047
1048
/*
1049
 * Compare a certificate with the one stored in a file
1050
 */
1051
int ssl_cmp_certs(char *filename, X509 * a)
1052
{
1053
	X509 *b;
1054
	int ret;
1055
1056
	if (!(b = get_X509_from_file(filename)))
1057
		return 1;
1058
1059
	ret = X509_cmp(a, b);
1060
	X509_free(b);
1061
1062
	return ret;
1063
1064
}
1065
1066
X509 *get_X509_from_file(char *filename)
1067
{
1068
	FILE *fp;
1069
	X509 *ret;
1070
1071
	if (!(fp = fopen(filename, "r")))
1072
		return NULL;
1073
1074
	ret = PEM_read_X509(fp, NULL, NULL, NULL);
1075
1076
	fclose(fp);
1077
1078
	return ret;
1079
}
1080
1081
/*
1082
 * Every sent & received message this callback function is invoked,
1083
 * so we know when alert messages have arrived or are sent and
1084
 * we can print debug information about TLS handshake.
1085
 */
1086
void
1087
ssl_msg_callback(int write_p, int version, int content_type,
1088
		 const void *buf, size_t len, SSL * ssl, void *arg)
1089
{
1090
	char string[256];
1091
	struct eaptls_session *ets = (struct eaptls_session *)arg;
1092
	unsigned char code;
1093
1094
	if(write_p)
1095
		strcpy(string, " -> ");
1096
	else
1097
		strcpy(string, " <- ");
1098
1099
	
1100
	switch(content_type) {
1101
1102
	case SSL3_RT_ALERT:	
1103
		strcat(string, "Alert: ");	
1104
		code = ((const unsigned char *)buf)[1];
1105
1106
		if (write_p) {
1107
			ets->alert_sent = 1;
1108
			ets->alert_sent_desc = code;
1109
		} else {
1110
			ets->alert_recv = 1;
1111
			ets->alert_recv_desc = code;
1112
		}
1113
1114
		strcat(string, SSL_alert_desc_string_long(code));
1115
		break;
1116
1117
	case SSL3_RT_CHANGE_CIPHER_SPEC:
1118
		strcat(string, "ChangeCipherSpec");
1119
		break;
1120
1121
	case SSL3_RT_HANDSHAKE:
1122
1123
		strcat(string, "Handshake: ");
1124
		code = ((const unsigned char *)buf)[0];
1125
1126
		switch(code) {
1127
			case SSL3_MT_HELLO_REQUEST:
1128
				strcat(string,"Hello Request");
1129
				break;
1130
			case SSL3_MT_CLIENT_HELLO:
1131
				strcat(string,"Client Hello");
1132
				break;
1133
			case SSL3_MT_SERVER_HELLO:
1134
				strcat(string,"Server Hello");
1135
				break;
1136
			case SSL3_MT_CERTIFICATE:
1137
				strcat(string,"Certificate");
1138
				break;
1139
			case SSL3_MT_SERVER_KEY_EXCHANGE:
1140
				strcat(string,"Server Key Exchange");
1141
				break;
1142
			case SSL3_MT_CERTIFICATE_REQUEST:
1143
				strcat(string,"Certificate Request");
1144
				break;
1145
			case SSL3_MT_SERVER_DONE:
1146
				strcat(string,"Server Hello Done");
1147
								break;
1148
			case SSL3_MT_CERTIFICATE_VERIFY:
1149
				strcat(string,"Certificate Verify");
1150
				break;
1151
			case SSL3_MT_CLIENT_KEY_EXCHANGE:
1152
				strcat(string,"Client Key Exchange");
1153
				break;
1154
			case SSL3_MT_FINISHED:
1155
				strcat(string,"Finished");
1156
				break;
1157
1158
			default:
1159
				sprintf( string, "Handshake: Unknown SSL3 code received: %d", code );
1160
		}
1161
		break;
1162
1163
	default:
1164
		sprintf( string, "SSL message contains unknown content type: %d", content_type );
1165
		
1166
	}
1167
1168
	/* Alert messages must always be displayed */
1169
	if(content_type == SSL3_RT_ALERT)
1170
		error("%s", string);
1171
	else
1172
		dbglog("%s", string);
1173
}
1174
(-)ppp-2.4.5.orig/pppd/eap-tls.h (+107 lines)
Line 0 Link Here
1
/*
2
 * eap-tls.h
3
 *
4
 * Copyright (c) Beniamino Galvani 2005 All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
8
 * are met:
9
 *
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 *
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in
15
 *    the documentation and/or other materials provided with the
16
 *    distribution.
17
 *
18
 * 3. The name(s) of the authors of this software must not be used to
19
 *    endorse or promote products derived from this software without
20
 *    prior written permission.
21
 *
22
 * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO
23
 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
24
 * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25
 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
26
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
27
 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
28
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
29
 *
30
 */
31
32
#ifndef __EAP_TLS_H__
33
#define __EAP_TLS_H__
34
35
#include "eap.h"
36
37
#include <openssl/ssl.h>
38
#include <openssl/bio.h>
39
#include <openssl/md5.h>
40
41
#define EAP_TLS_FLAGS_LI        128	/* length included flag */
42
#define EAP_TLS_FLAGS_MF        64	/* more fragments flag */
43
#define EAP_TLS_FLAGS_START     32	/* start flag */
44
45
#define EAP_TLS_MAX_LEN         65536	/* max eap tls packet size */
46
47
struct eaptls_session
48
{
49
	u_char *data;		/* buffered data */
50
	int datalen;		/* buffered data len */
51
	int offset;		/* from where to send */
52
	int tlslen;		/* total length of tls data */
53
	bool frag;		/* packet is fragmented */
54
	SSL_CTX *ctx;
55
	SSL *ssl;		/* ssl connection */
56
	BIO *from_ssl;
57
	BIO *into_ssl;
58
	char peer[MAXWORDLEN];	/* peer name */
59
	char peercertfile[MAXWORDLEN];
60
	bool alert_sent;
61
	u_char alert_sent_desc;
62
	bool alert_recv;
63
	u_char alert_recv_desc;
64
	char rtx[65536];	/* retransmission buffer */
65
	int rtx_len;
66
	int mtu;		/* unit mtu */
67
};
68
69
typedef struct pw_cb_data
70
{
71
	const void *password;
72
	const char *prompt_info;
73
} PW_CB_DATA;
74
75
76
int ssl_verify_callback(int, X509_STORE_CTX *);
77
void ssl_msg_callback(int write_p, int version, int ct, const void *buf,
78
		      size_t len, SSL * ssl, void *arg);
79
80
X509 *get_X509_from_file(char *filename);
81
int ssl_cmp_certs(char *filename, X509 * a);
82
83
SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile,
84
            char *certfile, char *peer_certfile, char *privkeyfile);
85
int eaptls_init_ssl_server(eap_state * esp);
86
int eaptls_init_ssl_client(eap_state * esp);
87
void eaptls_free_session(struct eaptls_session *ets);
88
89
int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len);
90
int eaptls_send(struct eaptls_session *ets, u_char ** outp);
91
void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp);
92
93
int get_eaptls_secret(int unit, char *client, char *server,
94
		      char *clicertfile, char *servcertfile, char *cacertfile,
95
		      char *pkfile, int am_server);
96
97
#ifdef MPPE
98
#include "mppe.h"   /* MPPE_MAX_KEY_LEN */
99
extern u_char mppe_send_key[MPPE_MAX_KEY_LEN];
100
extern u_char mppe_recv_key[MPPE_MAX_KEY_LEN];
101
extern int mppe_keys_set;
102
103
void eaptls_gen_mppe_keys(struct eaptls_session *ets, const char *prf_label, int client);
104
105
#endif
106
107
#endif
(-)ppp-2.4.5.orig/pppd/eap.c (-3 / +450 lines)
Lines 43-49 Link Here
43
 * Based on draft-ietf-pppext-eap-srp-03.txt.
43
 * Based on draft-ietf-pppext-eap-srp-03.txt.
44
 */
44
 */
45
45
46
#define RCSID	"$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $"
46
/*
47
 * Modification by Beniamino Galvani, Mar 2005
48
 * Implemented EAP-TLS authentication
49
 */
50
51
#define RCSID	"$Id: 80_all_eaptls-mppe-0.991-gentoo.patch,v 1.1 2012/08/10 04:12:45 vapier Exp $"
47
52
48
/*
53
/*
49
 * TODO:
54
 * TODO:
Lines 62-69 Link Here
62
67
63
#include "pppd.h"
68
#include "pppd.h"
64
#include "pathnames.h"
69
#include "pathnames.h"
65
#include "md5.h"
66
#include "eap.h"
70
#include "eap.h"
71
#ifdef USE_EAPTLS
72
#include "eap-tls.h"
73
#else
74
#include "md5.h"
75
#endif /* USE_EAPTLS */
67
76
68
#ifdef USE_SRP
77
#ifdef USE_SRP
69
#include <t_pwd.h>
78
#include <t_pwd.h>
Lines 209-214 Link Here
209
	esp->es_server.ea_id = (u_char)(drand48() * 0x100);
218
	esp->es_server.ea_id = (u_char)(drand48() * 0x100);
210
	esp->es_client.ea_timeout = EAP_DEFREQTIME;
219
	esp->es_client.ea_timeout = EAP_DEFREQTIME;
211
	esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
220
	esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ;
221
#ifdef USE_EAPTLS
222
	esp->es_client.ea_using_eaptls = 0;
223
#endif /* USE_EAPTLS */
212
}
224
}
213
225
214
/*
226
/*
Lines 436-443 Link Here
436
	u_char vals[2];
448
	u_char vals[2];
437
	struct b64state bs;
449
	struct b64state bs;
438
#endif /* USE_SRP */
450
#endif /* USE_SRP */
451
#ifdef USE_EAPTLS
452
	struct eaptls_session *ets;
453
	int secret_len;
454
	char secret[MAXWORDLEN];
455
#endif /* USE_EAPTLS */
439
456
440
	esp->es_server.ea_timeout = esp->es_savedtime;
457
	esp->es_server.ea_timeout = esp->es_savedtime;
458
#ifdef USE_EAPTLS
459
	esp->es_server.ea_prev_state = esp->es_server.ea_state;
460
#endif /* USE_EAPTLS */
441
	switch (esp->es_server.ea_state) {
461
	switch (esp->es_server.ea_state) {
442
	case eapBadAuth:
462
	case eapBadAuth:
443
		return;
463
		return;
Lines 562-570 Link Here
562
			break;
582
			break;
563
		}
583
		}
564
#endif /* USE_SRP */
584
#endif /* USE_SRP */
585
#ifdef USE_EAPTLS
586
                if (!get_secret(esp->es_unit, esp->es_server.ea_peer,
587
                    esp->es_server.ea_name, secret, &secret_len, 1)) {
588
589
			esp->es_server.ea_state = eapTlsStart;
590
			break;
591
		}
592
#endif /* USE_EAPTLS */
593
565
		esp->es_server.ea_state = eapMD5Chall;
594
		esp->es_server.ea_state = eapMD5Chall;
566
		break;
595
		break;
567
596
597
#ifdef USE_EAPTLS
598
	case eapTlsStart:
599
		/* Initialize ssl session */
600
		if(!eaptls_init_ssl_server(esp)) {
601
			esp->es_server.ea_state = eapBadAuth;
602
			break;
603
		}
604
605
		esp->es_server.ea_state = eapTlsRecv;
606
		break;
607
608
	case eapTlsRecv:
609
		ets = (struct eaptls_session *) esp->es_server.ea_session;
610
		
611
		if(ets->alert_sent) {
612
			esp->es_server.ea_state = eapTlsSendAlert;
613
			break;
614
		}
615
616
		if (status) {
617
			esp->es_server.ea_state = eapBadAuth;
618
			break;	
619
		}
620
		ets = (struct eaptls_session *) esp->es_server.ea_session;
621
622
		if(ets->frag)
623
			esp->es_server.ea_state = eapTlsSendAck;
624
		else
625
			esp->es_server.ea_state = eapTlsSend;
626
		break;
627
628
	case eapTlsSend:
629
		ets = (struct eaptls_session *) esp->es_server.ea_session;
630
631
		if(SSL_is_init_finished(ets->ssl)) {
632
			esp->es_server.ea_state = eapTlsRecvClient; 
633
			break;
634
		}
635
636
		if(ets->frag)
637
			esp->es_server.ea_state = eapTlsRecvAck;
638
		else
639
			esp->es_server.ea_state = eapTlsRecv;			
640
		break;
641
642
	case eapTlsSendAck:
643
			esp->es_server.ea_state = eapTlsRecv;
644
		break;
645
646
	case eapTlsRecvAck:
647
                if (status) {
648
                        esp->es_server.ea_state = eapBadAuth;
649
                        break;
650
                }
651
652
		esp->es_server.ea_state = eapTlsSend;
653
		break;
654
655
	case eapTlsSendAlert:
656
		esp->es_server.ea_state = eapTlsRecvAlertAck;
657
		break;
658
#endif /* USE_EAPTLS */
659
568
	case eapSRP1:
660
	case eapSRP1:
569
#ifdef USE_SRP
661
#ifdef USE_SRP
570
		ts = (struct t_server *)esp->es_server.ea_session;
662
		ts = (struct t_server *)esp->es_server.ea_session;
Lines 718-723 Link Here
718
		INCPTR(esp->es_server.ea_namelen, outp);
810
		INCPTR(esp->es_server.ea_namelen, outp);
719
		break;
811
		break;
720
812
813
#ifdef USE_EAPTLS
814
	case eapTlsStart:
815
		PUTCHAR(EAPT_TLS, outp);
816
		PUTCHAR(EAP_TLS_FLAGS_START, outp);
817
		eap_figure_next_state(esp, 0);
818
		break;
819
820
	case eapTlsSend:
821
		eaptls_send(esp->es_server.ea_session, &outp);
822
		eap_figure_next_state(esp, 0);
823
		break;
824
825
	case eapTlsSendAck:
826
		PUTCHAR(EAPT_TLS, outp);
827
		PUTCHAR(0, outp);
828
		eap_figure_next_state(esp, 0);
829
		break;
830
831
	case eapTlsSendAlert:
832
		eaptls_send(esp->es_server.ea_session, &outp);
833
		eap_figure_next_state(esp, 0);
834
		break;
835
#endif /* USE_EAPTLS */
836
721
#ifdef USE_SRP
837
#ifdef USE_SRP
722
	case eapSRP1:
838
	case eapSRP1:
723
		PUTCHAR(EAPT_SRP, outp);
839
		PUTCHAR(EAPT_SRP, outp);
Lines 904-914 Link Here
904
eap_server_timeout(arg)
1020
eap_server_timeout(arg)
905
void *arg;
1021
void *arg;
906
{
1022
{
1023
#ifdef USE_EAPTLS
1024
	u_char *outp;
1025
	u_char *lenloc;
1026
	int outlen;
1027
#endif /* USE_EAPTLS */
1028
907
	eap_state *esp = (eap_state *) arg;
1029
	eap_state *esp = (eap_state *) arg;
908
1030
909
	if (!eap_server_active(esp))
1031
	if (!eap_server_active(esp))
910
		return;
1032
		return;
911
1033
1034
#ifdef USE_EAPTLS
1035
	switch(esp->es_server.ea_prev_state) {
1036
1037
	/* 
1038
	 *  In eap-tls the state changes after a request, so we return to
1039
	 *  previous state ...
1040
	 */	
1041
	case(eapTlsStart):
1042
	case(eapTlsSendAck):
1043
		esp->es_server.ea_state = esp->es_server.ea_prev_state;
1044
		break;
1045
1046
	/*
1047
	 *  ... or resend the stored data
1048
	 */
1049
	case(eapTlsSend):
1050
	case(eapTlsSendAlert):
1051
		outp = outpacket_buf;
1052
		MAKEHEADER(outp, PPP_EAP);
1053
		PUTCHAR(EAP_REQUEST, outp);
1054
		PUTCHAR(esp->es_server.ea_id, outp);
1055
		lenloc = outp;
1056
		INCPTR(2, outp);
1057
1058
		eaptls_retransmit(esp->es_server.ea_session, &outp);
1059
1060
		outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1061
		PUTSHORT(outlen, lenloc);
1062
		output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN);
1063
		esp->es_server.ea_requests++;
1064
1065
		if (esp->es_server.ea_timeout > 0)
1066
			TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout);
1067
1068
		return;
1069
	default:
1070
		break;
1071
	}
1072
#endif /* USE_EAPTLS */
1073
912
	/* EAP ID number must not change on timeout. */
1074
	/* EAP ID number must not change on timeout. */
913
	eap_send_request(esp);
1075
	eap_send_request(esp);
914
}
1076
}
Lines 1166-1171 Link Here
1166
}
1328
}
1167
#endif /* USE_SRP */
1329
#endif /* USE_SRP */
1168
1330
1331
#ifdef USE_EAPTLS
1332
/*
1333
 * Send an EAP-TLS response message with tls data
1334
 */
1335
static void
1336
eap_tls_response(esp, id)
1337
eap_state *esp;
1338
u_char id;
1339
{
1340
        u_char *outp;
1341
        int outlen;
1342
	u_char *lenloc;
1343
	
1344
        outp = outpacket_buf;
1345
1346
        MAKEHEADER(outp, PPP_EAP);
1347
1348
        PUTCHAR(EAP_RESPONSE, outp);
1349
        PUTCHAR(id, outp);
1350
1351
	lenloc = outp;
1352
	INCPTR(2, outp);        
1353
1354
	/*
1355
	   If the id in the request is unchanged, we must retransmit
1356
	   the old data
1357
	*/
1358
	if(id == esp->es_client.ea_id)
1359
		eaptls_retransmit(esp->es_client.ea_session, &outp);
1360
	else
1361
		eaptls_send(esp->es_client.ea_session, &outp);
1362
1363
	outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1364
	PUTSHORT(outlen, lenloc);
1365
1366
	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1367
1368
	esp->es_client.ea_id = id;
1369
1370
}
1371
1372
/*
1373
 * Send an EAP-TLS ack
1374
 */
1375
static void
1376
eap_tls_sendack(esp, id)
1377
eap_state *esp;
1378
u_char id;
1379
{
1380
	u_char *outp;
1381
	int outlen;
1382
	u_char *lenloc;
1383
1384
	outp = outpacket_buf;
1385
1386
	MAKEHEADER(outp, PPP_EAP);
1387
1388
	PUTCHAR(EAP_RESPONSE, outp);
1389
	PUTCHAR(id, outp);
1390
	esp->es_client.ea_id = id;
1391
1392
	lenloc = outp;
1393
	INCPTR(2, outp);
1394
1395
	PUTCHAR(EAPT_TLS, outp);
1396
	PUTCHAR(0, outp);
1397
1398
	outlen = (outp - outpacket_buf) - PPP_HDRLEN;
1399
	PUTSHORT(outlen, lenloc);
1400
1401
	output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen);
1402
1403
}
1404
#endif /* USE_EAPTLS */
1405
1169
static void
1406
static void
1170
eap_send_nak(esp, id, type)
1407
eap_send_nak(esp, id, type)
1171
eap_state *esp;
1408
eap_state *esp;
Lines 1320-1325 Link Here
1320
	char rhostname[256];
1557
	char rhostname[256];
1321
	MD5_CTX mdContext;
1558
	MD5_CTX mdContext;
1322
	u_char hash[MD5_SIGNATURE_SIZE];
1559
	u_char hash[MD5_SIGNATURE_SIZE];
1560
#ifdef USE_EAPTLS
1561
	u_char flags;
1562
	struct eaptls_session *ets = esp->es_client.ea_session;
1563
#endif /* USE_EAPTLS */
1564
1323
#ifdef USE_SRP
1565
#ifdef USE_SRP
1324
	struct t_client *tc;
1566
	struct t_client *tc;
1325
	struct t_num sval, gval, Nval, *Ap, Bval;
1567
	struct t_num sval, gval, Nval, *Ap, Bval;
Lines 1456-1461 Link Here
1456
		    esp->es_client.ea_namelen);
1698
		    esp->es_client.ea_namelen);
1457
		break;
1699
		break;
1458
1700
1701
#ifdef USE_EAPTLS
1702
	case EAPT_TLS:
1703
1704
		switch(esp->es_client.ea_state) {
1705
		
1706
		case eapListen:
1707
1708
			GETCHAR(flags, inp);
1709
			if(flags & EAP_TLS_FLAGS_START){
1710
1711
				esp->es_client.ea_using_eaptls = 1;		
1712
1713
                                if (explicit_remote){
1714
                                        esp->es_client.ea_peer = strdup(remote_name);
1715
                                        esp->es_client.ea_peerlen = strlen(remote_name);
1716
                                } else
1717
                                        esp->es_client.ea_peer = NULL;
1718
	
1719
				/* Init ssl session */
1720
				if(!eaptls_init_ssl_client(esp)) {
1721
					dbglog("cannot init ssl");
1722
					eap_send_nak(esp, id, EAPT_TLS);
1723
					esp->es_client.ea_using_eaptls = 0;
1724
					break;
1725
				}
1726
1727
				ets = esp->es_client.ea_session;
1728
				eap_tls_response(esp, id);
1729
				esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck :
1730
								eapTlsRecv);
1731
				break;
1732
			}
1733
1734
			/* The server has sent a bad start packet. */
1735
			eap_send_nak(esp, id, EAPT_TLS);
1736
			break;
1737
1738
		case eapTlsRecvAck:
1739
			eap_tls_response(esp, id);
1740
			esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : 
1741
							eapTlsRecv);
1742
			break;
1743
1744
		case eapTlsRecv:
1745
			eaptls_receive(ets, inp, len);	
1746
		
1747
			if(ets->frag) {
1748
				eap_tls_sendack(esp, id);
1749
				esp->es_client.ea_state = eapTlsRecv;
1750
				break;
1751
			}	
1752
1753
			if(ets->alert_recv) {
1754
				eap_tls_sendack(esp, id);
1755
				esp->es_client.ea_state = eapTlsRecvFailure;
1756
				break;
1757
			}
1758
1759
			/* Check if TLS handshake is finished */
1760
			if(SSL_is_init_finished(ets->ssl)){
1761
#ifdef MPPE
1762
 				eaptls_gen_mppe_keys( ets, "client EAP encryption", 1 );
1763
#endif
1764
				eaptls_free_session(ets);
1765
				eap_tls_sendack(esp, id);
1766
				esp->es_client.ea_state = eapTlsRecvSuccess;
1767
				break;
1768
			}
1769
1770
			eap_tls_response(esp,id);
1771
                        esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck :
1772
                                                        eapTlsRecv);
1773
1774
                        break;
1775
1776
		default:
1777
			eap_send_nak(esp, id, EAPT_TLS);
1778
			esp->es_client.ea_using_eaptls = 0;
1779
			break;
1780
		}
1781
1782
		break;
1783
#endif /* USE_EAPTLS */
1784
1459
#ifdef USE_SRP
1785
#ifdef USE_SRP
1460
	case EAPT_SRP:
1786
	case EAPT_SRP:
1461
		if (len < 1) {
1787
		if (len < 1) {
Lines 1737-1742 Link Here
1737
	u_char dig[SHA_DIGESTSIZE];
2063
	u_char dig[SHA_DIGESTSIZE];
1738
#endif /* USE_SRP */
2064
#endif /* USE_SRP */
1739
2065
2066
#ifdef USE_EAPTLS
2067
	struct eaptls_session *ets;
2068
	u_char flags;
2069
#endif /* USE_EAPTLS */
2070
1740
	if (esp->es_server.ea_id != id) {
2071
	if (esp->es_server.ea_id != id) {
1741
		dbglog("EAP: discarding Response %d; expected ID %d", id,
2072
		dbglog("EAP: discarding Response %d; expected ID %d", id,
1742
		    esp->es_server.ea_id);
2073
		    esp->es_server.ea_id);
Lines 1776-1781 Link Here
1776
		eap_figure_next_state(esp, 0);
2107
		eap_figure_next_state(esp, 0);
1777
		break;
2108
		break;
1778
2109
2110
#ifdef USE_EAPTLS
2111
	case EAPT_TLS:
2112
		switch(esp->es_server.ea_state) {
2113
2114
		case eapTlsRecv:
2115
			ets = (struct eaptls_session *) esp->es_server.ea_session;
2116
			eap_figure_next_state(esp, 
2117
				eaptls_receive(esp->es_server.ea_session, inp, len));
2118
		
2119
			if(ets->alert_recv) {
2120
				eap_send_failure(esp);
2121
				break;
2122
			}
2123
			break;
2124
2125
		case eapTlsRecvAck:
2126
			if(len > 1) {
2127
				dbglog("EAP-TLS ACK with extra data");	
2128
			}
2129
			eap_figure_next_state(esp, 0);
2130
			break;
2131
2132
		case eapTlsRecvClient:
2133
			/* Receive authentication response from client */
2134
	
2135
			GETCHAR(flags, inp);
2136
2137
			if(len == 1 && !flags) {	/* Ack = ok */
2138
#ifdef MPPE
2139
 				eaptls_gen_mppe_keys( esp->es_server.ea_session, "client EAP encryption", 0 );
2140
#endif
2141
				eap_send_success(esp);
2142
			}
2143
			else {			/* failure */
2144
				eaptls_receive(esp->es_server.ea_session, inp, len);
2145
				warn("Server authentication failed");
2146
				eap_send_failure(esp);
2147
			}
2148
2149
			eaptls_free_session(esp->es_server.ea_session);
2150
2151
			break;
2152
2153
		case eapTlsRecvAlertAck:
2154
			eap_send_failure(esp);
2155
			break;
2156
2157
		default:
2158
			eap_figure_next_state(esp, 1);
2159
			break;
2160
		}
2161
		break;
2162
#endif /* USE_EAPTLS */
2163
1779
	case EAPT_NOTIFICATION:
2164
	case EAPT_NOTIFICATION:
1780
		dbglog("EAP unexpected Notification; response discarded");
2165
		dbglog("EAP unexpected Notification; response discarded");
1781
		break;
2166
		break;
Lines 1807-1812 Link Here
1807
			esp->es_server.ea_state = eapMD5Chall;
2192
			esp->es_server.ea_state = eapMD5Chall;
1808
			break;
2193
			break;
1809
2194
2195
#ifdef USE_EAPTLS
2196
			/* Send EAP-TLS start packet */
2197
		case EAPT_TLS:
2198
			esp->es_server.ea_state = eapTlsStart;
2199
			break;
2200
#endif /* USE_EAPTLS */
2201
			
1810
		default:
2202
		default:
1811
			dbglog("EAP: peer requesting unknown Type %d", vallen);
2203
			dbglog("EAP: peer requesting unknown Type %d", vallen);
1812
			switch (esp->es_server.ea_state) {
2204
			switch (esp->es_server.ea_state) {
Lines 2018-2030 Link Here
2018
int id;
2410
int id;
2019
int len;
2411
int len;
2020
{
2412
{
2021
	if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)) {
2413
	if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)
2414
#ifdef USE_EAPTLS
2415
		&& esp->es_client.ea_state != eapTlsRecvSuccess
2416
#endif /* USE_EAPTLS */
2417
		) {
2022
		dbglog("EAP unexpected success message in state %s (%d)",
2418
		dbglog("EAP unexpected success message in state %s (%d)",
2023
		    eap_state_name(esp->es_client.ea_state),
2419
		    eap_state_name(esp->es_client.ea_state),
2024
		    esp->es_client.ea_state);
2420
		    esp->es_client.ea_state);
2025
		return;
2421
		return;
2026
	}
2422
	}
2027
2423
2424
#ifdef USE_EAPTLS
2425
	if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state != 
2426
		eapTlsRecvSuccess) {
2427
		dbglog("EAP-TLS unexpected success message in state %s (%d)",
2428
                    eap_state_name(esp->es_client.ea_state),
2429
                    esp->es_client.ea_state);
2430
		return;
2431
	}
2432
#endif /* USE_EAPTLS */
2433
2028
	if (esp->es_client.ea_timeout > 0) {
2434
	if (esp->es_client.ea_timeout > 0) {
2029
		UNTIMEOUT(eap_client_timeout, (void *)esp);
2435
		UNTIMEOUT(eap_client_timeout, (void *)esp);
2030
	}
2436
	}
Lines 2150-2155 Link Here
2150
	int code, id, len, rtype, vallen;
2556
	int code, id, len, rtype, vallen;
2151
	u_char *pstart;
2557
	u_char *pstart;
2152
	u_int32_t uval;
2558
	u_int32_t uval;
2559
#ifdef USE_EAPTLS
2560
	u_char flags;
2561
#endif /* USE_EAPTLS */
2153
2562
2154
	if (inlen < EAP_HEADERLEN)
2563
	if (inlen < EAP_HEADERLEN)
2155
		return (0);
2564
		return (0);
Lines 2214-2219 Link Here
2214
			}
2623
			}
2215
			break;
2624
			break;
2216
2625
2626
#ifdef USE_EAPTLS
2627
		case EAPT_TLS:
2628
			if (len < 1)
2629
				break;
2630
			GETCHAR(flags, inp);
2631
			len--;
2632
2633
                        if(flags == 0 && len == 0){
2634
                                printer(arg, " Ack");
2635
                                break;
2636
                        }
2637
2638
			printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
2639
			printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
2640
			printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
2641
			break;
2642
#endif /* USE_EAPTLS */
2643
2217
		case EAPT_SRP:
2644
		case EAPT_SRP:
2218
			if (len < 3)
2645
			if (len < 3)
2219
				goto truncated;
2646
				goto truncated;
Lines 2325-2330 Link Here
2325
			}
2752
			}
2326
			break;
2753
			break;
2327
2754
2755
#ifdef USE_EAPTLS
2756
		case EAPT_TLS:
2757
			if (len < 1)
2758
				break;
2759
			GETCHAR(flags, inp);
2760
			len--;
2761
2762
                        if(flags == 0 && len == 0){
2763
                                printer(arg, " Ack");
2764
                                break;
2765
                        }
2766
2767
			printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
2768
			printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
2769
			printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
2770
			
2771
			break;												
2772
#endif /* USE_EAPTLS */
2773
2328
		case EAPT_NAK:
2774
		case EAPT_NAK:
2329
			if (len <= 0) {
2775
			if (len <= 0) {
2330
				printer(arg, " <missing hint>");
2776
				printer(arg, " <missing hint>");
Lines 2426-2428 Link Here
2426
2872
2427
	return (inp - pstart);
2873
	return (inp - pstart);
2428
}
2874
}
2875
(-)ppp-2.4.5.orig/pppd/eap.h (-1 / +31 lines)
Lines 84-89 Link Here
84
	eapClosed,	/* Authentication not in use */
84
	eapClosed,	/* Authentication not in use */
85
	eapListen,	/* Client ready (and timer running) */
85
	eapListen,	/* Client ready (and timer running) */
86
	eapIdentify,	/* EAP Identify sent */
86
	eapIdentify,	/* EAP Identify sent */
87
	eapTlsStart,	/* Send EAP-TLS start packet */
88
	eapTlsRecv,	/* Receive EAP-TLS tls data */
89
	eapTlsSendAck,	/* Send EAP-TLS ack */
90
	eapTlsSend,	/* Send EAP-TLS tls data */
91
	eapTlsRecvAck,	/* Receive EAP-TLS ack */
92
	eapTlsRecvClient, 	/* Receive EAP-TLS auth response from client*/
93
	eapTlsSendAlert,	/* Send EAP-TLS tls alert (server)*/
94
	eapTlsRecvAlertAck,	/* Receive EAP-TLS ack after sending alert */
95
	eapTlsRecvSuccess,	/* Receive EAP success */
96
	eapTlsRecvFailure,	/* Receive EAP failure */
87
	eapSRP1,	/* Sent EAP SRP-SHA1 Subtype 1 */
97
	eapSRP1,	/* Sent EAP SRP-SHA1 Subtype 1 */
88
	eapSRP2,	/* Sent EAP SRP-SHA1 Subtype 2 */
98
	eapSRP2,	/* Sent EAP SRP-SHA1 Subtype 2 */
89
	eapSRP3,	/* Sent EAP SRP-SHA1 Subtype 3 */
99
	eapSRP3,	/* Sent EAP SRP-SHA1 Subtype 3 */
Lines 95-103 Link Here
95
105
96
#define	EAP_STATES	\
106
#define	EAP_STATES	\
97
	"Initial", "Pending", "Closed", "Listen", "Identify", \
107
	"Initial", "Pending", "Closed", "Listen", "Identify", \
108
	"TlsStart", "TlsRecv", "TlsSendAck", "TlsSend", "TlsRecvAck", "TlsRecvClient",\
109
	"TlsSendAlert", "TlsRecvAlertAck" , "TlsRecvSuccess", "TlsRecvFailure", \
98
	"SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth"
110
	"SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth"
99
111
100
#define	eap_client_active(esp)	((esp)->es_client.ea_state == eapListen)
112
#ifdef USE_EAPTLS
113
#define	eap_client_active(esp)	((esp)->es_client.ea_state != eapInitial ||\
114
				 (esp)->es_client.ea_state != eapPending ||\
115
				 (esp)->es_client.ea_state != eapClosed)
116
#else
117
#define eap_client_active(esp)	((esp)->es_client.ea_state == eapListen)
118
#endif /* USE_EAPTLS */
119
101
#define	eap_server_active(esp)	\
120
#define	eap_server_active(esp)	\
102
	((esp)->es_server.ea_state >= eapIdentify && \
121
	((esp)->es_server.ea_state >= eapIdentify && \
103
	 (esp)->es_server.ea_state <= eapMD5Chall)
122
	 (esp)->es_server.ea_state <= eapMD5Chall)
Lines 112-122 Link Here
112
	u_short ea_namelen;	/* Length of our name */
131
	u_short ea_namelen;	/* Length of our name */
113
	u_short ea_peerlen;	/* Length of peer's name */
132
	u_short ea_peerlen;	/* Length of peer's name */
114
	enum eap_state_code ea_state;
133
	enum eap_state_code ea_state;
134
#ifdef USE_EAPTLS
135
	enum eap_state_code ea_prev_state;
136
#endif
115
	u_char ea_id;		/* Current id */
137
	u_char ea_id;		/* Current id */
116
	u_char ea_requests;	/* Number of Requests sent/received */
138
	u_char ea_requests;	/* Number of Requests sent/received */
117
	u_char ea_responses;	/* Number of Responses */
139
	u_char ea_responses;	/* Number of Responses */
118
	u_char ea_type;		/* One of EAPT_* */
140
	u_char ea_type;		/* One of EAPT_* */
119
	u_int32_t ea_keyflags;	/* SRP shared key usage flags */
141
	u_int32_t ea_keyflags;	/* SRP shared key usage flags */
142
#ifdef USE_EAPTLS
143
	bool ea_using_eaptls;
144
#endif
120
};
145
};
121
146
122
/*
147
/*
Lines 139-145 Link Here
139
 * Timeouts.
164
 * Timeouts.
140
 */
165
 */
141
#define	EAP_DEFTIMEOUT		3	/* Timeout (seconds) for rexmit */
166
#define	EAP_DEFTIMEOUT		3	/* Timeout (seconds) for rexmit */
167
#ifdef USE_EAPTLS
168
#define	EAP_DEFTRANSMITS	30	/* max # times to transmit */
169
					/* certificates can be long ... */
170
#else
142
#define	EAP_DEFTRANSMITS	10	/* max # times to transmit */
171
#define	EAP_DEFTRANSMITS	10	/* max # times to transmit */
172
#endif /* USE_EAPTLS */
143
#define	EAP_DEFREQTIME		20	/* Time to wait for peer request */
173
#define	EAP_DEFREQTIME		20	/* Time to wait for peer request */
144
#define	EAP_DEFALLOWREQ		20	/* max # times to accept requests */
174
#define	EAP_DEFALLOWREQ		20	/* max # times to accept requests */
145
175
(-)ppp-2.4.5.orig/pppd/md5.c (+4 lines)
Lines 33-38 Link Here
33
 ***********************************************************************
33
 ***********************************************************************
34
 */
34
 */
35
35
36
#ifndef USE_EAPTLS
37
36
#include <string.h>
38
#include <string.h>
37
#include "md5.h"
39
#include "md5.h"
38
40
Lines 305-307 Link Here
305
 ** End of md5.c                                                      **
307
 ** End of md5.c                                                      **
306
 ******************************** (cut) ********************************
308
 ******************************** (cut) ********************************
307
 */
309
 */
310
#endif /* USE_EAPTLS */
311
(-)ppp-2.4.5.orig/pppd/md5.h (+3 lines)
Lines 36-41 Link Here
36
 ** documentation and/or software.                                    **
36
 ** documentation and/or software.                                    **
37
 ***********************************************************************
37
 ***********************************************************************
38
 */
38
 */
39
#ifndef USE_EAPTLS
39
40
40
#ifndef __MD5_INCLUDE__
41
#ifndef __MD5_INCLUDE__
41
42
Lines 63-65 Link Here
63
64
64
#define __MD5_INCLUDE__
65
#define __MD5_INCLUDE__
65
#endif /* __MD5_INCLUDE__ */
66
#endif /* __MD5_INCLUDE__ */
67
68
#endif /* USE_EAPTLS */
(-)ppp-2.4.5.orig/pppd/options.c (+10 lines)
Lines 123-128 Link Here
123
bool	dryrun;			/* print out option values and exit */
123
bool	dryrun;			/* print out option values and exit */
124
char	*domain;		/* domain name set by domain option */
124
char	*domain;		/* domain name set by domain option */
125
int	child_wait = 5;		/* # seconds to wait for children at exit */
125
int	child_wait = 5;		/* # seconds to wait for children at exit */
126
#ifdef USE_EAPTLS
127
bool	only_update_crl_server = 0;	/* update server crl and exit */
128
bool	only_update_crl_client = 0;	/* update client crl and exit */
129
#endif /* USE_EAPTLS */
126
130
127
#ifdef MAXOCTETS
131
#ifdef MAXOCTETS
128
unsigned int  maxoctets = 0;    /* default - no limit */
132
unsigned int  maxoctets = 0;    /* default - no limit */
Lines 333-338 Link Here
333
    { "mo-timeout", o_int, &maxoctets_timeout,
337
    { "mo-timeout", o_int, &maxoctets_timeout,
334
      "Check for traffic limit every N seconds", OPT_PRIO | OPT_LLIMIT | 1 },
338
      "Check for traffic limit every N seconds", OPT_PRIO | OPT_LLIMIT | 1 },
335
#endif
339
#endif
340
#ifdef USE_EAPTLS
341
    { "only-update-crl-server", o_bool, &only_update_crl_server,
342
      "Update server CA CRLs and exit", 1 },
343
    { "only-update-crl-client", o_bool, &only_update_crl_client,
344
      "Update client CA CRLs and exit", 1 },
345
#endif /* USE_EAPTLS */
336
346
337
    { NULL }
347
    { NULL }
338
};
348
};
(-)ppp-2.4.5.orig/pppd/pathnames.h (+7 lines)
Lines 21-26 Link Here
21
#define _PATH_UPAPFILE 	 _ROOT_PATH "/etc/ppp/pap-secrets"
21
#define _PATH_UPAPFILE 	 _ROOT_PATH "/etc/ppp/pap-secrets"
22
#define _PATH_CHAPFILE 	 _ROOT_PATH "/etc/ppp/chap-secrets"
22
#define _PATH_CHAPFILE 	 _ROOT_PATH "/etc/ppp/chap-secrets"
23
#define _PATH_SRPFILE 	 _ROOT_PATH "/etc/ppp/srp-secrets"
23
#define _PATH_SRPFILE 	 _ROOT_PATH "/etc/ppp/srp-secrets"
24
25
#ifdef USE_EAPTLS
26
#define _PATH_EAPTLSCLIFILE	_ROOT_PATH "/etc/ppp/eaptls-client"
27
#define _PATH_EAPTLSSERVFILE	_ROOT_PATH "/etc/ppp/eaptls-server"
28
#define _PATH_OPENSSLCONFFILE	_ROOT_PATH "/etc/ppp/openssl.cnf"
29
#endif /* USE_EAPTLS */
30
24
#define _PATH_SYSOPTIONS _ROOT_PATH "/etc/ppp/options"
31
#define _PATH_SYSOPTIONS _ROOT_PATH "/etc/ppp/options"
25
#define _PATH_IPUP	 _ROOT_PATH "/etc/ppp/ip-up"
32
#define _PATH_IPUP	 _ROOT_PATH "/etc/ppp/ip-up"
26
#define _PATH_IPDOWN	 _ROOT_PATH "/etc/ppp/ip-down"
33
#define _PATH_IPDOWN	 _ROOT_PATH "/etc/ppp/ip-down"
(-)ppp-2.4.5.orig/pppd/plugins/Makefile.linux (+3 lines)
Lines 8-13 Link Here
8
LIBS = 
8
LIBS = 
9
INSTALL	= install
9
INSTALL	= install
10
10
11
# EAP-TLS
12
CFLAGS += -DUSE_EAPTLS=1
13
11
DESTDIR = $(INSTROOT)@DESTDIR@
14
DESTDIR = $(INSTROOT)@DESTDIR@
12
BINDIR = $(DESTDIR)/sbin
15
BINDIR = $(DESTDIR)/sbin
13
MANDIR = $(DESTDIR)/share/man/man8
16
MANDIR = $(DESTDIR)/share/man/man8
(-)ppp-2.4.5.orig/pppd/plugins/passprompt.c (+3 lines)
Lines 107-110 Link Here
107
{
107
{
108
    add_options(options);
108
    add_options(options);
109
    pap_passwd_hook = promptpass;
109
    pap_passwd_hook = promptpass;
110
#ifdef USE_EAPTLS
111
    eaptls_passwd_hook = promptpass;
112
#endif
110
}
113
}
(-)ppp-2.4.5.orig/pppd/plugins/passwordfd.c (+4 lines)
Lines 75-78 Link Here
75
75
76
    chap_check_hook = pwfd_check;
76
    chap_check_hook = pwfd_check;
77
    chap_passwd_hook = pwfd_passwd;
77
    chap_passwd_hook = pwfd_passwd;
78
79
#ifdef USE_EAPTLS
80
    eaptls_passwd_hook = pwfd_passwd;
81
#endif
78
}
82
}
(-)ppp-2.4.5.orig/pppd/pppd.h (+8 lines)
Lines 325-330 Link Here
325
extern bool	dryrun;		/* check everything, print options, exit */
325
extern bool	dryrun;		/* check everything, print options, exit */
326
extern int	child_wait;	/* # seconds to wait for children at end */
326
extern int	child_wait;	/* # seconds to wait for children at end */
327
327
328
#ifdef USE_EAPTLS
329
extern char	*crl_dir;
330
#endif /* USE_EAPTLS */
331
328
#ifdef MAXOCTETS
332
#ifdef MAXOCTETS
329
extern unsigned int maxoctets;	     /* Maximum octetes per session (in bytes) */
333
extern unsigned int maxoctets;	     /* Maximum octetes per session (in bytes) */
330
extern int       maxoctets_dir;      /* Direction :
334
extern int       maxoctets_dir;      /* Direction :
Lines 722-727 Link Here
722
extern int (*chap_passwd_hook) __P((char *user, char *passwd));
726
extern int (*chap_passwd_hook) __P((char *user, char *passwd));
723
extern void (*multilink_join_hook) __P((void));
727
extern void (*multilink_join_hook) __P((void));
724
728
729
#ifdef USE_EAPTLS
730
extern int (*eaptls_passwd_hook) __P((char *user, char *passwd));
731
#endif
732
725
/* Let a plugin snoop sent and received packets.  Useful for L2TP */
733
/* Let a plugin snoop sent and received packets.  Useful for L2TP */
726
extern void (*snoop_recv_hook) __P((unsigned char *p, int len));
734
extern void (*snoop_recv_hook) __P((unsigned char *p, int len));
727
extern void (*snoop_send_hook) __P((unsigned char *p, int len));
735
extern void (*snoop_send_hook) __P((unsigned char *p, int len));

Return to bug 436122