diff options
author | Rustem Shaykhutdinov | 2018-02-03 15:24:27 +0300 |
---|---|---|
committer | Rustem Shaykhutdinov | 2018-02-03 15:24:27 +0300 |
commit | 2f947e71f73480000b1e359b4a17e417c3668262 (patch) | |
tree | d0e71670e2fb07726f458e7e4f65eac6e908fb79 | |
download | aur-2f947e71f73480000b1e359b4a17e417c3668262.tar.gz |
EAP-TLS patch 0.999 for pppd 2.4.7
-rw-r--r-- | .SRCINFO | 58 | ||||
-rw-r--r-- | CVE-2015-3310.patch | 18 | ||||
-rw-r--r-- | LICENSE | 7 | ||||
-rw-r--r-- | PKGBUILD | 100 | ||||
-rw-r--r-- | ip-down | 12 | ||||
-rw-r--r-- | ip-down.d.dns.sh | 7 | ||||
-rw-r--r-- | ip-up | 12 | ||||
-rw-r--r-- | ip-up.d.dns.sh | 11 | ||||
-rw-r--r-- | ipv6-down | 12 | ||||
-rw-r--r-- | ipv6-up | 12 | ||||
-rw-r--r-- | ipv6-up.d.iface-config.sh | 4 | ||||
-rw-r--r-- | options | 352 | ||||
-rw-r--r-- | ppp-2.4.6-makefiles.patch | 270 | ||||
-rw-r--r-- | ppp-2.4.7-eaptls-mppe-0.999.patch | 3205 | ||||
-rw-r--r-- | ppp.systemd | 9 |
15 files changed, 4089 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..2022a943b462 --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,58 @@ +pkgbase = ppp-eap-tls + pkgdesc = EAP-TLS patched daemon which implements the Point-to-Point Protocol for dial-up networking. + pkgver = 2.4.7 + pkgrel = 1 + url = http://www.samba.org/ppp/ + arch = i686 + arch = x86_64 + license = GPL + license = BSD + depends = glibc + depends = libpcap>=1.0.0 + depends = openssl + provides = ppp + conflicts = ppp + backup = etc/ppp/chap-secrets + backup = etc/ppp/pap-secrets + backup = etc/ppp/options + backup = etc/ppp/ip-up + backup = etc/ppp/ip-down + backup = etc/ppp/ip-down.d/00-dns.sh + backup = etc/ppp/ip-up.d/00-dns.sh + backup = etc/ppp/ipv6-up.d/00-iface-config.sh + source = https://download.samba.org/pub/ppp/ppp-2.4.7.tar.gz + source = https://download.samba.org/pub/ppp/ppp-2.4.7.tar.gz.asc + source = https://www.nikhef.nl/~janjust/ppp/ppp-2.4.7-eaptls-mppe-0.999.patch + source = ppp-2.4.6-makefiles.patch + source = options + source = ip-up + source = ip-down + source = ip-up.d.dns.sh + source = ip-down.d.dns.sh + source = ipv6-up + source = ipv6-down + source = ipv6-up.d.iface-config.sh + source = ppp.systemd + source = CVE-2015-3310.patch + source = ppp-build-fix.patch::https://github.com/paulusmack/ppp/commit/50a2997b.patch + source = LICENSE + validpgpkeys = 631E179E370CD727A7F2A33A9E4295D605F66CE9 + sha256sums = 02e0a3dd3e4799e33103f70ec7df75348c8540966ee7c948e4ed8a42bbccfb30 + sha256sums = SKIP + sha256sums = 51fec18a1df323eed8bf96f69c868fac4be28d0de1607a24c5b7b8d566871e99 + sha256sums = f04f47318226c79594f45b8b75877c30710d22fe0fb1e2e17db3b4257dc4218c + sha256sums = 0933fecb9e0adaddd88ee1e049a5f3a0508e83b81dc1aa333df784e729ab4b6e + sha256sums = ddef42b2cc5d49e81556dc9dbacf5ee3bf8dc32704f3670c2233eed42c4a4efd + sha256sums = 658630ba4c5cb583df80af6d4df81df8ae20798f63cc4b9cec8d4dad13a6a897 + sha256sums = aafb75b978aa13225444dc6b914fab324d686821be93c49e893800e647aa7648 + sha256sums = 17b486fa69a71dafcbe543dc4f2b8cb9ed31e675aabc5f6c98ef94dbc1561c85 + sha256sums = bb3f44a4f2c4b8dbe7f84d77feae90a71caa9fa3c252a20c390e015d4f8ea248 + sha256sums = 77292b79f99f97a01aa9a75cd7cd93da70d746d3b8cc60f35b31dfe0568544c0 + sha256sums = 20780cf4bd0774bebb55ecb3bdae7667c9ae5cbe003a52a1ecb0bbc77d46260f + sha256sums = eb8ab2e2d71c3bb9c4297cf847b6e9d52616a3fdbf2257c479cc43dff318c831 + sha256sums = f0fe7e7d9b35141c2565a09e39c4f66b475ed3fe8e2528d10faa4412f480e338 + sha256sums = 94225c64e806e75d6f792649c4beb26a791c4994c2701dc6a47cfccf3d91e4bf + sha256sums = 96fd35104e3d0ec472517afecead88419913ae73ae0189476d5dad9029c2be42 + +pkgname = ppp-eap-tls + diff --git a/CVE-2015-3310.patch b/CVE-2015-3310.patch new file mode 100644 index 000000000000..c8cebe3d63db --- /dev/null +++ b/CVE-2015-3310.patch @@ -0,0 +1,18 @@ +Fix buffer overflow in rc_mksid() + +rc_mksid converts the PID of pppd to hex to generate a pseudo-unique string. +If the process id is bigger than 65535 (FFFF), its hex representation will be +longer than 4 characters, resulting in a buffer overflow. + +The bug can be exploited to cause a remote DoS. +--- ppp-2.4.7/pppd/plugins/radius/util.c ++++ ppp-2.4.7/pppd/plugins/radius/util.c +@@ -77,7 +77,7 @@ rc_mksid (void) + static unsigned short int cnt = 0; + sprintf (buf, "%08lX%04X%02hX", + (unsigned long int) time (NULL), +- (unsigned int) getpid (), ++ (unsigned int) getpid () & 0xFFFF, + cnt & 0xFF); + cnt++; + return buf; diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000000..b3846c7cb70e --- /dev/null +++ b/LICENSE @@ -0,0 +1,7 @@ +Copyrights: +*********** + +All of the code can be freely used and redistributed. The individual +source files each have their own copyright and permission notice. +Pppd, pppstats and pppdump are under BSD-style notices. Some of the +pppd plugins are GPL'd. Chat is public domain. diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..7a78a6e914b3 --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,100 @@ +# Maintainer: Thomas Baechler <thomas@archlinux.org> +# Maintainer: Rustem Shaykhutdinov <buzz.rustem@gmail.com> +pkgname=ppp-eap-tls +pkgver=2.4.7 +pkgrel=1 +pkgdesc="EAP-TLS patched daemon which implements the Point-to-Point Protocol for dial-up networking." +arch=(i686 x86_64) +url="http://www.samba.org/ppp/" +license=('GPL' 'BSD') +depends=('glibc' 'libpcap>=1.0.0' 'openssl') +provides=('ppp') +conflicts=('ppp') +backup=(etc/ppp/{chap-secrets,pap-secrets,options,ip-up,ip-down,ip-down.d/00-dns.sh,ip-up.d/00-dns.sh,ipv6-up.d/00-iface-config.sh}) +source=(https://download.samba.org/pub/ppp/ppp-${pkgver}.tar.gz{,.asc} + "https://www.nikhef.nl/~janjust/ppp/ppp-2.4.7-eaptls-mppe-0.999.patch" + ppp-2.4.6-makefiles.patch + options + ip-up + ip-down + ip-up.d.dns.sh + ip-down.d.dns.sh + ipv6-up + ipv6-down + ipv6-up.d.iface-config.sh + ppp.systemd + CVE-2015-3310.patch + ppp-build-fix.patch::"https://github.com/paulusmack/ppp/commit/50a2997b.patch" + LICENSE) +sha256sums=('02e0a3dd3e4799e33103f70ec7df75348c8540966ee7c948e4ed8a42bbccfb30' + 'SKIP' + '51fec18a1df323eed8bf96f69c868fac4be28d0de1607a24c5b7b8d566871e99' + 'f04f47318226c79594f45b8b75877c30710d22fe0fb1e2e17db3b4257dc4218c' + '0933fecb9e0adaddd88ee1e049a5f3a0508e83b81dc1aa333df784e729ab4b6e' + 'ddef42b2cc5d49e81556dc9dbacf5ee3bf8dc32704f3670c2233eed42c4a4efd' + '658630ba4c5cb583df80af6d4df81df8ae20798f63cc4b9cec8d4dad13a6a897' + 'aafb75b978aa13225444dc6b914fab324d686821be93c49e893800e647aa7648' + '17b486fa69a71dafcbe543dc4f2b8cb9ed31e675aabc5f6c98ef94dbc1561c85' + 'bb3f44a4f2c4b8dbe7f84d77feae90a71caa9fa3c252a20c390e015d4f8ea248' + '77292b79f99f97a01aa9a75cd7cd93da70d746d3b8cc60f35b31dfe0568544c0' + '20780cf4bd0774bebb55ecb3bdae7667c9ae5cbe003a52a1ecb0bbc77d46260f' + 'eb8ab2e2d71c3bb9c4297cf847b6e9d52616a3fdbf2257c479cc43dff318c831' + 'f0fe7e7d9b35141c2565a09e39c4f66b475ed3fe8e2528d10faa4412f480e338' + '94225c64e806e75d6f792649c4beb26a791c4994c2701dc6a47cfccf3d91e4bf' + '96fd35104e3d0ec472517afecead88419913ae73ae0189476d5dad9029c2be42') +validpgpkeys=('631E179E370CD727A7F2A33A9E4295D605F66CE9') # Paul Mackerras (Signing key) <paulus@samba.org> + +prepare() { + cd "${srcdir}/ppp-${pkgver}" + + patch -p1 -i "${srcdir}/ppp-2.4.6-makefiles.patch" + patch -p1 -i "${srcdir}/CVE-2015-3310.patch" + patch -p1 -i "${srcdir}/ppp-build-fix.patch" + patch -p1 -i "${srcdir}/ppp-2.4.7-eaptls-mppe-0.999.patch" + + # enable active filter + sed -i "s:^#FILTER=y:FILTER=y:" pppd/Makefile.linux + # enable ipv6 support + sed -i "s:^#HAVE_INET6=y:HAVE_INET6=y:" pppd/Makefile.linux + # Enable Microsoft proprietary Callback Control Protocol + sed -i "s:^#CBCP=y:CBCP=y:" pppd/Makefile.linux +} + +build() { + cd "${srcdir}/ppp-${pkgver}" + + # -D_GNU_SOURCE is needed for IPv6 to work apparently + CFLAGS="$CPPFLAGS $CFLAGS -D_GNU_SOURCE" LDFLAGS="$LDFLAGS" ./configure --prefix=/usr + make +} + +package() { + cd "${srcdir}/ppp-${pkgver}" + make INSTROOT="${pkgdir}" install + + install -D -m644 ../options "${pkgdir}/etc/ppp/options" + install -D -m755 ../ip-up "${pkgdir}/etc/ppp/ip-up" + install -D -m755 ../ip-down "${pkgdir}/etc/ppp/ip-down" + install -d -m755 "${pkgdir}/etc/ppp/ip-up.d" + install -d -m755 "${pkgdir}/etc/ppp/ip-down.d" + install -m755 ../ip-up.d.dns.sh "${pkgdir}/etc/ppp/ip-up.d/00-dns.sh" + install -m755 ../ip-down.d.dns.sh "${pkgdir}/etc/ppp/ip-down.d/00-dns.sh" + install -D -m755 ../ipv6-up "${pkgdir}/etc/ppp/ipv6-up" + install -D -m755 ../ipv6-down "${pkgdir}/etc/ppp/ipv6-down" + install -d -m755 "${pkgdir}/etc/ppp/ipv6-up.d" + install -d -m755 "${pkgdir}/etc/ppp/ipv6-down.d" + install -m755 ../ipv6-up.d.iface-config.sh "${pkgdir}/etc/ppp/ipv6-up.d/00-iface-config.sh" + + install -D -m755 scripts/pon "${pkgdir}/usr/bin/pon" + install -D -m755 scripts/poff "${pkgdir}/usr/bin/poff" + install -D -m755 scripts/plog "${pkgdir}/usr/bin/plog" + install -D -m644 scripts/pon.1 "${pkgdir}/usr/share/man/man1/pon.1" + install -D -m600 etc.ppp/pap-secrets "${pkgdir}/etc/ppp/pap-secrets" + install -D -m600 etc.ppp/chap-secrets "${pkgdir}/etc/ppp/chap-secrets" + install -d -m755 "${pkgdir}/etc/ppp/peers" + chmod 0755 "${pkgdir}/usr/lib/pppd/${pkgver}"/*.so + + install -D -m644 "${srcdir}"/ppp.systemd "${pkgdir}"/usr/lib/systemd/system/ppp@.service + + install -Dm644 "$srcdir"/LICENSE "$pkgdir"/usr/share/licenses/$pkgname/LICENSE +} diff --git a/ip-down b/ip-down new file mode 100644 index 000000000000..cfd3ae093b50 --- /dev/null +++ b/ip-down @@ -0,0 +1,12 @@ +#!/bin/sh +# +# This script is run by pppd after the connection has ended. +# + +# Execute all scripts in /etc/ppp/ip-down.d/ +for ipdown in /etc/ppp/ip-down.d/*.sh; do + if [ -x $ipdown ]; then + # Parameters: interface-name tty-device speed local-IP-address remote-IP-address ipparam + $ipdown "$@" + fi +done diff --git a/ip-down.d.dns.sh b/ip-down.d.dns.sh new file mode 100644 index 000000000000..c9da47a63b41 --- /dev/null +++ b/ip-down.d.dns.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +if [ -x /usr/bin/resolvconf ]; then + /usr/bin/resolvconf -fd ${IFNAME} +else + [ -e /etc/resolv.conf.backup.${IFNAME} ] && mv /etc/resolv.conf.backup.${IFNAME} /etc/resolv.conf +fi diff --git a/ip-up b/ip-up new file mode 100644 index 000000000000..20473d73a22d --- /dev/null +++ b/ip-up @@ -0,0 +1,12 @@ +#!/bin/sh +# +# This script is run by pppd when there's a successful ppp connection. +# + +# Execute all scripts in /etc/ppp/ip-up.d/ +for ipup in /etc/ppp/ip-up.d/*.sh; do + if [ -x $ipup ]; then + # Parameters: interface-name tty-device speed local-IP-address remote-IP-address ipparam + $ipup "$@" + fi +done diff --git a/ip-up.d.dns.sh b/ip-up.d.dns.sh new file mode 100644 index 000000000000..0fc737eca153 --- /dev/null +++ b/ip-up.d.dns.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +if [ "$USEPEERDNS" = "1" -a -f /etc/ppp/resolv.conf ]; then + if [ -x /usr/bin/resolvconf ]; then + /usr/bin/resolvconf -a ${IFNAME} </etc/ppp/resolv.conf + else + [ -e /etc/resolv.conf ] && mv /etc/resolv.conf /etc/resolv.conf.backup.${IFNAME} + mv /etc/ppp/resolv.conf /etc/resolv.conf + chmod 644 /etc/resolv.conf + fi +fi diff --git a/ipv6-down b/ipv6-down new file mode 100644 index 000000000000..d3b9e28b38d0 --- /dev/null +++ b/ipv6-down @@ -0,0 +1,12 @@ +#!/bin/sh +# +# This script is run by pppd after the connection has ended. +# + +# Execute all scripts in /etc/ppp/ipv6-down.d/ +for ipdown in /etc/ppp/ipv6-down.d/*.sh; do + if [ -x $ipdown ]; then + # Parameters: interface-name tty-device speed local-link-local-address remote-link-local-address ipparam + $ipdown "$@" + fi +done diff --git a/ipv6-up b/ipv6-up new file mode 100644 index 000000000000..b294aafdce8a --- /dev/null +++ b/ipv6-up @@ -0,0 +1,12 @@ +#!/bin/sh +# +# This script is run by pppd when there's a successful ppp connection. +# + +# Execute all scripts in /etc/ppp/ipv6-up.d/ +for ipup in /etc/ppp/ipv6-up.d/*.sh; do + if [ -x $ipup ]; then + # Parameters: interface-name tty-device speed local-link-local-address remote-link-local-address ipparam + $ipup "$@" + fi +done diff --git a/ipv6-up.d.iface-config.sh b/ipv6-up.d.iface-config.sh new file mode 100644 index 000000000000..b23d6f61dc53 --- /dev/null +++ b/ipv6-up.d.iface-config.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +echo 0 > /proc/sys/net/ipv6/conf/$1/use_tempaddr +echo 2 > /proc/sys/net/ipv6/conf/$1/accept_ra diff --git a/options b/options new file mode 100644 index 000000000000..63691842c91c --- /dev/null +++ b/options @@ -0,0 +1,352 @@ +# /etc/ppp/options +# +# Originally created by Jim Knoble <jmknoble@mercury.interpath.net> +# Modified for Debian by alvar Bray <alvar@meiko.co.uk> +# Modified for PPP Server setup by Christoph Lameter <clameter@debian.org> +# Modified for ArchLinux by Manolis Tzanidakis <manolis@archlinux.org> +# +# To quickly see what options are active in this file, use this command: +# egrep -v '#|^ *$' /etc/ppp/options + +# 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 +# ms-wins 192.168.1.50 +# ms-wins 192.168.1.51 + +# 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. +#disconnect "chat -- \d+++\d\c OK ath0 OK" + +# 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'. +asyncmap 0 + +# 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 + +# Use hardware flow control (i.e. RTS/CTS) to control the flow of data +# on the serial port. +crtscts + +# Use software flow control (i.e. XON/XOFF) to control the flow of data +# on the serial port. +#xonxoff + +# 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 + +# Don't use the modem control lines. +#local + +# Specifies that pppd should use a UUCP-style lock on the serial device +# to ensure exclusive access to the device. +lock + +# Don't show the passwords when logging the contents of PAP packets. +# This is the default. +hide-password + +# When logging the contents of PAP packets, this option causes pppd to +# show the password string in the log message. +#show-password + +# Use the modem control lines. On Ultrix, this option implies hardware +# flow control, as for the crtscts option. (This option is not fully +# implemented.) +modem + +# Set the MRU [Maximum Receive Unit] value to <n> for negotiation. pppd +# will ask the peer to send packets of no more than <n> 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 interface netmask to <n>, a 32 bit netmask in "decimal dot" +# notation (e.g. 255.255.255.0). +#netmask 255.255.255.0 + +# Disables the default behaviour when no local IP address is specified, +# which is to determine (if possible) the local IP address from the +# hostname. With this option, the peer will have to supply the local IP +# address during IPCP negotiation (unless it specified explicitly on the +# command line or in an options file). +#noipdefault + +# Enables the "passive" option in the LCP. With this option, pppd will +# attempt to initiate a connection; if no reply is received from the +# peer, pppd will then just wait passively for a valid LCP packet from +# the peer (instead of exiting, as it does without this option). +#passive + +# With this option, pppd will not transmit LCP packets to initiate a +# connection until a valid LCP packet is received from the peer (as for +# the "passive" option with old versions of pppd). +#silent + +# Don't request or allow negotiation of any options for LCP and IPCP +# (use default values). +#-all + +# Disable Address/Control compression negotiation (use default, i.e. +# address/control field disabled). +#-ac + +# Disable asyncmap negotiation (use the default asyncmap, i.e. escape +# all control characters). +#-am + +# Don't fork to become a background process (otherwise pppd will do so +# if a serial device is specified). +#-detach + +# Disable IP address negotiation (with this option, the remote IP +# address must be specified with an option on the command line or in +# an options file). +#-ip + +# Disable IPCP negotiation and IP communication. This option should +# only be required if the peer is buggy and gets confused by requests +# from pppd for IPCP negotiation. +#noip + +# Disable magic number negotiation. With this option, pppd cannot +# detect a looped-back line. +#-mn + +# Disable MRU [Maximum Receive Unit] negotiation (use default, i.e. +# 1500). +#-mru + +# Disable protocol field compression negotiation (use default, i.e. +# protocol field compression disabled). +#-pc + +# Require the peer to authenticate itself using PAP. +#+pap + +# Don't agree to authenticate using PAP. +#-pap + +# Require the peer to authenticate itself using CHAP [Cryptographic +# Handshake Authentication Protocol] authentication. +#+chap + +# Don't agree to authenticate using CHAP. +#-chap + +# Disable negotiation of Van Jacobson style IP header compression (use +# default, i.e. no compression). +#-vj + +# Increase debugging level (same as -d). If this option is given, pppd +# will log the contents of all control packets sent or received in a +# readable form. The packets are logged through syslog with facility +# daemon and level debug. This information can be directed to a file by +# setting up /etc/syslog.conf appropriately (see syslog.conf(5)). (If +# pppd is compiled with extra debugging enabled, it will log messages +# using facility local2 instead of daemon). +#debug + +# Append the domain name <d> to the local host name for authentication +# purposes. For example, if gethostname() returns the name porsche, +# but the fully qualified domain name is porsche.Quotron.COM, you would +# use the domain option to set the domain name to Quotron.COM. +#domain <d> + +# 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 + +# Set the MTU [Maximum Transmit Unit] value to <n>. 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 <n> + +# Set the name of the local system for authentication purposes to <n>. +# This is a privileged option. With this option, pppd will use lines in the +# secrets files which have <n> as the second field when looking for a +# secret to use in authenticating the peer. In addition, unless overridden +# with the user option, <n> will be used as the name to send to the peer +# when authenticating the local system to the peer. (Note that pppd does +# not append the domain name to <n>.) +#name <n> + +# Enforce the use of the hostname as the name of the local system for +# authentication purposes (overrides the name option). +#usehostname + +# Set the assumed name of the remote system for authentication purposes +# to <n>. +#remotename <n> + +# 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 + +# 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. 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 + +# Set the LCP restart interval (retransmission timeout) to <n> seconds +# (default 3). +#lcp-restart <n> + +# Set the maximum number of LCP terminate-request transmissions to <n> +# (default 3). +#lcp-max-terminate <n> + +# Set the maximum number of LCP configure-request transmissions to <n> +# (default 10). +#lcp-max-configure <n> + +# Set the maximum number of LCP configure-NAKs returned before starting +# to send configure-Rejects instead to <n> (default 10). +#lcp-max-failure <n> + +# Set the IPCP restart interval (retransmission timeout) to <n> +# seconds (default 3). +#ipcp-restart <n> + +# Set the maximum number of IPCP terminate-request transmissions to <n> +# (default 3). +#ipcp-max-terminate <n> + +# Set the maximum number of IPCP configure-request transmissions to <n> +# (default 10). +#ipcp-max-configure <n> + +# Set the maximum number of IPCP configure-NAKs returned before starting +# to send configure-Rejects instead to <n> (default 10). +#ipcp-max-failure <n> + +# Set the PAP restart interval (retransmission timeout) to <n> seconds +# (default 3). +#pap-restart <n> + +# Set the maximum number of PAP authenticate-request transmissions to +# <n> (default 10). +#pap-max-authreq <n> + +# Set the maximum time that pppd will wait for the peer to authenticate +# itself with PAP to <n> seconds (0 means no limit). +#pap-timeout <n> + +# Set the CHAP restart interval (retransmission timeout for +# challenges) to <n> seconds (default 3). +#chap-restart <n> + +# Set the maximum number of CHAP challenge transmissions to <n> +# (default 10). +#chap-max-challenge + +# If this option is given, pppd will rechallenge the peer every <n> +# seconds. +#chap-interval <n> + +# 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 + +# Disable the IPXCP and IPX protocols. +# To let pppd pass IPX packets comment this out --- you'll probably also +# want to install ipxripd, and have the Internal IPX Network option enabled +# in your kernel. /usr/doc/HOWTO/IPX-HOWTO.gz contains more info. +noipx + +# Exit once a connection has been made and terminated. This is the default, +# unless the `persist' or `demand' option has been specified. +#nopersist + +# Do not exit after a connection is terminated; instead try to reopen +# the connection. +#persist + +# Terminate after n consecutive failed connection attempts. +# A value of 0 means no limit. The default value is 10. +#maxfail <n> + +# Initiate the link only on demand, i.e. when data traffic is present. +# With this option, the remote IP address must be specified by the user on +# the command line or in an options file. Pppd will initially configure +# the interface and enable it for IP traffic without connecting to the peer. +# When traffic is available, pppd will connect to the peer and perform +# negotiation, authentication, etc. When this is completed, pppd will +# commence passing data packets (i.e., IP packets) across the link. +#demand + +# Specifies that pppd should disconnect if the link is idle for <n> seconds. +# The link is idle when no data packets (i.e. IP packets) are being sent or +# received. Note: it is not advisable to use this option with the persist +# option without the demand option. If the active-filter option is given, +# data packets which are rejected by the specified activity filter also +# count as the link being idle. +#idle <n> + +# Specifies how many seconds to wait before re-initiating the link after +# it terminates. This option only has any effect if the persist or demand +# option is used. The holdoff period is not applied if the link was +# terminated because it was idle. +#holdoff <n> + +# Wait for up n milliseconds after the connect script finishes for a valid +# PPP packet from the peer. At the end of this time, or when a valid PPP +# packet is received from the peer, pppd will commence negotiation by +# sending its first LCP packet. The default value is 1000 (1 second). +# This wait period only applies if the connect or pty option is used. +#connect-delay <n> + +# Packet filtering: for more information, see pppd(8) +# Any packets matching the filter expression will be interpreted as link +# activity, and will cause a "demand" connection to be activated, and reset +# the idle connection timer. (idle option) +# The filter expression is akin to that of tcpdump(1) +#active-filter <filter-expression> + +# uncomment the line below this if you use PPPoE +#plugin /usr/lib/pppd/plugins/pppoe.so + +# ---<End of File>--- diff --git a/ppp-2.4.6-makefiles.patch b/ppp-2.4.6-makefiles.patch new file mode 100644 index 000000000000..5fc7bccb5bf1 --- /dev/null +++ b/ppp-2.4.6-makefiles.patch @@ -0,0 +1,270 @@ +diff -Nur ppp-2.4.6.orig/chat/Makefile.linux ppp-2.4.6/chat/Makefile.linux +--- ppp-2.4.6.orig/chat/Makefile.linux 2014-01-02 05:42:08.000000000 +0100 ++++ ppp-2.4.6/chat/Makefile.linux 2014-02-24 09:00:16.666577906 +0100 +@@ -1,7 +1,7 @@ + # $Id: Makefile.linux,v 1.15 2006/06/04 05:07:46 paulus Exp $ + + DESTDIR = $(INSTROOT)@DESTDIR@ +-BINDIR = $(DESTDIR)/sbin ++BINDIR = $(DESTDIR)/bin + MANDIR = $(DESTDIR)/share/man/man8 + + CDEF1= -DTERMIOS # Use the termios structure +@@ -10,7 +10,8 @@ + CDEF4= -DFNDELAY=O_NDELAY # Old name value + CDEFS= $(CDEF1) $(CDEF2) $(CDEF3) $(CDEF4) + +-COPTS= -O2 -g -pipe ++COPTS= @CFLAGS@ ++LDFLAGS= @LDFLAGS@ + CFLAGS= $(COPTS) $(CDEFS) + + INSTALL= install +@@ -21,7 +22,7 @@ + $(CC) -o chat chat.o + + chat.o: chat.c +- $(CC) -c $(CFLAGS) -o chat.o chat.c ++ $(CC) -c $(CFLAGS) $(LDFLAGS) -o chat.o chat.c + + install: chat + mkdir -p $(BINDIR) $(MANDIR) +diff -Nur ppp-2.4.6.orig/configure ppp-2.4.6/configure +--- ppp-2.4.6.orig/configure 2014-01-02 05:42:08.000000000 +0100 ++++ ppp-2.4.6/configure 2014-02-24 09:00:16.743242620 +0100 +@@ -185,7 +185,10 @@ + rm -f $2 + if [ -f $1 ]; then + echo " $2 <= $1" +- sed -e "s,@DESTDIR@,$DESTDIR,g" -e "s,@SYSCONF@,$SYSCONF,g" $1 >$2 ++ sed -e "s|@DESTDIR@|$DESTDIR|g" \ ++ -e "s|@SYSCONF@|$SYSCONF|g" \ ++ -e "s|@CFLAGS@|$CFLAGS|g" \ ++ -e "s|@LDFLAGS@|$LDFLAGS|g" $1 >$2 + fi + } + +diff -Nur ppp-2.4.6.orig/linux/Makefile.top ppp-2.4.6/linux/Makefile.top +--- ppp-2.4.6.orig/linux/Makefile.top 2014-01-02 05:42:08.000000000 +0100 ++++ ppp-2.4.6/linux/Makefile.top 2014-02-24 09:00:16.743242620 +0100 +@@ -1,7 +1,7 @@ + # PPP top-level Makefile for Linux. + + DESTDIR = $(INSTROOT)@DESTDIR@ +-BINDIR = $(DESTDIR)/sbin ++BINDIR = $(DESTDIR)/bin + INCDIR = $(DESTDIR)/include + MANDIR = $(DESTDIR)/share/man + ETCDIR = $(INSTROOT)@SYSCONF@/ppp +diff -Nur ppp-2.4.6.orig/pppd/Makefile.linux ppp-2.4.6/pppd/Makefile.linux +--- ppp-2.4.6.orig/pppd/Makefile.linux 2014-01-02 05:42:08.000000000 +0100 ++++ ppp-2.4.6/pppd/Makefile.linux 2014-02-24 09:00:16.743242620 +0100 +@@ -5,7 +5,7 @@ + + # Default installation locations + DESTDIR = $(INSTROOT)@DESTDIR@ +-BINDIR = $(DESTDIR)/sbin ++BINDIR = $(DESTDIR)/bin + MANDIR = $(DESTDIR)/share/man/man8 + INCDIR = $(DESTDIR)/include + +@@ -32,7 +32,8 @@ + + # CC = gcc + # +-COPTS = -O2 -pipe -Wall -g ++COPTS = @CFLAGS@ ++LDFLAGS = @LDFLAGS@ + LIBS = + + # Uncomment the next 2 lines to include support for Microsoft's +diff -Nur ppp-2.4.6.orig/pppd/plugins/Makefile.linux ppp-2.4.6/pppd/plugins/Makefile.linux +--- ppp-2.4.6.orig/pppd/plugins/Makefile.linux 2014-01-02 05:42:08.000000000 +0100 ++++ ppp-2.4.6/pppd/plugins/Makefile.linux 2014-02-24 09:00:16.779908379 +0100 +@@ -1,11 +1,11 @@ + #CC = gcc +-COPTS = -O2 -g ++COPTS = @CFLAGS@ + CFLAGS = $(COPTS) -I.. -I../../include -fPIC +-LDFLAGS = -shared ++LDFLAGS = @LDFLAGS@ -shared + INSTALL = install + + DESTDIR = $(INSTROOT)@DESTDIR@ +-BINDIR = $(DESTDIR)/sbin ++BINDIR = $(DESTDIR)/bin + MANDIR = $(DESTDIR)/share/man/man8 + LIBDIR = $(DESTDIR)/lib/pppd/$(VERSION) + +diff -Nur ppp-2.4.6.orig/pppd/plugins/pppoatm/Makefile.linux ppp-2.4.6/pppd/plugins/pppoatm/Makefile.linux +--- ppp-2.4.6.orig/pppd/plugins/pppoatm/Makefile.linux 2014-01-02 05:42:08.000000000 +0100 ++++ ppp-2.4.6/pppd/plugins/pppoatm/Makefile.linux 2014-02-24 09:00:16.809907637 +0100 +@@ -1,7 +1,7 @@ + #CC = gcc +-COPTS = -O2 -g ++COPTS = @CFLAGS@ + CFLAGS = $(COPTS) -I../.. -I../../../include -fPIC +-LDFLAGS = -shared ++LDFLAGS = @LDFLAGS@ + INSTALL = install + + #*********************************************************************** +@@ -33,7 +33,7 @@ + all: $(PLUGIN) + + $(PLUGIN): $(PLUGIN_OBJS) +- $(CC) $(CFLAGS) -o $@ -shared $^ $(LIBS) ++ $(CC) $(CFLAGS) -o $@ $(LDFLAGS) -shared $^ $(LIBS) + + install: all + $(INSTALL) -d -m 755 $(LIBDIR) +diff -Nur ppp-2.4.6.orig/pppd/plugins/pppol2tp/Makefile.linux ppp-2.4.6/pppd/plugins/pppol2tp/Makefile.linux +--- ppp-2.4.6.orig/pppd/plugins/pppol2tp/Makefile.linux 2014-01-02 05:42:08.000000000 +0100 ++++ ppp-2.4.6/pppd/plugins/pppol2tp/Makefile.linux 2014-02-24 09:01:06.325349425 +0100 +@@ -1,12 +1,12 @@ + #CC = gcc +-COPTS = -O2 -g ++COPTS = @CFLAGS@ + CFLAGS = $(COPTS) -I. -I../.. -I../../../include -fPIC +-LDFLAGS = -shared ++LDFLAGS = @LDFLAGS@ + INSTALL = install + + #*********************************************************************** + +-DESTDIR = @DESTDIR@ ++DESTDIR = $(INSTROOT)@DESTDIR@ + LIBDIR = $(DESTDIR)/lib/pppd/$(VERSION) + + VERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../../patchlevel.h) +@@ -16,7 +16,7 @@ + all: $(PLUGINS) + + %.so: %.o +- $(CC) $(CFLAGS) -o $@ -shared $^ $(LIBS) ++ $(CC) $(CFLAGS) -o $@ $(LDFLAGS) -shared $^ $(LIBS) + + install: all + $(INSTALL) -d -m 755 $(LIBDIR) +diff -Nur ppp-2.4.6.orig/pppd/plugins/radius/Makefile.linux ppp-2.4.6/pppd/plugins/radius/Makefile.linux +--- ppp-2.4.6.orig/pppd/plugins/radius/Makefile.linux 2014-01-02 05:42:08.000000000 +0100 ++++ ppp-2.4.6/pppd/plugins/radius/Makefile.linux 2014-02-24 09:00:16.809907637 +0100 +@@ -12,7 +12,8 @@ + INSTALL = install + + PLUGIN=radius.so radattr.so radrealms.so +-CFLAGS=-I. -I../.. -I../../../include -O2 -fPIC -DRC_LOG_FACILITY=LOG_DAEMON ++CFLAGS=@CFLAGS@ -I. -I../.. -I../../../include -O2 -fPIC -DRC_LOG_FACILITY=LOG_DAEMON ++LDFLAGS=@LDFLAGS@ + + # Uncomment the next line to include support for Microsoft's + # MS-CHAP authentication protocol. +@@ -43,13 +44,13 @@ + $(INSTALL) -c -m 444 pppd-radattr.8 $(MANDIR) + + radius.so: radius.o libradiusclient.a +- $(CC) -o radius.so -shared radius.o libradiusclient.a ++ $(CC) -o radius.so -shared $(LDFLAGS) radius.o libradiusclient.a + + radattr.so: radattr.o +- $(CC) -o radattr.so -shared radattr.o ++ $(CC) -o radattr.so -shared $(LDFLAGS) radattr.o + + radrealms.so: radrealms.o +- $(CC) -o radrealms.so -shared radrealms.o ++ $(CC) -o radrealms.so -shared $(LDFLAGS) radrealms.o + + CLIENTOBJS = avpair.o buildreq.o config.o dict.o ip_util.o \ + clientid.o sendserver.o lock.o util.o md5.o +diff -Nur ppp-2.4.6.orig/pppd/plugins/rp-pppoe/Makefile.linux ppp-2.4.6/pppd/plugins/rp-pppoe/Makefile.linux +--- ppp-2.4.6.orig/pppd/plugins/rp-pppoe/Makefile.linux 2014-01-02 05:42:08.000000000 +0100 ++++ ppp-2.4.6/pppd/plugins/rp-pppoe/Makefile.linux 2014-02-24 09:00:16.809907637 +0100 +@@ -15,7 +15,7 @@ + #*********************************************************************** + + DESTDIR = $(INSTROOT)@DESTDIR@ +-BINDIR = $(DESTDIR)/sbin ++BINDIR = $(DESTDIR)/bin + LIBDIR = $(DESTDIR)/lib/pppd/$(PPPDVERSION) + + PPPDVERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../../patchlevel.h) +@@ -25,12 +25,14 @@ + # Version is set ONLY IN THE MAKEFILE! Don't delete this! + RP_VERSION=3.8p + +-COPTS=-O2 -g ++COPTS=@CFLAGS@ + CFLAGS=$(COPTS) -I../../../include '-DRP_VERSION="$(RP_VERSION)"' ++LDFLAGS=@LDFLAGS@ ++ + all: rp-pppoe.so pppoe-discovery + + pppoe-discovery: pppoe-discovery.o debug.o +- $(CC) -o pppoe-discovery pppoe-discovery.o debug.o ++ $(CC) -o pppoe-discovery $(LDFLAGS) pppoe-discovery.o debug.o + + pppoe-discovery.o: pppoe-discovery.c + $(CC) $(CFLAGS) -c -o pppoe-discovery.o pppoe-discovery.c +@@ -39,7 +41,7 @@ + $(CC) $(CFLAGS) -c -o debug.o debug.c + + rp-pppoe.so: plugin.o discovery.o if.o common.o +- $(CC) -o rp-pppoe.so -shared plugin.o discovery.o if.o common.o ++ $(CC) -o rp-pppoe.so -shared $(LDFLAGS) plugin.o discovery.o if.o common.o + + install: all + $(INSTALL) -d -m 755 $(LIBDIR) +diff -Nur ppp-2.4.6.orig/pppdump/Makefile.linux ppp-2.4.6/pppdump/Makefile.linux +--- ppp-2.4.6.orig/pppdump/Makefile.linux 2014-01-02 05:42:08.000000000 +0100 ++++ ppp-2.4.6/pppdump/Makefile.linux 2014-02-24 09:00:16.809907637 +0100 +@@ -1,8 +1,9 @@ + DESTDIR = $(INSTROOT)@DESTDIR@ +-BINDIR = $(DESTDIR)/sbin ++BINDIR = $(DESTDIR)/bin + MANDIR = $(DESTDIR)/share/man/man8 + +-CFLAGS= -O -I../include/net ++CFLAGS = @CFLAGS@ -I../include/net ++LDFLAGS = @LDFLAGS@ + OBJS = pppdump.o bsd-comp.o deflate.o zlib.o + + INSTALL= install +@@ -10,7 +11,7 @@ + all: pppdump + + pppdump: $(OBJS) +- $(CC) -o pppdump $(OBJS) ++ $(CC) $(LDFLAGS) -o pppdump $(OBJS) + + clean: + rm -f pppdump $(OBJS) *~ +diff -Nur ppp-2.4.6.orig/pppstats/Makefile.linux ppp-2.4.6/pppstats/Makefile.linux +--- ppp-2.4.6.orig/pppstats/Makefile.linux 2014-01-02 05:42:08.000000000 +0100 ++++ ppp-2.4.6/pppstats/Makefile.linux 2014-02-24 09:00:16.809907637 +0100 +@@ -3,14 +3,15 @@ + # $Id: Makefile.linux,v 1.9 2006/06/04 05:07:46 paulus Exp $ + # + DESTDIR = $(INSTROOT)@DESTDIR@ +-BINDIR = $(DESTDIR)/sbin ++BINDIR = $(DESTDIR)/bin + MANDIR = $(DESTDIR)/share/man/man8 + + PPPSTATSRCS = pppstats.c + PPPSTATOBJS = pppstats.o + + #CC = gcc +-COPTS = -O ++COPTS = @CFLAGS@ ++LDFLAGS = @LDFLAGS@ + COMPILE_FLAGS = -I../include + LIBS = + +@@ -26,7 +27,7 @@ + $(INSTALL) -c -m 444 pppstats.8 $(MANDIR) + + pppstats: $(PPPSTATSRCS) +- $(CC) $(CFLAGS) -o pppstats pppstats.c $(LIBS) ++ $(CC) $(CFLAGS) $(LDFLAGS) -o pppstats pppstats.c $(LIBS) + + clean: + rm -f pppstats *~ #* core diff --git a/ppp-2.4.7-eaptls-mppe-0.999.patch b/ppp-2.4.7-eaptls-mppe-0.999.patch new file mode 100644 index 000000000000..2f71a8e7a25c --- /dev/null +++ b/ppp-2.4.7-eaptls-mppe-0.999.patch @@ -0,0 +1,3205 @@ +diff -Naur ppp-2.4.7/README.eap-tls ppp-2.4.7-eaptls-mppe-0.999/README.eap-tls +--- ppp-2.4.7/README.eap-tls 1970-01-01 01:00:00.000000000 +0100 ++++ ppp-2.4.7-eaptls-mppe-0.999/README.eap-tls 2017-05-09 14:38:55.129084488 +0200 +@@ -0,0 +1,280 @@ ++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: ++ <engine>:<identifier> ++ 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: ++ <engine>:<identifier> ++ 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 <ca-file> ++ Use the CA public certificate found in <ca-file> in PEM format ++ cert <cert-file> ++ Use the client public certificate found in <cert-file> in PEM format ++ or in engine:engine_id format ++ key <key-file> ++ Use the client private key found in <key-file> in PEM format ++ or in engine:engine_id format ++ crl <crl-file> ++ Use the Certificate Revocation List (CRL) file <crl-file> in PEM format. ++ crl-dir <dir> ++ Use CRL files from directory <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. Example ++ ++ The following example can be used to connect a Linux client with the 'pptp' ++ package to a Linux server running the 'pptpd' (PoPToP) package. The server ++ was configured with a certificate with name (CN) 'pptp-server', the client ++ was configured with a certificate with name (CN) 'pptp-client', both ++ signed by the same Certificate Authority (CA). ++ ++ Server side: ++ - /etc/pptpd.conf file: ++ option /etc/ppp/options-pptpd-eaptls ++ localip 172.16.1.1 ++ remoteip 172.16.1.10-20 ++ - /etc/ppp/options-pptpd-eaptls file: ++ name pptp-server ++ lock ++ mtu 1500 ++ mru 1450 ++ auth ++ lcp-echo-failure 3 ++ lcp-echo-interval 5 ++ nodeflate ++ nobsdcomp ++ nopredictor1 ++ nopcomp ++ noaccomp ++ ++ require-eap ++ require-mppe-128 ++ ++ crl /home/janjust/ppp/keys/crl.pem ++ ++ debug ++ logfile /tmp/pppd.log ++ ++ - /etc/ppp/eaptls-server file: ++ * pptp-server - /etc/ppp/pptp-server.crt /etc/ppp/ca.crt /etc/ppp/pptp-server.key * ++ ++ - On the server, run ++ pptdp --conf /etc/pptpd.conf ++ ++ Client side: ++ - Run ++ pppd noauth require-eap require-mppe-128 \ ++ ipcp-accept-local ipcp-accept-remote noipdefault \ ++ cert /etc/ppp/keys/pptp-client.crt \ ++ key /etc/ppp/keys/pptp-client.key \ ++ ca /etc/ppp/keys/ca.crt \ ++ name pptp-client remotename pptp-server \ ++ debug logfile /tmp/pppd.log ++ pty "pptp pptp-server.example.com --nolaunchpppd" ++ ++ Check /var/log/messages and the files /tmp/pppd.log on both sides for debugging info. ++ ++7. Notes ++ ++ This is experimental code. ++ Send suggestions and comments to Jan Just Keijser <janjust@nikhef.nl> ++ ++8. Changelog of ppp-<>-eaptls-mppe-* patches ++ ++v0.7 (22-Nov-2005) ++ - First version of the patch to include MPPE support ++ - ppp-2.4.3 only ++v0.9 (25-Jul-2006) ++ - Bug fixes ++ - First version for ppp-2.4.4 ++v0.91 (03-Sep-2006) ++ - Added missing #include for md5.h ++ - Last version for ppp-2.4.3 ++v0.92 (22-Apr-2008) ++ - Fix for openssl 0.9.8 issue with md5 function overload. ++v0.93 (14-Aug-2008) ++ - Make sure 'noauth' option can be used to bypass server certificate verification. ++v0.94 (15-Oct-2008) ++ - Added support for password-protected private keys by (ab)using the 'password' field. ++v0.95 (23-Dec-2009) ++ - First version with OpenSSL engine support. ++v0.96 (27-Jan-2010) ++ - Added fully functional support for OpenSSL engines (PKCS#11) ++ - First version for ppp-2.4.5 ++v0.97 (20-Apr-2010) ++ - Some bug fixes for v0.96 ++ - Added support for entering the password via a plugin. The sample plugin ++ .../pppd/plugins/passprompt.c has been extended with EAP-TLS support. ++ The "old" methods using the password option or the /etc/ppp/openssl.cnf file still work. ++ - Added support for specifying the client CA, certificate and private key on the command-line ++ or via the ppp config file. ++v0.98 (20-Apr-2010) ++ - Fix initialisation bug when using ca/cert/key command-line options. ++ - Last version for ppp-2.4.4 ++v0.99 (05-Oct-2010) ++ - Fix coredump when using multilink option. ++v0.991 (08-Aug-2011) ++ - Fix compilation issue with openssl 1.0. ++v0.992 (01-Dec-2011) ++ - Fix compilation issue with eaptls_check_hook and passwordfd plugin. ++v0.993 (24-Apr-2012) ++ - Fix compilation issue when EAP_TLS=n in pppd/Makefile. ++v0.994 (11-Jun-2012) ++ - Fix compilation issue on Ubuntu 11.10. ++v0.995 (27-May-2014) ++ - Add support for a CRL file using the command-line option 'crl' ++ (prior only 'crl-dir' was supported). ++ - Fix segfault when pkcs11 enginename was not specified correctly. ++ - Fix segfault when client was misconfigured. ++ - Disable SSL Session Ticket support as Windows 8 does not support this. ++v0.996 (28-May-2014) ++ - Fix minor bug where SessionTicket message was printed as 'Unknown SSL3 code 4' ++ - Add EAP-TLS-specific options to pppd.8 manual page. ++ - Updated README.eap-tls file with new option and provide an example. ++v0.997 (19-Jun-2014) ++ - change SSL_OP_NO_TICKETS to SSL_OP_NO_TICKET ++ - fix bug in initialisation code with fragmented packets. ++ +diff -Naur ppp-2.4.7/etc.ppp/eaptls-client ppp-2.4.7-eaptls-mppe-0.999/etc.ppp/eaptls-client +--- ppp-2.4.7/etc.ppp/eaptls-client 1970-01-01 01:00:00.000000000 +0100 ++++ ppp-2.4.7-eaptls-mppe-0.999/etc.ppp/eaptls-client 2017-05-09 14:38:55.129084488 +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.7/etc.ppp/eaptls-server ppp-2.4.7-eaptls-mppe-0.999/etc.ppp/eaptls-server +--- ppp-2.4.7/etc.ppp/eaptls-server 1970-01-01 01:00:00.000000000 +0100 ++++ ppp-2.4.7-eaptls-mppe-0.999/etc.ppp/eaptls-server 2017-05-09 14:38:55.137084099 +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.7/etc.ppp/openssl.cnf ppp-2.4.7-eaptls-mppe-0.999/etc.ppp/openssl.cnf +--- ppp-2.4.7/etc.ppp/openssl.cnf 1970-01-01 01:00:00.000000000 +0100 ++++ ppp-2.4.7-eaptls-mppe-0.999/etc.ppp/openssl.cnf 2017-05-09 14:38:55.137084099 +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.7/linux/Makefile.top ppp-2.4.7-eaptls-mppe-0.999/linux/Makefile.top +--- ppp-2.4.7/linux/Makefile.top 2014-08-09 14:31:39.000000000 +0200 ++++ ppp-2.4.7-eaptls-mppe-0.999/linux/Makefile.top 2017-05-09 14:38:55.138084052 +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.7/pppd/Makefile.linux ppp-2.4.7-eaptls-mppe-0.999/pppd/Makefile.linux +--- ppp-2.4.7/pppd/Makefile.linux 2014-08-09 14:31:39.000000000 +0200 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/Makefile.linux 2017-05-09 14:38:55.138084052 +0200 +@@ -76,6 +76,9 @@ + # Use libutil + USE_LIBUTIL=y + ++# Enable EAP-TLS authentication (requires libssl and libcrypto) ++USE_EAPTLS=y ++ + MAXOCTETS=y + + INCLUDE_DIRS= -I../include +@@ -115,6 +118,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.7/pppd/auth.c ppp-2.4.7-eaptls-mppe-0.999/pppd/auth.c +--- ppp-2.4.7/pppd/auth.c 2014-08-09 14:31:39.000000000 +0200 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/auth.c 2017-05-09 14:38:55.139084004 +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,14 @@ + 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 */ ++char *crl_file = NULL; /* Certificate Revocation List (CRL) file (pem format) */ ++bool need_peer_eap = 0; /* Require peer to authenticate us */ ++#endif + + static char *uafname; /* name of most recent +ua file */ + +@@ -254,6 +270,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 +430,15 @@ + "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" }, ++ { "crl", o_string, &crl_file, "Use specific CRL file" }, ++ { "need-peer-eap", o_bool, &need_peer_eap, ++ "Require the peer to authenticate us", 1 }, ++#endif /* USE_EAPTLS */ + { NULL } + }; + +@@ -730,6 +768,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; + +@@ -764,6 +805,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) { +@@ -1277,6 +1334,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( +@@ -1331,7 +1397,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)) +@@ -1346,8 +1416,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; ++ + } + + +@@ -1707,6 +1783,7 @@ + } + + ++ + /* + * get_secret - open the CHAP secret file and return the secret + * for authenticating the given client on the given server. +@@ -2359,3 +2436,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.7/pppd/ccp.c ppp-2.4.7-eaptls-mppe-0.999/pppd/ccp.c +--- ppp-2.4.7/pppd/ccp.c 2014-08-09 14:31:39.000000000 +0200 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/ccp.c 2017-05-09 14:38:55.148083482 +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.7/pppd/chap-md5.c ppp-2.4.7-eaptls-mppe-0.999/pppd/chap-md5.c +--- ppp-2.4.7/pppd/chap-md5.c 2014-08-09 14:31:39.000000000 +0200 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/chap-md5.c 2017-05-09 14:38:55.148083482 +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.7/pppd/eap-tls.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.c +--- ppp-2.4.7/pppd/eap-tls.c 1970-01-01 01:00:00.000000000 +0100 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.c 2017-05-11 10:43:00.345739124 +0200 +@@ -0,0 +1,1308 @@ ++/* ++ * 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 <string.h> ++#include <unistd.h> ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <fcntl.h> ++ ++#include <openssl/conf.h> ++#include <openssl/engine.h> ++#include <openssl/hmac.h> ++#include <openssl/err.h> ++#include <openssl/x509v3.h> ++ ++#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 ++ ++#if OPENSSL_VERSION_NUMBER < 0x10100000L ++ ++/* ++ * https://wiki.openssl.org/index.php/1.1_API_Changes ++ * tries to provide some guidance but ultimately falls short. ++ */ ++ ++static void HMAC_CTX_free(HMAC_CTX *ctx) ++{ ++ if (ctx != NULL) { ++ HMAC_CTX_cleanup(ctx); ++ OPENSSL_free(ctx); ++ } ++} ++ ++static HMAC_CTX *HMAC_CTX_new(void) ++{ ++ HMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx)); ++ if (ctx != NULL) ++ HMAC_CTX_init(ctx); ++ return ctx; ++} ++ ++/* ++ * These were basically jacked directly from the OpenSSL tree ++ * without adjustments. ++ */ ++ ++static size_t SSL_get_client_random(const SSL *ssl, unsigned char *out, ++ size_t outlen) ++{ ++ if (outlen == 0) ++ return sizeof(ssl->s3->client_random); ++ if (outlen > sizeof(ssl->s3->client_random)) ++ outlen = sizeof(ssl->s3->client_random); ++ memcpy(out, ssl->s3->client_random, outlen); ++ return outlen; ++} ++ ++static size_t SSL_get_server_random(const SSL *ssl, unsigned char *out, ++ size_t outlen) ++{ ++ if (outlen == 0) ++ return sizeof(ssl->s3->server_random); ++ if (outlen > sizeof(ssl->s3->server_random)) ++ outlen = sizeof(ssl->s3->server_random); ++ memcpy(out, ssl->s3->server_random, outlen); ++ return outlen; ++} ++ ++static size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, ++ unsigned char *out, size_t outlen) ++{ ++ if (outlen == 0) ++ return session->master_key_length; ++ if (outlen > session->master_key_length) ++ outlen = session->master_key_length; ++ memcpy(out, session->master_key, outlen); ++ return outlen; ++} ++ ++/* Avoid a deprecated warning in OpenSSL 1.1 whilst still allowing to build against 1.0.x */ ++#define TLS_method TLSv1_method ++ ++#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ ++ ++/* ++ * 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; ++ ++ ctx_a = HMAC_CTX_new(); ++ ctx_out = HMAC_CTX_new(); ++ 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_free(ctx_a); ++ HMAC_CTX_free(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; ++ unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; ++ size_t master_key_length; ++ ++ prf_size = strlen(prf_label); ++ ++ memcpy(p, prf_label, prf_size); ++ p += prf_size; ++ ++ prf_size += SSL_get_client_random(s, p, SSL3_RANDOM_SIZE); ++ p += SSL3_RANDOM_SIZE; ++ ++ prf_size += SSL_get_server_random(s, p, SSL3_RANDOM_SIZE); ++ ++ master_key_length = SSL_SESSION_get_master_key(SSL_get_session(s), master_key, ++ sizeof(master_key)); ++ PRF(master_key, 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(TLS_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 ( cert_engine && 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; ++ } ++ ++ /* Explicitly set the NO_TICKETS flag to support Win7/Win8 clients */ ++ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 ++#ifdef SSL_OP_NO_TICKET ++ | SSL_OP_NO_TICKET ++#endif ++); ++ 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 (crl_file) { ++ FILE *fp = NULL; ++ X509_CRL *crl = NULL; ++ ++ fp = fopen(crl_file, "r"); ++ if (!fp) { ++ error("EAP-TLS: Cannot open CRL file '%s'", crl_file); ++ goto fail; ++ } ++ ++ crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL); ++ if (!crl) { ++ error("EAP-TLS: Cannot read CRL file '%s'", crl_file); ++ goto fail; ++ } ++ ++ if (!(certstore = SSL_CTX_get_cert_store(ctx))) { ++ error("EAP-TLS: Failed to get certificate store"); ++ goto fail; ++ } ++ if (!X509_STORE_add_crl(certstore, crl)) { ++ error("EAP-TLS: Cannot add CRL to certificate store"); ++ goto fail; ++ } ++ 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, ++ ets->peer, clicertfile, ++ servcertfile, cacertfile, pkfile, 0)) { ++ error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"", ++ esp->es_client.ea_name, ets->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; ++ const unsigned char*msg = buf; ++ int hvers = msg[1] << 8 | msg[2]; ++ ++ if(write_p) ++ strcpy(string, " -> "); ++ else ++ strcpy(string, " <- "); ++ ++ switch(content_type) { ++ ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L ++ case SSL3_RT_HEADER: ++ strcat(string, "SSL/TLS Header: "); ++ switch(hvers) { ++ case SSL3_VERSION: ++ strcat(string, "SSL 3.0"); ++ break; ++ case TLS1_VERSION: ++ strcat(string, "TLS 1.0"); ++ break; ++ case TLS1_1_VERSION: ++ strcat(string, "TLS 1.1"); ++ break; ++ case TLS1_2_VERSION: ++ strcat(string, "TLS 1.2"); ++ break; ++ case DTLS1_VERSION: ++ strcat(string, "DTLS 1.0"); ++ break; ++ case DTLS1_2_VERSION: ++ strcat(string, "DTLS 1.2"); ++ break; ++ default: ++ strcat(string, "Unknown version"); ++ } ++ break; ++#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ ++ ++ case SSL3_RT_ALERT: ++ strcat(string, "Alert: "); ++ code = msg[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 = msg[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; ++#ifdef SSL3_MT_NEWSESSION_TICKET ++ case SSL3_MT_NEWSESSION_TICKET: ++ strcat(string,"New Session Ticket"); ++ break; ++#endif ++ 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.7/pppd/eap-tls.h ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.h +--- ppp-2.4.7/pppd/eap-tls.h 1970-01-01 01:00:00.000000000 +0100 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/eap-tls.h 2017-05-09 14:38:55.150083347 +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 <openssl/ssl.h> ++#include <openssl/bio.h> ++#include <openssl/md5.h> ++ ++#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.7/pppd/eap.c ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c +--- ppp-2.4.7/pppd/eap.c 2014-08-09 14:31:39.000000000 +0200 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.c 2017-05-09 14:38:55.151083274 +0200 +@@ -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 <t_pwd.h> +@@ -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,79 @@ + 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(ets->frag) ++ esp->es_server.ea_state = eapTlsRecvAck; ++ else ++ if(SSL_is_init_finished(ets->ssl)) ++ esp->es_server.ea_state = eapTlsRecvClient; ++ 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 +808,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 +1018,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 +1326,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 +1555,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 +1696,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 +2061,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 +2105,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 +2190,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 +2408,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 +2554,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 +2621,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 +2750,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, " <missing hint>"); +@@ -2426,3 +2870,4 @@ + + return (inp - pstart); + } ++ +diff -Naur ppp-2.4.7/pppd/eap.h ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.h +--- ppp-2.4.7/pppd/eap.h 2014-08-09 14:31:39.000000000 +0200 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/eap.h 2017-05-09 14:38:55.152083200 +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.7/pppd/md5.c ppp-2.4.7-eaptls-mppe-0.999/pppd/md5.c +--- ppp-2.4.7/pppd/md5.c 2014-08-09 14:31:39.000000000 +0200 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/md5.c 2017-05-09 14:38:55.152083200 +0200 +@@ -33,6 +33,8 @@ + *********************************************************************** + */ + ++#ifndef USE_EAPTLS ++ + #include <string.h> + #include "md5.h" + +@@ -305,3 +307,5 @@ + ** End of md5.c ** + ******************************** (cut) ******************************** + */ ++#endif /* USE_EAPTLS */ ++ +diff -Naur ppp-2.4.7/pppd/md5.h ppp-2.4.7-eaptls-mppe-0.999/pppd/md5.h +--- ppp-2.4.7/pppd/md5.h 2014-08-09 14:31:39.000000000 +0200 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/md5.h 2017-05-09 14:38:55.152083200 +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.7/pppd/pathnames.h ppp-2.4.7-eaptls-mppe-0.999/pppd/pathnames.h +--- ppp-2.4.7/pppd/pathnames.h 2014-08-09 14:31:39.000000000 +0200 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/pathnames.h 2017-05-09 14:38:55.153083126 +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.7/pppd/plugins/Makefile.linux ppp-2.4.7-eaptls-mppe-0.999/pppd/plugins/Makefile.linux +--- ppp-2.4.7/pppd/plugins/Makefile.linux 2014-08-09 14:31:39.000000000 +0200 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/plugins/Makefile.linux 2017-05-09 14:38:55.153083126 +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.7/pppd/plugins/passprompt.c ppp-2.4.7-eaptls-mppe-0.999/pppd/plugins/passprompt.c +--- ppp-2.4.7/pppd/plugins/passprompt.c 2014-08-09 14:31:39.000000000 +0200 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/plugins/passprompt.c 2017-05-09 14:38:55.153083126 +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.7/pppd/plugins/passwordfd.c ppp-2.4.7-eaptls-mppe-0.999/pppd/plugins/passwordfd.c +--- ppp-2.4.7/pppd/plugins/passwordfd.c 2014-08-09 14:31:39.000000000 +0200 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/plugins/passwordfd.c 2017-05-09 14:38:55.154083052 +0200 +@@ -79,4 +79,8 @@ + + chap_check_hook = pwfd_check; + chap_passwd_hook = pwfd_passwd; ++ ++#ifdef USE_EAPTLS ++ eaptls_passwd_hook = pwfd_passwd; ++#endif + } +diff -Naur ppp-2.4.7/pppd/pppd.8 ppp-2.4.7-eaptls-mppe-0.999/pppd/pppd.8 +--- ppp-2.4.7/pppd/pppd.8 2014-08-09 14:31:39.000000000 +0200 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/pppd.8 2017-05-09 14:38:55.155082978 +0200 +@@ -248,6 +248,12 @@ + compression in the corresponding direction. Use \fInobsdcomp\fR or + \fIbsdcomp 0\fR to disable BSD-Compress compression entirely. + .TP ++.B ca \fIca-file ++(EAP-TLS) Use the file \fIca-file\fR as the X.509 Certificate Authority ++(CA) file (in PEM format), needed for setting up an EAP-TLS connection. ++This option is used on the client-side in conjunction with the \fBcert\fR ++and \fBkey\fR options. ++.TP + .B cdtrcts + Use a non-standard hardware flow control (i.e. DTR/CTS) to control + the flow of data on the serial port. If neither the \fIcrtscts\fR, +@@ -259,6 +265,12 @@ + bi-directional flow control. The sacrifice is that this flow + control mode does not permit using DTR as a modem control line. + .TP ++.B cert \fIcertfile ++(EAP-TLS) Use the file \fIcertfile\fR as the X.509 certificate (in PEM ++format), needed for setting up an EAP-TLS connection. This option is ++used on the client-side in conjunction with the \fBca\fR and ++\fBkey\fR options. ++.TP + .B chap\-interval \fIn + If this option is given, pppd will rechallenge the peer every \fIn\fR + seconds. +@@ -287,6 +299,18 @@ + 1000 (1 second). This wait period only applies if the \fBconnect\fR + or \fBpty\fR option is used. + .TP ++.B crl \fIfilename ++(EAP-TLS) Use the file \fIfilename\fR as the Certificate Revocation List ++to check for the validity of the peer's certificate. This option is not ++mandatory for setting up an EAP-TLS connection. Also see the \fBcrl-dir\fR ++option. ++.TP ++.B crl-dir \fIdirectory ++(EAP-TLS) Use the directory \fIdirectory\fR to scan for CRL files in ++has format ($hash.r0) to check for the validity of the peer's certificate. ++This option is not mandatory for setting up an EAP-TLS connection. ++Also see the \fBcrl\fR option. ++.TP + .B debug + Enables connection debugging facilities. + If this option is given, pppd will log the contents of all +@@ -551,6 +575,12 @@ + the kernel are logged by syslog(1) to a file as directed in the + /etc/syslog.conf configuration file. + .TP ++.B key \fIkeyfile ++(EAP-TLS) Use the file \fIkeyfile\fR as the private key file (in PEM ++format), needed for setting up an EAP-TLS connection. This option is ++used on the client-side in conjunction with the \fBca\fR and ++\fBcert\fR options. ++.TP + .B ktune + Enables pppd to alter kernel settings as appropriate. Under Linux, + pppd will enable IP forwarding (i.e. set /proc/sys/net/ipv4/ip_forward +@@ -709,6 +739,9 @@ + Disable Address/Control compression in both directions (send and + receive). + .TP ++.B need-peer-eap ++(EAP-TLS) Require the peer to verify our authentication credentials. ++.TP + .B noauth + Do not require the peer to authenticate itself. This option is + privileged. +diff -Naur ppp-2.4.7/pppd/pppd.h ppp-2.4.7-eaptls-mppe-0.999/pppd/pppd.h +--- ppp-2.4.7/pppd/pppd.h 2014-08-09 14:31:39.000000000 +0200 ++++ ppp-2.4.7-eaptls-mppe-0.999/pppd/pppd.h 2017-05-09 14:38:55.156082905 +0200 +@@ -325,6 +325,11 @@ + 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; ++extern char *crl_file; ++#endif /* USE_EAPTLS */ ++ + #ifdef MAXOCTETS + extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ + extern int maxoctets_dir; /* Direction : +@@ -741,6 +746,10 @@ + extern int (*chap_passwd_hook) __P((char *user, char *passwd)); + extern void (*multilink_join_hook) __P((void)); + ++#ifdef USE_EAPTLS ++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/ppp.systemd b/ppp.systemd new file mode 100644 index 000000000000..8a963af74745 --- /dev/null +++ b/ppp.systemd @@ -0,0 +1,9 @@ +[Unit] +Description=PPP link to %I +Before=network.target + +[Service] +ExecStart=/usr/sbin/pppd call %I nodetach nolog + +[Install] +WantedBy=multi-user.target |