From: Michael Tremer Date: Sat, 4 Jun 2011 13:26:10 +0000 (+0200) Subject: ppp: Fix for IPv6. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0bc5d371f2c01305cbede3024c45e02a12b69850;p=ipfire-3.x.git ppp: Fix for IPv6. pppd was not compiled properly for IPv6 and I needed to fix that. Anyway, there were lots of other fixes applied. --- diff --git a/pkgs/ppp/patches/ppp-2.3.6-sample.patch b/pkgs/ppp/patches/ppp-2.3.6-sample.patch new file mode 100644 index 000000000..92eee6c0e --- /dev/null +++ b/pkgs/ppp/patches/ppp-2.3.6-sample.patch @@ -0,0 +1,295 @@ +--- ppp-2.3.3/sample/auth-down.sample Tue Jan 6 17:53:27 1998 ++++ ppp-2.3.3/sample/auth-down Tue Jan 6 17:53:27 1998 +@@ -0,0 +1,17 @@ ++#!/bin/sh ++# ++# A program or script which is executed after the remote system ++# successfully authenticates itself. It is executed with the parameters ++# ++# ++ ++# ++# The environment is cleared before executing this script ++# so the path must be reset ++# ++PATH=/usr/sbin:/sbin:/usr/bin:/bin ++export PATH ++ ++echo auth-down `date +'%y/%m/%d %T'` $* >> /var/log/pppstats ++ ++# last line +--- ppp-2.3.3/sample/auth-up.sample Tue Jan 6 17:53:27 1998 ++++ ppp-2.3.3/sample/auth-up Tue Jan 6 17:53:27 1998 +@@ -0,0 +1,17 @@ ++#!/bin/sh ++# ++# A program or script which is executed after the remote system ++# successfully authenticates itself. It is executed with the parameters ++# ++# ++ ++# ++# The environment is cleared before executing this script ++# so the path must be reset ++# ++PATH=/usr/sbin:/sbin:/usr/bin:/bin ++export PATH ++ ++echo auth-up `date +'%y/%m/%d %T'` $* >> /var/log/pppstats ++ ++# last line +--- ppp-2.3.3/sample/ip-down.sample Tue Jan 6 17:53:27 1998 ++++ ppp-2.3.3/sample/ip-down Tue Jan 6 17:53:27 1998 +@@ -0,0 +1,22 @@ ++#!/bin/sh ++# ++# This script is run by the pppd _after_ the link is brought down. ++# It should be used to delete routes, unset IP addresses etc. ++# ++# This script is called with the following arguments: ++# Arg Name Example ++# $1 Interface name ppp0 ++# $2 The tty ttyS1 ++# $3 The link speed 38400 ++# $4 Local IP number 12.34.56.78 ++# $5 Peer IP number 12.34.56.99 ++# ++ ++# ++# The environment is cleared before executing this script ++# so the path must be reset ++# ++PATH=/usr/sbin:/sbin:/usr/bin:/bin ++export PATH ++ ++# last line +--- ppp-2.3.3/sample/ip-up.sample Tue Jan 6 17:53:27 1998 ++++ ppp-2.3.3/sample/ip-up Tue Jan 6 17:53:27 1998 +@@ -0,0 +1,23 @@ ++#!/bin/sh ++# ++# This script is run by the pppd after the link is established. ++# It should be used to add routes, set IP address, run the mailq ++# etc. ++# ++# This script is called with the following arguments: ++# Arg Name Example ++# $1 Interface name ppp0 ++# $2 The tty ttyS1 ++# $3 The link speed 38400 ++# $4 Local IP number 12.34.56.78 ++# $5 Peer IP number 12.34.56.99 ++# ++ ++# ++# The environment is cleared before executing this script ++# so the path must be reset ++# ++PATH=/usr/sbin:/sbin:/usr/bin:/bin ++export PATH ++ ++# last line +--- ppp-2.3.3/sample/options.sample Tue Jan 6 17:53:27 1998 ++++ ppp-2.3.3/sample/options Tue Jan 6 17:53:27 1998 +@@ -0,0 +1,153 @@ ++# /etc/ppp/options ++ ++# The name of this server. Often, the FQDN is used here. ++#name ++ ++# Enforce the use of the hostname as the name of the local system for ++# authentication purposes (overrides the name option). ++usehostname ++ ++# If no local IP address is given, pppd will use the first IP address ++# that belongs to the local hostname. If "noipdefault" is given, this ++# is disabled and the peer will have to supply an IP address. ++noipdefault ++ ++# With this option, pppd will accept the peer's idea of our local IP ++# address, even if the local IP address was specified in an option. ++#ipcp-accept-local ++ ++# With this option, pppd will accept the peer's idea of its (remote) IP ++# address, even if the remote IP address was specified in an option. ++#ipcp-accept-remote ++ ++# Specify which DNS Servers the incoming Win95 or WinNT Connection should use ++# Two Servers can be remotely configured ++#ms-dns 192.168.1.1 ++#ms-dns 192.168.1.2 ++ ++# Specify which WINS Servers the incoming connection Win95 or WinNT should use ++#wins-addr 192.168.1.50 ++#wins-addr 192.168.1.51 ++ ++# enable this on a server that already has a permanent default route ++#nodefaultroute ++ ++# Run the executable or shell command specified after pppd has terminated ++# the link. This script could, for example, issue commands to the modem ++# to cause it to hang up if hardware modem control signals were not ++# available. ++# If mgetty is running, it will reset the modem anyway. So there is no need ++# to do it here. ++#disconnect "chat -- \d+++\d\c OK ath0 OK" ++ ++# Increase debugging level (same as -d). The debug output is written ++# to syslog LOG_LOCAL2. ++debug ++ ++# Enable debugging code in the kernel-level PPP driver. The argument n ++# is a number which is the sum of the following values: 1 to enable ++# general debug messages, 2 to request that the contents of received ++# packets be printed, and 4 to request that the contents of transmitted ++# packets be printed. ++#kdebug n ++ ++# Require the peer to authenticate itself before allowing network ++# packets to be sent or received. ++# Please do not disable this setting. It is expected to be standard in ++# future releases of pppd. Use the call option (see manpage) to disable ++# authentication for specific peers. ++#auth ++ ++# authentication can either be pap or chap. As most people only want to ++# use pap, you can also disable chap: ++#require-pap ++#refuse-chap ++ ++# Use hardware flow control (i.e. RTS/CTS) to control the flow of data ++# on the serial port. ++crtscts ++ ++# Specifies that pppd should use a UUCP-style lock on the serial device ++# to ensure exclusive access to the device. ++lock ++ ++# Use the modem control lines. ++modem ++ ++# async character map -- 32-bit hex; each bit is a character ++# that needs to be escaped for pppd to receive it. 0x00000001 ++# represents '\x01', and 0x80000000 represents '\x1f'. ++# To allow pppd to work over a rlogin/telnet connection, ou should escape ++# XON (^Q), XOFF (^S) and ^]: (The peer should use "escape ff".) ++#asyncmap 200a0000 ++asyncmap 0 ++ ++# Specifies that certain characters should be escaped on transmission ++# (regardless of whether the peer requests them to be escaped with its ++# async control character map). The characters to be escaped are ++# specified as a list of hex numbers separated by commas. Note that ++# almost any character can be specified for the escape option, unlike ++# the asyncmap option which only allows control characters to be ++# specified. The characters which may not be escaped are those with hex ++# values 0x20 - 0x3f or 0x5e. ++#escape 11,13,ff ++ ++# Set the MRU [Maximum Receive Unit] value to for negotiation. pppd ++# will ask the peer to send packets of no more than bytes. The ++# minimum MRU value is 128. The default MRU value is 1500. A value of ++# 296 is recommended for slow links (40 bytes for TCP/IP header + 256 ++# bytes of data). ++#mru 542 ++ ++# Set the MTU [Maximum Transmit Unit] value to . Unless the peer ++# requests a smaller value via MRU negotiation, pppd will request that ++# the kernel networking code send data packets of no more than n bytes ++# through the PPP network interface. ++#mtu ++ ++# Set the interface netmask to , a 32 bit netmask in "decimal dot" ++# notation (e.g. 255.255.255.0). ++#netmask 255.255.255.0 ++ ++# Don't fork to become a background process (otherwise pppd will do so ++# if a serial device is specified). ++nodetach ++ ++# Set the assumed name of the remote system for authentication purposes ++# to . ++#remotename ++ ++# Add an entry to this system's ARP [Address Resolution Protocol] ++# table with the IP address of the peer and the Ethernet address of this ++# system. {proxyarp,noproxyarp} ++proxyarp ++ ++# Use the system password database for authenticating the peer using ++# PAP. Note: mgetty already provides this option. If this is specified ++# then dialin from users using a script under Linux to fire up ppp wont work. ++#login ++ ++# If this option is given, pppd will send an LCP echo-request frame to ++# the peer every n seconds. Under Linux, the echo-request is sent when ++# no packets have been received from the peer for n seconds. Normally ++# the peer should respond to the echo-request by sending an echo-reply. ++# This option can be used with the lcp-echo-failure option to detect ++# that the peer is no longer connected. ++lcp-echo-interval 30 ++ ++# If this option is given, pppd will presume the peer to be dead if n ++# LCP echo-requests are sent without receiving a valid LCP echo-reply. ++# If this happens, pppd will terminate the connection. Use of this ++# option requires a non-zero value for the lcp-echo-interval parameter. ++# This option can be used to enable pppd to terminate after the physical ++# connection has been broken (e.g., the modem has hung up) in ++# situations where no hardware modem control lines are available. ++lcp-echo-failure 4 ++ ++# Specifies that pppd should disconnect if the link is idle for n seconds. ++idle 600 ++ ++# Disable the IPXCP and IPX protocols. ++noipx ++ ++# ------ +--- ppp-2.3.3/sample/options.ttyXX.sample Tue Jan 6 17:53:27 1998 ++++ ppp-2.3.3/sample/options.ttyXX Tue Jan 6 17:53:27 1998 +@@ -0,0 +1,14 @@ ++# If you need to set up multiple serial lines then copy this file to ++# options. for each tty with a modem on it. ++# ++# The options.tty file will assign an IP address to each PPP connection ++# as it comes up. They must all be distinct! ++# ++# Example: ++# options.ttyS1 for com2 under DOS. ++# ++# Edit the following line so that the first IP address ++# mentioned is the ip address of the serial port while the second ++# is the IP address of your host ++# ++hostname-s1:hostname +--- ppp-2.3.3/sample/pap-secrets.sample Tue Jan 6 17:53:27 1998 ++++ ppp-2.3.3/sample/pap-secrets Tue Jan 6 17:53:27 1998 +@@ -0,0 +1,28 @@ ++# Secrets for authentication using PAP ++# client server secret IP addresses ++ ++# OUTBOUND CONNECTIONS ++# Here you should add your userid password to connect to your providers via ++# pap. The * means that the password is to be used for ANY host you connect ++# to. Thus you do not have to worry about the foreign machine name. Just ++# replace password with your password. ++# If you have different providers with different passwords then you better ++# remove the following line. ++#hostname * password ++ ++# INBOUND CONNECTIONS ++#client hostname 192.168.1.1 ++ ++# If you add "auth login -chap +pap" to /etc/mgetty+sendfax/login.config, ++# all users in /etc/passwd can use their password for pap-authentication. ++# ++# Every regular user can use PPP and has to use passwords from /etc/passwd ++#* hostname "" ++# UserIDs that cannot use PPP at all. Check your /etc/passwd and add any ++# other accounts that should not be able to use pppd! Replace hostname ++# with your local hostname. ++#guest hostname "*" - ++#master hostname "*" - ++#root hostname "*" - ++#support hostname "*" - ++#stats hostname "*" - diff --git a/pkgs/ppp/patches/ppp-2.4.1-varargs.patch b/pkgs/ppp/patches/ppp-2.4.1-varargs.patch new file mode 100644 index 000000000..0f757ec0a --- /dev/null +++ b/pkgs/ppp/patches/ppp-2.4.1-varargs.patch @@ -0,0 +1,12 @@ +diff -up ppp-2.4.4/pppd/utils.c.varargs ppp-2.4.4/pppd/utils.c +--- ppp-2.4.4/pppd/utils.c.varargs 2004-11-04 05:02:26.000000000 -0500 ++++ ppp-2.4.4/pppd/utils.c 2008-08-28 17:34:29.000000000 -0400 +@@ -290,7 +290,7 @@ vslprintf(buf, buflen, fmt, args) + #if 0 /* not used, and breaks on S/390, apparently */ + case 'r': + f = va_arg(args, char *); +-#ifndef __powerpc__ ++#if !defined (__powerpc__) && !defined(__s390__) && !defined(__s390x__) && !defined(__x86_64__) + n = vslprintf(buf, buflen + 1, f, va_arg(args, va_list)); + #else + /* On the powerpc, a va_list is an array of 1 structure */ diff --git a/pkgs/ppp/patches/ppp-2.4.2-change_resolv_conf.patch b/pkgs/ppp/patches/ppp-2.4.2-change_resolv_conf.patch new file mode 100644 index 000000000..99c9beb79 --- /dev/null +++ b/pkgs/ppp/patches/ppp-2.4.2-change_resolv_conf.patch @@ -0,0 +1,61 @@ +diff -urNp --exclude-from=/mdomsch2/excludes --minimal ppp-2.4.3.orig/pppd/pppd.8 ppp-2.4.3/pppd/pppd.8 +--- ppp-2.4.3.orig/pppd/pppd.8 2004-11-13 06:22:49.000000000 -0600 ++++ ppp-2.4.3/pppd/pppd.8 2005-08-03 22:10:34.000000000 -0500 +@@ -1035,7 +1035,7 @@ Ask the peer for up to 2 DNS server addr + by the peer (if any) are passed to the /etc/ppp/ip\-up script in the + environment variables DNS1 and DNS2, and the environment variable + USEPEERDNS will be set to 1. In addition, pppd will create an +-/etc/ppp/resolv.conf file containing one or two nameserver lines with ++/var/run/ppp/resolv.conf file containing one or two nameserver lines with + the address(es) supplied by the peer. + .TP + .B user \fIname +--- ppp-2.4.2/scripts/ip-down.local.add.change_resolv_conf 1999-02-27 05:32:42.000000000 +0100 ++++ ppp-2.4.2/scripts/ip-down.local.add 2004-09-14 14:36:20.058008752 +0200 +@@ -9,12 +9,13 @@ + # + # Nick Walker (nickwalker@email.com) + # ++. /etc/sysconfig/network-scripts/network-functions + +-if [ -n "$USEPEERDNS" -a -f /etc/ppp/resolv.conf ]; then +- if [ -f /etc/ppp/resolv.prev ]; then +- cp -f /etc/ppp/resolv.prev /etc/resolv.conf ++if [ -n "$USEPEERDNS" -a -f /var/run/ppp/resolv.conf ]; then ++ if [ -f /var/run/ppp/resolv.prev ]; then ++ change_resolv_conf /var/run/ppp/resolv.prev + else +- rm -f /etc/resolv.conf ++ change_resolv_conf + fi + fi + +--- ppp-2.4.2/scripts/ip-up.local.add.change_resolv_conf 1999-11-15 04:28:10.000000000 +0100 ++++ ppp-2.4.2/scripts/ip-up.local.add 2004-09-14 14:37:39.129061828 +0200 +@@ -9,16 +9,19 @@ + # + # Nick Walker (nickwalker@email.com) + # ++. /etc/sysconfig/network-scripts/network-functions + +-if [ -n "$USEPEERDNS" -a -f /etc/ppp/resolv.conf ]; then +- rm -f /etc/ppp/resolv.prev ++if [ -n "$USEPEERDNS" -a -f /var/run/ppp/resolv.conf ]; then ++ rm -f /var/run/ppp/resolv.prev + if [ -f /etc/resolv.conf ]; then +- cp /etc/resolv.conf /etc/ppp/resolv.prev +- grep domain /etc/ppp/resolv.prev > /etc/resolv.conf +- grep search /etc/ppp/resolv.prev >> /etc/resolv.conf +- cat /etc/ppp/resolv.conf >> /etc/resolv.conf ++ cp /etc/resolv.conf /var/run/ppp/resolv.prev ++ rscf=/var/run/ppp/resolv.new ++ grep domain /var/run/ppp/resolv.prev > $rscf ++ grep search /var/run/ppp/resolv.prev >> $rscf ++ change_resolv_conf $rscf ++ rm -f $rscf + else +- cp /etc/ppp/resolv.conf /etc ++ change_resolv_conf /var/run/ppp/resolv.conf + fi + fi + diff --git a/pkgs/ppp/patches/ppp-2.4.2-pppoatm-make.patch b/pkgs/ppp/patches/ppp-2.4.2-pppoatm-make.patch new file mode 100644 index 000000000..897e4fdee --- /dev/null +++ b/pkgs/ppp/patches/ppp-2.4.2-pppoatm-make.patch @@ -0,0 +1,10 @@ +diff -up ppp-2.4.4/pppd/plugins/pppoatm/Makefile.linux.atm-make ppp-2.4.4/pppd/plugins/pppoatm/Makefile.linux +--- ppp-2.4.4/pppd/plugins/pppoatm/Makefile.linux.atm-make 2008-08-28 17:36:10.000000000 -0400 ++++ ppp-2.4.4/pppd/plugins/pppoatm/Makefile.linux 2008-08-28 17:36:56.000000000 -0400 +@@ -1,5 +1,5 @@ + #CC = gcc +-COPTS = -O2 -g ++COPTS = $(RPM_OPT_FLAGS) + CFLAGS = $(COPTS) -I../.. -I../../../include -fPIC + LDFLAGS = -shared + INSTALL = install diff --git a/pkgs/ppp/patches/ppp-2.4.3-fix.patch b/pkgs/ppp/patches/ppp-2.4.3-fix.patch new file mode 100644 index 000000000..3df6db175 --- /dev/null +++ b/pkgs/ppp/patches/ppp-2.4.3-fix.patch @@ -0,0 +1,115 @@ +--- ppp-2.4.3/pppd/plugins/rp-pppoe/discovery.c.fix 2004-11-04 11:07:37.000000000 +0100 ++++ ppp-2.4.3/pppd/plugins/rp-pppoe/discovery.c 2004-11-22 16:00:24.522462124 +0100 +@@ -13,6 +13,8 @@ + #include "pppoe.h" + #include "pppd/pppd.h" + ++void warn __P((char *, ...)); /* log a warning message */ ++ + #include + #include + #include +--- ppp-2.4.3/pppd/ipv6cp.c.fix 2004-11-13 03:28:15.000000000 +0100 ++++ ppp-2.4.3/pppd/ipv6cp.c 2004-11-22 16:00:27.049114044 +0100 +@@ -151,6 +151,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -1064,7 +1065,9 @@ + return (rc); /* Return final code */ + } + +- ++#if defined(SOL2) || defined(__linux__) ++int ether_to_eui64(eui64_t *p_eui64); ++#endif + /* + * ipv6_check_options - check that any IP-related options are OK, + * and assign appropriate defaults. +--- ppp-2.4.3/pppdump/deflate.c.fix 2004-02-02 04:36:46.000000000 +0100 ++++ ppp-2.4.3/pppdump/deflate.c 2004-11-22 16:02:18.071820020 +0100 +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + #include + #include + #include "ppp_defs.h" +@@ -237,8 +238,8 @@ + { + struct deflate_state *state = (struct deflate_state *) arg; + u_char *rptr, *wptr; +- int rlen, olen, ospace; +- int seq, i, flush, r, decode_proto; ++ int rlen, olen; ++ int seq, r; + + rptr = mi; + if (*rptr == 0) +--- ppp-2.4.3/pppdump/bsd-comp.c.fix 2004-02-02 04:36:46.000000000 +0100 ++++ ppp-2.4.3/pppdump/bsd-comp.c 2004-11-22 16:00:27.052113631 +0100 +@@ -383,7 +383,7 @@ + || options[0] != CI_BSD_COMPRESS || options[1] != CILEN_BSD_COMPRESS + || BSD_VERSION(options[2]) != BSD_CURRENT_VERSION + || BSD_NBITS(options[2]) != db->maxbits +- || decomp && db->lens == NULL) ++ || (decomp && db->lens == NULL)) + return 0; + + if (decomp) { +@@ -556,11 +556,11 @@ + u_int n_bits = db->n_bits; + u_int tgtbitno = 32-n_bits; /* bitno when we have a code */ + struct bsd_dict *dictp; +- int explen, i, seq, len; ++ int explen, seq, len; + u_int incode, oldcode, finchar; + u_char *p, *rptr, *wptr; + int ilen; +- int dlen, space, codelen, extra; ++ int dlen=0, codelen, extra; + + rptr = cmsg; + if (*rptr == 0) +@@ -616,7 +616,7 @@ + } + + if (incode > max_ent + 2 || incode > db->maxmaxcode +- || incode > max_ent && oldcode == CLEAR) { ++ || (incode > max_ent && oldcode == CLEAR)) { + if (db->debug) { + printf("bsd_decomp%d: bad code 0x%x oldcode=0x%x ", + db->unit, incode, oldcode); +--- ppp-2.4.3/pppdump/pppdump.c.fix 2004-02-02 04:36:46.000000000 +0100 ++++ ppp-2.4.3/pppdump/pppdump.c 2004-11-22 16:00:27.054113356 +0100 +@@ -34,6 +34,7 @@ + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + #include ++#include + #include + #include + #include +@@ -191,7 +192,7 @@ + show_time(f, c); + break; + default: +- printf("?%.2x\n"); ++ printf("?%.2x\n", c); + } + } + } +@@ -421,7 +422,7 @@ + show_time(f, c); + break; + default: +- printf("?%.2x\n"); ++ printf("?%.2x\n", c); + } + } + } diff --git a/pkgs/ppp/patches/ppp-2.4.3-fix64.patch b/pkgs/ppp/patches/ppp-2.4.3-fix64.patch new file mode 100644 index 000000000..8a2c794d1 --- /dev/null +++ b/pkgs/ppp/patches/ppp-2.4.3-fix64.patch @@ -0,0 +1,10 @@ +--- ppp-2.4.3/pppd/sha1.c.fix64 2004-10-25 01:28:02.000000000 +0200 ++++ ppp-2.4.3/pppd/sha1.c 2004-11-22 16:44:16.850768926 +0100 +@@ -18,6 +18,7 @@ + + #include + #include /* htonl() */ ++#include /* u_int32_t */ + #include + #include "sha1.h" + diff --git a/pkgs/ppp/patches/ppp-2.4.3-make.patch b/pkgs/ppp/patches/ppp-2.4.3-make.patch new file mode 100644 index 000000000..4716ac1ac --- /dev/null +++ b/pkgs/ppp/patches/ppp-2.4.3-make.patch @@ -0,0 +1,91 @@ +--- ppp-2.4.3/pppd/Makefile.linux.make 2004-11-13 13:02:22.000000000 +0100 ++++ ppp-2.4.3/pppd/Makefile.linux 2004-11-22 15:46:49.871309478 +0100 +@@ -30,10 +30,10 @@ + include .depend + endif + +-# CC = gcc ++CC = gcc + # +-COPTS = -O2 -pipe -Wall -g +-LIBS = ++COPTS = -Wall $(RPM_OPT_FLAGS) ++LIBS = -lutil + + # Uncomment the next 2 lines to include support for Microsoft's + # MS-CHAP authentication protocol. Also, edit plugins/radius/Makefile.linux. +@@ -61,8 +61,8 @@ + USE_TDB=y + + HAS_SHADOW=y +-#USE_PAM=y +-#HAVE_INET6=y ++USE_PAM=y ++HAVE_INET6=y + + # Enable plugins + PLUGIN=y +--- ppp-2.4.3/pppd/plugins/Makefile.linux.make 2004-11-14 08:57:35.000000000 +0100 ++++ ppp-2.4.3/pppd/plugins/Makefile.linux 2004-11-22 15:46:49.873309203 +0100 +@@ -1,5 +1,5 @@ + #CC = gcc +-COPTS = -O2 -g ++COPTS = $(RPM_OPT_FLAGS) + CFLAGS = $(COPTS) -I.. -I../../include -fPIC + LDFLAGS = -shared + INSTALL = install +--- ppp-2.4.3/pppd/plugins/radius/Makefile.linux.make 2004-11-14 08:02:31.000000000 +0100 ++++ ppp-2.4.3/pppd/plugins/radius/Makefile.linux 2004-11-22 15:49:08.858233692 +0100 +@@ -12,7 +12,7 @@ + INSTALL = install + + PLUGIN=radius.so radattr.so radrealms.so +-CFLAGS=-I. -I../.. -I../../../include -O2 -fPIC -DRC_LOG_FACILITY=LOG_DAEMON ++CFLAGS=-I. -I../.. -I../../../include $(RPM_OPT_FLAGS) -DRC_LOG_FACILITY=LOG_DAEMON + + # Uncomment the next line to include support for Microsoft's + # MS-CHAP authentication protocol. +--- ppp-2.4.3/pppd/plugins/rp-pppoe/Makefile.linux.make 2004-11-14 08:58:37.000000000 +0100 ++++ ppp-2.4.3/pppd/plugins/rp-pppoe/Makefile.linux 2004-11-22 15:46:49.875308929 +0100 +@@ -25,7 +25,7 @@ + # Version is set ONLY IN THE MAKEFILE! Don't delete this! + RP_VERSION=3.8p + +-COPTS=-O2 -g ++COPTS=$(RPM_OPT_FLAGS) + CFLAGS=$(COPTS) -I../../../include '-DRP_VERSION="$(RP_VERSION)"' + all: rp-pppoe.so pppoe-discovery + +--- ppp-2.4.3/pppdump/Makefile.linux.make 2004-10-31 02:36:52.000000000 +0200 ++++ ppp-2.4.3/pppdump/Makefile.linux 2004-11-22 15:48:16.795379237 +0100 +@@ -2,7 +2,7 @@ + BINDIR = $(DESTDIR)/sbin + MANDIR = $(DESTDIR)/share/man/man8 + +-CFLAGS= -O -I../include/net ++CFLAGS= $(RPM_OPT_FLAGS) -I../include/net + OBJS = pppdump.o bsd-comp.o deflate.o zlib.o + + INSTALL= install +--- ppp-2.4.3/pppstats/Makefile.linux.make 2004-10-31 23:09:03.000000000 +0100 ++++ ppp-2.4.3/pppstats/Makefile.linux 2004-11-22 15:46:49.872309341 +0100 +@@ -10,7 +10,7 @@ + PPPSTATOBJS = pppstats.o + + #CC = gcc +-COPTS = -O ++COPTS = $(RPM_OPT_FLAGS) + COMPILE_FLAGS = -I../include + LIBS = + +--- ppp-2.4.3/chat/Makefile.linux.make 2004-11-03 12:51:47.000000000 +0100 ++++ ppp-2.4.3/chat/Makefile.linux 2004-11-22 15:47:59.445760450 +0100 +@@ -10,7 +10,7 @@ + CDEF4= -DFNDELAY=O_NDELAY # Old name value + CDEFS= $(CDEF1) $(CDEF2) $(CDEF3) $(CDEF4) + +-COPTS= -O2 -g -pipe ++COPTS= $(RPM_OPT_FLAGS) + CFLAGS= $(COPTS) $(CDEFS) + + INSTALL= install diff --git a/pkgs/ppp/patches/ppp-2.4.4-cbcp.patch b/pkgs/ppp/patches/ppp-2.4.4-cbcp.patch new file mode 100644 index 000000000..da8c6b234 --- /dev/null +++ b/pkgs/ppp/patches/ppp-2.4.4-cbcp.patch @@ -0,0 +1,11 @@ +--- ppp-2.4.4/pppd/Makefile.linux.cbcp 2006-07-19 16:11:41.000000000 +0200 ++++ ppp-2.4.4/pppd/Makefile.linux 2006-07-19 16:11:42.000000000 +0200 +@@ -69,7 +69,7 @@ + PLUGIN=y + + # Enable Microsoft proprietary Callback Control Protocol +-#CBCP=y ++CBCP=y + + # Enable EAP SRP-SHA1 authentication (requires libsrp) + #USE_SRP=y diff --git a/pkgs/ppp/patches/ppp-2.4.4-fd_leak.patch b/pkgs/ppp/patches/ppp-2.4.4-fd_leak.patch new file mode 100644 index 000000000..7c3c0605e --- /dev/null +++ b/pkgs/ppp/patches/ppp-2.4.4-fd_leak.patch @@ -0,0 +1,615 @@ +diff -up ppp-2.4.4/pppd/auth.c.fd_leak ppp-2.4.4/pppd/auth.c +--- ppp-2.4.4/pppd/auth.c.fd_leak 2006-06-18 13:26:00.000000000 +0200 ++++ ppp-2.4.4/pppd/auth.c 2009-10-08 21:22:59.789547513 +0200 +@@ -428,7 +428,7 @@ setupapfile(argv) + option_error("unable to reset uid before opening %s: %m", fname); + return 0; + } +- ufile = fopen(fname, "r"); ++ ufile = fopen_r(fname); + if (seteuid(euid) == -1) + fatal("unable to regain privileges: %m"); + if (ufile == NULL) { +@@ -1414,7 +1414,7 @@ check_passwd(unit, auser, userlen, apass + filename = _PATH_UPAPFILE; + addrs = opts = NULL; + ret = UPAP_AUTHNAK; +- f = fopen(filename, "r"); ++ f = fopen_r(filename); + if (f == NULL) { + error("Can't open PAP password file %s: %m", filename); + +@@ -1511,7 +1511,7 @@ null_login(unit) + if (ret <= 0) { + filename = _PATH_UPAPFILE; + addrs = NULL; +- f = fopen(filename, "r"); ++ f = fopen_r(filename); + if (f == NULL) + return 0; + check_access(f, filename); +@@ -1558,7 +1558,7 @@ get_pap_passwd(passwd) + } + + filename = _PATH_UPAPFILE; +- f = fopen(filename, "r"); ++ f = fopen_r(filename); + if (f == NULL) + return 0; + check_access(f, filename); +@@ -1596,7 +1596,7 @@ have_pap_secret(lacks_ipp) + } + + filename = _PATH_UPAPFILE; +- f = fopen(filename, "r"); ++ f = fopen_r(filename); + if (f == NULL) + return 0; + +@@ -1641,7 +1641,7 @@ have_chap_secret(client, server, need_ip + } + + filename = _PATH_CHAPFILE; +- f = fopen(filename, "r"); ++ f = fopen_r(filename); + if (f == NULL) + return 0; + +@@ -1683,7 +1683,7 @@ have_srp_secret(client, server, need_ip, + struct wordlist *addrs; + + filename = _PATH_SRPFILE; +- f = fopen(filename, "r"); ++ f = fopen_r(filename); + if (f == NULL) + return 0; + +@@ -1739,7 +1739,7 @@ get_secret(unit, client, server, secret, + addrs = NULL; + secbuf[0] = 0; + +- f = fopen(filename, "r"); ++ f = fopen_r(filename); + if (f == NULL) { + error("Can't open chap secret file %s: %m", filename); + return 0; +@@ -1796,7 +1796,7 @@ get_srp_secret(unit, client, server, sec + filename = _PATH_SRPFILE; + addrs = NULL; + +- fp = fopen(filename, "r"); ++ fp = fopen_r(filename); + if (fp == NULL) { + error("Can't open srp secret file %s: %m", filename); + return 0; +@@ -2202,7 +2202,7 @@ scan_authfile(f, client, server, secret, + */ + if (word[0] == '@' && word[1] == '/') { + strlcpy(atfile, word+1, sizeof(atfile)); +- if ((sf = fopen(atfile, "r")) == NULL) { ++ if ((sf = fopen_r(atfile)) == NULL) { + warn("can't open indirect secret file %s", atfile); + continue; + } +diff -up ppp-2.4.4/pppd/eap.c.fd_leak ppp-2.4.4/pppd/eap.c +--- ppp-2.4.4/pppd/eap.c.fd_leak 2004-11-09 23:39:25.000000000 +0100 ++++ ppp-2.4.4/pppd/eap.c 2009-10-08 21:22:59.791544181 +0200 +@@ -1226,7 +1226,7 @@ mode_t modebits; + + if ((path = name_of_pn_file()) == NULL) + return (-1); +- fd = open(path, modebits, S_IRUSR | S_IWUSR); ++ fd = open_fd(path, modebits, S_IRUSR | S_IWUSR); + err = errno; + free(path); + errno = err; +diff -up ppp-2.4.4/pppd/main.c.fd_leak ppp-2.4.4/pppd/main.c +--- ppp-2.4.4/pppd/main.c.fd_leak 2009-10-08 21:22:59.769544859 +0200 ++++ ppp-2.4.4/pppd/main.c 2009-10-08 21:30:32.356546561 +0200 +@@ -201,6 +201,8 @@ int ngroups; /* How many groups valid + + static struct timeval start_time; /* Time when link was started. */ + ++static int cloexec_works; /* controlls setting FD_CLOEXEC flag up */ ++ + static struct pppd_stats old_link_stats; + struct pppd_stats link_stats; + unsigned link_connect_time; +@@ -245,6 +247,7 @@ static void holdoff_end __P((void *)); + static void forget_child __P((int pid, int status)); + static int reap_kids __P((void)); + static void childwait_end __P((void *)); ++static void check_cloexec __P((int)); + + #ifdef USE_TDB + static void update_db_entry __P((void)); +@@ -419,7 +422,7 @@ main(argc, argv) + die(0); + + /* Make sure fds 0, 1, 2 are open to somewhere. */ +- fd_devnull = open(_PATH_DEVNULL, O_RDWR); ++ fd_devnull = open_fd(_PATH_DEVNULL, O_RDWR); + if (fd_devnull < 0) + fatal("Couldn't open %s: %m", _PATH_DEVNULL); + while (fd_devnull <= 2) { +@@ -865,6 +866,104 @@ holdoff_end(arg) + new_phase(PHASE_DORMANT); + } + ++ ++/* ++ * check_cloexec - checks for FD_CLOEXEC flag and adds it if necessary ++ */ ++static void ++check_cloexec(int fd) ++{ ++ if (cloexec_works == 0) { ++ int fl = fcntl(fd, F_GETFD); ++ cloexec_works = (fl & FD_CLOEXEC) ? 1 : -1; ++ } ++ if (cloexec_works > 0) ++ return; ++ fcntl(fd, F_SETFD, FD_CLOEXEC); ++ return; ++} ++ ++/* ++ * socket_fd - create an endpoint for communication. uses FD_CLOEXEC if supported ++ */ ++int ++socket_fd(int domain, int type, int protocol) ++{ ++ int fd; ++ ++#ifdef SOCK_CLOEXEC ++ if (cloexec_works != -1) ++ type |= SOCK_CLOEXEC; ++#endif ++ fd = socket(domain, type, protocol); ++ if (fd == -1) ++ return -1; ++ check_cloexec(fd); ++ return fd; ++} ++ ++/* ++ * open_fd - open file with FD_CLOEXEC flag ++ */ ++int ++open_fd(const char *path, int flags) ++{ ++ int fd; ++ ++#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) ++ if (cloexec_works != -1) ++ flags |= O_CLOEXEC; ++#endif ++ fd = open(path, flags); ++ if (fd == -1) ++ return -1; ++ check_cloexec(fd); ++ return fd; ++} ++ ++/* ++ * open_fd_mmode - open file with FD_CLOEXEC flag ++ */ ++int ++open_fd_mode(const char *path, int flags, int mode) ++{ ++ int fd; ++ ++#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) ++ if (cloexec_works != -1) ++ flags |= O_CLOEXEC; ++#endif ++ fd = open(path, flags, mode); ++ if (fd == -1) ++ return -1; ++ check_cloexec(fd); ++ return fd; ++} ++ ++/* ++ * fopen_r - open file with FD_CLOEXEC flag ++ */ ++FILE * ++fopen_r(const char *path) ++{ ++ FILE *f; ++ ++#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC) ++ if (cloexec_works != -1) { ++ f = fopen(path, "re"); ++ if (f != NULL) { ++ check_cloexec(fileno(f)); ++ return f; ++ } ++ } ++#endif ++ f = fopen(path, "r"); ++ if (f == NULL) ++ return NULL; ++ check_cloexec(fileno(f)); ++ return f; ++} ++ + /* List of protocol names, to make our messages a little more informative. */ + struct protocol_list { + u_short proto; +@@ -1618,7 +1717,7 @@ device_script(program, in, out, dont_wai + if (log_to_fd >= 0) + errfd = log_to_fd; + else +- errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); ++ errfd = open_fd_mode(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); + + ++conn_running; + pid = safe_fork(in, out, errfd); +diff -up ppp-2.4.4/pppd/options.c.fd_leak ppp-2.4.4/pppd/options.c +--- ppp-2.4.4/pppd/options.c.fd_leak 2006-06-18 13:26:00.000000000 +0200 ++++ ppp-2.4.4/pppd/options.c 2009-10-08 21:22:59.797544174 +0200 +@@ -409,7 +409,7 @@ options_from_file(filename, must_exist, + option_error("unable to drop privileges to open %s: %m", filename); + return 0; + } +- f = fopen(filename, "r"); ++ f = fopen_r(filename); + err = errno; + if (check_prot && seteuid(euid) == -1) + fatal("unable to regain privileges"); +@@ -1528,9 +1528,9 @@ setlogfile(argv) + option_error("unable to drop permissions to open %s: %m", *argv); + return 0; + } +- fd = open(*argv, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0644); ++ fd = open_fd_mode(*argv, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0644); + if (fd < 0 && errno == EEXIST) +- fd = open(*argv, O_WRONLY | O_APPEND); ++ fd = open_fd(*argv, O_WRONLY | O_APPEND); + err = errno; + if (!privileged_option && seteuid(euid) == -1) + fatal("unable to regain privileges: %m"); +diff -up ppp-2.4.4/pppd/pppd.h.fd_leak ppp-2.4.4/pppd/pppd.h +--- ppp-2.4.4/pppd/pppd.h.fd_leak 2005-08-26 01:59:34.000000000 +0200 ++++ ppp-2.4.4/pppd/pppd.h 2009-10-08 21:22:59.800544904 +0200 +@@ -494,6 +494,10 @@ int ppp_send_config __P((int, int, u_in + int ppp_recv_config __P((int, int, u_int32_t, int, int)); + const char *protocol_name __P((int)); + void remove_pidfiles __P((void)); ++int socket_fd __P((int, int, int)); ++int open_fd __P((const char *, int)); ++int open_fd_mode __P((const char *, int, int)); ++FILE *fopen_r __P((const char *)); + void lock_db __P((void)); + void unlock_db __P((void)); + +diff -up ppp-2.4.4/pppd/sys-linux.c.fd_leak ppp-2.4.4/pppd/sys-linux.c +--- ppp-2.4.4/pppd/sys-linux.c.fd_leak 2009-10-08 21:22:59.778544744 +0200 ++++ ppp-2.4.4/pppd/sys-linux.c 2009-10-08 21:22:59.803544377 +0200 +@@ -308,12 +308,12 @@ static int modify_flags(int fd, int clea + void sys_init(void) + { + /* Get an internet socket for doing socket ioctls. */ +- sock_fd = socket(AF_INET, SOCK_DGRAM, 0); ++ sock_fd = socket_fd(AF_INET, SOCK_DGRAM, 0); + if (sock_fd < 0) + fatal("Couldn't create IP socket: %m(%d)", errno); + + #ifdef INET6 +- sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0); ++ sock6_fd = socket_fd(AF_INET6, SOCK_DGRAM, 0); + if (sock6_fd < 0) + sock6_fd = -errno; /* save errno for later */ + #endif +@@ -459,7 +459,7 @@ int generic_establish_ppp (int fd) + goto err; + } + dbglog("using channel %d", chindex); +- fd = open("/dev/ppp", O_RDWR); ++ fd = open_fd("/dev/ppp", O_RDWR); + if (fd < 0) { + error("Couldn't reopen /dev/ppp: %m"); + goto err; +@@ -619,7 +619,7 @@ static int make_ppp_unit() + dbglog("in make_ppp_unit, already had /dev/ppp open?"); + close(ppp_dev_fd); + } +- ppp_dev_fd = open("/dev/ppp", O_RDWR); ++ ppp_dev_fd = open_fd("/dev/ppp", O_RDWR); + if (ppp_dev_fd < 0) + fatal("Couldn't open /dev/ppp: %m"); + flags = fcntl(ppp_dev_fd, F_GETFL); +@@ -693,7 +693,7 @@ int bundle_attach(int ifnum) + if (!new_style_driver) + return -1; + +- master_fd = open("/dev/ppp", O_RDWR); ++ master_fd = open_fd("/dev/ppp", O_RDWR); + if (master_fd < 0) + fatal("Couldn't open /dev/ppp: %m"); + if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) { +@@ -1412,7 +1412,7 @@ static char *path_to_procfs(const char * + /* Default the mount location of /proc */ + strlcpy (proc_path, "/proc", sizeof(proc_path)); + proc_path_len = 5; +- fp = fopen(MOUNTED, "r"); ++ fp = fopen_r(MOUNTED); + if (fp != NULL) { + while ((mntent = getmntent(fp)) != NULL) { + if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0) +@@ -1472,7 +1472,7 @@ static int open_route_table (void) + close_route_table(); + + path = path_to_procfs("/net/route"); +- route_fd = fopen (path, "r"); ++ route_fd = fopen_r(path); + if (route_fd == NULL) { + error("can't open routing table %s: %m", path); + return 0; +@@ -1713,7 +1713,7 @@ int sifproxyarp (int unit, u_int32_t his + if (tune_kernel) { + forw_path = path_to_procfs("/sys/net/ipv4/ip_forward"); + if (forw_path != 0) { +- int fd = open(forw_path, O_WRONLY); ++ int fd = open_fd(forw_path, O_WRONLY); + if (fd >= 0) { + if (write(fd, "1", 1) != 1) + error("Couldn't enable IP forwarding: %m"); +@@ -1857,7 +1857,7 @@ get_if_hwaddr(u_char *addr, char *name) + struct ifreq ifreq; + int ret, sock_fd; + +- sock_fd = socket(AF_INET, SOCK_DGRAM, 0); ++ sock_fd = socket_fd(AF_INET, SOCK_DGRAM, 0); + if (sock_fd < 0) + return 0; + memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr)); +@@ -2030,7 +2030,7 @@ int ppp_available(void) + sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch); + kernel_version = KVERSION(osmaj, osmin, ospatch); + +- fd = open("/dev/ppp", O_RDWR); ++ fd = open_fd("/dev/ppp", O_RDWR); + if (fd >= 0) { + new_style_driver = 1; + +@@ -2068,7 +2068,7 @@ int ppp_available(void) + /* + * Open a socket for doing the ioctl operations. + */ +- s = socket(AF_INET, SOCK_DGRAM, 0); ++ s = socket_fd(AF_INET, SOCK_DGRAM, 0); + if (s < 0) + return 0; + +@@ -2318,7 +2318,7 @@ int sifaddr (int unit, u_int32_t our_adr + int fd; + + path = path_to_procfs("/sys/net/ipv4/ip_dynaddr"); +- if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) { ++ if (path != 0 && (fd = open_fd(path, O_WRONLY)) >= 0) { + if (write(fd, "1", 1) != 1) + error("Couldn't enable dynamic IP addressing: %m"); + close(fd); +@@ -2494,7 +2494,7 @@ get_pty(master_fdp, slave_fdp, slave_nam + /* + * Try the unix98 way first. + */ +- mfd = open("/dev/ptmx", O_RDWR); ++ mfd = open_fd("/dev/ptmx", O_RDWR); + if (mfd >= 0) { + int ptn; + if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) { +@@ -2505,7 +2505,7 @@ get_pty(master_fdp, slave_fdp, slave_nam + if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0) + warn("Couldn't unlock pty slave %s: %m", pty_name); + #endif +- if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0) ++ if ((sfd = open_fd(pty_name, O_RDWR | O_NOCTTY)) < 0) + warn("Couldn't open pty slave %s: %m", pty_name); + } + } +@@ -2516,10 +2516,10 @@ get_pty(master_fdp, slave_fdp, slave_nam + for (i = 0; i < 64; ++i) { + slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x", + 'p' + i / 16, i % 16); +- mfd = open(pty_name, O_RDWR, 0); ++ mfd = open_fd_mode(pty_name, O_RDWR, 0); + if (mfd >= 0) { + pty_name[5] = 't'; +- sfd = open(pty_name, O_RDWR | O_NOCTTY, 0); ++ sfd = open_fd_mode(pty_name, O_RDWR | O_NOCTTY, 0); + if (sfd >= 0) { + fchown(sfd, uid, -1); + fchmod(sfd, S_IRUSR | S_IWUSR); +@@ -2784,7 +2784,7 @@ ether_to_eui64(eui64_t *p_eui64) + int skfd; + const unsigned char *ptr; + +- skfd = socket(PF_INET6, SOCK_DGRAM, 0); ++ skfd = socket_fd(PF_INET6, SOCK_DGRAM, 0); + if(skfd == -1) + { + warn("could not open IPv6 socket"); +diff -up ppp-2.4.4/pppd/tdb.c.fd_leak ppp-2.4.4/pppd/tdb.c +--- ppp-2.4.4/pppd/tdb.c.fd_leak 2004-11-13 08:13:07.000000000 +0100 ++++ ppp-2.4.4/pppd/tdb.c 2009-10-08 21:22:59.806583590 +0200 +@@ -1724,7 +1724,7 @@ TDB_CONTEXT *tdb_open_ex(const char *nam + goto internal; + } + +- if ((tdb->fd = open(name, open_flags, mode)) == -1) { ++ if ((tdb->fd = open_fd_mode(name, open_flags, mode)) == -1) { + TDB_LOG((tdb, 5, "tdb_open_ex: could not open file %s: %s\n", + name, strerror(errno))); + goto fail; /* errno set by open(2) */ +@@ -1967,7 +1967,7 @@ int tdb_reopen(TDB_CONTEXT *tdb) + } + if (close(tdb->fd) != 0) + TDB_LOG((tdb, 0, "tdb_reopen: WARNING closing tdb->fd failed!\n")); +- tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0); ++ tdb->fd = open_fd_mode(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0); + if (tdb->fd == -1) { + TDB_LOG((tdb, 0, "tdb_reopen: open failed (%s)\n", strerror(errno))); + goto fail; +diff -up ppp-2.4.4/pppd/tty.c.fd_leak ppp-2.4.4/pppd/tty.c +--- ppp-2.4.4/pppd/tty.c.fd_leak 2006-06-04 09:04:57.000000000 +0200 ++++ ppp-2.4.4/pppd/tty.c 2009-10-08 21:22:59.809544300 +0200 +@@ -569,7 +569,7 @@ int connect_tty() + status = EXIT_OPEN_FAILED; + goto errret; + } +- real_ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0); ++ real_ttyfd = open_fd_mode(devnam, O_NONBLOCK | O_RDWR, 0); + err = errno; + if (prio < OPRIO_ROOT && seteuid(0) == -1) + fatal("Unable to regain privileges"); +@@ -723,7 +723,7 @@ int connect_tty() + if (connector == NULL && modem && devnam[0] != 0) { + int i; + for (;;) { +- if ((i = open(devnam, O_RDWR)) >= 0) ++ if ((i = open_fd(devnam, O_RDWR)) >= 0) + break; + if (errno != EINTR) { + error("Failed to reopen %s: %m", devnam); +@@ -896,7 +896,8 @@ open_socket(dest) + *sep = ':'; + + /* get a socket and connect it to the other end */ +- sock = socket(PF_INET, SOCK_STREAM, 0); ++ //sock = socket(PF_INET, SOCK_STREAM, 0); ++ sock = socket_fd(PF_INET, SOCK_STREAM, 0); + if (sock < 0) { + error("Can't create socket: %m"); + return -1; +diff -up ppp-2.4.4/pppd/utils.c.fd_leak ppp-2.4.4/pppd/utils.c +--- ppp-2.4.4/pppd/utils.c.fd_leak 2009-10-08 21:22:59.620325739 +0200 ++++ ppp-2.4.4/pppd/utils.c 2009-10-08 21:22:59.811573725 +0200 +@@ -931,14 +931,14 @@ lock(dev) + slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev); + #endif + +- while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { ++ while ((fd = open_fd_mode(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { + if (errno != EEXIST) { + error("Can't create lock file %s: %m", lock_file); + break; + } + + /* Read the lock file to find out who has the device locked. */ +- fd = open(lock_file, O_RDONLY, 0); ++ fd = open_fd_mode(lock_file, O_RDONLY, 0); + if (fd < 0) { + if (errno == ENOENT) /* This is just a timing problem. */ + continue; +@@ -1017,7 +1017,7 @@ relock(pid) + + if (lock_file[0] == 0) + return -1; +- fd = open(lock_file, O_WRONLY, 0); ++ fd = open_fd_mode(lock_file, O_WRONLY, 0); + if (fd < 0) { + error("Couldn't reopen lock file %s: %m", lock_file); + lock_file[0] = 0; +diff -up ppp-2.4.5/pppd/plugins/pppoatm/pppoatm.c.test ppp-2.4.5/pppd/plugins/pppoatm/pppoatm.c +--- ppp-2.4.5/pppd/plugins/pppoatm/pppoatm.c.test 2010-11-16 09:56:56.083707000 +0100 ++++ ppp-2.4.5/pppd/plugins/pppoatm/pppoatm.c 2010-11-16 09:56:59.382707272 +0100 +@@ -137,7 +137,11 @@ static int connect_pppoatm(void) + + if (!device_got_set) + no_device_given_pppoatm(); ++#ifdef SOCK_CLOEXEC ++ fd = socket(AF_ATMPVC, SOCK_DGRAM | SOCK_CLOEXEC, 0); ++#else + fd = socket(AF_ATMPVC, SOCK_DGRAM, 0); ++#endif + if (fd < 0) + fatal("failed to create socket: %m"); + memset(&qos, 0, sizeof qos); +diff -up ppp-2.4.5/pppd/plugins/pppol2tp/openl2tp.c.test ppp-2.4.5/pppd/plugins/pppol2tp/openl2tp.c +--- ppp-2.4.5/pppd/plugins/pppol2tp/openl2tp.c.test 2010-11-16 09:58:17.499711288 +0100 ++++ ppp-2.4.5/pppd/plugins/pppol2tp/openl2tp.c 2010-11-16 10:00:15.791706960 +0100 +@@ -83,7 +83,11 @@ static int openl2tp_client_create(void) + int result; + + if (openl2tp_fd < 0) { ++#ifdef SOCK_CLOEXEC ++ openl2tp_fd = socket(PF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); ++#else + openl2tp_fd = socket(PF_UNIX, SOCK_DGRAM, 0); ++#endif + if (openl2tp_fd < 0) { + error("openl2tp connection create: %m"); + return -ENOTCONN; +diff -up ppp-2.4.5/pppd/plugins/pppol2tp/pppol2tp.c.test ppp-2.4.5/pppd/plugins/pppol2tp/pppol2tp.c +--- ppp-2.4.5/pppd/plugins/pppol2tp/pppol2tp.c.test 2010-11-16 09:57:44.448709467 +0100 ++++ ppp-2.4.5/pppd/plugins/pppol2tp/pppol2tp.c 2010-11-16 09:59:32.877707001 +0100 +@@ -208,7 +208,11 @@ static void send_config_pppol2tp(int mtu + struct ifreq ifr; + int fd; + ++#ifdef SOCK_CLOEXEC ++ fd = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); ++#else + fd = socket(AF_INET, SOCK_DGRAM, 0); ++#endif + if (fd >= 0) { + memset (&ifr, '\0', sizeof (ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); +diff -up ppp-2.4.5/pppd/plugins/rp-pppoe/if.c.test ppp-2.4.5/pppd/plugins/rp-pppoe/if.c +--- ppp-2.4.5/pppd/plugins/rp-pppoe/if.c.test 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5/pppd/plugins/rp-pppoe/if.c 2010-11-16 09:54:03.973706239 +0100 +@@ -116,6 +116,10 @@ openInterface(char const *ifname, UINT16 + stype = SOCK_PACKET; + #endif + ++#ifdef SOCK_CLOEXEC ++ stype |= SOCK_CLOEXEC; ++#endif ++ + if ((fd = socket(domain, stype, htons(type))) < 0) { + /* Give a more helpful message for the common error case */ + if (errno == EPERM) { +diff -up ppp-2.4.5/pppd/plugins/rp-pppoe/plugin.c.test ppp-2.4.5/pppd/plugins/rp-pppoe/plugin.c +--- ppp-2.4.5/pppd/plugins/rp-pppoe/plugin.c.test 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5/pppd/plugins/rp-pppoe/plugin.c 2010-11-16 09:40:23.355707001 +0100 +@@ -158,7 +158,11 @@ PPPOEConnectDevice(void) + ppp_session_number = ntohs(conn->session); + + /* Make the session socket */ ++#ifdef SOCK_CLOEXEC ++ conn->sessionSocket = socket(AF_PPPOX, SOCK_STREAM | SOCK_CLOEXEC, PX_PROTO_OE); ++#else + conn->sessionSocket = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_OE); ++#endif + if (conn->sessionSocket < 0) { + error("Failed to create PPPoE socket: %m"); + goto errout; +@@ -289,7 +293,11 @@ PPPoEDevnameHook(char *cmd, char **argv, + } + + /* Open a socket */ ++#ifdef SOCK_CLOEXEC ++ if ((fd = socket(PF_PACKET, SOCK_RAW | SOCK_CLOEXEC, 0)) < 0) { ++#else + if ((fd = socket(PF_PACKET, SOCK_RAW, 0)) < 0) { ++#endif + r = 0; + } + +diff -up ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe-discovery.c.test ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe-discovery.c +--- ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe-discovery.c.test 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe-discovery.c 2010-11-16 09:55:08.726707003 +0100 +@@ -121,6 +121,10 @@ openInterface(char const *ifname, UINT16 + stype = SOCK_PACKET; + #endif + ++#ifdef SOCK_CLOEXEC ++ stype |= SOCK_CLOEXEC; ++#endif ++ + if ((fd = socket(domain, stype, htons(type))) < 0) { + /* Give a more helpful message for the common error case */ + if (errno == EPERM) { diff --git a/pkgs/ppp/patches/ppp-2.4.4-lib64.patch b/pkgs/ppp/patches/ppp-2.4.4-lib64.patch new file mode 100644 index 000000000..b84204827 --- /dev/null +++ b/pkgs/ppp/patches/ppp-2.4.4-lib64.patch @@ -0,0 +1,89 @@ +--- ppp-2.4.4/pppd/plugins/rp-pppoe/Makefile.linux.lib64 2006-07-24 20:43:40.000000000 +0200 ++++ ppp-2.4.4/pppd/plugins/rp-pppoe/Makefile.linux 2006-07-24 20:44:56.000000000 +0200 +@@ -15,7 +15,7 @@ + + DESTDIR = $(INSTROOT)@DESTDIR@ + BINDIR = $(DESTDIR)/sbin +-LIBDIR = $(DESTDIR)/lib/pppd/$(PPPDVERSION) ++LIBDIR = $(DESTDIR)/lib/$(shell gcc -print-multi-os-directory 2> /dev/null)/pppd/$(PPPDVERSION) + + PPPDVERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../../patchlevel.h) + +--- ppp-2.4.4/pppd/plugins/radius/Makefile.linux.lib64 2006-07-24 20:43:40.000000000 +0200 ++++ ppp-2.4.4/pppd/plugins/radius/Makefile.linux 2006-07-24 20:44:45.000000000 +0200 +@@ -5,7 +5,7 @@ + + DESTDIR = $(INSTROOT)@DESTDIR@ + MANDIR = $(DESTDIR)/share/man/man8 +-LIBDIR = $(DESTDIR)/lib/pppd/$(VERSION) ++LIBDIR = $(DESTDIR)/lib/$(shell gcc -print-multi-os-directory 2> /dev/null)/pppd/$(VERSION) + + VERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../../patchlevel.h) + +--- ppp-2.4.4/pppd/plugins/pppoatm/Makefile.linux.lib64 2004-11-14 02:12:10.000000000 +0100 ++++ ppp-2.4.4/pppd/plugins/pppoatm/Makefile.linux 2006-07-24 20:44:29.000000000 +0200 +@@ -6,8 +6,8 @@ + + #*********************************************************************** + +-DESTDIR = $(INSTROOT)@DESTDIR@ +-LIBDIR = $(DESTDIR)/lib/pppd/$(VERSION) ++DESTDIR = $(INSTROOT)@DESTDIR@ ++LIBDIR = $(DESTDIR)/lib/$(shell gcc -print-multi-os-directory 2> /dev/null)/pppd/$(VERSION) + + VERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../../patchlevel.h) + +--- ppp-2.4.4/pppd/plugins/Makefile.linux.lib64 2006-07-24 20:43:40.000000000 +0200 ++++ ppp-2.4.4/pppd/plugins/Makefile.linux 2006-07-24 20:43:40.000000000 +0200 +@@ -7,7 +7,7 @@ + DESTDIR = $(INSTROOT)@DESTDIR@ + BINDIR = $(DESTDIR)/sbin + MANDIR = $(DESTDIR)/share/man/man8 +-LIBDIR = $(DESTDIR)/lib/pppd/$(VERSION) ++LIBDIR = $(DESTDIR)/lib/$(shell $(CC) -print-multi-os-directory 2> /dev/null)/pppd/$(VERSION) + + SUBDIRS := rp-pppoe pppoatm pppol2tp + # Uncomment the next line to include the radius authentication plugin +--- ppp-2.4.4/pppd/Makefile.linux.lib64 2006-07-24 20:43:40.000000000 +0200 ++++ ppp-2.4.4/pppd/Makefile.linux 2006-07-24 20:43:40.000000000 +0200 +@@ -8,6 +8,7 @@ + BINDIR = $(DESTDIR)/sbin + MANDIR = $(DESTDIR)/share/man/man8 + INCDIR = $(DESTDIR)/include ++LIBDIR = $(DESTDIR)/lib/$(shell gcc -print-multi-os-directory 2> /dev/null) + + TARGETS = pppd + +@@ -32,7 +33,7 @@ + + CC = gcc + # +-COPTS = -Wall $(RPM_OPT_FLAGS) ++COPTS = -Wall $(RPM_OPT_FLAGS) -DLIBDIR=\""$(LIBDIR)"\" + LIBS = -lutil + + # Uncomment the next 2 lines to include support for Microsoft's +--- ppp-2.4.4/pppd/pathnames.h.lib64 2005-08-26 01:59:34.000000000 +0200 ++++ ppp-2.4.4/pppd/pathnames.h 2006-07-24 20:43:40.000000000 +0200 +@@ -57,7 +57,7 @@ + + #ifdef PLUGIN + #ifdef __STDC__ +-#define _PATH_PLUGIN DESTDIR "/lib/pppd/" VERSION ++#define _PATH_PLUGIN LIBDIR "/pppd/" VERSION + #else /* __STDC__ */ + #define _PATH_PLUGIN "/usr/lib/pppd" + #endif /* __STDC__ */ +--- ppp-2.4.5/pppd/plugins/pppol2tp/Makefile.linux.lib64 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5/pppd/plugins/pppol2tp/Makefile.linux 2010-08-05 16:33:53.964898629 +0200 +@@ -6,8 +6,8 @@ + + #*********************************************************************** + +-DESTDIR = @DESTDIR@ +-LIBDIR = $(DESTDIR)/lib/pppd/$(VERSION) ++DESTDIR = $(INSTROOT)@DESTDIR@ ++LIBDIR = $(DESTDIR)/lib/$(shell gcc -print-multi-os-directory 2> /dev/null)/pppd/$(VERSION) + + VERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../../patchlevel.h) + diff --git a/pkgs/ppp/patches/ppp-2.4.5-eaptls-mppe-0.99.patch b/pkgs/ppp/patches/ppp-2.4.5-eaptls-mppe-0.99.patch new file mode 100644 index 000000000..eb6c2a669 --- /dev/null +++ b/pkgs/ppp/patches/ppp-2.4.5-eaptls-mppe-0.99.patch @@ -0,0 +1,2917 @@ +diff -Naur ppp-2.4.5/README.eap-tls ppp-2.4.5-eaptls-mppe-0.99/README.eap-tls +--- ppp-2.4.5/README.eap-tls 1970-01-01 01:00:00.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/README.eap-tls 2010-10-01 15:17:54.205272328 +0200 +@@ -0,0 +1,169 @@ ++EAP-TLS authentication support for PPP ++====================================== ++ ++1. Intro ++ ++ The Extensible Authentication Protocol (EAP; RFC 3748) is a ++ security protocol that can be used with PPP. It provides a means ++ to plug in multiple optional authentication methods. ++ ++ Transport Level Security (TLS; RFC 2246) provides for mutual ++ authentication, integrity-protected ciphersuite negotiation and ++ key exchange between two endpoints. It also provides for optional ++ MPPE encryption. ++ ++ EAP-TLS (RFC 2716) incapsulates the TLS messages in EAP packets, ++ allowing TLS mutual authentication to be used as a generic EAP ++ mechanism. It also provides optional encryption using the MPPE ++ protocol. ++ ++ This patch provide EAP-TLS support to pppd. ++ This authentication method can be used in both client or server ++ mode. ++ ++2. Building ++ ++ To build pppd with EAP-TLS support, OpenSSL (http://www.openssl.org) ++ is required. Any version from 0.9.7 should work. ++ ++ Configure, compile, and install as usual. ++ ++3. Configuration ++ ++ On the client side there are two ways to configure EAP-TLS: ++ ++ 1. supply the appropriate 'ca', 'cert' and 'key' command-line parameters ++ ++ 2. edit the /etc/ppp/eaptls-client file. ++ Insert a line for each system with which you use EAP-TLS. ++ The line is composed of this fields separated by tab: ++ ++ - Client name ++ The name used by the client for authentication, can be * ++ - Server name ++ The name of the server, can be * ++ - Client certificate file ++ The file containing the certificate chain for the ++ client in PEM format ++ - Server certificate file ++ If you want to specify the certificate that the ++ server is allowed to use, put the certificate file name. ++ Else put a dash '-'. ++ - CA certificate file ++ The file containing the trusted CA certificates in PEM ++ format. ++ - Client private key file ++ The file containing the client private key in PEM format. ++ ++ ++ On the server side edit the /etc/ppp/eaptls-server file. ++ Insert a line for each system with which you use EAP-TLS. ++ The line is composed of this fields separated by tab: ++ ++ - Client name ++ The name used by the client for authentication, can be * ++ - Server name ++ The name of the server, can be * ++ - Client certificate file ++ If you want to specify the certificate that the ++ client is allowed to use, put the certificate file name. ++ Else put a dash '-'. ++ - Server certificate file ++ The file containing the certificate chain for the ++ server in PEM format ++ - CA certificate file ++ The file containing the trusted CA certificates in PEM ++ format. ++ - Client private key file ++ The file containing the server private key in PEM format. ++ - addresses ++ A list of IP addresses the client is allowed to use. ++ ++ ++ OpenSSL engine support is included starting with v0.95 of this patch. ++ Currently the only engine tested is the 'pkcs11' engine (hardware token ++ support). To use the 'pksc11' engine: ++ - Use a special private key fileiname in the /etc/ppp/eaptls-client file: ++ : ++ e.g. ++ pkcs11:123456 ++ ++ - The certificate can also be loaded from the 'pkcs11' engine using ++ a special client certificate filename in the /etc/ppp/eaptls-client file: ++ : ++ e.g. ++ pkcs11:123456 ++ ++ - Create an /etc/ppp/openssl.cnf file to load the right OpenSSL engine prior ++ to starting 'pppd'. A sample openssl.cnf file is ++ ++ openssl_conf = openssl_def ++ ++ [ openssl_def ] ++ engines = engine_section ++ ++ [ engine_section ] ++ pkcs11 = pkcs11_section ++ ++ [ pkcs11_section ] ++ engine_id = pkcs11 ++ dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so ++ MODULE_PATH = /usr/lib64/libeTPkcs11.so ++ init = 0 ++ ++ - There are two ways to specify a password/PIN for the PKCS11 engine: ++ - inside the openssl.cnf file using ++ PIN = your-secret-pin ++ Note The keyword 'PIN' is case sensitive! ++ - Using the 'password' in the ppp options file. ++ From v0.97 of the eap-tls patch the password can also be supplied ++ using the appropriate 'eaptls_passwd_hook' (see plugins/passprompt.c ++ for an example). ++ ++ ++4. Options ++ ++ These pppd options are available: ++ ++ ca ++ Use the CA public certificate found in in PEM format ++ cert ++ Use the client public certificate found in in PEM format ++ or in engine:engine_id format ++ key ++ Use the client private key found in in PEM format ++ or in engine:engine_id format ++ crl-dir ++ Use CRL files from dir. It contains CRL files in PEM ++ format and each file contains a CRL. The files are looked up ++ by the issuer name hash value. Use the c_rehash utility ++ to create necessary links. ++ need-peer-eap ++ If the peer doesn't ask us to authenticate or doesn't use eap ++ to authenticate us, disconnect. ++ ++ Note: ++ password-encrypted certificates can be used as of v0.94 of this ++ patch. The password for the eap-tls.key file is specified using ++ the regular ++ password .... ++ statement in the ppp options file, or by using the appropriate ++ plugin which supplies a 'eaptls_passwd_hook' routine. ++ ++5. Connecting ++ ++ If you're setting up a pppd server, edit the EAP-TLS configuration file ++ as written above and then run pppd with the 'auth' option to authenticate ++ the client. The EAP-TLS method will be used if the other eap methods can't ++ be used (no secrets). ++ ++ If you're setting up a client, edit the configuration file and then run ++ pppd with 'remotename' option to specify the server name. Add the ++ 'need-peer-eap' option if you want to be sure the peer ask you to ++ authenticate (and to use eap) and to disconnect if it doesn't. ++ ++6. Notes ++ ++ This is experimental code. ++ Send suggestions and comments to Jan Just Keijser ++ +diff -Naur ppp-2.4.5/etc.ppp/eaptls-client ppp-2.4.5-eaptls-mppe-0.99/etc.ppp/eaptls-client +--- ppp-2.4.5/etc.ppp/eaptls-client 1970-01-01 01:00:00.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/etc.ppp/eaptls-client 2010-10-01 15:17:54.205272328 +0200 +@@ -0,0 +1,10 @@ ++# Parameters for authentication using EAP-TLS (client) ++ ++# client name (can be *) ++# server name (can be *) ++# client certificate file (required) ++# server certificate file (optional, if unused put '-') ++# CA certificate file (required) ++# client private key file (required) ++ ++#client server /root/cert/client.crt - /root/cert/ca.crt /root/cert/client.key +diff -Naur ppp-2.4.5/etc.ppp/eaptls-server ppp-2.4.5-eaptls-mppe-0.99/etc.ppp/eaptls-server +--- ppp-2.4.5/etc.ppp/eaptls-server 1970-01-01 01:00:00.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/etc.ppp/eaptls-server 2010-10-01 15:17:54.205272328 +0200 +@@ -0,0 +1,11 @@ ++# Parameters for authentication using EAP-TLS (server) ++ ++# client name (can be *) ++# server name (can be *) ++# client certificate file (optional, if unused put '-') ++# server certificate file (required) ++# CA certificate file (required) ++# server private key file (required) ++# allowed addresses (required, can be *) ++ ++#client server - /root/cert/server.crt /root/cert/ca.crt /root/cert/server.key 192.168.1.0/24 +diff -Naur ppp-2.4.5/etc.ppp/openssl.cnf ppp-2.4.5-eaptls-mppe-0.99/etc.ppp/openssl.cnf +--- ppp-2.4.5/etc.ppp/openssl.cnf 1970-01-01 01:00:00.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/etc.ppp/openssl.cnf 2010-10-01 15:17:54.206272162 +0200 +@@ -0,0 +1,14 @@ ++openssl_conf = openssl_def ++ ++[ openssl_def ] ++engines = engine_section ++ ++[ engine_section ] ++pkcs11 = pkcs11_section ++ ++[ pkcs11_section ] ++engine_id = pkcs11 ++dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so ++MODULE_PATH = /usr/lib64/libeTPkcs11.so ++init = 0 ++ +diff -Naur ppp-2.4.5/linux/Makefile.top ppp-2.4.5-eaptls-mppe-0.99/linux/Makefile.top +--- ppp-2.4.5/linux/Makefile.top 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/linux/Makefile.top 2010-10-01 15:17:54.206272162 +0200 +@@ -26,7 +26,7 @@ + cd pppdump; $(MAKE) $(MFLAGS) install + + install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \ +- $(ETCDIR)/chap-secrets ++ $(ETCDIR)/chap-secrets $(ETCDIR)/eaptls-server $(ETCDIR)/eaptls-client + + install-devel: + cd pppd; $(MAKE) $(MFLAGS) install-devel +@@ -37,6 +37,10 @@ + $(INSTALL) -c -m 600 etc.ppp/pap-secrets $@ + $(ETCDIR)/chap-secrets: + $(INSTALL) -c -m 600 etc.ppp/chap-secrets $@ ++$(ETCDIR)/eaptls-server: ++ $(INSTALL) -c -m 600 etc.ppp/eaptls-server $@ ++$(ETCDIR)/eaptls-client: ++ $(INSTALL) -c -m 600 etc.ppp/eaptls-client $@ + + $(BINDIR): + $(INSTALL) -d -m 755 $@ +diff -Naur ppp-2.4.5/pppd/Makefile.linux ppp-2.4.5-eaptls-mppe-0.99/pppd/Makefile.linux +--- ppp-2.4.5/pppd/Makefile.linux 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/Makefile.linux 2010-10-01 15:17:54.207272272 +0200 +@@ -73,6 +73,9 @@ + # Enable EAP SRP-SHA1 authentication (requires libsrp) + #USE_SRP=y + ++# Enable EAP-TLS authentication (requires libssl and libcurl) ++USE_EAPTLS=y ++ + MAXOCTETS=y + + INCLUDE_DIRS= -I../include +@@ -112,6 +115,15 @@ + PPPDOBJS += sha1.o + endif + ++# EAP-TLS ++ifdef USE_EAPTLS ++CFLAGS += -DUSE_EAPTLS=1 -I/usr/kerberos/include ++LIBS += -lssl -lcrypto ++PPPDSRC += eap-tls.c ++HEADERS += eap-tls.h ++PPPDOBJS += eap-tls.o ++endif ++ + ifdef HAS_SHADOW + CFLAGS += -DHAS_SHADOW + #LIBS += -lshadow $(LIBS) +diff -Naur ppp-2.4.5/pppd/auth.c ppp-2.4.5-eaptls-mppe-0.99/pppd/auth.c +--- ppp-2.4.5/pppd/auth.c 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/auth.c 2010-10-01 15:17:54.210272021 +0200 +@@ -109,6 +109,9 @@ + #include "upap.h" + #include "chap-new.h" + #include "eap.h" ++#ifdef USE_EAPTLS ++#include "eap-tls.h" ++#endif + #ifdef CBCP_SUPPORT + #include "cbcp.h" + #endif +@@ -183,6 +186,11 @@ + /* Hook for a plugin to get the CHAP password for authenticating us */ + int (*chap_passwd_hook) __P((char *user, char *passwd)) = NULL; + ++#ifdef USE_EAPTLS ++/* Hook for a plugin to get the EAP-TLS password for authenticating us */ ++int (*eaptls_passwd_hook) __P((char *user, char *passwd)) = NULL; ++#endif ++ + /* Hook for a plugin to say whether it is OK if the peer + refuses to authenticate. */ + int (*null_auth_hook) __P((struct wordlist **paddrs, +@@ -238,6 +246,13 @@ + bool explicit_user = 0; /* Set if "user" option supplied */ + bool explicit_passwd = 0; /* Set if "password" option supplied */ + char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ ++#ifdef USE_EAPTLS ++char *cacert_file = NULL; /* CA certificate file (pem format) */ ++char *cert_file = NULL; /* client certificate file (pem format) */ ++char *privkey_file = NULL; /* client private key file (pem format) */ ++char *crl_dir = NULL; /* directory containing CRL files */ ++bool need_peer_eap = 0; /* Require peer to authenticate us */ ++#endif + + static char *uafname; /* name of most recent +ua file */ + +@@ -254,6 +269,19 @@ + static int have_chap_secret __P((char *, char *, int, int *)); + static int have_srp_secret __P((char *client, char *server, int need_ip, + int *lacks_ipp)); ++ ++#ifdef USE_EAPTLS ++static int have_eaptls_secret_server ++__P((char *client, char *server, int need_ip, int *lacks_ipp)); ++static int have_eaptls_secret_client __P((char *client, char *server)); ++static int scan_authfile_eaptls __P((FILE * f, char *client, char *server, ++ char *cli_cert, char *serv_cert, ++ char *ca_cert, char *pk, ++ struct wordlist ** addrs, ++ struct wordlist ** opts, ++ char *filename, int flags)); ++#endif ++ + static int ip_addr_check __P((u_int32_t, struct permitted_ip *)); + static int scan_authfile __P((FILE *, char *, char *, char *, + struct wordlist **, struct wordlist **, +@@ -401,6 +429,14 @@ + "Set telephone number(s) which are allowed to connect", + OPT_PRIV | OPT_A2LIST }, + ++#ifdef USE_EAPTLS ++ { "ca", o_string, &cacert_file, "EAP-TLS CA certificate in PEM format" }, ++ { "cert", o_string, &cert_file, "EAP-TLS client certificate in PEM format" }, ++ { "key", o_string, &privkey_file, "EAP-TLS client private key in PEM format" }, ++ { "crl-dir", o_string, &crl_dir, "Use CRLs in directory" }, ++ { "need-peer-eap", o_bool, &need_peer_eap, ++ "Require the peer to authenticate us", 1 }, ++#endif /* USE_EAPTLS */ + { NULL } + }; + +@@ -731,6 +767,9 @@ + lcp_options *wo = &lcp_wantoptions[unit]; + lcp_options *go = &lcp_gotoptions[unit]; + lcp_options *ho = &lcp_hisoptions[unit]; ++#ifdef USE_EAPTLS ++ lcp_options *ao = &lcp_allowoptions[unit]; ++#endif + int i; + struct protent *protp; + +@@ -765,6 +804,22 @@ + } + } + ++#ifdef USE_EAPTLS ++ if (need_peer_eap && !ao->neg_eap) { ++ warn("eap required to authenticate us but no suitable secrets"); ++ lcp_close(unit, "couldn't negotiate eap"); ++ status = EXIT_AUTH_TOPEER_FAILED; ++ return; ++ } ++ ++ if (need_peer_eap && !ho->neg_eap) { ++ warn("peer doesn't want to authenticate us with eap"); ++ lcp_close(unit, "couldn't negotiate eap"); ++ status = EXIT_PEER_AUTH_FAILED; ++ return; ++ } ++#endif ++ + new_phase(PHASE_AUTHENTICATE); + auth = 0; + if (go->neg_eap) { +@@ -1278,6 +1333,15 @@ + our_name, 1, &lacks_ip); + } + ++#ifdef USE_EAPTLS ++ if (!can_auth && wo->neg_eap) { ++ can_auth = ++ have_eaptls_secret_server((explicit_remote ? remote_name : ++ NULL), our_name, 1, &lacks_ip); ++ ++ } ++#endif ++ + if (auth_required && !can_auth && noauth_addrs == NULL) { + if (default_auth) { + option_error( +@@ -1332,7 +1396,11 @@ + passwd[0] != 0 || + (hadchap == 1 || (hadchap == -1 && have_chap_secret(user, + (explicit_remote? remote_name: NULL), 0, NULL))) || +- have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)); ++ have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL) ++#ifdef USE_EAPTLS ++ || have_eaptls_secret_client(user, (explicit_remote? remote_name: NULL))) ++#endif ++ ; + + hadchap = -1; + if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) +@@ -1347,8 +1415,14 @@ + !have_chap_secret((explicit_remote? remote_name: NULL), our_name, + 1, NULL))) && + !have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1, +- NULL)) ++ NULL) ++#ifdef USE_EAPTLS ++ && !have_eaptls_secret_server((explicit_remote? remote_name: NULL), ++ our_name, 1, NULL) ++#endif ++ ) + go->neg_eap = 0; ++ + } + + +@@ -1706,6 +1780,7 @@ + } + + ++ + /* + * get_secret - open the CHAP secret file and return the secret + * for authenticating the given client on the given server. +@@ -2358,3 +2433,335 @@ + + auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL, 0); + } ++ ++ ++#ifdef USE_EAPTLS ++static int ++have_eaptls_secret_server(client, server, need_ip, lacks_ipp) ++ char *client; ++ char *server; ++ int need_ip; ++ int *lacks_ipp; ++{ ++ FILE *f; ++ int ret; ++ char *filename; ++ struct wordlist *addrs; ++ char servcertfile[MAXWORDLEN]; ++ char clicertfile[MAXWORDLEN]; ++ char cacertfile[MAXWORDLEN]; ++ char pkfile[MAXWORDLEN]; ++ ++ filename = _PATH_EAPTLSSERVFILE; ++ f = fopen(filename, "r"); ++ if (f == NULL) ++ return 0; ++ ++ if (client != NULL && client[0] == 0) ++ client = NULL; ++ else if (server != NULL && server[0] == 0) ++ server = NULL; ++ ++ ret = ++ scan_authfile_eaptls(f, client, server, clicertfile, servcertfile, ++ cacertfile, pkfile, &addrs, NULL, filename, ++ 0); ++ ++ fclose(f); ++ ++/* ++ if (ret >= 0 && !eaptls_init_ssl(1, cacertfile, servcertfile, ++ clicertfile, pkfile)) ++ ret = -1; ++*/ ++ ++ if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { ++ if (lacks_ipp != 0) ++ *lacks_ipp = 1; ++ ret = -1; ++ } ++ if (addrs != 0) ++ free_wordlist(addrs); ++ ++ return ret >= 0; ++} ++ ++ ++static int ++have_eaptls_secret_client(client, server) ++ char *client; ++ char *server; ++{ ++ FILE *f; ++ int ret; ++ char *filename; ++ struct wordlist *addrs = NULL; ++ char servcertfile[MAXWORDLEN]; ++ char clicertfile[MAXWORDLEN]; ++ char cacertfile[MAXWORDLEN]; ++ char pkfile[MAXWORDLEN]; ++ ++ if (client != NULL && client[0] == 0) ++ client = NULL; ++ else if (server != NULL && server[0] == 0) ++ server = NULL; ++ ++ if (cacert_file && cert_file && privkey_file) ++ return 1; ++ ++ filename = _PATH_EAPTLSCLIFILE; ++ f = fopen(filename, "r"); ++ if (f == NULL) ++ return 0; ++ ++ ret = ++ scan_authfile_eaptls(f, client, server, clicertfile, servcertfile, ++ cacertfile, pkfile, &addrs, NULL, filename, ++ 0); ++ fclose(f); ++ ++/* ++ if (ret >= 0 && !eaptls_init_ssl(0, cacertfile, clicertfile, ++ servcertfile, pkfile)) ++ ret = -1; ++*/ ++ ++ if (addrs != 0) ++ free_wordlist(addrs); ++ ++ return ret >= 0; ++} ++ ++ ++static int ++scan_authfile_eaptls(f, client, server, cli_cert, serv_cert, ca_cert, pk, ++ addrs, opts, filename, flags) ++ FILE *f; ++ char *client; ++ char *server; ++ char *cli_cert; ++ char *serv_cert; ++ char *ca_cert; ++ char *pk; ++ struct wordlist **addrs; ++ struct wordlist **opts; ++ char *filename; ++ int flags; ++{ ++ int newline; ++ int got_flag, best_flag; ++ struct wordlist *ap, *addr_list, *alist, **app; ++ char word[MAXWORDLEN]; ++ ++ if (addrs != NULL) ++ *addrs = NULL; ++ if (opts != NULL) ++ *opts = NULL; ++ addr_list = NULL; ++ if (!getword(f, word, &newline, filename)) ++ return -1; /* file is empty??? */ ++ newline = 1; ++ best_flag = -1; ++ for (;;) { ++ /* ++ * Skip until we find a word at the start of a line. ++ */ ++ while (!newline && getword(f, word, &newline, filename)); ++ if (!newline) ++ break; /* got to end of file */ ++ ++ /* ++ * Got a client - check if it's a match or a wildcard. ++ */ ++ got_flag = 0; ++ if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) { ++ newline = 0; ++ continue; ++ } ++ if (!ISWILD(word)) ++ got_flag = NONWILD_CLIENT; ++ ++ /* ++ * Now get a server and check if it matches. ++ */ ++ if (!getword(f, word, &newline, filename)) ++ break; ++ if (newline) ++ continue; ++ if (!ISWILD(word)) { ++ if (server != NULL && strcmp(word, server) != 0) ++ continue; ++ got_flag |= NONWILD_SERVER; ++ } ++ ++ /* ++ * Got some sort of a match - see if it's better than what ++ * we have already. ++ */ ++ if (got_flag <= best_flag) ++ continue; ++ ++ /* ++ * Get the cli_cert ++ */ ++ if (!getword(f, word, &newline, filename)) ++ break; ++ if (newline) ++ continue; ++ if (strcmp(word, "-") != 0) { ++ strlcpy(cli_cert, word, MAXWORDLEN); ++ } else ++ cli_cert[0] = 0; ++ ++ /* ++ * Get serv_cert ++ */ ++ if (!getword(f, word, &newline, filename)) ++ break; ++ if (newline) ++ continue; ++ if (strcmp(word, "-") != 0) { ++ strlcpy(serv_cert, word, MAXWORDLEN); ++ } else ++ serv_cert[0] = 0; ++ ++ /* ++ * Get ca_cert ++ */ ++ if (!getword(f, word, &newline, filename)) ++ break; ++ if (newline) ++ continue; ++ strlcpy(ca_cert, word, MAXWORDLEN); ++ ++ /* ++ * Get pk ++ */ ++ if (!getword(f, word, &newline, filename)) ++ break; ++ if (newline) ++ continue; ++ strlcpy(pk, word, MAXWORDLEN); ++ ++ ++ /* ++ * Now read address authorization info and make a wordlist. ++ */ ++ app = &alist; ++ for (;;) { ++ if (!getword(f, word, &newline, filename) || newline) ++ break; ++ ap = (struct wordlist *) ++ malloc(sizeof(struct wordlist) + strlen(word) + 1); ++ if (ap == NULL) ++ novm("authorized addresses"); ++ ap->word = (char *) (ap + 1); ++ strcpy(ap->word, word); ++ *app = ap; ++ app = &ap->next; ++ } ++ *app = NULL; ++ /* ++ * This is the best so far; remember it. ++ */ ++ best_flag = got_flag; ++ if (addr_list) ++ free_wordlist(addr_list); ++ addr_list = alist; ++ ++ if (!newline) ++ break; ++ } ++ ++ /* scan for a -- word indicating the start of options */ ++ for (app = &addr_list; (ap = *app) != NULL; app = &ap->next) ++ if (strcmp(ap->word, "--") == 0) ++ break; ++ /* ap = start of options */ ++ if (ap != NULL) { ++ ap = ap->next; /* first option */ ++ free(*app); /* free the "--" word */ ++ *app = NULL; /* terminate addr list */ ++ } ++ if (opts != NULL) ++ *opts = ap; ++ else if (ap != NULL) ++ free_wordlist(ap); ++ if (addrs != NULL) ++ *addrs = addr_list; ++ else if (addr_list != NULL) ++ free_wordlist(addr_list); ++ ++ return best_flag; ++} ++ ++ ++int ++get_eaptls_secret(unit, client, server, clicertfile, servcertfile, ++ cacertfile, pkfile, am_server) ++ int unit; ++ char *client; ++ char *server; ++ char *clicertfile; ++ char *servcertfile; ++ char *cacertfile; ++ char *pkfile; ++ int am_server; ++{ ++ FILE *fp; ++ int ret; ++ char *filename = NULL; ++ struct wordlist *addrs = NULL; ++ struct wordlist *opts = NULL; ++ ++ /* in client mode the ca+cert+privkey can also be specified as options */ ++ if (!am_server && cacert_file && cert_file && privkey_file ) ++ { ++ strlcpy( clicertfile, cert_file, MAXWORDLEN ); ++ strlcpy( cacertfile, cacert_file, MAXWORDLEN ); ++ strlcpy( pkfile, privkey_file, MAXWORDLEN ); ++ servcertfile[0] = '\0'; ++ } ++ else ++ { ++ filename = (am_server ? _PATH_EAPTLSSERVFILE : _PATH_EAPTLSCLIFILE); ++ addrs = NULL; ++ ++ fp = fopen(filename, "r"); ++ if (fp == NULL) ++ { ++ error("Can't open eap-tls secret file %s: %m", filename); ++ return 0; ++ } ++ ++ check_access(fp, filename); ++ ++ ret = scan_authfile_eaptls(fp, client, server, clicertfile, servcertfile, ++ cacertfile, pkfile, &addrs, &opts, filename, 0); ++ ++ fclose(fp); ++ ++ if (ret < 0) return 0; ++ } ++ ++ if (eaptls_passwd_hook) ++ { ++ dbglog( "Calling eaptls password hook" ); ++ if ( (*eaptls_passwd_hook)(pkfile, passwd) < 0) ++ { ++ error("Unable to obtain EAP-TLS password for %s (%s) from plugin", ++ client, pkfile); ++ return 0; ++ } ++ } ++ if (am_server) ++ set_allowed_addrs(unit, addrs, opts); ++ else if (opts != NULL) ++ free_wordlist(opts); ++ if (addrs != NULL) ++ free_wordlist(addrs); ++ ++ return 1; ++} ++#endif ++ +diff -Naur ppp-2.4.5/pppd/ccp.c ppp-2.4.5-eaptls-mppe-0.99/pppd/ccp.c +--- ppp-2.4.5/pppd/ccp.c 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/ccp.c 2010-10-01 15:17:54.211272258 +0200 +@@ -540,6 +540,9 @@ + if (go->mppe) { + ccp_options *ao = &ccp_allowoptions[f->unit]; + int auth_mschap_bits = auth_done[f->unit]; ++#ifdef USE_EAPTLS ++ int auth_eap_bits = auth_done[f->unit]; ++#endif + int numbits; + + /* +@@ -567,8 +570,23 @@ + lcp_close(f->unit, "MPPE required but not available"); + return; + } ++ ++#ifdef USE_EAPTLS ++ /* ++ * MPPE is also possible in combination with EAP-TLS. ++ * It is not possible to detect if we're doing EAP or EAP-TLS ++ * at this stage, hence we accept all forms of EAP. If TLS is ++ * not used then the MPPE keys will not be derived anyway. ++ */ ++ /* Leave only the eap auth bits set */ ++ auth_eap_bits &= (EAP_WITHPEER | EAP_PEER ); ++ ++ if ((numbits == 0) && (auth_eap_bits == 0)) { ++ error("MPPE required, but MS-CHAP[v2] nor EAP-TLS auth are performed."); ++#else + if (!numbits) { +- error("MPPE required, but MS-CHAP[v2] auth not performed."); ++ error("MPPE required, but MS-CHAP[v2] auth not performed."); ++#endif + lcp_close(f->unit, "MPPE required but not available"); + return; + } +diff -Naur ppp-2.4.5/pppd/chap-md5.c ppp-2.4.5-eaptls-mppe-0.99/pppd/chap-md5.c +--- ppp-2.4.5/pppd/chap-md5.c 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/chap-md5.c 2010-10-01 15:17:54.212272142 +0200 +@@ -36,7 +36,11 @@ + #include "chap-new.h" + #include "chap-md5.h" + #include "magic.h" ++#ifdef USE_EAPTLS ++#include "eap-tls.h" ++#else + #include "md5.h" ++#endif /* USE_EAPTLS */ + + #define MD5_HASH_SIZE 16 + #define MD5_MIN_CHALLENGE 16 +diff -Naur ppp-2.4.5/pppd/eap-tls.c ppp-2.4.5-eaptls-mppe-0.99/pppd/eap-tls.c +--- ppp-2.4.5/pppd/eap-tls.c 1970-01-01 01:00:00.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/eap-tls.c 2010-10-05 15:12:45.881615580 +0200 +@@ -0,0 +1,1174 @@ ++/* ++ * eap-tls.c - EAP-TLS implementation for PPP ++ * ++ * Copyright (c) Beniamino Galvani 2005 All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. The name(s) of the authors of this software must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. ++ * ++ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO ++ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ++ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY ++ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN ++ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING ++ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "pppd.h" ++#include "eap.h" ++#include "eap-tls.h" ++#include "fsm.h" ++#include "lcp.h" ++#include "pathnames.h" ++ ++/* The openssl configuration file and engines can be loaded only once */ ++static CONF *ssl_config = NULL; ++static ENGINE *cert_engine = NULL; ++static ENGINE *pkey_engine = NULL; ++ ++#ifdef MPPE ++ ++/* ++ * TLS PRF from RFC 2246 ++ */ ++static void P_hash(const EVP_MD *evp_md, ++ const unsigned char *secret, unsigned int secret_len, ++ const unsigned char *seed, unsigned int seed_len, ++ unsigned char *out, unsigned int out_len) ++{ ++ HMAC_CTX ctx_a, ctx_out; ++ unsigned char a[HMAC_MAX_MD_CBLOCK]; ++ unsigned int size; ++ ++ HMAC_CTX_init(&ctx_a); ++ HMAC_CTX_init(&ctx_out); ++ HMAC_Init_ex(&ctx_a, secret, secret_len, evp_md, NULL); ++ HMAC_Init_ex(&ctx_out, secret, secret_len, evp_md, NULL); ++ ++ size = HMAC_size(&ctx_out); ++ ++ /* Calculate A(1) */ ++ HMAC_Update(&ctx_a, seed, seed_len); ++ HMAC_Final(&ctx_a, a, NULL); ++ ++ while (1) { ++ /* Calculate next part of output */ ++ HMAC_Update(&ctx_out, a, size); ++ HMAC_Update(&ctx_out, seed, seed_len); ++ ++ /* Check if last part */ ++ if (out_len < size) { ++ HMAC_Final(&ctx_out, a, NULL); ++ memcpy(out, a, out_len); ++ break; ++ } ++ ++ /* Place digest in output buffer */ ++ HMAC_Final(&ctx_out, out, NULL); ++ HMAC_Init_ex(&ctx_out, NULL, 0, NULL, NULL); ++ out += size; ++ out_len -= size; ++ ++ /* Calculate next A(i) */ ++ HMAC_Init_ex(&ctx_a, NULL, 0, NULL, NULL); ++ HMAC_Update(&ctx_a, a, size); ++ HMAC_Final(&ctx_a, a, NULL); ++ } ++ ++ HMAC_CTX_cleanup(&ctx_a); ++ HMAC_CTX_cleanup(&ctx_out); ++ memset(a, 0, sizeof(a)); ++} ++ ++static void PRF(const unsigned char *secret, unsigned int secret_len, ++ const unsigned char *seed, unsigned int seed_len, ++ unsigned char *out, unsigned char *buf, unsigned int out_len) ++{ ++ unsigned int i; ++ unsigned int len = (secret_len + 1) / 2; ++ const unsigned char *s1 = secret; ++ const unsigned char *s2 = secret + (secret_len - len); ++ ++ P_hash(EVP_md5(), s1, len, seed, seed_len, out, out_len); ++ P_hash(EVP_sha1(), s2, len, seed, seed_len, buf, out_len); ++ ++ for (i=0; i < out_len; i++) { ++ out[i] ^= buf[i]; ++ } ++} ++ ++#define EAPTLS_MPPE_KEY_LEN 32 ++ ++/* ++ * Generate keys according to RFC 2716 and add to reply ++ */ ++void eaptls_gen_mppe_keys(struct eaptls_session *ets, const char *prf_label, ++ int client) ++{ ++ unsigned char out[4*EAPTLS_MPPE_KEY_LEN], buf[4*EAPTLS_MPPE_KEY_LEN]; ++ unsigned char seed[64 + 2*SSL3_RANDOM_SIZE]; ++ unsigned char *p = seed; ++ SSL *s = ets->ssl; ++ size_t prf_size; ++ ++ prf_size = strlen(prf_label); ++ ++ memcpy(p, prf_label, prf_size); ++ p += prf_size; ++ ++ memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); ++ p += SSL3_RANDOM_SIZE; ++ prf_size += SSL3_RANDOM_SIZE; ++ ++ memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE); ++ prf_size += SSL3_RANDOM_SIZE; ++ ++ PRF(s->session->master_key, s->session->master_key_length, ++ seed, prf_size, out, buf, sizeof(out)); ++ ++ /* ++ * We now have the master send and receive keys. ++ * From these, generate the session send and receive keys. ++ * (see RFC3079 / draft-ietf-pppext-mppe-keys-03.txt for details) ++ */ ++ if (client) ++ { ++ p = out; ++ BCOPY( p, mppe_send_key, sizeof(mppe_send_key) ); ++ p += EAPTLS_MPPE_KEY_LEN; ++ BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) ); ++ } ++ else ++ { ++ p = out; ++ BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) ); ++ p += EAPTLS_MPPE_KEY_LEN; ++ BCOPY( p, mppe_send_key, sizeof(mppe_send_key) ); ++ } ++ ++ mppe_keys_set = 1; ++} ++ ++#endif ++ ++void log_ssl_errors( void ) ++{ ++ unsigned long ssl_err = ERR_get_error(); ++ ++ if (ssl_err != 0) ++ dbglog("EAP-TLS SSL error stack:"); ++ while (ssl_err != 0) { ++ dbglog( ERR_error_string( ssl_err, NULL ) ); ++ ssl_err = ERR_get_error(); ++ } ++} ++ ++ ++int password_callback (char *buf, int size, int rwflag, void *u) ++{ ++ if (buf) ++ { ++ strncpy (buf, passwd, size); ++ return strlen (buf); ++ } ++ return 0; ++} ++ ++ ++CONF *eaptls_ssl_load_config( void ) ++{ ++ CONF *config; ++ int ret_code; ++ long error_line = 33; ++ ++ config = NCONF_new( NULL ); ++ dbglog( "Loading OpenSSL config file" ); ++ ret_code = NCONF_load( config, _PATH_OPENSSLCONFFILE, &error_line ); ++ if (ret_code == 0) ++ { ++ warn( "EAP-TLS: Error in OpenSSL config file %s at line %d", _PATH_OPENSSLCONFFILE, error_line ); ++ NCONF_free( config ); ++ config = NULL; ++ ERR_clear_error(); ++ } ++ ++ dbglog( "Loading OpenSSL built-ins" ); ++ ENGINE_load_builtin_engines(); ++ OPENSSL_load_builtin_modules(); ++ ++ dbglog( "Loading OpenSSL configured modules" ); ++ if (CONF_modules_load( config, NULL, 0 ) <= 0 ) ++ { ++ warn( "EAP-TLS: Error loading OpenSSL modules" ); ++ log_ssl_errors(); ++ config = NULL; ++ } ++ ++ return config; ++} ++ ++ENGINE *eaptls_ssl_load_engine( char *engine_name ) ++{ ++ ENGINE *e = NULL; ++ ++ dbglog( "Enabling OpenSSL auto engines" ); ++ ENGINE_register_all_complete(); ++ ++ dbglog( "Loading OpenSSL '%s' engine support", engine_name ); ++ e = ENGINE_by_id( engine_name ); ++ if (!e) ++ { ++ dbglog( "EAP-TLS: Cannot load '%s' engine support, trying 'dynamic'", engine_name ); ++ e = ENGINE_by_id( "dynamic" ); ++ if (e) ++ { ++ if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine_name, 0) ++ || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) ++ { ++ warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name ); ++ log_ssl_errors(); ++ ENGINE_free(e); ++ e = NULL; ++ } ++ } ++ else ++ { ++ warn( "EAP-TLS: Cannot load dynamic engine support" ); ++ } ++ } ++ ++ if (e) ++ { ++ dbglog( "Initialising engine" ); ++ if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) ++ { ++ warn( "EAP-TLS: Cannot use that engine" ); ++ log_ssl_errors(); ++ ENGINE_free(e); ++ e = NULL; ++ } ++ } ++ ++ return e; ++} ++ ++/* ++ * Initialize the SSL stacks and tests if certificates, key and crl ++ * for client or server use can be loaded. ++ */ ++SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, ++ char *certfile, char *peer_certfile, char *privkeyfile) ++{ ++ char *cert_engine_name = NULL; ++ char *cert_identifier = NULL; ++ char *pkey_engine_name = NULL; ++ char *pkey_identifier = NULL; ++ SSL_CTX *ctx; ++ X509_STORE *certstore; ++ X509_LOOKUP *lookup; ++ X509 *tmp; ++ ++ /* ++ * Without these can't continue ++ */ ++ if (!cacertfile[0]) ++ { ++ error("EAP-TLS: CA certificate missing"); ++ return NULL; ++ } ++ ++ if (!certfile[0]) ++ { ++ error("EAP-TLS: User certificate missing"); ++ return NULL; ++ } ++ ++ if (!privkeyfile[0]) ++ { ++ error("EAP-TLS: User private key missing"); ++ return NULL; ++ } ++ ++ SSL_library_init(); ++ SSL_load_error_strings(); ++ ++ ctx = SSL_CTX_new(TLSv1_method()); ++ ++ if (!ctx) { ++ error("EAP-TLS: Cannot initialize SSL CTX context"); ++ goto fail; ++ } ++ ++ /* if the certificate filename is of the form engine:id. e.g. ++ pkcs11:12345 ++ then we try to load and use this engine. ++ If the certificate filename starts with a / or . then we ++ ALWAYS assume it is a file and not an engine/pkcs11 identifier ++ */ ++ if ( index( certfile, '/' ) == NULL && index( certfile, '.') == NULL ) ++ { ++ cert_identifier = index( certfile, ':' ); ++ ++ if (cert_identifier) ++ { ++ cert_engine_name = certfile; ++ *cert_identifier = '\0'; ++ cert_identifier++; ++ ++ dbglog( "Found certificate engine '%s'", cert_engine_name ); ++ dbglog( "Found certificate identifier '%s'", cert_identifier ); ++ } ++ } ++ ++ /* if the privatekey filename is of the form engine:id. e.g. ++ pkcs11:12345 ++ then we try to load and use this engine. ++ If the privatekey filename starts with a / or . then we ++ ALWAYS assume it is a file and not an engine/pkcs11 identifier ++ */ ++ if ( index( privkeyfile, '/' ) == NULL && index( privkeyfile, '.') == NULL ) ++ { ++ pkey_identifier = index( privkeyfile, ':' ); ++ ++ if (pkey_identifier) ++ { ++ pkey_engine_name = privkeyfile; ++ *pkey_identifier = '\0'; ++ pkey_identifier++; ++ ++ dbglog( "Found privatekey engine '%s'", pkey_engine_name ); ++ dbglog( "Found privatekey identifier '%s'", pkey_identifier ); ++ } ++ } ++ ++ if (cert_identifier && pkey_identifier) ++ { ++ if (strlen( cert_identifier ) == 0) ++ { ++ if (strlen( pkey_identifier ) == 0) ++ error( "EAP-TLS: both the certificate and privatekey identifiers are missing!" ); ++ else ++ { ++ dbglog( "Substituting privatekey identifier for certificate identifier" ); ++ cert_identifier = pkey_identifier; ++ } ++ } ++ else ++ { ++ if (strlen( pkey_identifier ) == 0) ++ { ++ dbglog( "Substituting certificate identifier for privatekey identifier" ); ++ pkey_identifier = cert_identifier; ++ } ++ } ++ ++ } ++ ++ /* load the openssl config file only once */ ++ if (!ssl_config) ++ { ++ if (cert_engine_name || pkey_engine_name) ++ ssl_config = eaptls_ssl_load_config(); ++ ++ if (ssl_config && cert_engine_name) ++ cert_engine = eaptls_ssl_load_engine( cert_engine_name ); ++ ++ if (ssl_config && pkey_engine_name) ++ { ++ /* don't load the same engine twice */ ++ if ( strcmp( cert_engine_name, pkey_engine_name) == 0 ) ++ pkey_engine = cert_engine; ++ else ++ pkey_engine = eaptls_ssl_load_engine( pkey_engine_name ); ++ } ++ } ++ ++ SSL_CTX_set_default_passwd_cb (ctx, password_callback); ++ ++ if (!SSL_CTX_load_verify_locations(ctx, cacertfile, NULL)) ++ { ++ error("EAP-TLS: Cannot load or verify CA file %s", cacertfile); ++ goto fail; ++ } ++ ++ if (init_server) ++ SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(cacertfile)); ++ ++ if (cert_engine) ++ { ++ struct ++ { ++ const char *s_slot_cert_id; ++ X509 *cert; ++ } cert_info; ++ ++ cert_info.s_slot_cert_id = cert_identifier; ++ cert_info.cert = NULL; ++ ++ if (!ENGINE_ctrl_cmd( cert_engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0 ) ) ++ { ++ error( "EAP-TLS: Error loading certificate with id '%s' from engine", cert_identifier ); ++ goto fail; ++ } ++ ++ if (cert_info.cert) ++ { ++ dbglog( "Got the certificate, adding it to SSL context" ); ++ dbglog( "subject = %s", X509_NAME_oneline( X509_get_subject_name( cert_info.cert ), NULL, 0 ) ); ++ if (SSL_CTX_use_certificate(ctx, cert_info.cert) <= 0) ++ { ++ error("EAP-TLS: Cannot use PKCS11 certificate %s", cert_identifier); ++ goto fail; ++ } ++ } ++ else ++ { ++ warn("EAP-TLS: Cannot load PKCS11 key %s", cert_identifier); ++ log_ssl_errors(); ++ } ++ } ++ else ++ { ++ if (!SSL_CTX_use_certificate_file(ctx, certfile, SSL_FILETYPE_PEM)) ++ { ++ error( "EAP-TLS: Cannot use public certificate %s", certfile ); ++ goto fail; ++ } ++ } ++ ++ if (pkey_engine) ++ { ++ EVP_PKEY *pkey = NULL; ++ PW_CB_DATA cb_data; ++ ++ cb_data.password = passwd; ++ cb_data.prompt_info = pkey_identifier; ++ ++ dbglog( "Loading private key '%s' from engine", pkey_identifier ); ++ pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, NULL, &cb_data); ++ if (pkey) ++ { ++ dbglog( "Got the private key, adding it to SSL context" ); ++ if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0) ++ { ++ error("EAP-TLS: Cannot use PKCS11 key %s", pkey_identifier); ++ goto fail; ++ } ++ } ++ else ++ { ++ warn("EAP-TLS: Cannot load PKCS11 key %s", pkey_identifier); ++ log_ssl_errors(); ++ } ++ } ++ else ++ { ++ if (!SSL_CTX_use_PrivateKey_file(ctx, privkeyfile, SSL_FILETYPE_PEM)) ++ { ++ error("EAP-TLS: Cannot use private key %s", privkeyfile); ++ goto fail; ++ } ++ } ++ ++ if (SSL_CTX_check_private_key(ctx) != 1) { ++ error("EAP-TLS: Private key %s fails security check", privkeyfile); ++ goto fail; ++ } ++ ++ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); ++ SSL_CTX_set_verify_depth(ctx, 5); ++ SSL_CTX_set_verify(ctx, ++ SSL_VERIFY_PEER | ++ SSL_VERIFY_FAIL_IF_NO_PEER_CERT, ++ &ssl_verify_callback); ++ ++ if (crl_dir) { ++ if (!(certstore = SSL_CTX_get_cert_store(ctx))) { ++ error("EAP-TLS: Failed to get certificate store"); ++ goto fail; ++ } ++ ++ if (!(lookup = ++ X509_STORE_add_lookup(certstore, X509_LOOKUP_hash_dir()))) { ++ error("EAP-TLS: Store lookup for CRL failed"); ++ ++ goto fail; ++ } ++ ++ X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM); ++ X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK); ++ } ++ ++ /* ++ * If a peer certificate file was specified, it must be valid, else fail ++ */ ++ if (peer_certfile[0]) { ++ if (!(tmp = get_X509_from_file(peer_certfile))) { ++ error("EAP-TLS: Error loading client certificate from file %s", ++ peer_certfile); ++ goto fail; ++ } ++ X509_free(tmp); ++ } ++ ++ return ctx; ++ ++fail: ++ log_ssl_errors(); ++ SSL_CTX_free(ctx); ++ return NULL; ++} ++ ++/* ++ * Determine the maximum packet size by looking at the LCP handshake ++ */ ++ ++int eaptls_get_mtu(int unit) ++{ ++ int mtu, mru; ++ ++ lcp_options *wo = &lcp_wantoptions[unit]; ++ lcp_options *go = &lcp_gotoptions[unit]; ++ lcp_options *ho = &lcp_hisoptions[unit]; ++ lcp_options *ao = &lcp_allowoptions[unit]; ++ ++ mtu = ho->neg_mru? ho->mru: PPP_MRU; ++ mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU; ++ mtu = MIN(MIN(mtu, mru), ao->mru)- PPP_HDRLEN - 10; ++ ++ dbglog("MTU = %d", mtu); ++ return mtu; ++} ++ ++ ++/* ++ * Init the ssl handshake (server mode) ++ */ ++int eaptls_init_ssl_server(eap_state * esp) ++{ ++ struct eaptls_session *ets; ++ char servcertfile[MAXWORDLEN]; ++ char clicertfile[MAXWORDLEN]; ++ char cacertfile[MAXWORDLEN]; ++ char pkfile[MAXWORDLEN]; ++ /* ++ * Allocate new eaptls session ++ */ ++ esp->es_server.ea_session = malloc(sizeof(struct eaptls_session)); ++ if (!esp->es_server.ea_session) ++ fatal("Allocation error"); ++ ets = esp->es_server.ea_session; ++ ++ if (!esp->es_server.ea_peer) { ++ error("EAP-TLS: Error: client name not set (BUG)"); ++ return 0; ++ } ++ ++ strncpy(ets->peer, esp->es_server.ea_peer, MAXWORDLEN); ++ ++ dbglog( "getting eaptls secret" ); ++ if (!get_eaptls_secret(esp->es_unit, esp->es_server.ea_peer, ++ esp->es_server.ea_name, clicertfile, ++ servcertfile, cacertfile, pkfile, 1)) { ++ error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"", ++ esp->es_server.ea_peer, esp->es_server.ea_name ); ++ return 0; ++ } ++ ++ ets->mtu = eaptls_get_mtu(esp->es_unit); ++ ++ ets->ctx = eaptls_init_ssl(1, cacertfile, servcertfile, clicertfile, pkfile); ++ if (!ets->ctx) ++ goto fail; ++ ++ if (!(ets->ssl = SSL_new(ets->ctx))) ++ goto fail; ++ ++ /* ++ * Set auto-retry to avoid timeouts on BIO_read ++ */ ++ SSL_set_mode(ets->ssl, SSL_MODE_AUTO_RETRY); ++ ++ /* ++ * Initialize the BIOs we use to read/write to ssl engine ++ */ ++ ets->into_ssl = BIO_new(BIO_s_mem()); ++ ets->from_ssl = BIO_new(BIO_s_mem()); ++ SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl); ++ ++ SSL_set_msg_callback(ets->ssl, ssl_msg_callback); ++ SSL_set_msg_callback_arg(ets->ssl, ets); ++ ++ /* ++ * Attach the session struct to the connection, so we can later ++ * retrieve it when doing certificate verification ++ */ ++ SSL_set_ex_data(ets->ssl, 0, ets); ++ ++ SSL_set_accept_state(ets->ssl); ++ ++ ets->data = NULL; ++ ets->datalen = 0; ++ ets->alert_sent = 0; ++ ets->alert_recv = 0; ++ ++ /* ++ * If we specified the client certificate file, store it in ets->peercertfile, ++ * so we can check it later in ssl_verify_callback() ++ */ ++ if (clicertfile[0]) ++ strncpy(&ets->peercertfile[0], clicertfile, MAXWORDLEN); ++ else ++ ets->peercertfile[0] = 0; ++ ++ return 1; ++ ++fail: ++ SSL_CTX_free(ets->ctx); ++ return 0; ++} ++ ++/* ++ * Init the ssl handshake (client mode) ++ */ ++int eaptls_init_ssl_client(eap_state * esp) ++{ ++ struct eaptls_session *ets; ++ char servcertfile[MAXWORDLEN]; ++ char clicertfile[MAXWORDLEN]; ++ char cacertfile[MAXWORDLEN]; ++ char pkfile[MAXWORDLEN]; ++ ++ /* ++ * Allocate new eaptls session ++ */ ++ esp->es_client.ea_session = malloc(sizeof(struct eaptls_session)); ++ if (!esp->es_client.ea_session) ++ fatal("Allocation error"); ++ ets = esp->es_client.ea_session; ++ ++ /* ++ * If available, copy server name in ets; it will be used in cert ++ * verify ++ */ ++ if (esp->es_client.ea_peer) ++ strncpy(ets->peer, esp->es_client.ea_peer, MAXWORDLEN); ++ else ++ ets->peer[0] = 0; ++ ++ ets->mtu = eaptls_get_mtu(esp->es_unit); ++ ++ dbglog( "calling get_eaptls_secret" ); ++ if (!get_eaptls_secret(esp->es_unit, esp->es_client.ea_name, ++ esp->es_client.ea_peer, clicertfile, ++ servcertfile, cacertfile, pkfile, 0)) { ++ error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"", ++ esp->es_client.ea_name, esp->es_client.ea_peer ); ++ return 0; ++ } ++ ++ dbglog( "calling eaptls_init_ssl" ); ++ ets->ctx = eaptls_init_ssl(0, cacertfile, clicertfile, servcertfile, pkfile); ++ if (!ets->ctx) ++ goto fail; ++ ++ ets->ssl = SSL_new(ets->ctx); ++ ++ if (!ets->ssl) ++ goto fail; ++ ++ /* ++ * Initialize the BIOs we use to read/write to ssl engine ++ */ ++ dbglog( "Initializing SSL BIOs" ); ++ ets->into_ssl = BIO_new(BIO_s_mem()); ++ ets->from_ssl = BIO_new(BIO_s_mem()); ++ SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl); ++ ++ SSL_set_msg_callback(ets->ssl, ssl_msg_callback); ++ SSL_set_msg_callback_arg(ets->ssl, ets); ++ ++ /* ++ * Attach the session struct to the connection, so we can later ++ * retrieve it when doing certificate verification ++ */ ++ SSL_set_ex_data(ets->ssl, 0, ets); ++ ++ SSL_set_connect_state(ets->ssl); ++ ++ ets->data = NULL; ++ ets->datalen = 0; ++ ets->alert_sent = 0; ++ ets->alert_recv = 0; ++ ++ /* ++ * If we specified the server certificate file, store it in ++ * ets->peercertfile, so we can check it later in ++ * ssl_verify_callback() ++ */ ++ if (servcertfile[0]) ++ strncpy(ets->peercertfile, servcertfile, MAXWORDLEN); ++ else ++ ets->peercertfile[0] = 0; ++ ++ return 1; ++ ++fail: ++ dbglog( "eaptls_init_ssl_client: fail" ); ++ SSL_CTX_free(ets->ctx); ++ return 0; ++ ++} ++ ++void eaptls_free_session(struct eaptls_session *ets) ++{ ++ if (ets->ssl) ++ SSL_free(ets->ssl); ++ ++ if (ets->ctx) ++ SSL_CTX_free(ets->ctx); ++ ++ free(ets); ++} ++ ++/* ++ * Handle a received packet, reassembling fragmented messages and ++ * passing them to the ssl engine ++ */ ++int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len) ++{ ++ u_char flags; ++ u_int tlslen; ++ u_char dummy[65536]; ++ ++ GETCHAR(flags, inp); ++ len--; ++ ++ if (flags & EAP_TLS_FLAGS_LI && !ets->data) { ++ ++ /* ++ * This is the first packet of a message ++ */ ++ ++ GETLONG(tlslen, inp); ++ len -= 4; ++ ++ if (tlslen > EAP_TLS_MAX_LEN) { ++ error("Error: tls message length > %d, truncated", ++ EAP_TLS_MAX_LEN); ++ tlslen = EAP_TLS_MAX_LEN; ++ } ++ ++ /* ++ * Allocate memory for the whole message ++ */ ++ ets->data = malloc(tlslen); ++ if (!ets->data) ++ fatal("EAP TLS: allocation error\n"); ++ ++ ets->datalen = 0; ++ ets->tlslen = tlslen; ++ ++ } ++ else if (flags & EAP_TLS_FLAGS_LI && ets->data) { ++ /* ++ * Non first with LI (strange...) ++ */ ++ ++ GETLONG(tlslen, inp); ++ len -= 4; ++ ++ } ++ else if (!ets->data) { ++ /* ++ * A non fragmented message without LI flag ++ */ ++ ++ ets->data = malloc(len); ++ if (!ets->data) ++ fatal("EAP TLS: allocation error\n"); ++ ++ ets->datalen = 0; ++ ets->tlslen = len; ++ } ++ ++ if (flags & EAP_TLS_FLAGS_MF) ++ ets->frag = 1; ++ else ++ ets->frag = 0; ++ ++ if (len + ets->datalen > ets->tlslen) { ++ warn("EAP TLS: received data > TLS message length"); ++ return 1; ++ } ++ ++ BCOPY(inp, ets->data + ets->datalen, len); ++ ets->datalen += len; ++ ++ if (!ets->frag) { ++ ++ /* ++ * If we have the whole message, pass it to ssl ++ */ ++ ++ if (ets->datalen != ets->tlslen) { ++ warn("EAP TLS: received data != TLS message length"); ++ return 1; ++ } ++ ++ if (BIO_write(ets->into_ssl, ets->data, ets->datalen) == -1) ++ log_ssl_errors(); ++ ++ SSL_read(ets->ssl, dummy, 65536); ++ ++ free(ets->data); ++ ets->data = NULL; ++ ets->datalen = 0; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Return an eap-tls packet in outp. ++ * A TLS message read from the ssl engine is buffered in ets->data. ++ * At each call we control if there is buffered data and send a ++ * packet of mtu bytes. ++ */ ++int eaptls_send(struct eaptls_session *ets, u_char ** outp) ++{ ++ bool first = 0; ++ int size; ++ u_char fromtls[65536]; ++ int res; ++ u_char *start; ++ ++ start = *outp; ++ ++ if (!ets->data) { ++ ++ if(!ets->alert_sent) ++ SSL_read(ets->ssl, fromtls, 65536); ++ ++ /* ++ * Read from ssl ++ */ ++ if ((res = BIO_read(ets->from_ssl, fromtls, 65536)) == -1) ++ fatal("No data from BIO_read"); ++ ++ ets->datalen = res; ++ ++ ets->data = malloc(ets->datalen); ++ BCOPY(fromtls, ets->data, ets->datalen); ++ ++ ets->offset = 0; ++ first = 1; ++ ++ } ++ ++ size = ets->datalen - ets->offset; ++ ++ if (size > ets->mtu) { ++ size = ets->mtu; ++ ets->frag = 1; ++ } else ++ ets->frag = 0; ++ ++ PUTCHAR(EAPT_TLS, *outp); ++ ++ /* ++ * Set right flags and length if necessary ++ */ ++ if (ets->frag && first) { ++ PUTCHAR(EAP_TLS_FLAGS_LI | EAP_TLS_FLAGS_MF, *outp); ++ PUTLONG(ets->datalen, *outp); ++ } else if (ets->frag) { ++ PUTCHAR(EAP_TLS_FLAGS_MF, *outp); ++ } else ++ PUTCHAR(0, *outp); ++ ++ /* ++ * Copy the data in outp ++ */ ++ BCOPY(ets->data + ets->offset, *outp, size); ++ INCPTR(size, *outp); ++ ++ /* ++ * Copy the packet in retransmission buffer ++ */ ++ BCOPY(start, &ets->rtx[0], *outp - start); ++ ets->rtx_len = *outp - start; ++ ++ ets->offset += size; ++ ++ if (ets->offset >= ets->datalen) { ++ ++ /* ++ * The whole message has been sent ++ */ ++ ++ free(ets->data); ++ ets->data = NULL; ++ ets->datalen = 0; ++ ets->offset = 0; ++ } ++ ++ return 0; ++} ++ ++/* ++ * Get the sent packet from the retransmission buffer ++ */ ++void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp) ++{ ++ BCOPY(ets->rtx, *outp, ets->rtx_len); ++ INCPTR(ets->rtx_len, *outp); ++} ++ ++/* ++ * Verify a certificate. ++ * Most of the work (signatures and issuer attributes checking) ++ * is done by ssl; we check the CN in the peer certificate ++ * against the peer name. ++ */ ++int ssl_verify_callback(int preverify_ok, X509_STORE_CTX * ctx) ++{ ++ char subject[256]; ++ char cn_str[256]; ++ X509 *peer_cert; ++ int err, depth; ++ int ok = preverify_ok; ++ SSL *ssl; ++ struct eaptls_session *ets; ++ ++ peer_cert = X509_STORE_CTX_get_current_cert(ctx); ++ err = X509_STORE_CTX_get_error(ctx); ++ depth = X509_STORE_CTX_get_error_depth(ctx); ++ ++ dbglog("certificate verify depth: %d", depth); ++ ++ if (auth_required && !ok) { ++ X509_NAME_oneline(X509_get_subject_name(peer_cert), ++ subject, 256); ++ ++ X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert), ++ NID_commonName, cn_str, 256); ++ ++ dbglog("Certificate verification error:\n depth: %d CN: %s" ++ "\n err: %d (%s)\n", depth, cn_str, err, ++ X509_verify_cert_error_string(err)); ++ ++ return 0; ++ } ++ ++ ssl = X509_STORE_CTX_get_ex_data(ctx, ++ SSL_get_ex_data_X509_STORE_CTX_idx()); ++ ++ ets = (struct eaptls_session *)SSL_get_ex_data(ssl, 0); ++ ++ if (ets == NULL) { ++ error("Error: SSL_get_ex_data returned NULL"); ++ return 0; ++ } ++ ++ log_ssl_errors(); ++ ++ if (!depth) { /* This is the peer certificate */ ++ ++ X509_NAME_oneline(X509_get_subject_name(peer_cert), ++ subject, 256); ++ ++ X509_NAME_get_text_by_NID(X509_get_subject_name(peer_cert), ++ NID_commonName, cn_str, 256); ++ ++ /* ++ * If acting as client and the name of the server wasn't specified ++ * explicitely, we can't verify the server authenticity ++ */ ++ if (!ets->peer[0]) { ++ warn("Peer name not specified: no check"); ++ return 1; ++ } ++ ++ /* ++ * Check the CN ++ */ ++ if (strcmp(cn_str, ets->peer)) { ++ error ++ ("Certificate verification error: CN (%s) != peer_name (%s)", ++ cn_str, ets->peer); ++ return 0; ++ } ++ ++ warn("Certificate CN: %s , peer name %s", cn_str, ets->peer); ++ ++ /* ++ * If a peer certificate file was specified, here we check it ++ */ ++ if (ets->peercertfile[0]) { ++ if (ssl_cmp_certs(&ets->peercertfile[0], peer_cert) ++ != 0) { ++ error ++ ("Peer certificate doesn't match stored certificate"); ++ return 0; ++ } ++ } ++ } ++ ++ return 1; ++} ++ ++/* ++ * Compare a certificate with the one stored in a file ++ */ ++int ssl_cmp_certs(char *filename, X509 * a) ++{ ++ X509 *b; ++ int ret; ++ ++ if (!(b = get_X509_from_file(filename))) ++ return 1; ++ ++ ret = X509_cmp(a, b); ++ X509_free(b); ++ ++ return ret; ++ ++} ++ ++X509 *get_X509_from_file(char *filename) ++{ ++ FILE *fp; ++ X509 *ret; ++ ++ if (!(fp = fopen(filename, "r"))) ++ return NULL; ++ ++ ret = PEM_read_X509(fp, NULL, NULL, NULL); ++ ++ fclose(fp); ++ ++ return ret; ++} ++ ++/* ++ * Every sent & received message this callback function is invoked, ++ * so we know when alert messages have arrived or are sent and ++ * we can print debug information about TLS handshake. ++ */ ++void ++ssl_msg_callback(int write_p, int version, int content_type, ++ const void *buf, size_t len, SSL * ssl, void *arg) ++{ ++ char string[256]; ++ struct eaptls_session *ets = (struct eaptls_session *)arg; ++ unsigned char code; ++ ++ if(write_p) ++ strcpy(string, " -> "); ++ else ++ strcpy(string, " <- "); ++ ++ ++ switch(content_type) { ++ ++ case SSL3_RT_ALERT: ++ strcat(string, "Alert: "); ++ code = ((const unsigned char *)buf)[1]; ++ ++ if (write_p) { ++ ets->alert_sent = 1; ++ ets->alert_sent_desc = code; ++ } else { ++ ets->alert_recv = 1; ++ ets->alert_recv_desc = code; ++ } ++ ++ strcat(string, SSL_alert_desc_string_long(code)); ++ break; ++ ++ case SSL3_RT_CHANGE_CIPHER_SPEC: ++ strcat(string, "ChangeCipherSpec"); ++ break; ++ ++ case SSL3_RT_HANDSHAKE: ++ ++ strcat(string, "Handshake: "); ++ code = ((const unsigned char *)buf)[0]; ++ ++ switch(code) { ++ case SSL3_MT_HELLO_REQUEST: ++ strcat(string,"Hello Request"); ++ break; ++ case SSL3_MT_CLIENT_HELLO: ++ strcat(string,"Client Hello"); ++ break; ++ case SSL3_MT_SERVER_HELLO: ++ strcat(string,"Server Hello"); ++ break; ++ case SSL3_MT_CERTIFICATE: ++ strcat(string,"Certificate"); ++ break; ++ case SSL3_MT_SERVER_KEY_EXCHANGE: ++ strcat(string,"Server Key Exchange"); ++ break; ++ case SSL3_MT_CERTIFICATE_REQUEST: ++ strcat(string,"Certificate Request"); ++ break; ++ case SSL3_MT_SERVER_DONE: ++ strcat(string,"Server Hello Done"); ++ break; ++ case SSL3_MT_CERTIFICATE_VERIFY: ++ strcat(string,"Certificate Verify"); ++ break; ++ case SSL3_MT_CLIENT_KEY_EXCHANGE: ++ strcat(string,"Client Key Exchange"); ++ break; ++ case SSL3_MT_FINISHED: ++ strcat(string,"Finished"); ++ break; ++ ++ default: ++ sprintf( string, "Handshake: Unknown SSL3 code received: %d", code ); ++ } ++ break; ++ ++ default: ++ sprintf( string, "SSL message contains unknown content type: %d", content_type ); ++ ++ } ++ ++ /* Alert messages must always be displayed */ ++ if(content_type == SSL3_RT_ALERT) ++ error("%s", string); ++ else ++ dbglog("%s", string); ++} ++ +diff -Naur ppp-2.4.5/pppd/eap-tls.h ppp-2.4.5-eaptls-mppe-0.99/pppd/eap-tls.h +--- ppp-2.4.5/pppd/eap-tls.h 1970-01-01 01:00:00.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/eap-tls.h 2010-10-01 15:17:54.213271816 +0200 +@@ -0,0 +1,107 @@ ++/* ++ * eap-tls.h ++ * ++ * Copyright (c) Beniamino Galvani 2005 All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * ++ * 3. The name(s) of the authors of this software must not be used to ++ * endorse or promote products derived from this software without ++ * prior written permission. ++ * ++ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO ++ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ++ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY ++ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN ++ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING ++ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ */ ++ ++#ifndef __EAP_TLS_H__ ++#define __EAP_TLS_H__ ++ ++#include "eap.h" ++ ++#include ++#include ++#include ++ ++#define EAP_TLS_FLAGS_LI 128 /* length included flag */ ++#define EAP_TLS_FLAGS_MF 64 /* more fragments flag */ ++#define EAP_TLS_FLAGS_START 32 /* start flag */ ++ ++#define EAP_TLS_MAX_LEN 65536 /* max eap tls packet size */ ++ ++struct eaptls_session ++{ ++ u_char *data; /* buffered data */ ++ int datalen; /* buffered data len */ ++ int offset; /* from where to send */ ++ int tlslen; /* total length of tls data */ ++ bool frag; /* packet is fragmented */ ++ SSL_CTX *ctx; ++ SSL *ssl; /* ssl connection */ ++ BIO *from_ssl; ++ BIO *into_ssl; ++ char peer[MAXWORDLEN]; /* peer name */ ++ char peercertfile[MAXWORDLEN]; ++ bool alert_sent; ++ u_char alert_sent_desc; ++ bool alert_recv; ++ u_char alert_recv_desc; ++ char rtx[65536]; /* retransmission buffer */ ++ int rtx_len; ++ int mtu; /* unit mtu */ ++}; ++ ++typedef struct pw_cb_data ++{ ++ const void *password; ++ const char *prompt_info; ++} PW_CB_DATA; ++ ++ ++int ssl_verify_callback(int, X509_STORE_CTX *); ++void ssl_msg_callback(int write_p, int version, int ct, const void *buf, ++ size_t len, SSL * ssl, void *arg); ++ ++X509 *get_X509_from_file(char *filename); ++int ssl_cmp_certs(char *filename, X509 * a); ++ ++SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, ++ char *certfile, char *peer_certfile, char *privkeyfile); ++int eaptls_init_ssl_server(eap_state * esp); ++int eaptls_init_ssl_client(eap_state * esp); ++void eaptls_free_session(struct eaptls_session *ets); ++ ++int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len); ++int eaptls_send(struct eaptls_session *ets, u_char ** outp); ++void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp); ++ ++int get_eaptls_secret(int unit, char *client, char *server, ++ char *clicertfile, char *servcertfile, char *cacertfile, ++ char *pkfile, int am_server); ++ ++#ifdef MPPE ++#include "mppe.h" /* MPPE_MAX_KEY_LEN */ ++extern u_char mppe_send_key[MPPE_MAX_KEY_LEN]; ++extern u_char mppe_recv_key[MPPE_MAX_KEY_LEN]; ++extern int mppe_keys_set; ++ ++void eaptls_gen_mppe_keys(struct eaptls_session *ets, const char *prf_label, int client); ++ ++#endif ++ ++#endif +diff -Naur ppp-2.4.5/pppd/eap.c ppp-2.4.5-eaptls-mppe-0.99/pppd/eap.c +--- ppp-2.4.5/pppd/eap.c 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/eap.c 2010-01-29 16:31:29.000000000 +0100 +@@ -43,6 +43,11 @@ + * Based on draft-ietf-pppext-eap-srp-03.txt. + */ + ++/* ++ * Modification by Beniamino Galvani, Mar 2005 ++ * Implemented EAP-TLS authentication ++ */ ++ + #define RCSID "$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $" + + /* +@@ -62,8 +67,12 @@ + + #include "pppd.h" + #include "pathnames.h" +-#include "md5.h" + #include "eap.h" ++#ifdef USE_EAPTLS ++#include "eap-tls.h" ++#else ++#include "md5.h" ++#endif /* USE_EAPTLS */ + + #ifdef USE_SRP + #include +@@ -209,6 +218,9 @@ + esp->es_server.ea_id = (u_char)(drand48() * 0x100); + esp->es_client.ea_timeout = EAP_DEFREQTIME; + esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ; ++#ifdef USE_EAPTLS ++ esp->es_client.ea_using_eaptls = 0; ++#endif /* USE_EAPTLS */ + } + + /* +@@ -436,8 +448,16 @@ + u_char vals[2]; + struct b64state bs; + #endif /* USE_SRP */ ++#ifdef USE_EAPTLS ++ struct eaptls_session *ets; ++ int secret_len; ++ char secret[MAXWORDLEN]; ++#endif /* USE_EAPTLS */ + + esp->es_server.ea_timeout = esp->es_savedtime; ++#ifdef USE_EAPTLS ++ esp->es_server.ea_prev_state = esp->es_server.ea_state; ++#endif /* USE_EAPTLS */ + switch (esp->es_server.ea_state) { + case eapBadAuth: + return; +@@ -562,9 +582,81 @@ + break; + } + #endif /* USE_SRP */ ++#ifdef USE_EAPTLS ++ if (!get_secret(esp->es_unit, esp->es_server.ea_peer, ++ esp->es_server.ea_name, secret, &secret_len, 1)) { ++ ++ esp->es_server.ea_state = eapTlsStart; ++ break; ++ } ++#endif /* USE_EAPTLS */ ++ + esp->es_server.ea_state = eapMD5Chall; + break; + ++#ifdef USE_EAPTLS ++ case eapTlsStart: ++ /* Initialize ssl session */ ++ if(!eaptls_init_ssl_server(esp)) { ++ esp->es_server.ea_state = eapBadAuth; ++ break; ++ } ++ ++ esp->es_server.ea_state = eapTlsRecv; ++ break; ++ ++ case eapTlsRecv: ++ ets = (struct eaptls_session *) esp->es_server.ea_session; ++ ++ if(ets->alert_sent) { ++ esp->es_server.ea_state = eapTlsSendAlert; ++ break; ++ } ++ ++ if (status) { ++ esp->es_server.ea_state = eapBadAuth; ++ break; ++ } ++ ets = (struct eaptls_session *) esp->es_server.ea_session; ++ ++ if(ets->frag) ++ esp->es_server.ea_state = eapTlsSendAck; ++ else ++ esp->es_server.ea_state = eapTlsSend; ++ break; ++ ++ case eapTlsSend: ++ ets = (struct eaptls_session *) esp->es_server.ea_session; ++ ++ if(SSL_is_init_finished(ets->ssl)) { ++ esp->es_server.ea_state = eapTlsRecvClient; ++ break; ++ } ++ ++ if(ets->frag) ++ esp->es_server.ea_state = eapTlsRecvAck; ++ else ++ esp->es_server.ea_state = eapTlsRecv; ++ break; ++ ++ case eapTlsSendAck: ++ esp->es_server.ea_state = eapTlsRecv; ++ break; ++ ++ case eapTlsRecvAck: ++ if (status) { ++ esp->es_server.ea_state = eapBadAuth; ++ break; ++ } ++ ++ esp->es_server.ea_state = eapTlsSend; ++ break; ++ ++ case eapTlsSendAlert: ++ esp->es_server.ea_state = eapTlsRecvAlertAck; ++ break; ++#endif /* USE_EAPTLS */ ++ + case eapSRP1: + #ifdef USE_SRP + ts = (struct t_server *)esp->es_server.ea_session; +@@ -718,6 +810,30 @@ + INCPTR(esp->es_server.ea_namelen, outp); + break; + ++#ifdef USE_EAPTLS ++ case eapTlsStart: ++ PUTCHAR(EAPT_TLS, outp); ++ PUTCHAR(EAP_TLS_FLAGS_START, outp); ++ eap_figure_next_state(esp, 0); ++ break; ++ ++ case eapTlsSend: ++ eaptls_send(esp->es_server.ea_session, &outp); ++ eap_figure_next_state(esp, 0); ++ break; ++ ++ case eapTlsSendAck: ++ PUTCHAR(EAPT_TLS, outp); ++ PUTCHAR(0, outp); ++ eap_figure_next_state(esp, 0); ++ break; ++ ++ case eapTlsSendAlert: ++ eaptls_send(esp->es_server.ea_session, &outp); ++ eap_figure_next_state(esp, 0); ++ break; ++#endif /* USE_EAPTLS */ ++ + #ifdef USE_SRP + case eapSRP1: + PUTCHAR(EAPT_SRP, outp); +@@ -904,11 +1020,57 @@ + eap_server_timeout(arg) + void *arg; + { ++#ifdef USE_EAPTLS ++ u_char *outp; ++ u_char *lenloc; ++ int outlen; ++#endif /* USE_EAPTLS */ ++ + eap_state *esp = (eap_state *) arg; + + if (!eap_server_active(esp)) + return; + ++#ifdef USE_EAPTLS ++ switch(esp->es_server.ea_prev_state) { ++ ++ /* ++ * In eap-tls the state changes after a request, so we return to ++ * previous state ... ++ */ ++ case(eapTlsStart): ++ case(eapTlsSendAck): ++ esp->es_server.ea_state = esp->es_server.ea_prev_state; ++ break; ++ ++ /* ++ * ... or resend the stored data ++ */ ++ case(eapTlsSend): ++ case(eapTlsSendAlert): ++ outp = outpacket_buf; ++ MAKEHEADER(outp, PPP_EAP); ++ PUTCHAR(EAP_REQUEST, outp); ++ PUTCHAR(esp->es_server.ea_id, outp); ++ lenloc = outp; ++ INCPTR(2, outp); ++ ++ eaptls_retransmit(esp->es_server.ea_session, &outp); ++ ++ outlen = (outp - outpacket_buf) - PPP_HDRLEN; ++ PUTSHORT(outlen, lenloc); ++ output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN); ++ esp->es_server.ea_requests++; ++ ++ if (esp->es_server.ea_timeout > 0) ++ TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout); ++ ++ return; ++ default: ++ break; ++ } ++#endif /* USE_EAPTLS */ ++ + /* EAP ID number must not change on timeout. */ + eap_send_request(esp); + } +@@ -1166,6 +1328,81 @@ + } + #endif /* USE_SRP */ + ++#ifdef USE_EAPTLS ++/* ++ * Send an EAP-TLS response message with tls data ++ */ ++static void ++eap_tls_response(esp, id) ++eap_state *esp; ++u_char id; ++{ ++ u_char *outp; ++ int outlen; ++ u_char *lenloc; ++ ++ outp = outpacket_buf; ++ ++ MAKEHEADER(outp, PPP_EAP); ++ ++ PUTCHAR(EAP_RESPONSE, outp); ++ PUTCHAR(id, outp); ++ ++ lenloc = outp; ++ INCPTR(2, outp); ++ ++ /* ++ If the id in the request is unchanged, we must retransmit ++ the old data ++ */ ++ if(id == esp->es_client.ea_id) ++ eaptls_retransmit(esp->es_client.ea_session, &outp); ++ else ++ eaptls_send(esp->es_client.ea_session, &outp); ++ ++ outlen = (outp - outpacket_buf) - PPP_HDRLEN; ++ PUTSHORT(outlen, lenloc); ++ ++ output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen); ++ ++ esp->es_client.ea_id = id; ++ ++} ++ ++/* ++ * Send an EAP-TLS ack ++ */ ++static void ++eap_tls_sendack(esp, id) ++eap_state *esp; ++u_char id; ++{ ++ u_char *outp; ++ int outlen; ++ u_char *lenloc; ++ ++ outp = outpacket_buf; ++ ++ MAKEHEADER(outp, PPP_EAP); ++ ++ PUTCHAR(EAP_RESPONSE, outp); ++ PUTCHAR(id, outp); ++ esp->es_client.ea_id = id; ++ ++ lenloc = outp; ++ INCPTR(2, outp); ++ ++ PUTCHAR(EAPT_TLS, outp); ++ PUTCHAR(0, outp); ++ ++ outlen = (outp - outpacket_buf) - PPP_HDRLEN; ++ PUTSHORT(outlen, lenloc); ++ ++ output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen); ++ ++} ++#endif /* USE_EAPTLS */ ++ + static void + eap_send_nak(esp, id, type) + eap_state *esp; +@@ -1320,6 +1557,11 @@ + char rhostname[256]; + MD5_CTX mdContext; + u_char hash[MD5_SIGNATURE_SIZE]; ++#ifdef USE_EAPTLS ++ u_char flags; ++ struct eaptls_session *ets = esp->es_client.ea_session; ++#endif /* USE_EAPTLS */ ++ + #ifdef USE_SRP + struct t_client *tc; + struct t_num sval, gval, Nval, *Ap, Bval; +@@ -1456,6 +1698,90 @@ + esp->es_client.ea_namelen); + break; + ++#ifdef USE_EAPTLS ++ case EAPT_TLS: ++ ++ switch(esp->es_client.ea_state) { ++ ++ case eapListen: ++ ++ GETCHAR(flags, inp); ++ if(flags & EAP_TLS_FLAGS_START){ ++ ++ esp->es_client.ea_using_eaptls = 1; ++ ++ if (explicit_remote){ ++ esp->es_client.ea_peer = strdup(remote_name); ++ esp->es_client.ea_peerlen = strlen(remote_name); ++ } else ++ esp->es_client.ea_peer = NULL; ++ ++ /* Init ssl session */ ++ if(!eaptls_init_ssl_client(esp)) { ++ dbglog("cannot init ssl"); ++ eap_send_nak(esp, id, EAPT_TLS); ++ esp->es_client.ea_using_eaptls = 0; ++ break; ++ } ++ ++ ets = esp->es_client.ea_session; ++ eap_tls_response(esp, id); ++ esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : ++ eapTlsRecv); ++ break; ++ } ++ ++ /* The server has sent a bad start packet. */ ++ eap_send_nak(esp, id, EAPT_TLS); ++ break; ++ ++ case eapTlsRecvAck: ++ eap_tls_response(esp, id); ++ esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : ++ eapTlsRecv); ++ break; ++ ++ case eapTlsRecv: ++ eaptls_receive(ets, inp, len); ++ ++ if(ets->frag) { ++ eap_tls_sendack(esp, id); ++ esp->es_client.ea_state = eapTlsRecv; ++ break; ++ } ++ ++ if(ets->alert_recv) { ++ eap_tls_sendack(esp, id); ++ esp->es_client.ea_state = eapTlsRecvFailure; ++ break; ++ } ++ ++ /* Check if TLS handshake is finished */ ++ if(SSL_is_init_finished(ets->ssl)){ ++#ifdef MPPE ++ eaptls_gen_mppe_keys( ets, "client EAP encryption", 1 ); ++#endif ++ eaptls_free_session(ets); ++ eap_tls_sendack(esp, id); ++ esp->es_client.ea_state = eapTlsRecvSuccess; ++ break; ++ } ++ ++ eap_tls_response(esp,id); ++ esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : ++ eapTlsRecv); ++ ++ break; ++ ++ default: ++ eap_send_nak(esp, id, EAPT_TLS); ++ esp->es_client.ea_using_eaptls = 0; ++ break; ++ } ++ ++ break; ++#endif /* USE_EAPTLS */ ++ + #ifdef USE_SRP + case EAPT_SRP: + if (len < 1) { +@@ -1737,6 +2063,11 @@ + u_char dig[SHA_DIGESTSIZE]; + #endif /* USE_SRP */ + ++#ifdef USE_EAPTLS ++ struct eaptls_session *ets; ++ u_char flags; ++#endif /* USE_EAPTLS */ ++ + if (esp->es_server.ea_id != id) { + dbglog("EAP: discarding Response %d; expected ID %d", id, + esp->es_server.ea_id); +@@ -1776,6 +2107,60 @@ + eap_figure_next_state(esp, 0); + break; + ++#ifdef USE_EAPTLS ++ case EAPT_TLS: ++ switch(esp->es_server.ea_state) { ++ ++ case eapTlsRecv: ++ ets = (struct eaptls_session *) esp->es_server.ea_session; ++ eap_figure_next_state(esp, ++ eaptls_receive(esp->es_server.ea_session, inp, len)); ++ ++ if(ets->alert_recv) { ++ eap_send_failure(esp); ++ break; ++ } ++ break; ++ ++ case eapTlsRecvAck: ++ if(len > 1) { ++ dbglog("EAP-TLS ACK with extra data"); ++ } ++ eap_figure_next_state(esp, 0); ++ break; ++ ++ case eapTlsRecvClient: ++ /* Receive authentication response from client */ ++ ++ GETCHAR(flags, inp); ++ ++ if(len == 1 && !flags) { /* Ack = ok */ ++#ifdef MPPE ++ eaptls_gen_mppe_keys( esp->es_server.ea_session, "client EAP encryption", 0 ); ++#endif ++ eap_send_success(esp); ++ } ++ else { /* failure */ ++ eaptls_receive(esp->es_server.ea_session, inp, len); ++ warn("Server authentication failed"); ++ eap_send_failure(esp); ++ } ++ ++ eaptls_free_session(esp->es_server.ea_session); ++ ++ break; ++ ++ case eapTlsRecvAlertAck: ++ eap_send_failure(esp); ++ break; ++ ++ default: ++ eap_figure_next_state(esp, 1); ++ break; ++ } ++ break; ++#endif /* USE_EAPTLS */ ++ + case EAPT_NOTIFICATION: + dbglog("EAP unexpected Notification; response discarded"); + break; +@@ -1807,6 +2192,13 @@ + esp->es_server.ea_state = eapMD5Chall; + break; + ++#ifdef USE_EAPTLS ++ /* Send EAP-TLS start packet */ ++ case EAPT_TLS: ++ esp->es_server.ea_state = eapTlsStart; ++ break; ++#endif /* USE_EAPTLS */ ++ + default: + dbglog("EAP: peer requesting unknown Type %d", vallen); + switch (esp->es_server.ea_state) { +@@ -2018,13 +2410,27 @@ + int id; + int len; + { +- if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)) { ++ if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp) ++#ifdef USE_EAPTLS ++ && esp->es_client.ea_state != eapTlsRecvSuccess ++#endif /* USE_EAPTLS */ ++ ) { + dbglog("EAP unexpected success message in state %s (%d)", + eap_state_name(esp->es_client.ea_state), + esp->es_client.ea_state); + return; + } + ++#ifdef USE_EAPTLS ++ if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state != ++ eapTlsRecvSuccess) { ++ dbglog("EAP-TLS unexpected success message in state %s (%d)", ++ eap_state_name(esp->es_client.ea_state), ++ esp->es_client.ea_state); ++ return; ++ } ++#endif /* USE_EAPTLS */ ++ + if (esp->es_client.ea_timeout > 0) { + UNTIMEOUT(eap_client_timeout, (void *)esp); + } +@@ -2150,6 +2556,9 @@ + int code, id, len, rtype, vallen; + u_char *pstart; + u_int32_t uval; ++#ifdef USE_EAPTLS ++ u_char flags; ++#endif /* USE_EAPTLS */ + + if (inlen < EAP_HEADERLEN) + return (0); +@@ -2214,6 +2623,24 @@ + } + break; + ++#ifdef USE_EAPTLS ++ case EAPT_TLS: ++ if (len < 1) ++ break; ++ GETCHAR(flags, inp); ++ len--; ++ ++ if(flags == 0 && len == 0){ ++ printer(arg, " Ack"); ++ break; ++ } ++ ++ printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -"); ++ printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-"); ++ printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- "); ++ break; ++#endif /* USE_EAPTLS */ ++ + case EAPT_SRP: + if (len < 3) + goto truncated; +@@ -2325,6 +2752,25 @@ + } + break; + ++#ifdef USE_EAPTLS ++ case EAPT_TLS: ++ if (len < 1) ++ break; ++ GETCHAR(flags, inp); ++ len--; ++ ++ if(flags == 0 && len == 0){ ++ printer(arg, " Ack"); ++ break; ++ } ++ ++ printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -"); ++ printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-"); ++ printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- "); ++ ++ break; ++#endif /* USE_EAPTLS */ ++ + case EAPT_NAK: + if (len <= 0) { + printer(arg, " "); +@@ -2426,3 +2872,4 @@ + + return (inp - pstart); + } ++ +diff -Naur ppp-2.4.5/pppd/eap.h ppp-2.4.5-eaptls-mppe-0.99/pppd/eap.h +--- ppp-2.4.5/pppd/eap.h 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/eap.h 2010-10-01 15:17:54.214270927 +0200 +@@ -84,6 +84,16 @@ + eapClosed, /* Authentication not in use */ + eapListen, /* Client ready (and timer running) */ + eapIdentify, /* EAP Identify sent */ ++ eapTlsStart, /* Send EAP-TLS start packet */ ++ eapTlsRecv, /* Receive EAP-TLS tls data */ ++ eapTlsSendAck, /* Send EAP-TLS ack */ ++ eapTlsSend, /* Send EAP-TLS tls data */ ++ eapTlsRecvAck, /* Receive EAP-TLS ack */ ++ eapTlsRecvClient, /* Receive EAP-TLS auth response from client*/ ++ eapTlsSendAlert, /* Send EAP-TLS tls alert (server)*/ ++ eapTlsRecvAlertAck, /* Receive EAP-TLS ack after sending alert */ ++ eapTlsRecvSuccess, /* Receive EAP success */ ++ eapTlsRecvFailure, /* Receive EAP failure */ + eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */ + eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */ + eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */ +@@ -95,9 +105,18 @@ + + #define EAP_STATES \ + "Initial", "Pending", "Closed", "Listen", "Identify", \ ++ "TlsStart", "TlsRecv", "TlsSendAck", "TlsSend", "TlsRecvAck", "TlsRecvClient",\ ++ "TlsSendAlert", "TlsRecvAlertAck" , "TlsRecvSuccess", "TlsRecvFailure", \ + "SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth" + +-#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen) ++#ifdef USE_EAPTLS ++#define eap_client_active(esp) ((esp)->es_client.ea_state != eapInitial ||\ ++ (esp)->es_client.ea_state != eapPending ||\ ++ (esp)->es_client.ea_state != eapClosed) ++#else ++#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen) ++#endif /* USE_EAPTLS */ ++ + #define eap_server_active(esp) \ + ((esp)->es_server.ea_state >= eapIdentify && \ + (esp)->es_server.ea_state <= eapMD5Chall) +@@ -112,11 +131,17 @@ + u_short ea_namelen; /* Length of our name */ + u_short ea_peerlen; /* Length of peer's name */ + enum eap_state_code ea_state; ++#ifdef USE_EAPTLS ++ enum eap_state_code ea_prev_state; ++#endif + u_char ea_id; /* Current id */ + u_char ea_requests; /* Number of Requests sent/received */ + u_char ea_responses; /* Number of Responses */ + u_char ea_type; /* One of EAPT_* */ + u_int32_t ea_keyflags; /* SRP shared key usage flags */ ++#ifdef USE_EAPTLS ++ bool ea_using_eaptls; ++#endif + }; + + /* +@@ -139,7 +164,12 @@ + * Timeouts. + */ + #define EAP_DEFTIMEOUT 3 /* Timeout (seconds) for rexmit */ ++#ifdef USE_EAPTLS ++#define EAP_DEFTRANSMITS 30 /* max # times to transmit */ ++ /* certificates can be long ... */ ++#else + #define EAP_DEFTRANSMITS 10 /* max # times to transmit */ ++#endif /* USE_EAPTLS */ + #define EAP_DEFREQTIME 20 /* Time to wait for peer request */ + #define EAP_DEFALLOWREQ 20 /* max # times to accept requests */ + +diff -Naur ppp-2.4.5/pppd/md5.c ppp-2.4.5-eaptls-mppe-0.99/pppd/md5.c +--- ppp-2.4.5/pppd/md5.c 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/md5.c 2010-10-01 15:17:54.214270927 +0200 +@@ -33,6 +33,8 @@ + *********************************************************************** + */ + ++#ifndef USE_EAPTLS ++ + #include + #include "md5.h" + +@@ -305,3 +307,5 @@ + ** End of md5.c ** + ******************************** (cut) ******************************** + */ ++#endif /* USE_EAPTLS */ ++ +diff -Naur ppp-2.4.5/pppd/md5.h ppp-2.4.5-eaptls-mppe-0.99/pppd/md5.h +--- ppp-2.4.5/pppd/md5.h 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/md5.h 2010-10-01 15:17:54.215271014 +0200 +@@ -36,6 +36,7 @@ + ** documentation and/or software. ** + *********************************************************************** + */ ++#ifndef USE_EAPTLS + + #ifndef __MD5_INCLUDE__ + +@@ -63,3 +64,5 @@ + + #define __MD5_INCLUDE__ + #endif /* __MD5_INCLUDE__ */ ++ ++#endif /* USE_EAPTLS */ +diff -Naur ppp-2.4.5/pppd/options.c ppp-2.4.5-eaptls-mppe-0.99/pppd/options.c +--- ppp-2.4.5/pppd/options.c 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/options.c 2010-10-01 15:17:54.215271014 +0200 +@@ -119,6 +119,10 @@ + bool dryrun; /* print out option values and exit */ + char *domain; /* domain name set by domain option */ + int child_wait = 5; /* # seconds to wait for children at exit */ ++#ifdef USE_EAPTLS ++bool only_update_crl_server = 0; /* update server crl and exit */ ++bool only_update_crl_client = 0; /* update client crl and exit */ ++#endif /* USE_EAPTLS */ + + #ifdef MAXOCTETS + unsigned int maxoctets = 0; /* default - no limit */ +@@ -320,6 +324,12 @@ + { "mo-timeout", o_int, &maxoctets_timeout, + "Check for traffic limit every N seconds", OPT_PRIO | OPT_LLIMIT | 1 }, + #endif ++#ifdef USE_EAPTLS ++ { "only-update-crl-server", o_bool, &only_update_crl_server, ++ "Update server CA CRLs and exit", 1 }, ++ { "only-update-crl-client", o_bool, &only_update_crl_client, ++ "Update client CA CRLs and exit", 1 }, ++#endif /* USE_EAPTLS */ + + { NULL } + }; +diff -Naur ppp-2.4.5/pppd/pathnames.h ppp-2.4.5-eaptls-mppe-0.99/pppd/pathnames.h +--- ppp-2.4.5/pppd/pathnames.h 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/pathnames.h 2010-10-01 15:17:54.215271014 +0200 +@@ -21,6 +21,13 @@ + #define _PATH_UPAPFILE _ROOT_PATH "/etc/ppp/pap-secrets" + #define _PATH_CHAPFILE _ROOT_PATH "/etc/ppp/chap-secrets" + #define _PATH_SRPFILE _ROOT_PATH "/etc/ppp/srp-secrets" ++ ++#ifdef USE_EAPTLS ++#define _PATH_EAPTLSCLIFILE _ROOT_PATH "/etc/ppp/eaptls-client" ++#define _PATH_EAPTLSSERVFILE _ROOT_PATH "/etc/ppp/eaptls-server" ++#define _PATH_OPENSSLCONFFILE _ROOT_PATH "/etc/ppp/openssl.cnf" ++#endif /* USE_EAPTLS */ ++ + #define _PATH_SYSOPTIONS _ROOT_PATH "/etc/ppp/options" + #define _PATH_IPUP _ROOT_PATH "/etc/ppp/ip-up" + #define _PATH_IPDOWN _ROOT_PATH "/etc/ppp/ip-down" +diff -Naur ppp-2.4.5/pppd/plugins/Makefile.linux ppp-2.4.5-eaptls-mppe-0.99/pppd/plugins/Makefile.linux +--- ppp-2.4.5/pppd/plugins/Makefile.linux 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/plugins/Makefile.linux 2010-10-01 15:17:54.215271014 +0200 +@@ -4,6 +4,9 @@ + LDFLAGS = -shared + INSTALL = install + ++# EAP-TLS ++CFLAGS += -DUSE_EAPTLS=1 ++ + DESTDIR = $(INSTROOT)@DESTDIR@ + BINDIR = $(DESTDIR)/sbin + MANDIR = $(DESTDIR)/share/man/man8 +diff -Naur ppp-2.4.5/pppd/plugins/passprompt.c ppp-2.4.5-eaptls-mppe-0.99/pppd/plugins/passprompt.c +--- ppp-2.4.5/pppd/plugins/passprompt.c 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/plugins/passprompt.c 2010-10-01 15:17:54.215271014 +0200 +@@ -107,4 +107,7 @@ + { + add_options(options); + pap_passwd_hook = promptpass; ++#ifdef USE_EAPTLS ++ eaptls_passwd_hook = promptpass; ++#endif + } +diff -Naur ppp-2.4.5/pppd/plugins/passwordfd.c ppp-2.4.5-eaptls-mppe-0.99/pppd/plugins/passwordfd.c +--- ppp-2.4.5/pppd/plugins/passwordfd.c 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/plugins/passwordfd.c 2010-10-01 15:17:54.216270820 +0200 +@@ -79,4 +79,9 @@ + + chap_check_hook = pwfd_check; + chap_passwd_hook = pwfd_passwd; ++ ++#ifdef USE_EAPTLS ++ eaptls_check_hook = pwfd_check; ++ eaptls_passwd_hook = pwfd_passwd; ++#endif + } +diff -Naur ppp-2.4.5/pppd/pppd.h ppp-2.4.5-eaptls-mppe-0.99/pppd/pppd.h +--- ppp-2.4.5/pppd/pppd.h 2009-11-16 23:26:07.000000000 +0100 ++++ ppp-2.4.5-eaptls-mppe-0.99/pppd/pppd.h 2010-10-01 15:17:54.216270820 +0200 +@@ -320,6 +320,10 @@ + extern bool dryrun; /* check everything, print options, exit */ + extern int child_wait; /* # seconds to wait for children at end */ + ++#ifdef USE_EAPTLS ++extern char *crl_dir; ++#endif /* USE_EAPTLS */ ++ + #ifdef MAXOCTETS + extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ + extern int maxoctets_dir; /* Direction : +@@ -717,6 +721,11 @@ + extern int (*chap_passwd_hook) __P((char *user, char *passwd)); + extern void (*multilink_join_hook) __P((void)); + ++#ifdef USE_EAPTLS ++extern int (*eaptls_check_hook) __P((void)); ++extern int (*eaptls_passwd_hook) __P((char *user, char *passwd)); ++#endif ++ + /* Let a plugin snoop sent and received packets. Useful for L2TP */ + extern void (*snoop_recv_hook) __P((unsigned char *p, int len)); + extern void (*snoop_send_hook) __P((unsigned char *p, int len)); diff --git a/pkgs/ppp/patches/ppp-2.4.5-eth.patch b/pkgs/ppp/patches/ppp-2.4.5-eth.patch new file mode 100644 index 000000000..0e7e52596 --- /dev/null +++ b/pkgs/ppp/patches/ppp-2.4.5-eth.patch @@ -0,0 +1,124 @@ +diff -up ppp-2.4.5/pppd/ether.c.inc.eth ppp-2.4.5/pppd/ether.c.inc +--- ppp-2.4.5/pppd/ether.c.inc.eth 2011-06-01 10:28:35.356139063 +0200 ++++ ppp-2.4.5/pppd/ether.c.inc 2011-06-01 11:20:37.876897352 +0200 +@@ -0,0 +1,46 @@ ++#define PREF_ETH "eth" ++#define PREF_EM "em" ++ ++static char *dev_file = "/proc/self/net/dev"; ++ ++/* ++ * get_first_ethernet - return the name of the first ethernet-style ++ * interface on this system. ++ */ ++char * ++get_first_ethernet() ++{ ++ FILE *f; ++ char buf[255], *dv, *smc; ++ char pci[16]; ++ ++ memset(pci, 0, sizeof(pci)); ++ if ((f = fopen(dev_file, "r")) != NULL) ++ { ++ // go through network dev file ++ while (fgets (buf, sizeof(buf), f) != NULL) ++ { ++ // the line describes interface ++ if ((smc = strchr(buf, ':')) != NULL) ++ { ++ // trim white characters ++ for (dv=buf, *smc=0; *dv <= ' '; dv++) ; ++ // is "eth" (originial ethernet name) or "em" (ethernet on board) ++ if (!strncmp(dv, PREF_ETH, strlen(PREF_ETH)) || ++ !strncmp(dv, PREF_EM, strlen(PREF_EM))) ++ { ++ return strdup(dv); ++ } ++ // remember the first pci NIC-card ++ if (strlen(pci) == 0 && dv[0] == 'p' && isdigit(dv[1])) ++ { ++ strcpy(pci, dv); ++ } ++ } ++ } ++ fclose(f); ++ } ++ // return pci NIC-card or nil if no if name ++ return strlen(pci) > 0 ? strdup(pci) : 0L; ++} ++ +diff -up ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe-discovery.c.eth ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe-discovery.c +--- ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe-discovery.c.eth 2011-06-01 09:39:13.099343548 +0200 ++++ ppp-2.4.5/pppd/plugins/rp-pppoe/pppoe-discovery.c 2011-06-01 11:41:02.188252304 +0200 +@@ -47,6 +47,8 @@ + #include + #endif + ++#include "../../ether.c.inc" ++ + char *xstrdup(const char *s); + void usage(void); + +@@ -686,7 +688,7 @@ int main(int argc, char *argv[]) + + /* default interface name */ + if (!conn->ifName) +- conn->ifName = strdup("eth0"); ++ conn->ifName = get_first_ethernet(); + + conn->discoverySocket = -1; + conn->sessionSocket = -1; +diff -up ppp-2.4.5/pppd/sys-linux.c.eth ppp-2.4.5/pppd/sys-linux.c +--- ppp-2.4.5/pppd/sys-linux.c.eth 2011-06-01 09:39:13.074343397 +0200 ++++ ppp-2.4.5/pppd/sys-linux.c 2011-06-01 11:50:13.736565685 +0200 +@@ -144,6 +144,8 @@ + #include + #endif + ++#include "ether.c.inc" ++ + #ifdef INET6 + #ifndef _LINUX_IN6_H + /* +@@ -1869,16 +1871,6 @@ get_if_hwaddr(u_char *addr, char *name) + return ret; + } + +-/* +- * get_first_ethernet - return the name of the first ethernet-style +- * interface on this system. +- */ +-char * +-get_first_ethernet() +-{ +- return "eth0"; +-} +- + /******************************************************************** + * + * Return user specified netmask, modified by any mask we might determine +@@ -2783,6 +2775,7 @@ ether_to_eui64(eui64_t *p_eui64) + struct ifreq ifr; + int skfd; + const unsigned char *ptr; ++ char warn_msg[80]; + + skfd = socket_fd(PF_INET6, SOCK_DGRAM, 0); + if(skfd == -1) +@@ -2791,11 +2784,13 @@ ether_to_eui64(eui64_t *p_eui64) + return 0; + } + +- strcpy(ifr.ifr_name, "eth0"); ++ strcpy(ifr.ifr_name, get_first_ethernet()); + if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) + { + close(skfd); +- warn("could not obtain hardware address for eth0"); ++ snprintf(warn_msg, sizeof(warn_msg), ++ "could not obtain hardware address for %s", ifr.ifr_name); ++ warn(warn_msg); + return 0; + } + close(skfd); diff --git a/pkgs/ppp/patches/ppp-2.4.5-lock.patch b/pkgs/ppp/patches/ppp-2.4.5-lock.patch new file mode 100644 index 000000000..6bda62018 --- /dev/null +++ b/pkgs/ppp/patches/ppp-2.4.5-lock.patch @@ -0,0 +1,12 @@ +diff -up ppp-2.4.5/pppd/utils.c.lock ppp-2.4.5/pppd/utils.c +--- ppp-2.4.5/pppd/utils.c.lock 2011-05-30 15:30:36.432371849 +0200 ++++ ppp-2.4.5/pppd/utils.c 2011-05-30 15:30:48.575495854 +0200 +@@ -859,7 +859,7 @@ complete_read(int fd, void *buf, size_t + /* Procedures for locking the serial device using a lock file. */ + #ifndef LOCK_DIR + #ifdef __linux__ +-#define LOCK_DIR "/var/lock" ++#define LOCK_DIR "/var/lock/ppp" + #else + #ifdef SVR4 + #define LOCK_DIR "/var/spool/locks" diff --git a/pkgs/ppp/patches/ppp-2.4.5-man.patch b/pkgs/ppp/patches/ppp-2.4.5-man.patch new file mode 100644 index 000000000..9ad4f2ed9 --- /dev/null +++ b/pkgs/ppp/patches/ppp-2.4.5-man.patch @@ -0,0 +1,94 @@ +--- ppp-2.4.5/chat/chat.8.man 2010-12-16 10:20:08.000000000 +0000 ++++ ppp-2.4.5/chat/chat.8 2010-12-19 16:40:31.000000000 +0000 +@@ -50,7 +50,7 @@ + to \fIstderr\fR. + .TP + .B \-E +-Enables environment variable substituion within chat scripts using the ++Enables environment variable substitution within chat scripts using the + standard \fI$xxx\fR syntax. + .TP + .B \-v +@@ -77,7 +77,7 @@ + error messages from being sent to the SYSLOG. + .TP + .B \-T \fI +-Pass in an arbitary string, usually a phone number, that will be ++Pass in an arbitrary string, usually a phone number, that will be + substituted for the \\T substitution metacharacter in a send string. + .TP + .B \-U \fI +@@ -204,7 +204,7 @@ + .LP + \fBSAY\fR strings must be enclosed in single or double quotes. If + carriage return and line feed are needed in the string to be output, +-you must explicitely add them to your string. ++you must explicitly add them to your string. + .LP + The SAY strings could be used to give progress messages in sections of + the script where you want to have 'ECHO OFF' but still let the user +@@ -457,7 +457,7 @@ + Environment variables are available within chat scripts, if the \fI\-E\fR + option was specified in the command line. The metacharacter \fI$\fR is used + to introduce the name of the environment variable to substitute. If the +-substition fails, because the requested environment variable is not set, ++substitution fails, because the requested environment variable is not set, + \fInothing\fR is replaced for the variable. + .SH TERMINATION CODES + The \fIchat\fR program will terminate with the following completion +--- ppp-2.4.5/pppd/pppd.8.man 2010-12-16 10:20:10.000000000 +0000 ++++ ppp-2.4.5/pppd/pppd.8 2010-12-21 23:26:50.000000000 +0000 +@@ -195,7 +195,7 @@ + .TP + .B ipv6 \fI\fR,\fI + Set the local and/or remote 64-bit interface identifier. Either one may be +-omitted. The identifier must be specified in standard ascii notation of ++omitted. The identifier must be specified in standard ASCII notation of + IPv6 addresses (e.g. ::dead:beef). If the + \fIipv6cp\-use\-ipaddr\fR + option is given, the local identifier is the local IPv4 address (see above). +@@ -328,7 +328,7 @@ + The \fIdemand\fR option implies the \fIpersist\fR option. If this + behaviour is not desired, use the \fInopersist\fR option after the + \fIdemand\fR option. The \fIidle\fR and \fIholdoff\fR +-options are also useful in conjuction with the \fIdemand\fR option. ++options are also useful in conjunction with the \fIdemand\fR option. + .TP + .B domain \fId + Append the domain name \fId\fR to the local host name for authentication +@@ -515,7 +515,7 @@ + send before it rejects the options. The default value is 3. + .TP + .B ipxcp\-max\-terminate \fIn +-Set the maximum nuber of IPXCP terminate request frames before the ++Set the maximum number of IPXCP terminate request frames before the + local system considers that the peer is not listening to them. The + default value is 3. + .TP +@@ -907,7 +907,7 @@ + device. The \fIscript\fR will be run in a child process with the + pseudo-tty master as its standard input and output. An explicit + device name may not be given if this option is used. (Note: if the +-\fIrecord\fR option is used in conjuction with the \fIpty\fR option, ++\fIrecord\fR option is used in conjunction with the \fIpty\fR option, + the child process will have pipes on its standard input and output.) + .TP + .B receive\-all +@@ -1015,7 +1015,7 @@ + .TP + .B srp\-use\-pseudonym + When operating as an EAP SRP\-SHA1 client, attempt to use the pseudonym +-stored in ~/.ppp_psuedonym first as the identity, and save in this ++stored in ~/.ppp_pseudonym first as the identity, and save in this + file any pseudonym offered by the peer during authentication. + .TP + .B sync +@@ -1885,7 +1885,7 @@ + prior written permission. + .LP + 4. Redistributions of any form whatsoever must retain the following +- acknowledgments: ++ acknowledgements: + .br + "This product includes software developed by Computing Services + at Carnegie Mellon University (http://www.cmu.edu/computing/)." diff --git a/pkgs/ppp/patches/ppp-2.4.5-ppp_resolv.patch b/pkgs/ppp/patches/ppp-2.4.5-ppp_resolv.patch new file mode 100644 index 000000000..e2f0e2982 --- /dev/null +++ b/pkgs/ppp/patches/ppp-2.4.5-ppp_resolv.patch @@ -0,0 +1,13 @@ +diff -up ppp-2.4.5/scripts/ip-up.local.add.ppp_resolv ppp-2.4.5/scripts/ip-up.local.add +--- ppp-2.4.5/scripts/ip-up.local.add.ppp_resolv 2010-07-13 10:29:23.227943994 +0200 ++++ ppp-2.4.5/scripts/ip-up.local.add 2010-07-13 10:32:27.729695487 +0200 +@@ -18,6 +18,9 @@ if [ -n "$USEPEERDNS" -a -f /var/run/ppp + rscf=/var/run/ppp/resolv.new + grep domain /var/run/ppp/resolv.prev > $rscf + grep search /var/run/ppp/resolv.prev >> $rscf ++ if [ -f /var/run/ppp/resolv.conf ]; then ++ cat /var/run/ppp/resolv.conf >> $rscf ++ fi + change_resolv_conf $rscf + rm -f $rscf + else diff --git a/pkgs/ppp/patches/ppp-2.4.5-var_run_ppp.patch b/pkgs/ppp/patches/ppp-2.4.5-var_run_ppp.patch index 2c4992773..bd01883d8 100644 --- a/pkgs/ppp/patches/ppp-2.4.5-var_run_ppp.patch +++ b/pkgs/ppp/patches/ppp-2.4.5-var_run_ppp.patch @@ -1,30 +1,30 @@ diff -up ppp-2.4.5/pppd/pathnames.h.var_run_ppp ppp-2.4.5/pppd/pathnames.h ---- ppp-2.4.5/pppd/pathnames.h.var_run_ppp 2010-02-12 16:36:14.479362718 +0100 -+++ ppp-2.4.5/pppd/pathnames.h 2010-02-12 16:38:24.995330994 +0100 -@@ -7,9 +7,13 @@ +--- ppp-2.4.5/pppd/pathnames.h.var_run_ppp 2010-11-23 10:14:24.557427000 +0100 ++++ ppp-2.4.5/pppd/pathnames.h 2010-11-23 10:24:07.432426793 +0100 +@@ -6,8 +6,9 @@ + #ifdef HAVE_PATHS_H #include - -+#define _SUBPATH_PPP "ppp/" +- ++#define _PPP_SUBDIR "ppp/" #else /* HAVE_PATHS_H */ ++#define _PPP_SUBDIR #ifndef _PATH_VARRUN #define _PATH_VARRUN "/etc/ppp/" -+#define _SUBPATH_PPP -+#else -+#define _SUBPATH_PPP "ppp/" #endif - #define _PATH_DEVNULL "/dev/null" - #endif /* HAVE_PATHS_H */ -@@ -46,10 +50,10 @@ +@@ -46,13 +54,9 @@ #endif /* IPX_CHANGE */ #ifdef __STDC__ -#define _PATH_PPPDB _ROOT_PATH _PATH_VARRUN "pppd2.tdb" -+#define _PATH_PPPDB _ROOT_PATH _PATH_VARRUN _SUBPATH_PPP "pppd2.tdb" ++#define _PATH_PPPDB _ROOT_PATH _PATH_VARRUN _PPP_SUBDIR "pppd2.tdb" #else /* __STDC__ */ - #ifdef HAVE_PATHS_H +-#ifdef HAVE_PATHS_H -#define _PATH_PPPDB "/var/run/pppd2.tdb" -+#define _PATH_PPPDB "/var/run/ppp/pppd2.tdb" - #else - #define _PATH_PPPDB "/etc/ppp/pppd2.tdb" - #endif +-#else +-#define _PATH_PPPDB "/etc/ppp/pppd2.tdb" +-#endif ++#define _PATH_PPPDB _PATH_VARRUN _PPP_SUBDIR "pppd2.tdb" + #endif /* __STDC__ */ + + #ifdef PLUGIN diff --git a/pkgs/ppp/ppp.nm b/pkgs/ppp/ppp.nm index 0eb7774ac..de1eebbd2 100644 --- a/pkgs/ppp/ppp.nm +++ b/pkgs/ppp/ppp.nm @@ -26,7 +26,7 @@ include $(PKGROOT)/Include PKG_NAME = ppp PKG_VER = 2.4.5 -PKG_REL = 1 +PKG_REL = 2 PKG_MAINTAINER = PKG_GROUPS = System/Daemons @@ -34,7 +34,7 @@ PKG_URL = ftp://ftp.samba.org/pub/ppp/ PKG_LICENSE = BSD and LGPLv2+ and GPLv2+ and Public Domain PKG_SUMMARY = The PPP (Point-to-Point Protocol) daemon. -PKG_BUILD_DEPS+= libpcap-devel linux-atm-devel pam-devel +PKG_BUILD_DEPS+= libpcap-devel linux-atm-devel openssl-devel pam-devel define PKG_DESCRIPTION The ppp package contains the PPP (Point-to-Point Protocol) daemon and \ @@ -49,8 +49,6 @@ PKG_TARBALL = $(THISAPP).tar.gz PKG_PACKAGES += $(PKG_NAME)-devel define STAGE_PREPARE_CMDS - cd $(DIR_APP) && sed -e "s/^LIBS =/LIBS=-lutil/" -i pppd/Makefile.linux - cd $(DIR_APP) && sed -e "s@^RUNDIR .*@RUNDIR = /var/run/ppp@" \ -e "s@^LOGDIR .*@LOGDIR = /var/log/ppp@" \ -i linux/Makefile.top @@ -67,8 +65,7 @@ define STAGE_BUILD ./configure \ --prefix=/usr - cd $(DIR_APP) && make CC="gcc $(CFLAGS)" $(PARALLELISMFLAGS) \ - HAVE_INET6=yes USE_PAM=y + cd $(DIR_APP) && make CC="gcc $(CFLAGS)" $(PARALLELISMFLAGS) endef define STAGE_INSTALL