]> git.ozlabs.org Git - ppp.git/commitdiff
Merge pull request #297 from mjeveritt/patch-11-test-pr
authorPaul Mackerras <paulus@ozlabs.org>
Sat, 16 Oct 2021 03:01:46 +0000 (14:01 +1100)
committerGitHub <noreply@github.com>
Sat, 16 Oct 2021 03:01:46 +0000 (14:01 +1100)
pppd: Add option to ask peer for WINS address

This adds a 'usepeerwins' option, analogous to the usepeerdns option,
to ask the peer for WINS server addresses.  Nothing is done with
the addresses provided other than to pass them to the ip-up
script in environment variables.

With this, if the peer sends an IPCP Configure-NAK containing
WINS addresses, we will request them in the following IPCP
Configure-Request.

Co-authored-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Michael Everitt <gentoo@veremit.xyz>
Signed-off-by: Lars Wendler <polynomial-c@gentoo.org>
Signed-off-by: Michael Everitt <michael@2e0cer.net>
149 files changed:
.github/workflows/buildroot.yaml
.github/workflows/solaris.yaml
.github/workflows/ubuntu.yaml [new file with mode: 0644]
.gitignore
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
NEWS [new file with mode: 0644]
README.eap-tls
README.pppoe
autogen.sh [new file with mode: 0755]
chat/Makefile.am [new file with mode: 0644]
chat/Makefile.linux [deleted file]
chat/Makefile.sol2 [deleted file]
chat/chat.c
common/Makefile.am [new file with mode: 0644]
configure [deleted file]
configure.ac [new file with mode: 0644]
contrib/Makefile.am [new file with mode: 0644]
contrib/pppgetpass/.gitignore [new file with mode: 0644]
contrib/pppgetpass/Makefile.am [new file with mode: 0644]
contrib/pppgetpass/Makefile.linux [deleted file]
include/Makefile.am [new file with mode: 0644]
linux/Makefile.top [deleted file]
m4/ax_check_atm.m4 [new file with mode: 0644]
m4/ax_check_openssl.m4 [new file with mode: 0644]
m4/ax_check_openssl_func.m4 [new file with mode: 0644]
m4/ax_check_pam.m4 [new file with mode: 0644]
m4/ax_check_pcap.m4 [new file with mode: 0644]
m4/ax_check_srp.m4 [new file with mode: 0644]
m4/pkg.m4 [new file with mode: 0644]
modules/Makefile.am [new file with mode: 0644]
pppd/Makefile.am [new file with mode: 0644]
pppd/Makefile.linux [deleted file]
pppd/Makefile.sol2 [deleted file]
pppd/auth.c
pppd/cbcp.c
pppd/cbcp.h
pppd/ccp.c
pppd/ccp.h
pppd/chap-md5.c
pppd/chap-md5.h
pppd/chap-new.c
pppd/chap-new.h
pppd/chap_ms.c
pppd/chap_ms.h
pppd/demand.c
pppd/eap-tls.c
pppd/eap-tls.h
pppd/eap.c
pppd/eap.h
pppd/ecp.c
pppd/ecp.h
pppd/eui64.c
pppd/eui64.h
pppd/fsm.c
pppd/fsm.h
pppd/ipcp.c
pppd/ipcp.h
pppd/ipv6cp.c
pppd/ipv6cp.h
pppd/ipxcp.c
pppd/ipxcp.h
pppd/lcp.c
pppd/lcp.h
pppd/magic.c
pppd/magic.h
pppd/main.c
pppd/md4.c
pppd/md4.h
pppd/md5.c
pppd/md5.h
pppd/mppe.c [new file with mode: 0644]
pppd/mppe.h
pppd/multilink.c
pppd/options.c
pppd/patchlevel.h
pppd/pathnames.h
pppd/peap.c [new file with mode: 0644]
pppd/peap.h [new file with mode: 0644]
pppd/plugins/Makefile.am [new file with mode: 0644]
pppd/plugins/Makefile.linux [deleted file]
pppd/plugins/Makefile.sol2 [deleted file]
pppd/plugins/minconn.c
pppd/plugins/passprompt.c
pppd/plugins/passwordfd.c
pppd/plugins/pppoatm/Makefile.am [new file with mode: 0644]
pppd/plugins/pppoatm/Makefile.linux [deleted file]
pppd/plugins/pppoatm/pppoatm.c
pppd/plugins/pppoe/Makefile.am [new file with mode: 0644]
pppd/plugins/pppoe/Makefile.linux [deleted file]
pppd/plugins/pppoe/common.c
pppd/plugins/pppoe/config.h [deleted file]
pppd/plugins/pppoe/debug.c
pppd/plugins/pppoe/discovery.c
pppd/plugins/pppoe/if.c
pppd/plugins/pppoe/plugin.c
pppd/plugins/pppoe/pppoe-discovery.c
pppd/plugins/pppoe/pppoe.h
pppd/plugins/pppol2tp/Makefile.am [new file with mode: 0644]
pppd/plugins/pppol2tp/Makefile.linux [deleted file]
pppd/plugins/pppol2tp/openl2tp.c
pppd/plugins/pppol2tp/pppol2tp.c
pppd/plugins/radius/Makefile.am [new file with mode: 0644]
pppd/plugins/radius/Makefile.linux [deleted file]
pppd/plugins/radius/avpair.c
pppd/plugins/radius/buildreq.c
pppd/plugins/radius/config.c
pppd/plugins/radius/dict.c
pppd/plugins/radius/radattr.c
pppd/plugins/radius/radius.c
pppd/plugins/radius/radrealms.c
pppd/plugins/radius/sendserver.c
pppd/plugins/radius/util.c
pppd/plugins/winbind.c
pppd/pppcrypt.c
pppd/pppcrypt.h
pppd/pppd.8
pppd/pppd.h
pppd/pppd.pc.in [new file with mode: 0644]
pppd/pppdconf.h.in [new file with mode: 0644]
pppd/session.c
pppd/session.h
pppd/sha1.c
pppd/sha1.h
pppd/spinlock.c
pppd/spinlock.h
pppd/srp-entry.c
pppd/sys-linux.c
pppd/sys-solaris.c
pppd/tdb.c
pppd/tdb.h
pppd/termios_linux.h [new file with mode: 0644]
pppd/tls.c [new file with mode: 0644]
pppd/tls.h [new file with mode: 0644]
pppd/tty.c
pppd/upap.c
pppd/upap.h
pppd/utils.c
pppdump/Makefile.am [new file with mode: 0644]
pppdump/Makefile.linux [deleted file]
pppdump/Makefile.sol2 [deleted file]
pppstats/Makefile.am [new file with mode: 0644]
pppstats/Makefile.linux [deleted file]
pppstats/Makefile.sol2 [deleted file]
pppstats/pppstats.c
sample/options
scripts/Makefile.am [new file with mode: 0644]

index 4da78dddd0a400069dbdbdd8d09373c838ee5145..3429d1764e28056c269be55898f85a48256f2718 100644 (file)
@@ -10,7 +10,7 @@ jobs:
         libc_name: [glibc, uclibc, musl]
     steps:
       - name: Checkout Buildroot sources
-        run: git clone --depth=1 --branch=2020.11.1 https://git.busybox.net/buildroot
+        run: git clone --depth=1 --branch=2021.02.3 https://git.busybox.net/buildroot
       - name: Select latest PPP version
         working-directory: buildroot/package/pppd
         run: |
@@ -24,10 +24,26 @@ jobs:
           rm -f 0001-pppd-Fix-bounds-check.patch
           # Get package sources from head of master branch
           sed -i "/PPPD_VERSION =/c\\PPPD_VERSION = ${GITHUB_SHA}" pppd.mk
-          sed -i '/PPPD_SITE =/c\\PPPD_SITE = https://github.com/paulusmack/ppp' pppd.mk
+          sed -i '/PPPD_SITE =/c\\PPPD_SITE = https://github.com/ppp-project/ppp' pppd.mk
           sed -i '9iPPPD_SITE_METHOD = git' pppd.mk
-          # Plugin rp-pppoe has been renamed in "pppoe"
-          sed -i 's/rp-pppoe/pppoe/g' pppd.mk
+          # Tell Buildroot to run autoreconf.sh
+          sed -i '16iPPPD_AUTORECONF = YES' pppd.mk
+          # Filters feature needs libpcap
+          sed -i '17iPPPD_DEPENDENCIES = libpcap openssl' pppd.mk
+          # Enable verbose build commands and force OpenSSL directory, otherwise the host system one might be used instead of Buildroot one
+          sed -i '18iPPPD_CONF_OPTS = --disable-silent-rules --with-openssl="$(STAGING_DIR)/usr"' pppd.mk
+          # Do not install build artifacts to staging directory
+          sed -i 's/PPPD_INSTALL_STAGING = YES/PPPD_INSTALL_STAGING = NO/' pppd.mk
+          # Delete custom configuration tool, it is now automatically handled by Buildroot
+          sed -i '/PPPD_CONFIGURE_CMDS/,+4d' pppd.mk
+          # Delete custom build rule, it is now generated by Autotools
+          sed -i '/define PPPD_BUILD_CMDS/,+4d' pppd.mk
+          # Delete custom installation to target rule, it is now generated by Autotools
+          sed -i '/define PPPD_INSTALL_TARGET_CMDS/,+27d' pppd.mk
+          # Delete custom staging installation rule as PPP does not need to be installed to staging in this CI
+          sed -i '/define PPPD_INSTALL_STAGING_CMDS/,+3d' pppd.mk
+          # Tell Buildroot that this package uses Autotools
+          sed -i 's/$(eval $(generic-package))/$(eval $(autotools-package))/' pppd.mk
       - name: Enable PPP build
         working-directory: buildroot
         run: |
index 32ef9094d55e6fa29e785fde5a71ff2546ae4feb..b36b1b5a6a704edfe1107acb5da156daf00437ce 100644 (file)
@@ -12,6 +12,7 @@ jobs:
       with:
         run: |
           pkg update
-          pkg install gcc
-          ./configure
+          pkg install gcc automake autoconf libtool
+          ./autogen.sh CFLAGS="-Wno-deprecated-declarations"
           make
+          make install
diff --git a/.github/workflows/ubuntu.yaml b/.github/workflows/ubuntu.yaml
new file mode 100644 (file)
index 0000000..028193b
--- /dev/null
@@ -0,0 +1,23 @@
+name: Build and Test
+on: [push, pull_request]
+
+jobs:
+  build_and_test:
+    runs-on: ubuntu-latest
+    env:
+      configure_flags: --enable-ipxcp --enable-multilink
+
+    steps:
+    - uses: actions/checkout@v2
+
+    - name: install required packages
+      run: sudo DEBIAN_FRONTEND=noninteractive apt-get -y -qq install build-essential autoconf automake pkg-config libtool m4 autoconf-archive libssl-dev libatm1-dev libpcap-dev
+
+    - name: configure
+      run: ./autogen.sh ${{ env.configure_flags }}
+
+    - name: build
+      run: make V=1 CFLAGS="-O2 -g -Wno-unused-result"
+
+    - name: distcheck
+      run: make distcheck DISTCHECK_CONFIGURE_FLAGS="${{ env.configure_flags }}"
index eb7087cb08f9d0bfbc82d70dd6d465a5484ca6dc..133a3dfea3cdf9a61e0302896bb27c78c10628e4 100644 (file)
@@ -3,5 +3,57 @@
 *.o
 *.so
 *.a
+*.pc
 *.cat8
+*.lo
+*.la
+*.swp
+.deps
+.libs
+
+
+# http://www.gnu.org/software/autoconf
+autom4te.cache
+/autoscan.log
+/autoscan-*.log
+/aclocal.m4
+/compile
+/config.cache
+/config.guess
+/config.log
+/config.status
+/config.sub
+/configure
+/configure.scan
+/depcomp
+/install-sh
+/test-driver
+/missing
+/INSTALL
+/pppd/stamp-h1
+/pppd/stamp-h2
+/pppd/config.h
+/pppd/config.h.in
+/pppd/pppdconf.h
+
+# https://www.gnu.org/software/libtool/
+/libtool
+/ltmain.sh
+
+# http://www.gnu.org/software/m4/
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
+
+# Generated Makefile
 Makefile
+Makefile.in
+
+# Test related stuff
+utest_*
+test-suite.log
+
+# Distfiles
+/ppp-*.tar.gz
diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..ff1a48f
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,7 @@
+The pppd Project
+https://github.com/ppp-project/ppp
+
+Primary Author of this package:
+Linux                  Paul Mackerras <paulus@samba.org>
+Solaris                        James Carlson <carlson@workingcode.com>
+
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..b3846c7
--- /dev/null
+++ b/COPYING
@@ -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/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..f9fadce
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,4 @@
+2021-07-11  Eivind Naess <eivnaes@yahoo.com>
+
+       Introduction of Autotools to pppd project
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..15b2d09
--- /dev/null
@@ -0,0 +1,80 @@
+ACLOCAL_AMFLAGS="-Im4"
+
+SUBDIRS = chat contrib pppd pppstats pppdump
+
+if WITH_PLUGINS
+SUBDIRS += pppd/plugins
+endif
+
+DIST_SUBDIRS = $(SUBDIRS) common include modules scripts
+
+#
+# *HACK*
+#   This is to work around the kernel module for PPP on Sun Solaris
+if SUNOS
+all-am:
+       (cd solaris ; $(MAKE) -f Makefile)
+
+clean-generic:
+       (cd solaris ; $(MAKE) -f Makefile clean)
+
+install-am:
+       (cd solaris ; $(MAKE) -f Makefile install)
+endif
+
+install-data-hook:
+       (cd $(DESTDIR)/$(sysconfdir)/$(PACKAGE) ; \
+        chmod 600 chap-secrets pap-secrets eaptls-server eaptls-client)
+
+sampledir = $(sysconfdir)/$(PACKAGE)
+sample_DATA = \
+    etc.ppp/options \
+    etc.ppp/chap-secrets \
+    etc.ppp/pap-secrets \
+    etc.ppp/eaptls-server \
+    etc.ppp/eaptls-client \
+    etc.ppp/openssl.cnf
+
+EXTRA_README = \
+    Changes-2.3 \
+    FAQ \
+    README \
+    README.cbcp \
+    README.eap-srp \
+    README.eap-tls \
+    README.linux \
+    README.MPPE \
+    README.MSCHAP80 \
+    README.MSCHAP81 \
+    README.pppoe \
+    README.pppol2tp \
+    README.pwfd \
+    README.sol2 \
+    PLUGINS \
+    SETUP \
+    Submitting-patches.md
+
+EXTRA_SOLARIS = \
+    solaris/Makedefs \
+    solaris/Makedefs.gcc \
+    solaris/Makedefs.sol2 \
+    solaris/Makefile.sol2 \
+    solaris/Makefile.sol2-64 \
+    solaris/Makefile.sol2-64x \
+    solaris/Makefile.sol2gcc \
+    solaris/Makefile.sol2gcc-64 \
+    solaris/Makefile.sol2gcc-64x \
+    solaris/Makefile.top \
+    solaris/ppp_ahdlc.c \
+    solaris/ppp_ahdlc_mod.c \
+    solaris/ppp.c \
+    solaris/ppp_comp.c \
+    solaris/ppp_comp_mod.c \
+    solaris/ppp.conf \
+    solaris/ppp_mod.c \
+    solaris/ppp_mod.h
+
+EXTRA_DIST= \
+    $(sample_DATA) \
+    $(EXTRA_README) \
+    $(EXTRA_SOLARIS)
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..9d6c7fb
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,278 @@
+What's new in ppp-2.4.9.
+************************
+
+* Support for new EAP (Extensible Authentication Protocol) methods:
+  - Support for EAP-TLS, from Jan Just Keijser and others
+  - Support for EAP-MSCHAPv2, from Eivind Næss, Thomas Omerzu, Tijs
+    Van Buggenhout and others
+
+* New pppd options:
+  - chap-timeout
+  - chapms-strip-domain
+  - replacedefaultroute
+  - noreplacedefaultroute
+  - ipv6cp-accept-remote
+  - lcp-echo-adaptive
+  - ip-up-script
+  - ip-down-script
+  - ca
+  - capath
+  - cert
+  - key
+  - crl-dir
+  - crl
+  - max-tls-version
+  - need-peer-eap
+
+* Fixes for CVE-2020-8597 and CVE-2015-3310.
+
+* libpcap is now required when compiling on Linux (previously, if
+  libpcap was not present, pppd would be compiled without packet
+  filtering support).
+
+* The rp-pppoe plugin has been renamed to pppoe, to distinguish it
+  from the upstream rp-pppoe code.  Its options have changed names,
+  but the old names are kept as aliases.
+
+* The configure script now supports cross-compilation.
+
+* Many bug fixes and cleanups.
+  
+
+What was new in ppp-2.4.8.
+**************************
+
+* New pppd options have been added:
+  - ifname, to set the name for the PPP interface device
+  - defaultroute-metric, to set the metric for the default route
+  - defaultroute6, to add an IPv6 default route (with nodefaultroute6
+    to prevent adding an IPv6 default route)
+  - up_sdnotify, to have pppd notify systemd when the link is up.
+
+* The rp-pppoe plugin has new options:
+  - host-uniq, to set the Host-Uniq value to send
+  - pppoe-padi-timeout, to set the timeout for discovery packets
+  - pppoe-padi-attempts, to set the number of discovery attempts.
+
+* Added the CLASS attribute in radius packets.
+
+* Sundry bug fixes.
+
+* Fixed warnings and issues found by static analysis.
+
+* Added Submitting-patches.md.
+
+
+What was new in ppp-2.4.7.
+**************************
+
+* Fixed a potential security issue in parsing option files (CVE-2014-3158).
+
+* There is a new "stop-bits" option, which takes an argument of 1 or 2,
+  indicating the number of stop bits to use for async serial ports.
+
+* Various bug fixes.
+
+
+What was new in ppp-2.4.6.
+**************************
+
+* Man page updates.
+
+* Several bug fixes.
+
+* Options files can now set and unset environment variables for
+  scripts.
+
+* The timeout for chat scripts can now be taken from an environment
+  variable.
+
+* There is a new option, master_detach, which allows pppd to detach
+  from the controlling terminal when it is the multilink bundle master
+  but its own link has terminated, even if the nodetach option has
+  been given.
+
+
+What was new in ppp-2.4.5.
+**************************
+
+* Under Linux, pppd can now operate in a mode where it doesn't request
+  the peer's IP address, as some peers refuse to supply an IP address.
+  Since Linux supports device routes as well as gateway routes, it's
+  possible to have no remote IP address assigned to the ppp interface
+  and still route traffic over it.
+
+* Pppd now works better with 3G modems that do strange things such as
+  sending IPCP Configure-Naks with the same values over and over again.
+
+* The PPP over L2TP plugin is included, which works with the pppol2tp
+  PPP channel code in the Linux kernel.  This allows pppd to be used
+  to set up tunnels using the Layer 2 Tunneling Protocol.
+
+* A new 'enable-session' option has been added, which enables session
+  accounting via PAM or wtwp/wtmpx, as appropriate.  See the pppd man
+  page for details.
+
+* Several bugs have been fixed.
+
+
+What was new in ppp-2.4.4.
+**************************
+
+* Pppd will now run /etc/ppp/ip-pre-up, if it exists, after creating
+  the ppp interface and configuring its IP addresses but before
+  bringing it up.  This can be used, for example, for adding firewall
+  rules for the interface.
+
+* Lots of bugs fixed, particularly in the area of demand-dialled and
+  persistent connections.
+
+* The rp-pppoe plugin now accepts any interface name (that isn't an
+  existing pppd option name) without putting "nic-" on the front of
+  it, not just eth*, nas*, tap* and br*.
+
+
+What was new in ppp-2.4.3.
+**************************
+
+* The configure script now accepts --prefix and --sysconfdir options.
+  These default to /usr/local and /etc.  If you want pppd put in
+  /usr/sbin as before, use ./configure --prefix=/usr.
+
+* Doing `make install' no longer puts example configuration files in
+  /etc/ppp.  Use `make install-etcppp' if you want that.
+
+* The code has been updated to work with version 0.8.3 of libpcap.
+  Unfortunately the libpcap maintainers removed support for the
+  "inbound" and "outbound" keywords on PPP links, meaning that if you
+  link pppd with libpcap-0.8.3, you can't use those keywords in the
+  active-filter and pass-filter expressions.  The support has been
+  reinstated in the CVS version and should be in future libpcap
+  releases.  If you need the in/outbound keywords, use a later release
+  than 0.8.3, or get the CVS version from http://www.tcpdump.org.
+
+* There is a new option, child-timeout, which sets the length of time
+  that pppd will wait for child processes (such as the command
+  specified with the pty option) to exit before exiting itself.  It
+  defaults to 5 seconds.  After the timeout, pppd will send a SIGTERM
+  to any remaining child processes and exit.  A value of 0 means no
+  timeout.
+
+* Various bugs have been fixed, including some CBCP packet parsing
+  bugs that could lead to the peer being able to crash pppd if CBCP
+  support is enabled.
+
+* Various fixes and enhancements to the radius and rp-pppoe plugins
+  have been added.
+
+* There is a new winbind plugin, from Andrew Bartlet of the Samba
+  team, which provides the ability to authenticate the peer against an
+  NT domain controller using MS-CHAP or MS-CHAPV2.
+
+* There is a new pppoatm plugin, by various authors, sent in by David
+  Woodhouse.
+
+* The multilink code has been substantially reworked.  The first pppd
+  for a bundle still controls the ppp interface, but it doesn't exit
+  until all the links in the bundle have terminated.  If the first
+  pppd is signalled to exit, it signals all the other pppds
+  controlling links in the bundle.
+
+* The TDB code has been updated to the latest version.  This should
+  eliminate the problem that some people have seen where the database
+  file (/var/run/pppd.tdb) keeps on growing.  Unfortunately, however,
+  the new code uses an incompatible database format.  For this reason,
+  pppd now uses /var/run/pppd2.tdb as the database filename.
+
+
+What was new in ppp-2.4.2.
+**************************
+
+* The CHAP code has been rewritten.  Pppd now has support for MS-CHAP
+  V1 and V2 authentication, both as server and client.  The new CHAP
+  code is cleaner than the old code and avoids some copyright problems
+  that existed in the old code.
+
+* MPPE (Microsoft Point-to-Point Encryption) support has been added,
+  although the current implementation shouldn't be considered
+  completely secure.  (There is no assurance that the current code
+  won't ever transmit an unencrypted packet.)
+
+* James Carlson's implementation of the Extensible Authentication
+  Protocol (EAP) has been added.
+
+* Support for the Encryption Control Protocol (ECP) has been added.
+
+* Some new plug-ins have been included:
+  - A plug-in for kernel-mode PPPoE (PPP over Ethernet)
+  - A plug-in for supplying the PAP password over a pipe from another
+    process
+  - A plug-in for authenticating using a Radius server.
+
+* Updates and bug-fixes for the Solaris port.
+
+* The CBCP (Call Back Control Protocol) code has been updated.  There
+  are new options `remotenumber' and `allow-number'.
+
+* Extra hooks for plugins to use have been added.
+
+* There is now a `maxoctets' option, which causes pppd to terminate
+  the link once the number of bytes passed on the link exceeds a given
+  value.
+
+* There are now options to control whether pppd can use the IPCP
+  IP-Address and IP-Addresses options: `ipcp-no-address' and
+  `ipcp-no-addresses'.
+
+* Fixed several bugs, including potential buffer overflows in chat.
+
+
+What was new in ppp-2.4.1.
+**************************
+
+* Pppd can now print out the set of options that are in effect.  The
+  new `dump' option causes pppd to print out the option values after
+  option parsing is complete.  The `dryrun' option causes pppd to
+  print the options and then exit.
+
+* The option parsing code has been fixed so that options in the
+  per-tty options file are parsed correctly, and don't override values
+  from the command line in most cases.
+
+* The plugin option now looks in /usr/lib/pppd/<pppd-version> (for
+  example, /usr/lib/pppd/2.4.1b1) for shared objects for plugins if
+  there is no slash in the plugin name.
+
+* When loading a plugin, pppd will now check the version of pppd for
+  which the plugin was compiled, and refuse to load it if it is
+  different to pppd's version string.  To enable this, the plugin
+  source needs to #include "pppd.h" and have a line saying:
+       char pppd_version[] = VERSION;
+
+* There is a bug in zlib, discovered by James Carlson, which can cause
+  kernel memory corruption if Deflate is used with the lowest setting,
+  8.  As a workaround pppd will now insist on using at least 9.
+
+* Pppd should compile on Solaris and SunOS again.
+
+* Pppd should now set the MTU correctly on demand-dialled interfaces.
+
+
+What was new in ppp-2.4.0.
+**************************
+
+* Multilink: this package now allows you to combine multiple serial
+  links into one logical link or `bundle', for increased bandwidth and
+  reduced latency.  This is currently only supported under the
+  2.4.x and later Linux kernels.
+
+* All the pppd processes running on a system now write information
+  into a common database.  I used the `tdb' code from samba for this.
+
+* New hooks have been added.
+
+For a list of the changes made during the 2.3 series releases of this
+package, see the Changes-2.3 file.
+
+
+
index ab3794eaa53566e7a3e72805cce1b4c5988f154b..ad81ab25fbcd443369252b54bd3a74a4b4ca7b92 100644 (file)
@@ -126,7 +126,7 @@ EAP-TLS authentication support for PPP
 
       ca <ca-file>
         Use the CA public certificate found in <ca-file> in PEM format
-      ca-path <directory>
+      capath <directory>
         Use the directory <directory> as the CA public certificate directory
       cert <cert-file>
         Use the client public certificate found in <cert-file> in PEM format
@@ -134,6 +134,9 @@ EAP-TLS authentication support for PPP
       key <key-file>
         Use the client private key found in <key-file> in PEM format
         or in engine:engine_id format
+      pkcs12 <pkcs12-file>
+        Use a pkcs12 envelope as a substitute for cert and key. A password may be
+        required to use this file. 
       crl <crl-file>
         Use the Certificate Revocation List (CRL) file <crl-file> in PEM format.
       crl-dir <dir>
@@ -147,6 +150,11 @@ EAP-TLS authentication support for PPP
       max-tls-version <1.0|1.1|1.2 (default)|1.3>
         Specify the maximum TLS protocol version to negotiate with peers. Defaults
         to TLSv1.2 as the TLSv1.3 code is experimental.
+      tls-verify-key-usage
+        Validate certificate purpose and extended key usage
+      tls-verify-method <none|subject|name|suffix>
+        Compare the remotename against the subject, certificate name, or
+        match by suffix. Default is 'name'.
 
     Note: 
       password-encrypted certificates can be used as of v0.94 of this 
index 2909e1310a31f23f62719bc97cd0538084240704..7fe0139a671cda216db5a4fb58c2486efb1f2543 100644 (file)
@@ -60,7 +60,7 @@ to connect to their ISP who is providing PPPoE based services.
 
 5.  Add the necessary authentication options to your pppd
     configuration (i.e. PAP/CHAP information).  If you wish to
-    maintain seperate configurations for different devices you may
+    maintain separate configurations for different devices you may
     place configuration options in device-specific configuration
     files: /etc/ppp/options.devname (devname=ttyS0, ttyS1, eth0, eth1
     or any other valid device name).
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..e27d631
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/sh
+# Run this to generate all the initial makefiles, etc.
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+REQUIRED_AUTOMAKE_VERSION=1.9
+PKG_NAME=pppd
+
+(test -f $srcdir/configure.ac \
+  && test -f $srcdir/pppd/main.c) || {
+      echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
+      echo " top-level $PKG_NAME directory"
+      exit 1
+  }
+
+(cd $srcdir;
+ autoreconf --install --symlink &&
+ autoreconf &&
+ ./configure --enable-maintainer-mode $@
+)
+
diff --git a/chat/Makefile.am b/chat/Makefile.am
new file mode 100644 (file)
index 0000000..0a29869
--- /dev/null
@@ -0,0 +1,5 @@
+sbin_PROGRAMS = chat
+dist_man8_MANS = chat.8
+
+chat_SOURCES = chat.c
+chat_CPPFLAGS = -DTERMIOS -DSIGTYPE=void -UNO_SLEEP -DFNDELAY=O_NDELAY
diff --git a/chat/Makefile.linux b/chat/Makefile.linux
deleted file mode 100644 (file)
index 407cc12..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-CROSS_COMPILE=@CROSS_COMPILE@
-CC=$(CROSS_COMPILE)@CC@
-COPTS=@CFLAGS@
-
-DESTDIR = $(INSTROOT)@DESTDIR@
-BINDIR = $(DESTDIR)/sbin
-MANDIR = $(DESTDIR)/share/man/man8
-
-CDEF1= -DTERMIOS                       # Use the termios structure
-CDEF2= -DSIGTYPE=void                  # Standard definition
-CDEF3= -UNO_SLEEP                      # Use the usleep function
-CDEF4= -DFNDELAY=O_NDELAY              # Old name value
-CDEFS= $(CDEF1) $(CDEF2) $(CDEF3) $(CDEF4)
-
-CFLAGS=        $(COPTS) $(CDEFS)
-
-INSTALL= install
-
-all:   chat
-
-chat:  chat.o
-       $(CC) $(LDFLAGS) -o chat chat.o
-
-chat.o:        chat.c
-       $(CC) -c $(CFLAGS) -o chat.o chat.c
-
-install: chat
-       mkdir -p $(BINDIR) $(MANDIR)
-       $(INSTALL) -c chat $(BINDIR)
-       $(INSTALL) -c -m 644 chat.8 $(MANDIR)
-
-clean:
-       rm -f chat.o chat *~
diff --git a/chat/Makefile.sol2 b/chat/Makefile.sol2
deleted file mode 100644 (file)
index 10d3314..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#
-# Makefile for chat on Solaris 2
-#
-
-include ../Makedefs.com
-
-CFLAGS = $(COPTS) -DNO_USLEEP -DSOL2
-
-all:   chat
-
-chat: chat.o
-       $(CC) -o chat chat.o
-
-install: chat
-       $(INSTALL) -f $(BINDIR) chat
-       $(INSTALL) -m 444 -f $(MANDIR)/man8 chat.8
-
-clean:
-       rm -f *~ *.o chat
index 1639b3e440692f6bbb92da8ab60314d5ad4e15d3..64d96c230bfcd943c28e9182711c7fbaee7d20ad 100644 (file)
@@ -201,7 +201,7 @@ SIGTYPE sighup (int signo);
 void unalarm (void);
 void init (void);
 void set_tty_parameters (void);
-void echo_stderr (int);
+int  echo_stderr (int);
 void break_sequence (void);
 void terminate (int status);
 void do_file (char *chat_file);
@@ -210,7 +210,7 @@ int  put_string (register char *s);
 int  write_char (int c);
 int  put_char (int c);
 int  get_char (void);
-void chat_send (register char *s);
+int  chat_send (register char *s);
 char *character (int c);
 void chat_expect (register char *s);
 char *clean (register char *s, int sending);
@@ -983,16 +983,18 @@ char *character(int c)
 /*
  *  process the reply string
  */
-void chat_send (register char *s)
+int chat_send (register char *s)
 {
     char file_data[STR_LEN];
+    int len, ret = 0;
 
     if (say_next) {
        say_next = 0;
        s = clean(s, 1);
-       write(2, s, strlen(s));
+       len = strlen(s);
+       ret = write(2, s, len) != len;
         free(s);
-       return;
+       return ret;
     }
 
     if (hup_next) {
@@ -1001,13 +1003,13 @@ void chat_send (register char *s)
            signal(SIGHUP, SIG_IGN);
         else
            signal(SIGHUP, sighup);
-        return;
+        return 0;
     }
 
     if (echo_next) {
        echo_next = 0;
        echo = (strcmp(s, "ON") == 0);
-       return;
+       return 0;
     }
 
     if (abort_next) {
@@ -1020,15 +1022,14 @@ void chat_send (register char *s)
        
        s1 = clean(s, 0);
        
-       if (strlen(s1) > strlen(s)
-           || strlen(s1) + 1 > sizeof(fail_buffer))
+       if (strlen(s1) + 1 > sizeof(fail_buffer))
            fatal(1, "Illegal or too-long ABORT string ('%v')", s);
 
        abort_string[n_aborts++] = s1;
 
        if (verbose)
-           msgf("abort on (%v)", s);
-       return;
+           msgf("abort on (%v)", s1);
+       return 0;
     }
 
     if (clear_abort_next) {
@@ -1041,8 +1042,7 @@ void chat_send (register char *s)
        
        s1 = clean(s, 0);
        
-       if (strlen(s1) > strlen(s)
-           || strlen(s1) + 1 > sizeof(fail_buffer))
+       if (strlen(s1) + 1 > sizeof(fail_buffer))
            fatal(1, "Illegal or too-long CLR_ABORT string ('%v')", s);
 
         old_max = n_aborts;
@@ -1053,13 +1053,13 @@ void chat_send (register char *s)
                pack++;
                n_aborts--;
                if (verbose)
-                   msgf("clear abort on (%v)", s);
+                   msgf("clear abort on (%v)", s1);
            }
        }
         free(s1);
        if (pack)
            pack_array(abort_string,old_max);
-       return;
+       return 0;
     }
 
     if (report_next) {
@@ -1070,15 +1070,14 @@ void chat_send (register char *s)
            fatal(2, "Too many REPORT strings");
        
        s1 = clean(s, 0);
-       if (strlen(s1) > strlen(s)
-           || strlen(s1) + 1 > sizeof(fail_buffer))
+       if (strlen(s1) + 1 > sizeof(fail_buffer))
            fatal(1, "Illegal or too-long REPORT string ('%v')", s);
        
        report_string[n_reports++] = s1;
        
        if (verbose)
-           msgf("report (%v)", s);
-       return;
+           msgf("report (%v)", s1);
+       return 0;
     }
 
     if (clear_report_next) {
@@ -1091,8 +1090,7 @@ void chat_send (register char *s)
        
        s1 = clean(s, 0);
        
-       if (strlen(s1) > strlen(s)
-           || strlen(s1) + 1 > sizeof(fail_buffer))
+       if (strlen(s1) + 1 > sizeof(fail_buffer))
            fatal(1, "Illegal or too-long REPORT string ('%v')", s);
 
        old_max = n_reports;
@@ -1103,14 +1101,14 @@ void chat_send (register char *s)
                pack++;
                n_reports--;
                if (verbose)
-                   msgf("clear report (%v)", s);
+                   msgf("clear report (%v)", s1);
            }
        }
         free(s1);
         if (pack)
            pack_array(report_string,old_max);
        
-       return;
+       return 0;
     }
 
     if (timeout_next) {
@@ -1124,7 +1122,7 @@ void chat_send (register char *s)
        if (verbose)
            msgf("timeout set to %d seconds", timeout);
 
-       return;
+       return 0;
     }
 
     /*
@@ -1171,6 +1169,8 @@ void chat_send (register char *s)
 
     if (!put_string(s))
        fatal(1, "Failed");
+
+    return 0;
 }
 
 int get_char(void)
@@ -1296,10 +1296,11 @@ int put_string(register char *s)
  *     When called with -1, a '\n' character is generated when
  *     the cursor is not at the beginning of a line.
  */
-void echo_stderr(int n)
+int echo_stderr(int n)
 {
     static int need_lf;
     char *s;
+    int len, ret = 0;
 
     switch (n) {
     case '\r':         /* ignore '\r' */
@@ -1309,15 +1310,17 @@ void echo_stderr(int n)
            break;
        /* fall through */
     case '\n':
-       write(2, "\n", 1);
+       ret = write(2, "\n", 1) != 1;
        need_lf = 0;
        break;
     default:
        s = character(n);
-       write(2, s, strlen(s));
+       len = strlen(s);
+       ret = write(2, s, len) != len;
        need_lf = 1;
        break;
     }
+    return ret;
 }
 
 /*
@@ -1356,8 +1359,11 @@ int get_string(register char *string)
     while ( ! alarmed && (c = get_char()) >= 0) {
        int n, abort_len, report_len;
 
-       if (echo)
-           echo_stderr(c);
+       if (echo) {
+           if (echo_stderr(c) != 0) {
+               fatal(2, "Could not write to stderr, %m");
+           }
+       }
        if (verbose && c == '\n') {
            if (s == logged)
                msgf("");       /* blank line */
diff --git a/common/Makefile.am b/common/Makefile.am
new file mode 100644 (file)
index 0000000..27169d5
--- /dev/null
@@ -0,0 +1,6 @@
+EXTRA_ZLIB = \
+    zlib.c \
+    zlib.h
+
+EXTRA_DIST = \
+    $(EXTRA_ZLIB)
diff --git a/configure b/configure
deleted file mode 100755 (executable)
index b0c3d2b..0000000
--- a/configure
+++ /dev/null
@@ -1,145 +0,0 @@
-#!/bin/sh
-# $Id: configure,v 1.38 2008/06/15 07:08:49 paulus Exp $
-
-# Where to install stuff by default
-DESTDIR=/usr/local
-SYSCONF=/etc
-
-# Compile defaults
-CROSS_COMPILE=
-CC=cc
-CFLAGS=
-
-system=`uname -s`
-release=`uname -r`
-arch=`uname -m`
-state="unknown"
-
-case $system in
-  Linux)
-    makext="linux";
-    ksrc="linux";
-    state="known";
-    CFLAGS="-O2 -g -pipe";;
-  SunOS)
-    karch=`/usr/bin/isainfo -k`
-    case $release in
-      5.[7-9]*|5.[1-9][0-9]*)  state="known"; ksrc="solaris"; makext="sol2";
-              case "$karch" in
-               amd64)          archvariant='-64x';;
-               sparcv9)        archvariant='-64';;
-               *)      ;;
-             esac;;
-      5.[1-6]*)        state="known"; ksrc="solaris"; makext="sol2";;
-    esac
-    if [ "$1" = gcc ]; then
-       shift
-       usegcc=gcc
-    fi
-    if [ "$1" = 32 ]; then
-       shift
-       archvariant=
-    fi
-    if [ -x /opt/SUNWspro/bin/cc -a "$usegcc" != gcc ] &&
-       /opt/SUNWspro/bin/cc -flags >/dev/null 2>&1; then
-      if [ "$archvariant" = "-64x" ]; then
-        ( cd /tmp; echo "int x;" > ppp$$.c
-         /opt/SUNWspro/bin/cc -c -errwarn -xchip=opteron -m64 ppp$$.c >/dev/null 2>&1 || (
-           echo "WorkShop C is unable to make 64 bit modules, and your $karch system needs"
-           echo "them.  Consider upgrading cc on this machine."
-           rm -f ppp$$.c
-           exit 1
-         ) || exit 1
-         rm -f ppp$$.c ppp$$.o
-        ) || exit 1
-      fi
-    elif gcc --version >/dev/null 2>&1; then
-      archvariant=gcc$archvariant
-      compiletype=.gcc
-      if [ "$archvariant" = "gcc-64" -o"$archvariant" = "gcc-64x" ]; then
-        ( cd /tmp; touch ppp$$.c
-         gcc -c -m64 ppp$$.c >/dev/null 2>&1 || (
-           echo "gcc is unable to make 64 bit modules, and your $karch system needs them."
-           echo "Consider upgrading gcc on this machine, or switching to Sun WorkShop."
-           rm -f ppp$$.c
-           exit 1
-         ) || exit 1
-         rm -f ppp$$.c ppp$$.o
-        ) || exit 1
-      fi
-    else
-      echo "C compiler not found; hoping for the best."
-    fi;;
-  NetBSD|FreeBSD|ULTRIX|OSF1|NeXTStep|SINIX-?|UNIX_SV|UNIX_System_V)
-    state="notincluded";;
-esac
-
-if [ -d "$ksrc" ]; then :; else
-  state="notincluded"
-  unset ksrc
-fi
-
-case $state in
-  unknown)
-    echo "This software has not been ported to $system.  Sorry.";;
-  notincluded)
-    echo "Support for $system has not been included"
-    echo "in this distribution.  Sorry.";;
-  known)
-    echo "Configuring for $system";;
-esac
-
-# Parse arguments
-while [ $# -gt 0 ]; do
-    arg=$1
-    val=
-    shift
-    case $arg in
-       *=*)
-           val=`expr "x$arg" : 'x[^=]*=\(.*\)'`
-           arg=`expr "x$arg" : 'x\([^=]*\)=.*'`
-           ;;
-       --prefix|--sysconf)
-           if [ $# -eq 0 ]; then
-               echo "error: the $arg argument requires a value" 1>&2
-               exit 1
-           fi
-           val=$1
-           shift
-           ;;
-    esac
-    case $arg in
-       --prefix)        DESTDIR=$val ;;
-       --sysconfdir)    SYSCONF=$val ;;
-       --cross_compile) CROSS_COMPILE=$val ;;
-       --cc)            CC=$val ;;
-       --cflags)        CFLAGS=$val ;;
-    esac
-done
-
-mkmkf() {
-    rm -f $2
-    if [ -f $1 ]; then
-       echo "  $2 <= $1"
-       sed -e "s,@DESTDIR@,$DESTDIR,g" -e "s,@SYSCONF@,$SYSCONF,g" \
-           -e "s,@CROSS_COMPILE@,$CROSS_COMPILE,g" -e "s,@CC@,$CC,g" \
-           -e "s|@CFLAGS@|$CFLAGS|g" $1 >$2
-    fi
-}
-
-if [ -d "$ksrc" ]; then
-    echo "Creating Makefiles."
-    mkmkf $ksrc/Makefile.top Makefile
-    mkmkf $ksrc/Makedefs$compiletype Makedefs.com
-    for dir in pppd pppstats chat pppdump pppd/plugins pppd/plugins/pppoe \
-              pppd/plugins/radius pppd/plugins/pppoatm \
-              pppd/plugins/pppol2tp; do
-       mkmkf $dir/Makefile.$makext $dir/Makefile
-    done
-    if [ -f $ksrc/Makefile.$makext$archvariant ]; then
-       mkmkf $ksrc/Makefile.$makext$archvariant $ksrc/Makefile
-    fi
-else
-  echo "Unable to locate kernel source $ksrc"
-  exit 1
-fi
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..283b666
--- /dev/null
@@ -0,0 +1,426 @@
+AC_PREREQ([2.69])
+AC_INIT([ppp],
+        [2.4.10-dev],
+        [https://github.com/ppp-project/ppp])
+
+m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
+AC_CONFIG_MACRO_DIR([m4])
+
+AM_INIT_AUTOMAKE
+AM_MAINTAINER_MODE([enable])
+
+AC_LANG(C)
+AC_CONFIG_SRCDIR([pppd/main.c])
+AC_CONFIG_HEADERS([pppd/config.h pppd/pppdconf.h])
+
+# Checks for programs.
+AC_PROG_CC
+AM_PROG_CC_C_O
+AC_PROG_INSTALL
+AC_PROG_LIBTOOL
+AC_PROG_LN_S
+
+PKG_PROG_PKG_CONFIG
+
+AC_CANONICAL_HOST
+build_linux=no
+build_sunos=no
+
+case "${host_os}" in
+    linux*)
+       build_linux=yes
+       ;;
+    solaris2*)
+       build_sunos=yes
+       ;;
+    *)
+       AC_MSG_ERROR(["OS ${host_os} not supported"])
+       ;;
+esac
+
+AM_CONDITIONAL([LINUX], [test "${build_linux}" = "yes" ])
+AM_CONDITIONAL([SUNOS], [test "${build_sunos}" = "yes" ])
+AM_COND_IF([SUNOS],
+      CFLAGS="$CFLAGS -DSOL2 -DSRV4")
+
+#
+# Checks for header files, these will set the HAVE_[FILE]_H macros in config.h
+AC_HEADER_STDBOOL
+AC_CHECK_HEADERS([  \
+    asm/types.h     \
+    crypt.h         \
+    paths.h         \
+    shadow.h        \
+    sys/dlpi.h      \
+    sys/ioctl.h     \
+    sys/socket.h    \
+    sys/time.h      \
+    sys/uio.h       \
+    time.h          \
+    unistd.h        \
+    utmp.h])
+
+#
+# Check for linux specific headers, required by pppoe, or pppol2tp
+AM_COND_IF([LINUX], [
+    AC_CHECK_HEADERS([          \
+        net/bpf.h               \
+        net/if.h                \
+        net/if_types.h          \
+        net/if_arp.h            \
+        linux/if.h              \
+        linux/if_ether.h        \
+        linux/if_packet.h       \
+        netinet/if_ether.h      \
+        netpacket/packet.h])])
+
+AC_CHECK_SIZEOF(unsigned int)
+AC_CHECK_SIZEOF(unsigned long)
+AC_CHECK_SIZEOF(unsigned short)
+
+# Checks for library functions.
+AC_CHECK_FUNCS([    \
+    mmap            \
+    logwtmp         \
+    strerror])
+
+#
+# If libc doesn't provide logwtmp, check if libutil provides logwtmp(), and if so link to it.
+AS_IF([test "x${ac_cv_func_logwtmp}" != "xyes"], [
+    AC_CHECK_LIB([util], [logwtmp], [
+        AC_DEFINE(HAVE_LOGWTMP, 1, ["System provides the logwtmp() function"])
+        AC_SUBST([UTIL_LIBS], ["-lutil"])
+    ])
+])
+
+#
+# Check if libcrypt have crypt() function
+AC_CHECK_LIB([crypt], [crypt],
+    AC_SUBST([CRYPT_LIBS], ["-lcrypt"]))
+
+#
+# Should pppd link with -lsystemd (Linux only)
+AC_ARG_ENABLE([systemd],
+    AS_HELP_STRING([--enable-systemd], [Enable support for systemd notification]))
+AM_CONDITIONAL(WITH_SYSTEMD, test "x${enable_systemd}" = "xyes")
+AM_COND_IF([WITH_SYSTEMD],
+    AC_DEFINE([SYSTEMD], 1, [Enable support for systemd notifications]))
+
+#
+# Enable Callback Protocol Support, disabled by default
+AC_ARG_ENABLE([cbcp],
+    AS_HELP_STRING([--enable-cbcp], [Enable Callback Protocol]))
+AM_CONDITIONAL(WITH_CBCP, test "x${enable_cbcp}" = "xyes")
+AM_COND_IF([WITH_CBCP],
+    AC_DEFINE([CBCP_SUPPORT], 1, [Have Callback Protocol support]))
+
+#
+# Disable support for IPX control protocol
+AC_ARG_ENABLE([ipxcp],
+    AS_HELP_STRING([--enable-ipxcp], [Enable IPX Control Protocol support]))
+AM_CONDITIONAL(WITH_IPXCP, test "x${enable_ipxcp}" = "xyes")
+AM_COND_IF(WITH_IPXCP,
+    AC_DEFINE([IPX_CHANGE], 1, ["Have IPX Control Protocol"]))
+AS_IF([test "x${build_sunos}" = "xyes" && test "x${enable_ipxcp}" = "xyes"],
+    [AC_MSG_ERROR([IPXCP is not supported on SunOS, disable using --disable-ipxcp])])
+
+#
+# Disable support for limiting session duration by maximum octets
+AC_ARG_ENABLE([maxoctets],
+    AS_HELP_STRING([--disable-maxoctets], [Disable support for limiting session by maximum octets]))
+AS_IF([test "x$enable_maxoctets" != "xno"],
+    AC_DEFINE([MAXOCTETS], 1, ["Limit sessions by maximum number of octets"]))
+
+#
+# Disable Microsoft extensions will remove CHAP and MPPE support
+AC_ARG_ENABLE([microsoft-extensions],
+    AS_HELP_STRING([--disable-microsoft-extensions], [Disable Microsoft CHAP / MPPE extensions]))
+
+AM_CONDITIONAL(WITH_CHAPMS, test "x${enable_microsoft_extensions}" != "xno")
+AM_COND_IF([WITH_CHAPMS],
+    AC_DEFINE([CHAPMS], 1, ["Have Microsoft CHAP support"]))
+
+AM_CONDITIONAL(WITH_MPPE, test "x${enable_microsoft_extensions}" != "xno")
+AM_COND_IF([WITH_MPPE],
+    AC_DEFINE([MPPE], 1, ["Have Microsoft MPPE support"]))
+
+#
+# Enable Microsoft LAN Manager support, depends on Microsoft Extensions
+AC_ARG_ENABLE([mslanman],
+    AS_HELP_STRING([--enable-mslanman], [Enable Microsoft LAN Manager support]))
+AS_IF([test "x${enable_mslanman}" = "xyes" && test "x${enable_microsoft_extensions}" != "xno"],
+    AC_DEFINE([MSLANMAN], 1, ["Have Microsoft LAN Manager support"]))
+
+#
+# Disable IPv6 support
+AC_ARG_ENABLE([ipv6-support],
+    AS_HELP_STRING([--disable-ipv6-support], [Disable IPv6 support]))
+AM_CONDITIONAL(WITH_INET6, test "x${enable_ipv6_support}" != "xno")
+AM_COND_IF([WITH_INET6],
+    AC_DEFINE(INET6, 1, ["Have IPv6 support"]))
+
+#
+# Disable Multilink support
+AC_ARG_ENABLE([multilink],
+    AS_HELP_STRING([--enable-multilink], [Enable multilink support]))
+AM_CONDITIONAL(WITH_MULTILINK, test "x${enable_multilink}" = "xyes")
+AM_COND_IF([WITH_MULTILINK],
+    AC_DEFINE([HAVE_MULTILINK], 1, ["Have multilink support"]))
+AS_IF([test "x${build_sunos}" = "xyes" && test "x${enable_multilink}" = "xyes"],
+    [AC_MSG_ERROR([Multilink is not supported on SunOS])])
+
+#
+# Multilink require Trivial Database Support
+AM_CONDITIONAL(WITH_TDB, test "x${enable_multilink}" = "xyes")
+AM_COND_IF([WITH_TDB],
+    AC_DEFINE([USE_TDB], 1, ["Include TDB support"]))
+
+#
+# Enable support for loadable plugins
+AC_ARG_ENABLE([plugins],
+    AS_HELP_STRING([--disable-plugins], [Disable support for loadable plugins]))
+AS_IF([test "x$enable_plugins" != "xno"],
+    AC_DEFINE([PLUGIN], 1, ["Have support for loadable plugins"]))
+AM_CONDITIONAL(WITH_PLUGINS, test "${enable_plugins}" != "no")
+
+#
+# Disable EAP-TLS support
+AC_ARG_ENABLE([eaptls],
+    AS_HELP_STRING([--disable-eaptls], [Disable EAP-TLS authentication support]))
+AS_IF([test "x$enable_eaptls" != "xno"],
+    AC_DEFINE([USE_EAPTLS], 1, ["Have EAP-TLS authentication support"]))
+AM_CONDITIONAL(WITH_EAPTLS, test "x${enable_eaptls}" != "xno")
+
+#
+# Disable PEAP support
+AC_ARG_ENABLE([peap],
+    AS_HELP_STRING([--disable-peap], [Disable PEAP authentication support]))
+AS_IF([test "x${enable_peap}" != "xno"],
+    AC_DEFINE([USE_PEAP], 1, ["Have PEAP authentication support"]))
+AM_CONDITIONAL([WITH_PEAP], test "x${enable_peap}" != "xno")
+
+#
+# Disable OpenSSL engine support
+AC_ARG_ENABLE([openssl-engine],
+    AS_HELP_STRING([--disable-openssl-engine], [Disable OpenSSL engine support]))
+AS_IF([test "x$enable_openssl_engine" != "xno"], [],
+    AC_DEFINE([OPENSSL_NO_ENGINE], 1, ["OpenSSL engine support"]))
+
+#
+# Specify runtime directory
+AC_ARG_WITH([plugin-dir],
+       AC_HELP_STRING([--with-plugin-dir=DIR], [Specify the plugin directory for pppd]))
+AS_IF([test -n "$with_plugin_dir"],
+       [PPPD_PLUGIN_DIR="$with_plugin_dir"],
+       [PPPD_PLUGIN_DIR="${libdir}/pppd/$VERSION"])
+AC_SUBST(PPPD_PLUGIN_DIR, "$PPPD_PLUGIN_DIR", [The pppd plugin directory])
+
+#
+# Specify runtime directory
+AC_ARG_WITH([runtime-dir],
+       AC_HELP_STRING([--with-runtime-dir=DIR], [Specify the runtime directory for pppd]))
+AS_IF([test -n "$with_runtime_dir"],
+       [PPPD_RUNTIME_DIR="$with_runtime_dir"],
+       [PPPD_RUNTIME_DIR="${localstatedir}/run/pppd"])
+AC_SUBST(PPPD_RUNTIME_DIR)
+
+#
+# Specify runtime directory
+AC_ARG_WITH([logfile-dir],
+       AC_HELP_STRING([--with-logfile-dir=DIR], [Specify the log directory for pppd]))
+AS_IF([test -n "$with_logfile_dir"],
+       [PPPD_LOGFILE_DIR="$with_logfile_dir"],
+       [PPPD_LOGFILE_DIR="${localstatedir}/log/pppd"])
+AC_SUBST(PPPD_LOGFILE_DIR)
+
+#
+# Check for OpenSSL
+AX_CHECK_OPENSSL
+AM_CONDITIONAL(WITH_OPENSSL, test "${with_openssl}" != "no")
+
+#
+# Check if OpenSSL has compiled in support for various ciphers
+AS_IF([test "x${with_openssl}" != "xno" ], [
+    AX_CHECK_OPENSSL_DEFINE([OPENSSL_NO_MD4], [md4])
+    AX_CHECK_OPENSSL_DEFINE([OPENSSL_NO_MD5], [md5])
+    AX_CHECK_OPENSSL_DEFINE([OPENSSL_NO_DES], [des])
+    AX_CHECK_OPENSSL_DEFINE([OPENSSL_NO_SHA], [sha])
+], [
+    AS_IF([test "x${enable_eaptls}" != "xno" || test "x${enable_peap}" != "xno"],
+        [AC_MSG_ERROR([OpenSSL not found, and if this is your intention then run configure --disable-eaptls and --disable-peap])])
+])
+
+AM_CONDITIONAL([OPENSSL_HAVE_MD4], test "x${ac_cv_openssl_md4}" = "xyes")
+AM_COND_IF([OPENSSL_HAVE_MD4],,
+    AC_DEFINE([USE_MD4], 1, [Use included md4 included with pppd]))
+
+AM_CONDITIONAL([OPENSSL_HAVE_MD5], test "x${ac_cv_openssl_md5}" = "xyes")
+AM_COND_IF([OPENSSL_HAVE_MD5],,
+    AC_DEFINE([USE_MD5], 1, [Use included md5 included with pppd]))
+
+AM_CONDITIONAL([OPENSSL_HAVE_SHA], test "x${ac_cv_openssl_sha}" = "xyes")
+AM_COND_IF([OPENSSL_HAVE_SHA],,
+    AC_DEFINE([USE_SHA], 1, [Use included sha included with pppd]))
+
+AM_CONDITIONAL([OPENSSL_HAVE_DES], test "x${ac_cv_openssl_des}" = "xyes")
+AM_COND_IF([OPENSSL_HAVE_DES],,
+    AC_DEFINE([USE_CRYPT], 1, [Use included des included with pppd]))
+
+#
+# If OpenSSL doesn't support DES, then use the one from libcrypt (glibc dropped support for this in 2.27).
+AS_IF([test "${ac_cv_openssl_des}" = "no" ], [
+    AC_CHECK_LIB([crypt], [encrypt],
+        [LIBS="$LIBS -lcrypt"],
+        [AC_MSG_ERROR([OpenSSL not found or does not support DES, and libcrypt also doesn't support encrypt])]
+    )
+])
+
+#
+# With libsrp support
+AX_CHECK_SRP
+
+#
+# With libatm support
+AX_CHECK_ATM
+
+#
+# With libpam support
+AX_CHECK_PAM(AC_DEFINE([USE_PAM], 1, ["Support for Pluggable Authentication Modules"]))
+AM_CONDITIONAL(WITH_PAM, test "x${with_pam}" = "xyes")
+
+#
+# With libpcap support, activate pppd on network activity
+AX_CHECK_PCAP
+
+#
+# SunOS provides a version of libpcap that would work, but SunOS has no support for activity filter
+AM_CONDITIONAL([WITH_FILTER], [ test "x${with_pcap}" = "xyes" && test "x${build_sunos}" != "xyes" ])
+AM_COND_IF([WITH_FILTER], [
+    AC_DEFINE([PPP_FILTER], 1, ["Have packet activity filter support"])], [
+    AS_IF([test "x${build_sunos}" = "xyes"], [
+        AC_MSG_WARN([Packet activity filter not supported on SunOS])
+        with_pcap="no"
+        ])
+    ])
+
+#
+# Some contributions require GTK/GLIB
+AC_ARG_WITH([gtk], AS_HELP_STRING([--with-gtk], [Build contributions with the GTK+ interface]))
+if test "x${with_gtk}" = "xyes"; then
+    PKG_CHECK_MODULES([GTK], [gtk+-2.0])
+    PKG_CHECK_MODULES([GLIB], [glib-2.0])
+fi
+AM_CONDITIONAL([WITH_GTK], test "x${with_gtk}" = "xyes")
+
+
+AC_CONFIG_FILES([
+    Makefile
+    chat/Makefile
+    contrib/Makefile
+    contrib/pppgetpass/Makefile
+    common/Makefile
+    include/Makefile
+    modules/Makefile
+    pppd/Makefile
+    pppd/pppd.pc
+    pppd/plugins/Makefile
+    pppd/plugins/pppoe/Makefile
+    pppd/plugins/pppoatm/Makefile
+    pppd/plugins/pppol2tp/Makefile
+    pppd/plugins/radius/Makefile
+    pppdump/Makefile
+    pppstats/Makefile
+    scripts/Makefile
+    ])
+AC_OUTPUT
+
+
+AS_IF([test "x${build_sunos}" = "xyes" ], [[
+    echo "
+Setting up SunOS kernel module(s)"
+    mkmkf() {
+        rm -f $2
+        if [ -f $1 ]; then
+            echo "  $2 <= $1"
+            sed -e "s,@DESTDIR@,$prefix,g" \
+                -e "s,@SYSCONF@,$sysconfdir,g" \
+                -e "s,@CC@,$CC,g" \
+                -e "s|@CFLAGS@|$CFLAGS|g" $1 > $2
+        fi
+    }
+
+    release=`uname -r`
+    karch=`/usr/bin/isainfo -k`
+    makext="sol2"
+    archvariant=
+
+    case "$karch" in
+        amd64)
+            archvariant='-64x'
+            ;;
+        sparcv9)
+            archvariant='-64'
+            ;;
+        *)
+            ;;
+    esac
+
+    usegcc=$CC
+    if [ -x /opt/SUNWspro/bin/cc -a "$usegcc" != gcc ] &&
+       /opt/SUNWspro/bin/cc -flags >/dev/null 2>&1; then
+      if [ "$archvariant" = "-64x" ]; then
+        ( cd /tmp; echo "int x;" > ppp$$.c
+         /opt/SUNWspro/bin/cc -c -errwarn -xchip=opteron -m64 ppp$$.c >/dev/null 2>&1 || (
+           echo "WorkShop C is unable to make 64 bit modules, and your $karch system needs"
+           echo "them.  Consider upgrading cc on this machine."
+           rm -f ppp$$.c
+           exit 1
+         ) || exit 1
+         rm -f ppp$$.c ppp$$.o
+        ) || exit 1
+      fi
+    elif gcc --version >/dev/null 2>&1; then
+      archvariant=gcc$archvariant
+      compiletype=.gcc
+      if [ "$archvariant" = "gcc-64" -o"$archvariant" = "gcc-64x" ]; then
+        ( cd /tmp; touch ppp$$.c
+         gcc -c -m64 ppp$$.c >/dev/null 2>&1 || (
+           echo "gcc is unable to make 64 bit modules, and your $karch system needs them."
+           echo "Consider upgrading gcc on this machine, or switching to Sun WorkShop."
+           rm -f ppp$$.c
+           exit 1
+         ) || exit 1
+         rm -f ppp$$.c ppp$$.o
+        ) || exit 1
+      fi
+    else
+      echo "C compiler not found; hoping for the best."
+    fi
+
+    mkmkf solaris/Makedefs$compiletype Makedefs.com
+    mkmkf solaris/Makefile.sol2$archvariant solaris/Makefile
+]])
+
+echo "
+$PACKAGE_NAME version $PACKAGE_VERSION
+    Prefix...............: $prefix
+    Runtime Dir..........: $PPPD_RUNTIME_DIR
+    Logfile Dir..........: $PPPD_LOGFILE_DIR
+    Plugin Dir...........: $PPPD_PLUGIN_DIR
+    With OpenSSL.........: ${with_openssl:-yes}
+    With libatm..........: ${with_atm:-no}
+    With libpam..........: ${with_pam:-no}
+    With libpcap.........: ${with_pcap:-no}
+    With libsrp..........: ${with_srp:-no}
+    C Compiler...........: $CC $CFLAGS
+    Linker...............: $LD $LDFLAGS $LIBS
+
+Features enabled
+    Microsoft Extensions.: ${enable_microsoft_extensions:-yes}
+    Multilink............: ${enable_multilink:-no}
+    Plugins..............: ${enable_plugins:-yes}
+    CBCP.................: ${enable_cbcp:-no}
+    IPXCP................: ${enable_ipxcp:-no}
+    EAP-TLS..............: ${enable_eaptls:-yes}
+    PEAP.................: ${enable_peap:-yes}
+"
diff --git a/contrib/Makefile.am b/contrib/Makefile.am
new file mode 100644 (file)
index 0000000..fb9a390
--- /dev/null
@@ -0,0 +1 @@
+SUBDIRS = pppgetpass
diff --git a/contrib/pppgetpass/.gitignore b/contrib/pppgetpass/.gitignore
new file mode 100644 (file)
index 0000000..1b8a1c8
--- /dev/null
@@ -0,0 +1,2 @@
+pppgetpass.vt
+pppgetpass.gtk
diff --git a/contrib/pppgetpass/Makefile.am b/contrib/pppgetpass/Makefile.am
new file mode 100644 (file)
index 0000000..530e82f
--- /dev/null
@@ -0,0 +1,17 @@
+noinst_PROGRAMS = pppgetpass.vt
+noinst_man8_MANS = pppgetpass.8
+
+pppgetpass_vt_SOURCES = pppgetpass.vt.c
+pppgetpass_vt_CPPFLAGS = -Wno-unused-result
+
+if WITH_GTK
+noinst_PROGRAMS += pppgetpass.gtk
+
+pppgetpass_gtk_SOURCES = pppgetpass.gtk.c
+pppgetpass_gtk_CPPFLAGS = -Wno-deprecated-declarations -Wno-discarded-qualifiers
+pppgetpass_gtk_CPPFLAGS += $(GLIB_CFLAGS) $(GTK_CFLAGS)
+pppgetpass_gtk_LDADD = $(GLIB_LIBS) $(GTK_LIBS)
+endif
+
+EXTRA_DIST = \
+    pppgetpass.sh
diff --git a/contrib/pppgetpass/Makefile.linux b/contrib/pppgetpass/Makefile.linux
deleted file mode 100644 (file)
index eb16f5b..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-all: pppgetpass.vt pppgetpass.gtk
-
-pppgetpass.vt: pppgetpass.vt.o
-
-pppgetpass.gtk: pppgetpass.gtk.o
-       $(CC) $(LDFLAGS) pppgetpass.gtk.o -o pppgetpass.gtk `pkg-config --libs glib-2.0 gtk+-2.0`
-pppgetpass.gtk.o: pppgetpass.gtk.c
-       $(CC) $(CFLAGS) -c pppgetpass.gtk.c `pkg-config --cflags glib-2.0 gtk+-2.0`
-
-install: all
-       install -m 755 pppgetpass.sh /usr/bin/pppgetpass
-       install -m 4755 -o root -g root pppgetpass.vt /usr/bin/
-       install -m 755 -o root -g root pppgetpass.gtk /usr/X11/bin/
-
-clean:
-       rm -f *.o pppgetpass.gtk pppgetpass.vt core
diff --git a/include/Makefile.am b/include/Makefile.am
new file mode 100644 (file)
index 0000000..2a576c1
--- /dev/null
@@ -0,0 +1,13 @@
+EXTRA_HEADERS = \
+    linux/if_ppp.h \
+    linux/ppp-comp.h \
+    linux/ppp_defs.h \
+    net/if_ppp.h \
+    net/ppp-comp.h \
+    net/ppp_defs.h \
+    net/pppio.h \
+    net/slcompress.h \
+    net/vjcompress.h
+
+EXTRA_DIST = \
+    $(EXTRA_HEADERS)
diff --git a/linux/Makefile.top b/linux/Makefile.top
deleted file mode 100644 (file)
index 894f8f3..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-# PPP top-level Makefile for Linux.
-
-DESTDIR = $(INSTROOT)@DESTDIR@
-BINDIR = $(DESTDIR)/sbin
-INCDIR = $(DESTDIR)/include
-MANDIR = $(DESTDIR)/share/man
-ETCDIR = $(INSTROOT)@SYSCONF@/ppp
-
-# uid 0 = root
-INSTALL= install
-
-all:
-       cd chat; $(MAKE) $(MFLAGS) all
-       cd pppd/plugins; $(MAKE) $(MFLAGS) all
-       cd pppd; $(MAKE) $(MFLAGS) all
-       cd pppstats; $(MAKE) $(MFLAGS) all
-       cd pppdump; $(MAKE) $(MFLAGS) all
-
-install: $(BINDIR) $(MANDIR)/man8 install-progs install-devel
-
-install-progs:
-       cd chat; $(MAKE) $(MFLAGS) install
-       cd pppd/plugins; $(MAKE) $(MFLAGS) install
-       cd pppd; $(MAKE) $(MFLAGS) install
-       cd pppstats; $(MAKE) $(MFLAGS) install
-       cd pppdump; $(MAKE) $(MFLAGS) install
-
-install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \
-       $(ETCDIR)/chap-secrets $(ETCDIR)/eaptls-server $(ETCDIR)/eaptls-client
-
-install-devel:
-       cd pppd; $(MAKE) $(MFLAGS) install-devel
-
-$(ETCDIR)/options:
-       $(INSTALL) -c -m 644 etc.ppp/options $@
-$(ETCDIR)/pap-secrets:
-       $(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 $@
-$(MANDIR)/man8:
-       $(INSTALL) -d -m 755 $@
-$(ETCDIR):
-       $(INSTALL) -d -m 755 $@
-
-clean:
-       rm -f `find . -name '*.[oas]' -print`
-       rm -f `find . -name 'core' -print`
-       rm -f `find . -name '*~' -print`
-       cd chat; $(MAKE) clean
-       cd pppd/plugins; $(MAKE) clean
-       cd pppd; $(MAKE) clean
-       cd pppstats; $(MAKE) clean
-       cd pppdump; $(MAKE) clean
-
-dist-clean:    clean
-       rm -f Makefile `find . -name Makefile -print`
-
-#kernel:
-#      cd linux; ./kinstall.sh
-
-# no tests yet, one day...
-installcheck:
-       true
diff --git a/m4/ax_check_atm.m4 b/m4/ax_check_atm.m4
new file mode 100644 (file)
index 0000000..004fe9f
--- /dev/null
@@ -0,0 +1,93 @@
+# SYNOPSIS
+#
+#   AX_CHECK_ATM([action-if-found[, action-if-not-found]])
+#
+# DESCRIPTION
+#
+#   Look for libatm in a number of default locations, or in a provided location
+#   (via --with-atm=). Sets
+#       ATM_CFLAGS
+#       ATM_LDFLAGS
+#       ATM_LIBS
+#
+#   and calls ACTION-IF-FOUND or ACTION-IF-NOT-FOUND appropriately
+#
+# LICENSE
+#
+#   Copyright (c) 2021 Eivind Naess <eivnaes@yahoo.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 1
+
+AC_DEFUN([AX_CHECK_ATM], [
+    AC_ARG_WITH([atm],
+        [AS_HELP_STRING([--with-atm=DIR],
+            [With libatm support, see http://linux-atm.sourceforge.net])],
+        [
+            case "$withval" in
+            "" | y | ye | yes)
+                atmdirs="/usr/local /usr/lib /usr"  
+              ;;
+            n | no)
+                with_atm="no"
+              ;;
+            *)
+                atmdirs="$withval"
+              ;;
+            esac
+        ])
+    
+    if [ test "x${with_atm}" != "xno" ] ; then
+        ATM_LIBS="-latm"
+        for atmdir in $atmdirs; do
+            AC_MSG_CHECKING([for atm.h in $atmdir])
+            if test -f "$atmdir/include/atm.h"; then
+                ATM_CFLAGS="-I$atmdir/include"
+                ATM_LDFLAGS="-L$atmdir/lib"
+                AC_MSG_RESULT([yes])
+                break
+            else
+                AC_MSG_RESULT([no])
+            fi
+        done
+
+        # try the preprocessor and linker with our new flags,
+        # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS
+
+        AC_MSG_CHECKING([if compiling and linking against libatm works])
+
+        save_LIBS="$LIBS"
+        save_LDFLAGS="$LDFLAGS"
+        save_CPPFLAGS="$CPPFLAGS"
+        LDFLAGS="$LDFLAGS $ATM_LDFLAGS"
+        LIBS="$ATM_LIBS $LIBS"
+        CPPFLAGS="$ATM_CFLAGS $CPPFLAGS"
+        AC_LINK_IFELSE(
+            [AC_LANG_PROGRAM(
+                [#include <atm.h>
+                 #include <stddef.h>], 
+                [text2atm(NULL,NULL,0,0);])],
+            [
+                AC_MSG_RESULT([yes])
+                with_atm=yes
+                $1
+            ], [
+                AC_MSG_RESULT([no])
+                with_atm=""
+                $2
+            ])
+        CPPFLAGS="$save_CPPFLAGS"
+        LDFLAGS="$save_LDFLAGS"
+        LIBS="$save_LIBS"
+
+        AC_SUBST([ATM_CFLAGS])
+        AC_SUBST([ATM_LIBS])
+        AC_SUBST([ATM_LDFLAGS])
+    fi
+    AM_CONDITIONAL(WITH_LIBATM, test -n "${with_atm}")
+])
+
diff --git a/m4/ax_check_openssl.m4 b/m4/ax_check_openssl.m4
new file mode 100644 (file)
index 0000000..8ae39ca
--- /dev/null
@@ -0,0 +1,119 @@
+# ===========================================================================
+#     http://www.gnu.org/software/autoconf-archive/ax_check_openssl.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CHECK_OPENSSL([action-if-found[, action-if-not-found]])
+#
+# DESCRIPTION
+#
+#   Look for OpenSSL in a number of default spots, or in a user-selected
+#   spot (via --with-openssl).  Sets
+#
+#     OPENSSL_INCLUDES to the include directives required
+#     OPENSSL_LIBS to the -l directives required
+#     OPENSSL_LDFLAGS to the -L or -R flags required
+#
+#   and calls ACTION-IF-FOUND or ACTION-IF-NOT-FOUND appropriately
+#
+#   This macro sets OPENSSL_INCLUDES such that source files should use the
+#   openssl/ directory in include directives:
+#
+#     #include <openssl/hmac.h>
+#
+# LICENSE
+#
+#   Copyright (c) 2009,2010 Zmanda Inc. <http://www.zmanda.com/>
+#   Copyright (c) 2009,2010 Dustin J. Mitchell <dustin@zmanda.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 9
+
+AU_ALIAS([CHECK_SSL], [AX_CHECK_OPENSSL])
+AC_DEFUN([AX_CHECK_OPENSSL], [
+    found=false
+    AC_ARG_WITH([openssl],
+        [AS_HELP_STRING([--with-openssl=DIR],
+            [With openssl support, see http://www.openssl.org])],
+        [
+            case "$withval" in
+            "" | y | ye | yes )
+                ssldirs="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr"
+              ;;
+            n | no )
+              ;;
+            *) ssldirs="$withval"
+              ;;
+            esac
+        ], [
+            ssldirs="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr"
+        ])
+
+    AS_IF([test "${with_openssl}" != "no"], [
+        OPENSSL_INCLUDES=
+        for ssldir in $ssldirs; do
+            AC_MSG_CHECKING([for openssl/ssl.h in $ssldir])
+            AS_IF([ test -f "$ssldir/include/openssl/ssl.h" ], [
+                OPENSSL_INCLUDES="-I$ssldir/include"
+                OPENSSL_LDFLAGS="-L$ssldir/lib"
+                OPENSSL_LIBS="-lssl -lcrypto"
+                found=true
+                AC_MSG_RESULT([yes])
+                break
+            ], [
+                AC_MSG_RESULT([no])
+            ])
+        done])
+     
+    AS_IF([test "${with_openssl}" != "no" && test ! ${found}], [ 
+        # if pkg-config is installed and openssl has installed a .pc file,
+        # then use that information and don't search ssldirs
+        AC_PATH_PROG([PKG_CONFIG], [pkg-config])
+        if test x"$PKG_CONFIG" != x""; then
+            OPENSSL_LDFLAGS=`$PKG_CONFIG openssl --libs-only-L 2>/dev/null`
+            if test $? = 0; then
+                OPENSSL_LIBS=`$PKG_CONFIG openssl --libs-only-l 2>/dev/null`
+                OPENSSL_INCLUDES=`$PKG_CONFIG openssl --cflags-only-I 2>/dev/null`
+                found=true
+            fi
+        fi
+    ])
+
+    AS_IF([test "${with_openssl}" != "no" && test ${found}], [
+
+        # try the preprocessor and linker with our new flags,
+        # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS
+
+        AC_MSG_CHECKING([whether compiling and linking against OpenSSL works])
+        echo "Trying link with OPENSSL_LDFLAGS=$OPENSSL_LDFLAGS;" \
+            "OPENSSL_LIBS=$OPENSSL_LIBS; OPENSSL_INCLUDES=$OPENSSL_INCLUDES" >&AS_MESSAGE_LOG_FD
+
+        save_LIBS="$LIBS"
+        save_LDFLAGS="$LDFLAGS"
+        save_CPPFLAGS="$CPPFLAGS"
+        LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS"
+        LIBS="$OPENSSL_LIBS $LIBS"
+        CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS"
+        AC_LINK_IFELSE(
+            [AC_LANG_PROGRAM([#include <openssl/ssl.h>], [SSL_new(NULL)])],
+            [
+                AC_MSG_RESULT([yes])
+                $1
+            ], [
+                AC_MSG_RESULT([no])
+                $2
+            ])
+        CPPFLAGS="$save_CPPFLAGS"
+        LDFLAGS="$save_LDFLAGS"
+        LIBS="$save_LIBS"
+
+        AC_SUBST([OPENSSL_INCLUDES])
+        AC_SUBST([OPENSSL_LIBS])
+        AC_SUBST([OPENSSL_LDFLAGS])
+    ], [ $2 ])
+])
diff --git a/m4/ax_check_openssl_func.m4 b/m4/ax_check_openssl_func.m4
new file mode 100644 (file)
index 0000000..d269af8
--- /dev/null
@@ -0,0 +1,44 @@
+# SYNOPSIS
+#
+#   AX_CHECK_OPENSSL_DEFINE([DEFINE], [VAR][, action-if-found[, action-if-not-found]])
+#
+# DESCRIPTION
+#
+#   Check if OpenSSL has a define set in it's features provided, i.e. OPENSSL_NO_MD4.
+#   If so, the var argument ac_cv_openssl_[VAR] is set to yes, and action-is-found is
+#   run, else action-if-not-found is executed.
+#
+#   This module require AX_CHECK_OPENSSL
+#
+# LICENSE
+#
+#   Copyright (c) 2021 Eivind Naess <eivnaes@yahoo.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 1
+
+AC_DEFUN([AX_CHECK_OPENSSL_DEFINE], [
+    AC_REQUIRE([AX_CHECK_OPENSSL])
+    AC_MSG_CHECKING([for $2 support in openssl])
+    save_CPPFLAGS="$CPPFLAGS"
+    CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS"
+    AC_PREPROC_IFELSE([
+        AC_LANG_PROGRAM(
+            [[@%:@include <openssl/opensslconf.h>]],
+            [[#ifdef $1
+              #error "No support for $1"
+              #endif]])],
+        AC_MSG_RESULT([yes])
+        [ac_cv_openssl_$2=yes]
+        $3,
+        AC_MSG_RESULT([no])
+        [ac_cv_openssl_$2=no]
+        $4
+    )
+    CPPFLAGS="$save_CPPFLAGS"
+])
+
diff --git a/m4/ax_check_pam.m4 b/m4/ax_check_pam.m4
new file mode 100644 (file)
index 0000000..edb30e3
--- /dev/null
@@ -0,0 +1,93 @@
+# SYNOPSIS
+#
+#   AX_CHECK_PAM([action-if-found[, action-if-not-found]])
+#
+# DESCRIPTION
+#
+#   Look for libpam in a number of default locations, or in a provided location
+#   (via --with-pam=). Sets
+#       PAM_CFLAGS
+#       PAM_LDFLAGS
+#       PAM_LIBS
+#
+#   and calls ACTION-IF-FOUND or ACTION-IF-NOT-FOUND appropriately
+#
+# LICENSE
+#
+#   Copyright (c) 2021 Eivind Naess <eivnaes@yahoo.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 1
+
+AC_DEFUN([AX_CHECK_PAM], [
+    AC_ARG_WITH([pam],
+        [AS_HELP_STRING([--with-pam=DIR],
+            [With libpam support, see ftp.redhat.com:/pub/pam])],
+        [
+            case "$withval" in
+            "" | y | ye | yes)
+                pamdirs="/usr/local /usr/lib /usr"  
+              ;;
+            n | no)
+                with_pam="no"
+              ;;
+            *)
+                pamdirs="$withval"
+              ;;
+            esac
+        ])
+    
+    if [ test "x${with_pam}" != "xno" ] ; then
+        PAM_LIBS="-lpam"
+        for pamdir in $pamdirs; do
+            AC_MSG_CHECKING([for pam_appl.h in $pamdir])
+            if test -f "$pamdir/include/security/pam_appl.h"; then
+                PAM_CFLAGS="-I$pamdir/include"
+                PAM_LDFLAGS="-L$pamdir/lib"
+                AC_MSG_RESULT([yes])
+                break
+            else
+                AC_MSG_RESULT([no])
+            fi
+        done
+
+        # try the preprocessor and linker with our new flags,
+        # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS
+
+        AC_MSG_CHECKING([if compiling and linking against libpam works])
+
+        save_LIBS="$LIBS"
+        save_LDFLAGS="$LDFLAGS"
+        save_CPPFLAGS="$CPPFLAGS"
+        LDFLAGS="$LDFLAGS $PAM_LDFLAGS"
+        LIBS="$PAM_LIBS $LIBS"
+        CPPFLAGS="$PAM_CFLAGS $CPPFLAGS"
+        AC_LINK_IFELSE(
+            [AC_LANG_PROGRAM(
+                [#include <security/pam_appl.h>
+                 #include <stddef.h>], 
+                [pam_authenticate(NULL, 0);])],
+            [
+                AC_MSG_RESULT([yes])
+                with_pam=yes
+                $1
+            ], [
+                AC_MSG_RESULT([no])
+                with_pam=""
+                $2
+            ])
+        CPPFLAGS="$save_CPPFLAGS"
+        LDFLAGS="$save_LDFLAGS"
+        LIBS="$save_LIBS"
+
+        AC_SUBST([PAM_CFLAGS])
+        AC_SUBST([PAM_LIBS])
+        AC_SUBST([PAM_LDFLAGS])
+    fi
+    AM_CONDITIONAL(WITH_LIBPAM, test -n "${with_pam}")
+])
+
diff --git a/m4/ax_check_pcap.m4 b/m4/ax_check_pcap.m4
new file mode 100644 (file)
index 0000000..6d70ec1
--- /dev/null
@@ -0,0 +1,93 @@
+# SYNOPSIS
+#
+#   AX_CHECK_PCAP([action-if-found[, action-if-not-found]]
+#
+# DESCRIPTION
+#
+#   Look for libpcap in a number of default locations, or in a provided location
+#   (via --with-pcap=). Sets
+#       PCAP_CFLAGS
+#       PCAP_LDFLAGS
+#       PCAP_LIBS
+#
+#   and calls ACTION-IF-FOUND or ACTION-IF-NOT-FOUND appropriately
+#
+# LICENSE
+#
+#   Copyright (c) 2021 Eivind Naess <eivnaes@yahoo.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 1
+
+AC_DEFUN([AX_CHECK_PCAP], [
+    AC_ARG_WITH([pcap],
+        [AS_HELP_STRING([--with-pcap=DIR],
+            [With libpcap support, see https://www.tcpdump.org])],
+        [
+            case "$withval" in
+            "" | y | ye | yes)
+                pcapdirs="/usr/local /usr/lib /usr"  
+              ;;
+            n | no)
+                with_pcap="no"
+              ;;
+            *)
+                pcapdirs="$withval"
+              ;;
+            esac
+        ])
+    
+    if [ test "x${with_pcap}" != "xno" ] ; then
+        PCAP_LIBS="-lpcap"
+        for pcapdir in $pcapdirs; do
+            AC_MSG_CHECKING([for pcap.h in $pcapdir])
+            if test -f "$pcapdir/include/pcap.h"; then
+                PCAP_CFLAGS="-I$pcapdir/include"
+                PCAP_LDFLAGS="-L$pcapdir/lib"
+                AC_MSG_RESULT([yes])
+                break
+            else
+                AC_MSG_RESULT([no])
+            fi
+        done
+
+        # try the preprocessor and linker with our new flags,
+        # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS
+
+        AC_MSG_CHECKING([if compiling and linking against libpcap works])
+
+        save_LIBS="$LIBS"
+        save_LDFLAGS="$LDFLAGS"
+        save_CPPFLAGS="$CPPFLAGS"
+        LDFLAGS="$PCAP_LDFLAGS $LDFLAGS"
+        LIBS="$PCAP_LIBS $LIBS"
+        CPPFLAGS="$PCAP_CFLAGS $CPPFLAGS"
+        AC_LINK_IFELSE(
+            [AC_LANG_PROGRAM(
+                [@%:@include <pcap.h>],
+                [pcap_create(0,0);])],
+            [
+                AC_MSG_RESULT([yes])
+                with_pcap=yes
+                $1
+            ], [
+                AC_MSG_RESULT([no])
+                with_pcap=""
+                $2
+            ])
+        CPPFLAGS="$save_CPPFLAGS"
+        LDFLAGS="$save_LDFLAGS"
+        LIBS="$save_LIBS"
+
+        AC_SUBST([PCAP_CFLAGS])
+        AC_SUBST([PCAP_LIBS])
+        AC_SUBST([PCAP_LDFLAGS])
+    fi
+
+    AM_CONDITIONAL(WITH_PCAP, test -n "${with_pcap}")
+])
+
diff --git a/m4/ax_check_srp.m4 b/m4/ax_check_srp.m4
new file mode 100644 (file)
index 0000000..631341d
--- /dev/null
@@ -0,0 +1,94 @@
+# SYNOPSIS
+#
+#   AX_CHECK_SRP([action-if-found[, action-if-not-found]])
+#
+# DESCRIPTION
+#
+#   Look for libsrp in a number of default locations, or in a provided location
+#   (via --with-srp=). Sets
+#       SRP_CFLAGS
+#       SRP_LDFLAGS
+#       SRP_LIBS
+#
+#   and calls ACTION-IF-FOUND or ACTION-IF-NOT-FOUND appropriately
+#
+# LICENSE
+#
+#   Copyright (c) 2021 Eivind Naess <eivnaes@yahoo.com>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 1
+
+AC_DEFUN([AX_CHECK_SRP], [
+    AC_ARG_WITH([srp],
+        [AS_HELP_STRING([--with-srp=DIR],
+            [With libsrp support, see http://srp.stanford.edu])],
+        [
+            case "$withval" in
+            "" | y | ye | yes)
+                srpdirs="/usr/local /usr/lib /usr"  
+              ;;
+            n | no)
+                with_srp="no"
+              ;;
+            *)
+                srpdirs="$withval"
+              ;;
+            esac
+        ])
+    
+    if [ test "x${with_srp}" != "xno" ] ; then
+        SRP_LIBS="-lsrp"
+        for srpdir in $srpdirs; do
+            AC_MSG_CHECKING([for srp.h in $srpdir])
+            if test -f "$srpdir/include/srp.h"; then
+                SRP_CFLAGS="-I$srpdir/include"
+                SRP_LDFLAGS="-L$srpdir/lib"
+                AC_MSG_RESULT([yes])
+                break
+            else
+                AC_MSG_RESULT([no])
+            fi
+        done
+
+        # try the preprocessor and linker with our new flags,
+        # being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS
+
+        AC_MSG_CHECKING([if compiling and linking against libsrp works])
+
+        save_LIBS="$LIBS"
+        save_LDFLAGS="$LDFLAGS"
+        save_CPPFLAGS="$CPPFLAGS"
+        LDFLAGS="$SRP_LDFLAGS $OPENSSL_LDFLAGS $LDFLAGS"
+        LIBS="$SRP_LIBS $OPENSSL_LIBS $LIBS"
+        CPPFLAGS="$SRP_CFLAGS $OPENSSL_INCLUDES $CPPFLAGS"
+        AC_LINK_IFELSE(
+            [AC_LANG_PROGRAM(
+                [#include <srp.h>
+                 #include <stddef.h>], 
+                [SRP_use_engine(NULL);])],
+            [
+                AC_MSG_RESULT([yes])
+                with_srp=yes
+                $1
+            ], [
+                AC_MSG_RESULT([no])
+                with_srp=""
+                $2
+            ])
+        CPPFLAGS="$save_CPPFLAGS"
+        LDFLAGS="$save_LDFLAGS"
+        LIBS="$save_LIBS"
+
+        AC_SUBST([SRP_CFLAGS])
+        AC_SUBST([SRP_LIBS])
+        AC_SUBST([SRP_LDFLAGS])
+    fi
+
+    AM_CONDITIONAL(WITH_SRP, test -n "${with_srp}")
+])
+
diff --git a/m4/pkg.m4 b/m4/pkg.m4
new file mode 100644 (file)
index 0000000..13a8890
--- /dev/null
+++ b/m4/pkg.m4
@@ -0,0 +1,275 @@
+# pkg.m4 - Macros to locate and utilise pkg-config.   -*- Autoconf -*-
+# serial 12 (pkg-config-0.29.2)
+
+dnl Copyright Â© 2004 Scott James Remnant <scott@netsplit.com>.
+dnl Copyright Â© 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 2 of the License, or
+dnl (at your option) any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful, but
+dnl WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+dnl General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+dnl 02111-1307, USA.
+dnl
+dnl As a special exception to the GNU General Public License, if you
+dnl distribute this file as part of a program that contains a
+dnl configuration script generated by Autoconf, you may include it under
+dnl the same distribution terms that you use for the rest of that
+dnl program.
+
+dnl PKG_PREREQ(MIN-VERSION)
+dnl -----------------------
+dnl Since: 0.29
+dnl
+dnl Verify that the version of the pkg-config macros are at least
+dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
+dnl installed version of pkg-config, this checks the developer's version
+dnl of pkg.m4 when generating configure.
+dnl
+dnl To ensure that this macro is defined, also add:
+dnl m4_ifndef([PKG_PREREQ],
+dnl     [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
+dnl
+dnl See the "Since" comment for each macro you use to see what version
+dnl of the macros you require.
+m4_defun([PKG_PREREQ],
+[m4_define([PKG_MACROS_VERSION], [0.29.2])
+m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
+    [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
+])dnl PKG_PREREQ
+
+dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
+dnl ----------------------------------
+dnl Since: 0.16
+dnl
+dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
+dnl first found in the path. Checks that the version of pkg-config found
+dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
+dnl used since that's the first version where most current features of
+dnl pkg-config existed.
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
+m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
+AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
+AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+       AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+       _pkg_min_version=m4_default([$1], [0.9.0])
+       AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+       if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+               AC_MSG_RESULT([yes])
+       else
+               AC_MSG_RESULT([no])
+               PKG_CONFIG=""
+       fi
+fi[]dnl
+])dnl PKG_PROG_PKG_CONFIG
+
+dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------------------------------
+dnl Since: 0.18
+dnl
+dnl Check to see whether a particular set of modules exists. Similar to
+dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
+dnl
+dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+dnl only at the first occurence in configure.ac, so if the first place
+dnl it's called might be skipped (such as if it is within an "if", you
+dnl have to call PKG_CHECK_EXISTS manually
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+    AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+  m4_default([$2], [:])
+m4_ifvaln([$3], [else
+  $3])dnl
+fi])
+
+dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+dnl ---------------------------------------------
+dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
+dnl pkg_failed based on the result.
+m4_define([_PKG_CONFIG],
+[if test -n "$$1"; then
+    pkg_cv_[]$1="$$1"
+ elif test -n "$PKG_CONFIG"; then
+    PKG_CHECK_EXISTS([$3],
+                     [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
+                     test "x$?" != "x0" && pkg_failed=yes ],
+                    [pkg_failed=yes])
+ else
+    pkg_failed=untried
+fi[]dnl
+])dnl _PKG_CONFIG
+
+dnl _PKG_SHORT_ERRORS_SUPPORTED
+dnl ---------------------------
+dnl Internal check to see if pkg-config supports short errors.
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi[]dnl
+])dnl _PKG_SHORT_ERRORS_SUPPORTED
+
+
+dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl   [ACTION-IF-NOT-FOUND])
+dnl --------------------------------------------------------------
+dnl Since: 0.4.0
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
+dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $2])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+        AC_MSG_RESULT([no])
+        _PKG_SHORT_ERRORS_SUPPORTED
+        if test $_pkg_short_errors_supported = yes; then
+               $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
+        else
+               $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
+        fi
+       # Put the nasty error message in config.log where it belongs
+       echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+       m4_default([$4], [AC_MSG_ERROR(
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT])[]dnl
+        ])
+elif test $pkg_failed = untried; then
+        AC_MSG_RESULT([no])
+       m4_default([$4], [AC_MSG_FAILURE(
+[The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
+        ])
+else
+       $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+       $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+        AC_MSG_RESULT([yes])
+       $3
+fi[]dnl
+])dnl PKG_CHECK_MODULES
+
+
+dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+dnl   [ACTION-IF-NOT-FOUND])
+dnl ---------------------------------------------------------------------
+dnl Since: 0.29
+dnl
+dnl Checks for existence of MODULES and gathers its build flags with
+dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
+dnl and VARIABLE-PREFIX_LIBS from --libs.
+dnl
+dnl Note that if there is a possibility the first call to
+dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
+dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
+dnl configure.ac.
+AC_DEFUN([PKG_CHECK_MODULES_STATIC],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+_save_PKG_CONFIG=$PKG_CONFIG
+PKG_CONFIG="$PKG_CONFIG --static"
+PKG_CHECK_MODULES($@)
+PKG_CONFIG=$_save_PKG_CONFIG[]dnl
+])dnl PKG_CHECK_MODULES_STATIC
+
+
+dnl PKG_INSTALLDIR([DIRECTORY])
+dnl -------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable pkgconfigdir as the location where a module
+dnl should install pkg-config .pc files. By default the directory is
+dnl $libdir/pkgconfig, but the default can be changed by passing
+dnl DIRECTORY. The user can override through the --with-pkgconfigdir
+dnl parameter.
+AC_DEFUN([PKG_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+    [pkg-config installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([pkgconfigdir],
+    [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
+    [with_pkgconfigdir=]pkg_default)
+AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_INSTALLDIR
+
+
+dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
+dnl --------------------------------
+dnl Since: 0.27
+dnl
+dnl Substitutes the variable noarch_pkgconfigdir as the location where a
+dnl module should install arch-independent pkg-config .pc files. By
+dnl default the directory is $datadir/pkgconfig, but the default can be
+dnl changed by passing DIRECTORY. The user can override through the
+dnl --with-noarch-pkgconfigdir parameter.
+AC_DEFUN([PKG_NOARCH_INSTALLDIR],
+[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
+m4_pushdef([pkg_description],
+    [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
+AC_ARG_WITH([noarch-pkgconfigdir],
+    [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
+    [with_noarch_pkgconfigdir=]pkg_default)
+AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
+m4_popdef([pkg_default])
+m4_popdef([pkg_description])
+])dnl PKG_NOARCH_INSTALLDIR
+
+
+dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+dnl -------------------------------------------
+dnl Since: 0.28
+dnl
+dnl Retrieves the value of the pkg-config variable for the given module.
+AC_DEFUN([PKG_CHECK_VAR],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
+
+_PKG_CONFIG([$1], [variable="][$3]["], [$2])
+AS_VAR_COPY([$1], [pkg_cv_][$1])
+
+AS_VAR_IF([$1], [""], [$5], [$4])dnl
+])dnl PKG_CHECK_VAR
diff --git a/modules/Makefile.am b/modules/Makefile.am
new file mode 100644 (file)
index 0000000..ddd53bc
--- /dev/null
@@ -0,0 +1,12 @@
+EXTRA_MODULE = \
+    bsd-comp.c \
+    deflate.c \
+    if_ppp.c \
+    ppp_ahdlc.c \
+    ppp.c \
+    ppp_comp.c \
+    ppp_mod.h \
+    vjcompress.c
+
+EXTRA_DIST = \
+    $(EXTRA_MODULE)
diff --git a/pppd/Makefile.am b/pppd/Makefile.am
new file mode 100644 (file)
index 0000000..e6aaac0
--- /dev/null
@@ -0,0 +1,197 @@
+sbin_PROGRAMS = pppd
+dist_man8_MANS = pppd.8
+check_PROGRAMS =
+
+utest_chap_SOURCES = chap_ms.c pppcrypt.c utils.c
+utest_chap_CPPFLAGS = -DUNIT_TEST
+utest_chap_LDFLAGS =
+
+utest_peap_SOURCES = peap.c utils.c mppe.c
+utest_peap_CPPFLAGS = -DUNIT_TEST -I${top_srcdir}/include
+utest_peap_LDFLAGS =
+
+if WITH_SRP
+sbin_PROGRAMS += srp-entry
+dist_man8_MANS += srp-entry.8
+endif
+
+pkgconfigdir   = $(libdir)/pkgconfig
+pkgconfig_DATA = pppd.pc
+
+pppd_includedir = $(includedir)/pppd
+pppd_include_HEADERS = \
+    cbcp.h \
+    ccp.h \
+    chap-md5.h \
+    chap_ms.h \
+    chap-new.h \
+    eap.h \
+    eap-tls.h \
+    ecp.h \
+    eui64.h \
+    fsm.h \
+    ipcp.h \
+    ipv6cp.h \
+    ipxcp.h \
+    lcp.h \
+    magic.h \
+    md4.h \
+    md5.h \
+    mppe.h \
+    patchlevel.h \
+    pathnames.h \
+    peap.h \
+    pppcrypt.h \
+    pppd.h \
+    pppdconf.h \
+    session.h \
+    sha1.h \
+    spinlock.h \
+    tls.h \
+    tdb.h \
+    upap.h 
+
+pppd_SOURCES = \
+    auth.c \
+    ccp.c \
+    chap-md5.c \
+    chap-new.c \
+    demand.c \
+    eap.c \
+    ecp.c \
+    fsm.c \
+    ipcp.c \
+    lcp.c \
+    magic.c \
+    main.c \
+    options.c \
+    session.c \
+    tty.c \
+    upap.c \
+    utils.c
+
+pppd_CPPFLAGS = -I${top_srcdir}/include -DPPPD_RUNTIME_DIR='"@PPPD_RUNTIME_DIR@"' -DPPPD_LOGFILE_DIR='"@PPPD_LOGFILE_DIR@"'
+pppd_LDFLAGS =
+pppd_LIBS =
+
+if LINUX
+pppd_SOURCES += sys-linux.c termios_linux.h
+pppd_LIBS += $(CRYPT_LIBS) $(UTIL_LIBS)
+endif
+
+if SUNOS
+pppd_SOURCES += sys-solaris.c
+pppd_LIBS += -lsocket -lnsl
+endif
+
+if WITH_CHAPMS
+pppd_SOURCES += chap_ms.c
+pppd_SOURCES += pppcrypt.c
+check_PROGRAMS += utest_chap
+else
+if WITH_SRP
+pppd_SOURCES += pppcrypt.c
+endif
+endif
+
+if WITH_CBCP
+pppd_SOURCES += cbcp.c
+endif
+
+if WITH_IPXCP
+pppd_SOURCES += ipxcp.c
+endif
+
+if WITH_MPPE
+pppd_SOURCES += mppe.c
+endif
+
+if WITH_FILTER
+pppd_CPPFLAGS += $(PCAP_CFLAGS)
+pppd_LDFLAGS += $(PCAP_LDFLAGS)
+pppd_LIBS += $(PCAP_LIBS)
+endif
+
+if WITH_PLUGINS
+pppd_CPPFLAGS += -DPPPD_PLUGIN_DIR='"@PPPD_PLUGIN_DIR@"'
+pppd_LIBS += -ldl
+if LINUX
+pppd_LDFLAGS += -Wl,-E
+endif
+endif
+
+if WITH_MULTILINK
+pppd_SOURCES += multilink.c
+endif
+
+if WITH_TDB
+pppd_SOURCES += tdb.c spinlock.c
+endif
+
+if WITH_INET6
+pppd_SOURCES += ipv6cp.c eui64.c
+endif
+
+if WITH_PAM
+pppd_LIBS += -lpam -ldl
+endif
+
+if WITH_EAPTLS
+pppd_SOURCES += eap-tls.c tls.c
+else
+if WITH_PEAP
+pppd_SOURCES += tls.c
+endif
+endif
+
+if WITH_PEAP
+pppd_SOURCES += peap.c
+check_PROGRAMS += utest_peap
+endif
+
+noinst_LTLIBRARIES = libppp_crypt.la
+libppp_crypt_la_SOURCES=
+
+if !WITH_OPENSSL
+libppp_crypt_la_SOURCES += md4.c md5.c sha1.c
+else
+libppp_crypt_la_CPPFLAGS=$(OPENSSL_INCLUDES)
+libppp_crypt_la_LDFLAGS=$(OPENSSL_LDFLAGS)
+libppp_crypt_la_LIBADD=$(OPENSSL_LIBS)
+if !OPENSSL_HAVE_SHA
+libppp_crypt_la_SOURCES += sha1.c
+endif
+if !OPENSSL_HAVE_MD5
+libppp_crypt_la_SOURCES += md5.c
+endif
+if !OPENSSL_HAVE_MD4
+libppp_crypt_la_SOURCES += md4.c
+endif
+endif
+
+utest_peap_LDADD = libppp_crypt.la
+utest_chap_LDADD = libppp_crypt.la
+pppd_LIBS += libppp_crypt.la
+
+if WITH_SYSTEMD
+pppd_LIBS += -lsystemd
+endif
+
+if WITH_SRP
+srp_entry_SOURCES = srp-entry.c
+srp_entry_CPPFLAGS = $(OPENSSL_INCLUDES) $(SRP_CFLAGS)
+srp_entry_LDADD = $(SRP_LIBS) $(OPENSSL_LIBS)
+srp_entry_LDFLAGS = $(OPENSSL_LDFLAGS) $(SRP_LDFLAGS)
+
+pppd_CPPFLAGS += $(SRP_CFLAGS)
+pppd_LDFLAGS += $(SRP_LDFLAGS)
+pppd_LIBS += $(SRP_LIBS)
+endif
+
+pppd_LDADD = $(pppd_LIBS)
+
+EXTRA_DIST = \
+    ppp.pam
+
+TESTS = $(check_PROGRAMS)
+
diff --git a/pppd/Makefile.linux b/pppd/Makefile.linux
deleted file mode 100644 (file)
index 312580b..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-#
-# pppd makefile for Linux
-# Processed by configure to produce pppd/Makefile
-#
-
-CROSS_COMPILE=@CROSS_COMPILE@
-CC=$(CROSS_COMPILE)@CC@
-COPTS=@CFLAGS@
-
-# Default installation locations
-DESTDIR = $(INSTROOT)@DESTDIR@
-BINDIR = $(DESTDIR)/sbin
-MANDIR = $(DESTDIR)/share/man/man8
-INCDIR = $(DESTDIR)/include
-
-TARGETS = pppd
-
-PPPDSRCS = main.c magic.c fsm.c lcp.c ipcp.c upap.c chap-new.c md5.c ccp.c \
-          ecp.c ipxcp.c auth.c options.c sys-linux.c md4.c chap_ms.c \
-          demand.c utils.c tty.c eap.c chap-md5.c session.c
-
-HEADERS = ccp.h session.h chap-new.h ecp.h fsm.h ipcp.h \
-       ipxcp.h lcp.h magic.h md5.h patchlevel.h pathnames.h pppd.h \
-       upap.h eap.h
-
-MANPAGES = pppd.8
-PPPDOBJS = main.o magic.o fsm.o lcp.o ipcp.o upap.o chap-new.o md5.o ccp.o \
-          ecp.o auth.o options.o demand.o utils.o sys-linux.o ipxcp.o tty.o \
-          eap.o chap-md5.o session.o
-
-#
-# include dependencies if present
-ifeq (.depend,$(wildcard .depend))
-include .depend
-endif
-
-LIBS = -lrt
-
-# Uncomment the next line to include support for Microsoft's
-# MS-CHAP authentication protocol.  Also, edit plugins/radius/Makefile.linux.
-CHAPMS=y
-#USE_CRYPT=y
-# Don't use MSLANMAN unless you really know what you're doing.
-#MSLANMAN=y
-# Uncomment the next line to include support for MPPE.  CHAPMS (above) must
-# also be enabled.  Also, edit plugins/radius/Makefile.linux.
-MPPE=y
-
-# Uncomment the next line to include support for PPP packet filtering.
-# This requires that the libpcap library and headers be installed
-# and that the kernel driver support PPP packet filtering.
-FILTER=y
-
-# Uncomment the next line to enable multilink PPP (enabled by default)
-# Linux distributions: Please leave multilink ENABLED in your builds
-# of pppd!
-HAVE_MULTILINK=y
-
-# Uncomment the next line to enable the TDB database (enabled by default.)
-# If you enable multilink, then TDB is automatically enabled also.
-# Linux distributions: Please leave TDB ENABLED in your builds.
-USE_TDB=y
-
-# Uncomment the next line to enable Type=notify services in systemd
-# If enabled, and the user sets the up_sdnotify option, then
-# pppd will not detach and will notify systemd when up.
-#SYSTEMD=y
-
-HAS_SHADOW=y
-#USE_PAM=y
-HAVE_INET6=y
-
-# Enable plugins
-PLUGIN=y
-
-# Enable Microsoft proprietary Callback Control Protocol
-#CBCP=y
-
-# Enable EAP SRP-SHA1 authentication (requires libsrp)
-#USE_SRP=y
-
-# Use libutil; test if logwtmp is declared in <utmp.h> to detect
-UTMPHEADER = "\#include <utmp.h>"
-ifeq ($(shell echo $(UTMPHEADER) | $(CC) -E - 2>/dev/null | grep -q logwtmp && echo yes),yes)
-USE_LIBUTIL=y
-endif
-
-# Enable EAP-TLS authentication (requires MPPE support, libssl and libcrypto)
-USE_EAPTLS=y
-
-MAXOCTETS=y
-
-INCLUDE_DIRS= -I../include
-
-COMPILE_FLAGS= -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MMAP -pipe
-
-CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) '-DDESTDIR="@DESTDIR@"'
-
-ifdef CHAPMS
-CFLAGS   += -DCHAPMS=1
-NEEDDES=y
-PPPDOBJS += md4.o chap_ms.o
-HEADERS        += md4.h chap_ms.h
-ifdef MSLANMAN
-CFLAGS   += -DMSLANMAN=1
-endif
-ifdef MPPE
-CFLAGS   += -DMPPE=1
-HEADERS  += mppe.h
-endif
-endif
-
-# EAP SRP-SHA1
-ifdef USE_SRP
-CFLAGS += -DUSE_SRP -DOPENSSL -I/usr/local/ssl/include
-LIBS   += -lsrp -L/usr/local/ssl/lib
-NEEDCRYPTOLIB = y
-TARGETS        += srp-entry
-EXTRAINSTALL = $(INSTALL) -c -m 555 srp-entry $(BINDIR)/srp-entry
-MANPAGES += srp-entry.8
-EXTRACLEAN += srp-entry.o
-NEEDDES=y
-else
-# OpenSSL has an integrated version of SHA-1, and its implementation
-# is incompatible with this local SHA-1 implementation.  We must use
-# one or the other, not both.
-PPPDSRCS += sha1.c
-HEADERS += sha1.h
-PPPDOBJS += sha1.o
-endif
-
-# EAP-TLS
-ifdef USE_EAPTLS
-CFLAGS += -DUSE_EAPTLS=1
-LIBS += -lssl
-NEEDCRYPTOLIB = y
-PPPDSRC += eap-tls.c
-HEADERS += eap-tls.h
-PPPDOBJS += eap-tls.o
-endif
-
-ifdef HAS_SHADOW
-CFLAGS   += -DHAS_SHADOW
-#LIBS     += -lshadow $(LIBS)
-endif
-
-CRYPTHEADER = "\#include <utmp.h>"
-ifeq ($(shell echo $(CRYPTHEADER) | $(CC) -E - >/dev/null 2>&1 && echo yes),yes)
-CFLAGS  += -DHAVE_CRYPT_H=1
-LIBS   += -lcrypt
-endif
-
-ifdef USE_LIBUTIL
-CFLAGS += -DHAVE_LOGWTMP=1
-LIBS   += -lutil
-endif
-
-ifdef NEEDDES
-ifndef USE_CRYPT
-CFLAGS   += -I$(shell $(CC) --print-sysroot)/usr/include/openssl
-NEEDCRYPTOLIB = y
-else
-CFLAGS   += -DUSE_CRYPT=1
-endif
-PPPDOBJS += pppcrypt.o
-HEADERS += pppcrypt.h
-endif
-
-ifdef NEEDCRYPTOLIB
-LIBS     += -lcrypto
-endif
-
-# For "Pluggable Authentication Modules", see ftp.redhat.com:/pub/pam/.
-ifdef USE_PAM
-CFLAGS   += -DUSE_PAM
-LIBS     += -lpam -ldl
-endif
-
-# Multi-linnk
-ifdef HAVE_MULTILINK
-       # Multilink implies the use of TDB
-       USE_TDB=y
-
-       CFLAGS += -DHAVE_MULTILINK
-       PPPDSRCS += multilink.c
-       PPPDOBJS += multilink.o
-endif
-
-# TDB
-ifdef USE_TDB
-       CFLAGS += -DUSE_TDB=1
-       PPPDSRCS += tdb.c spinlock.c
-       PPPDOBJS += tdb.o spinlock.o
-       HEADERS += tdb.h spinlock.h
-endif
-
-# Lock library binary for Linux is included in 'linux' subdirectory.
-ifdef LOCKLIB
-LIBS     += -llock
-CFLAGS   += -DLOCKLIB=1
-endif
-
-ifdef SYSTEMD
-LIBS += -lsystemd
-CFLAGS   += -DSYSTEMD=1
-endif
-
-ifdef PLUGIN
-CFLAGS += -DPLUGIN
-LDFLAGS_PLUGIN += -Wl,-E
-LIBS   += -ldl
-endif
-
-ifdef FILTER
-LIBS    += -lpcap
-CFLAGS  += -DPPP_FILTER
-endif
-
-ifdef HAVE_INET6
-     PPPDSRCS += ipv6cp.c eui64.c
-     HEADERS  += ipv6cp.h eui64.h
-     PPPDOBJS += ipv6cp.o eui64.o
-     CFLAGS   += -DINET6=1
-endif
-
-ifdef CBCP
-     PPPDSRCS += cbcp.c
-     PPPDOBJS += cbcp.o
-     CFLAGS += -DCBCP_SUPPORT
-     HEADERS += cbcp.h
-endif
-
-ifdef MAXOCTETS
-     CFLAGS += -DMAXOCTETS
-endif
-
-INSTALL= install
-
-all: $(TARGETS)
-
-install: pppd
-       mkdir -p $(BINDIR) $(MANDIR)
-       $(EXTRAINSTALL)
-       $(INSTALL) -c -m 755 pppd $(BINDIR)/pppd
-       if chgrp pppusers $(BINDIR)/pppd 2>/dev/null; then \
-         chmod o-rx,u+s $(BINDIR)/pppd; fi
-       $(INSTALL) -c -m 644 pppd.8 $(MANDIR)
-
-pppd: $(PPPDOBJS)
-       $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_PLUGIN) -o pppd $(PPPDOBJS) $(LIBS)
-
-srp-entry:     srp-entry.c
-       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ srp-entry.c $(LIBS)
-
-install-devel:
-       mkdir -p $(INCDIR)/pppd
-       $(INSTALL) -c -m 644 $(HEADERS) $(INCDIR)/pppd
-
-clean:
-       rm -f $(PPPDOBJS) $(EXTRACLEAN) $(TARGETS) *~ #* core
-
-depend:
-       $(CPP) -M $(CFLAGS) $(PPPDSRCS) >.depend
diff --git a/pppd/Makefile.sol2 b/pppd/Makefile.sol2
deleted file mode 100644 (file)
index 809cb4b..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-#
-# Makefile for pppd under Solaris 2.
-# $Id: Makefile.sol2,v 1.30 2008/01/30 14:26:52 carlsonj Exp $
-#
-
-include ../Makedefs.com
-
-CFLAGS =  -I../include -DSVR4 -DSOL2 $(COPTS) '-DDESTDIR="@DESTDIR@"'
-LIBS   = -lsocket -lnsl
-
-OBJS   =  main.o magic.o fsm.o lcp.o ipcp.o upap.o chap-new.o eap.o md5.o \
-       tty.o ccp.o ecp.o auth.o options.o demand.o utils.o sys-solaris.o \
-       chap-md5.o session.o
-
-# Solaris uses shadow passwords
-CFLAGS += -DHAS_SHADOW
-
-#
-# Comment the following out to disable plugins
-#
-CFLAGS += -DPLUGIN
-LIBS   += -ldl
-
-#
-# Solaris 8 and above accomodates /var/run, so uncomment the
-# following to place pppd process IDs on that location
-#
-#CFLAGS += -D_PATH_VARRUN='"/var/run/"'
-
-#
-# uncomment the following to enable IPv6
-#
-# Solaris 8 and on includes support for IPv6
-#
-CFLAGS += -DINET6
-OBJS   += ipv6cp.o eui64.o
-
-# Uncomment to enable MS-CHAP
-CFLAGS += -DUSE_CRYPT -DCHAPMS -DMSLANMAN -DHAVE_CRYPT_H
-OBJS += chap_ms.o pppcrypt.o md4.o sha1.o
-
-# Uncomment to enable MPPE (in both CHAP and EAP-TLS)
-CFLAGS += -DMPPE
-
-# Uncomment to enable EAP-TLS
-CFLAGS += -DUSE_EAPTLS
-LIBS += -lcrypto -lssl
-OBJS += eap-tls.o
-
-# Uncomment for CBCP
-#CFLAGS += -DCBCP_SUPPORT
-#OBJS += cbcp.o
-
-# Uncomment for PAM
-#CFLAGS += -DUSE_PAM
-#LIBS += -lpam
-
-#
-# Make targets
-#
-all: pppd
-
-pppd:  $(OBJS)
-       $(CC) -o pppd $(OBJS) $(LIBS)
-
-install:
-       $(INSTALL) -f $(BINDIR) -m 4755 -u root pppd
-       $(INSTALL) -f $(MANDIR)/man8 -m 444 pppd.8
-
-clean:
-       rm -f $(OBJS) pppd *~ core y.tab.c y.tab.h
index b1271c4f8739e4631740a44880586b4d3e92ceb9..01ece576ba2a7b5c57fffda29b4fb380d8b23e9a 100644 (file)
 
 #define RCSID  "$Id: auth.c,v 1.117 2008/07/01 12:27:56 paulus Exp $"
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdio.h>
 #include <stddef.h>
 #include <stdlib.h>
@@ -93,7 +97,7 @@
 #include <arpa/inet.h>
 
 
-#ifdef HAS_SHADOW
+#ifdef HAVE_SHADOW_H
 #include <shadow.h>
 #ifndef PW_PPP
 #define PW_PPP PW_LOGIN
 #endif
 #include <time.h>
 
+#ifdef HAVE_CRYPT_H
+#include <crypt.h>
+#endif
+
 #ifdef SYSTEMD
 #include <systemd/sd-daemon.h>
 #endif
@@ -250,20 +258,25 @@ bool explicit_remote = 0; /* User specified explicit remote name */
 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 *ca_path      = NULL;     /* directory with CA certificates */
-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) */
-char *max_tls_version = NULL;  /* Maximum TLS protocol version (default=1.2) */
-bool need_peer_eap = 0;                        /* Require peer to authenticate us */
+
+#if defined(USE_EAPTLS) || defined(USE_PEAP)
+char *cacert_file  = NULL;  /* CA certificate file (pem format) */
+char *ca_path      = NULL;  /* Directory with CA certificates */
+char *crl_dir      = NULL;  /* Directory containing CRL files */
+char *crl_file     = NULL;  /* Certificate Revocation List (CRL) file (pem format) */
+char *max_tls_version = NULL;   /* Maximum TLS protocol version (default=1.2) */
+char *tls_verify_method = NULL; /* Verify certificate method */
+bool  tls_verify_key_usage = 0; /* Verify peer certificate key usage */
 #endif
 
-static char *uafname;          /* name of most recent +ua file */
+#if defined(USE_EAPTLS)
+char *cert_file    = NULL;  /* Client certificate file (pem format) */
+char *privkey_file = NULL;  /* Client private key file (pem format) */
+char *pkcs12_file  = NULL;  /* Client private key envelope file (pkcs12 format) */
+bool need_peer_eap = 0;            /* Require peer to authenticate us */
+#endif
 
-extern char *crypt (const char *, const char *);
+static char *uafname;          /* name of most recent +ua file */
 
 /* Prototypes for procedures local to this file. */
 
@@ -436,18 +449,26 @@ option_t auth_options[] = {
       "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" },
-    { "capath", o_string, &ca_path,   "EAP-TLS CA certificate directory" },
-    { "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" },
+#if defined(USE_EAPTLS) || defined(USE_PEAP)
+    { "ca", o_string, &cacert_file,     "CA certificate in PEM format" },
+    { "capath", o_string, &ca_path,     "TLS CA certificate directory" },
+    { "crl-dir", o_string, &crl_dir,    "Use CRLs in directory" },
+    { "crl", o_string, &crl_file,       "Use specific CRL file" },
     { "max-tls-version", o_string, &max_tls_version,
       "Maximum TLS version (1.0/1.1/1.2 (default)/1.3)" },
+    { "tls-verify-key-usage", o_bool, &tls_verify_key_usage,
+      "Verify certificate type and extended key usage" },
+    { "tls-verify-method", o_string, &tls_verify_method,
+      "Verify peer by method (none|subject|name|suffix)" },
+#endif
+
+#if defined(USE_EAPTLS)
+    { "cert", o_string, &cert_file,     "client certificate in PEM format" },
+    { "key", o_string, &privkey_file,   "client private key in PEM format" },
+    { "pkcs12", o_string, &pkcs12_file, "EAP-TLS client credentials in PKCS12 format" },
     { "need-peer-eap", o_bool, &need_peer_eap,
       "Require the peer to authenticate us", 1 },
-#endif /* USE_EAPTLS */
+#endif
     { NULL }
 };
 
@@ -1509,8 +1530,10 @@ check_passwd(int unit,
            if (secret[0] != 0 && !login_secret) {
                /* password given in pap-secrets - must match */
                if (cryptpap || strcmp(passwd, secret) != 0) {
+#ifdef HAVE_CRYPT_H
                    char *cbuf = crypt(passwd, secret);
                    if (!cbuf || strcmp(cbuf, secret) != 0)
+#endif
                        ret = UPAP_AUTHNAK;
                }
            }
@@ -2458,6 +2481,8 @@ have_eaptls_secret_client(char *client, char *server)
 
        if ((cacert_file || ca_path) && cert_file && privkey_file)
                return 1;
+       if (pkcs12_file)
+               return 1;
 
     filename = _PATH_EAPTLSCLIFILE;
     f = fopen(filename, "r");
@@ -2641,7 +2666,7 @@ scan_authfile_eaptls(FILE *f, char *client, char *server,
 int
 get_eaptls_secret(int unit, char *client, char *server,
                  char *clicertfile, char *servcertfile, char *cacertfile,
-                 char *capath, char *pkfile, int am_server)
+                 char *capath, char *pkfile, char *pkcs12, int am_server)
 {
     FILE *fp;
     int ret;
@@ -2655,6 +2680,7 @@ get_eaptls_secret(int unit, char *client, char *server,
        bzero(cacertfile, MAXWORDLEN);
        bzero(capath, MAXWORDLEN);
        bzero(pkfile, MAXWORDLEN);
+       bzero(pkcs12, MAXWORDLEN);
 
        /* the ca+cert+privkey can also be specified as options */
        if (!am_server && (cacert_file || ca_path) && cert_file && privkey_file )
@@ -2666,6 +2692,14 @@ get_eaptls_secret(int unit, char *client, char *server,
                        strlcpy( capath, ca_path, MAXWORDLEN );
                strlcpy( pkfile, privkey_file, MAXWORDLEN );
        }
+    else if (!am_server && pkcs12_file)
+       {
+               strlcpy( pkcs12, pkcs12_file, MAXWORDLEN );
+               if (cacert_file)
+                       strlcpy( cacertfile, cacert_file, MAXWORDLEN );
+               if (ca_path)
+                       strlcpy( capath, ca_path, MAXWORDLEN );
+       }
        else
        {
                filename = (am_server ? _PATH_EAPTLSSERVFILE : _PATH_EAPTLSCLIFILE);
index e3566336982709115b1b121e56f3f5526401598c..87bf9c002c0c72c3600216936a3edb4fe3519c4d 100644 (file)
@@ -32,6 +32,9 @@
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
 #include <stdio.h>
 #include <string.h>
index c2ab3f68991f189b6ebd93ae45dbdb21725072f5..c74b5f8c8a2daef6f70ddb8851f9fd5f21f5eaa9 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef CBCP_H
 #define CBCP_H
 
+#include "pppdconf.h"
+
 typedef struct cbcp_state {
     int    us_unit;    /* Interface unit number */
     u_char us_id;              /* Current id */
index 052c4c61081bdc74489ea282e8e0df46ed1891fc..644a9d1128ad65691fb72f748d0b3a916f546bd6 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #define RCSID  "$Id: ccp.c,v 1.50 2005/06/26 19:34:41 carlsonj Exp $"
 
 #include <stdlib.h>
 #include "ccp.h"
 #include <net/ppp-comp.h>
 
-#ifdef MPPE
-#include "chap_ms.h"   /* mppe_xxxx_key, mppe_keys_set */
+#include "chap_ms.h"
+#include "mppe.h"
 #include "lcp.h"       /* lcp_close(), lcp_fsm */
-#endif
 
 
 /*
@@ -574,7 +577,7 @@ ccp_resetci(fsm *f)
        }
 
        /* A plugin (eg radius) may not have obtained key material. */
-       if (!mppe_keys_set) {
+       if (!mppe_keys_isset()) {
            error("MPPE required, but keys are not available.  "
                  "Possible plugin problem?");
            lcp_close(f->unit, "MPPE required but not available");
@@ -705,7 +708,7 @@ static void
        p[1] = opt_buf[1] = CILEN_MPPE;
        MPPE_OPTS_TO_CI(go->mppe, &p[2]);
        MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]);
-       BCOPY(mppe_recv_key, &opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN);
+       mppe_get_recv_key(&opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN);
        res = ccp_test(f->unit, opt_buf, CILEN_MPPE + MPPE_MAX_KEY_LEN, 0);
        if (res > 0)
            p += CILEN_MPPE;
@@ -1156,8 +1159,7 @@ ccp_reqci(fsm *f, u_char *p, int *lenp, int dont_nak)
                    int mtu;
 
                    BCOPY(p, opt_buf, CILEN_MPPE);
-                   BCOPY(mppe_send_key, &opt_buf[CILEN_MPPE],
-                         MPPE_MAX_KEY_LEN);
+                   mppe_get_send_key(&opt_buf[CILEN_MPPE], MPPE_MAX_KEY_LEN);
                    if (ccp_test(f->unit, opt_buf,
                                 CILEN_MPPE + MPPE_MAX_KEY_LEN, 1) <= 0) {
                        /* This shouldn't happen, we've already tested it! */
@@ -1426,8 +1428,7 @@ ccp_up(fsm *f)
        notice("%s transmit compression enabled", method_name(ho, NULL));
 #ifdef MPPE
     if (go->mppe) {
-       BZERO(mppe_recv_key, MPPE_MAX_KEY_LEN);
-       BZERO(mppe_send_key, MPPE_MAX_KEY_LEN);
+       mppe_clear_keys();
        continue_networks(f->unit);             /* Bring up IP et al */
     }
 #endif
index 76446db007c00604120f7044cc67be520ad3650c..35961b9b75a46ea0eee7625d6958b24c7e52a11d 100644 (file)
@@ -29,6 +29,7 @@
  *
  * $Id: ccp.h,v 1.12 2004/11/04 10:02:26 paulus Exp $
  */
+#include "pppdconf.h"
 
 typedef struct ccp_options {
     bool bsd_compress;         /* do BSD Compress? */
index 77dd4ecc705984bad999cb51fb6b8889f5b82f48..000f880e89e3d0859698b018689437acb120023e 100644 (file)
 
 #define RCSID  "$Id: chap-md5.c,v 1.4 2004/11/09 22:39:25 paulus Exp $"
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdlib.h>
 #include <string.h>
 #include "pppd.h"
index 30d06588ee51dace373bf8699a67be31b5d78866..4dbbfd1ed590b6dac3dfbfa1645a95c7e7799fc2 100644 (file)
@@ -27,5 +27,6 @@
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#include "pppdconf.h"
 
 extern void chap_md5_init(void);
index ad2f5eb975de779f2b8f707c73fe77d40153aeb0..ab4302b96a207313d81a1cfaf24897d19d63743a 100644 (file)
 
 #define RCSID  "$Id: chap-new.c,v 1.9 2007/06/19 02:08:35 carlsonj Exp $"
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdlib.h>
 #include <string.h>
 #include "pppd.h"
@@ -171,11 +175,11 @@ chap_register_digest(struct chap_digest_type *dp)
  */
 struct chap_digest_type *
 chap_find_digest(int digest_code) {
-    struct chap_digest_type *dp = NULL;
+       struct chap_digest_type *dp = NULL;
        for (dp = chap_digests; dp != NULL; dp = dp->next)
                if (dp->code == digest_code)
                        break;
-    return dp;
+       return dp;
 }
 
 /*
@@ -222,9 +226,8 @@ chap_auth_peer(int unit, char *our_name, int digest_code)
                error("CHAP: peer authentication already started!");
                return;
        }
-       for (dp = chap_digests; dp != NULL; dp = dp->next)
-               if (dp->code == digest_code)
-                       break;
+
+       dp = chap_find_digest(digest_code);
        if (dp == NULL)
                fatal("CHAP digest 0x%x requested but not available",
                      digest_code);
index e5330da57630c7365ac3aea5981836411d9761e8..b4b0ee23eb6d5bf6121e842d236a1e2214a745bb 100644 (file)
@@ -28,6 +28,8 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include "pppdconf.h"
+
 /*
  * CHAP packets begin with a standard header with code, id, len (2 bytes).
  */
index e6b84f203fc3fc2f62ca2a471b17e11d8422e975..c6e4b34bd60001ab30b05189726f3550c95a5fcb 100644 (file)
 
 #define RCSID  "$Id: chap_ms.c,v 1.38 2007/12/01 20:10:51 carlsonj Exp $"
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #ifdef CHAPMS
 
 #include <stdio.h>
 #include "sha1.h"
 #include "pppcrypt.h"
 #include "magic.h"
+#include "mppe.h"
 
-
+#ifdef UNIT_TEST
+#undef MPPE
+#endif
 
 static void    ascii2unicode (char[], int, u_char[]);
 static void    NTPasswordHash (u_char *, int, u_char[MD4_SIGNATURE_SIZE]);
@@ -109,21 +116,12 @@ static void       GenerateAuthenticatorResponsePlain
 static void    ChapMS_LANMan (u_char *, char *, int, u_char *);
 #endif
 
-#ifdef MPPE
-static void    Set_Start_Key (u_char *, char *, int);
-static void    SetMasterKeys (char *, int, u_char[24], int);
-#endif
-
 #ifdef MSLANMAN
 bool   ms_lanman = 0;          /* Use LanMan password instead of NT */
                                /* Has meaning only with MS-CHAP challenges */
 #endif
 
 #ifdef MPPE
-u_char mppe_send_key[MPPE_MAX_KEY_LEN];
-u_char mppe_recv_key[MPPE_MAX_KEY_LEN];
-int mppe_keys_set = 0;         /* Have the MPPE keys been set? */
-
 #ifdef DEBUGMPPEKEY
 /* For MPPE debug */
 /* Use "[]|}{?/><,`!2&&(" (sans quotes) for RFC 3079 MS-CHAPv2 test value */
@@ -575,7 +573,7 @@ ascii2unicode(char ascii[], int ascii_len, u_char unicode[])
 static void
 NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE])
 {
-#ifdef __NetBSD__
+#if defined(__NetBSD__) || !defined(USE_MD4)
     /* NetBSD uses the libc md4 routines which take bytes instead of bits */
     int                        mdlen = secret_len;
 #else
@@ -584,12 +582,14 @@ NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE])
     MD4_CTX            md4Context;
 
     MD4Init(&md4Context);
-    /* MD4Update can take at most 64 bytes at a time */
+#if !defined(USE_MD4)
+    /* Internal MD4Update can take at most 64 bytes at a time */
     while (mdlen > 512) {
        MD4Update(&md4Context, secret, 512);
        secret += 64;
        mdlen -= 512;
     }
+#endif
     MD4Update(&md4Context, secret, mdlen);
     MD4Final(hash, &md4Context);
 
@@ -719,28 +719,6 @@ GenerateAuthenticatorResponsePlain
 
 
 #ifdef MPPE
-/*
- * Set mppe_xxxx_key from the NTPasswordHashHash.
- * RFC 2548 (RADIUS support) requires us to export this function (ugh).
- */
-void
-mppe_set_keys(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE])
-{
-    SHA1_CTX   sha1Context;
-    u_char     Digest[SHA1_SIGNATURE_SIZE];    /* >= MPPE_MAX_KEY_LEN */
-
-    SHA1_Init(&sha1Context);
-    SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
-    SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
-    SHA1_Update(&sha1Context, rchallenge, 8);
-    SHA1_Final(Digest, &sha1Context);
-
-    /* Same key in both directions. */
-    BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key));
-    BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key));
-
-    mppe_keys_set = 1;
-}
 
 /*
  * Set mppe_xxxx_key from MS-CHAP credentials. (see RFC 3079)
@@ -757,104 +735,7 @@ Set_Start_Key(u_char *rchallenge, char *secret, int secret_len)
     NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
     NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash);
 
-    mppe_set_keys(rchallenge, PasswordHashHash);
-}
-
-/*
- * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079)
- *
- * This helper function used in the Winbind module, which gets the
- * NTHashHash from the server.
- */
-void
-mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
-              u_char NTResponse[24], int IsServer)
-{
-    SHA1_CTX   sha1Context;
-    u_char     MasterKey[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */
-    u_char     Digest[SHA1_SIGNATURE_SIZE];    /* >= MPPE_MAX_KEY_LEN */
-
-    u_char SHApad1[40] =
-       { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-    u_char SHApad2[40] =
-       { 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
-         0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
-         0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
-         0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 };
-
-    /* "This is the MPPE Master Key" */
-    u_char Magic1[27] =
-       { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
-         0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
-         0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 };
-    /* "On the client side, this is the send key; "
-       "on the server side, it is the receive key." */
-    u_char Magic2[84] =
-       { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
-         0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
-         0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
-         0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
-         0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
-         0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65,
-         0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
-         0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
-         0x6b, 0x65, 0x79, 0x2e };
-    /* "On the client side, this is the receive key; "
-       "on the server side, it is the send key." */
-    u_char Magic3[84] =
-       { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
-         0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
-         0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
-         0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
-         0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
-         0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73,
-         0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73,
-         0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20,
-         0x6b, 0x65, 0x79, 0x2e };
-    u_char *s;
-
-    SHA1_Init(&sha1Context);
-    SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
-    SHA1_Update(&sha1Context, NTResponse, 24);
-    SHA1_Update(&sha1Context, Magic1, sizeof(Magic1));
-    SHA1_Final(MasterKey, &sha1Context);
-
-    /*
-     * generate send key
-     */
-    if (IsServer)
-       s = Magic3;
-    else
-       s = Magic2;
-    SHA1_Init(&sha1Context);
-    SHA1_Update(&sha1Context, MasterKey, 16);
-    SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1));
-    SHA1_Update(&sha1Context, s, 84);
-    SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2));
-    SHA1_Final(Digest, &sha1Context);
-
-    BCOPY(Digest, mppe_send_key, sizeof(mppe_send_key));
-
-    /*
-     * generate recv key
-     */
-    if (IsServer)
-       s = Magic2;
-    else
-       s = Magic3;
-    SHA1_Init(&sha1Context);
-    SHA1_Update(&sha1Context, MasterKey, 16);
-    SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1));
-    SHA1_Update(&sha1Context, s, 84);
-    SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2));
-    SHA1_Final(Digest, &sha1Context);
-
-    BCOPY(Digest, mppe_recv_key, sizeof(mppe_recv_key));
-
-    mppe_keys_set = 1;
+    mppe_set_chapv1(rchallenge, PasswordHashHash);
 }
 
 /*
@@ -870,7 +751,7 @@ SetMasterKeys(char *secret, int secret_len, u_char NTResponse[24], int IsServer)
     ascii2unicode(secret, secret_len, unicodePassword);
     NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash);
     NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash);
-    mppe_set_keys2(PasswordHashHash, NTResponse, IsServer);
+    mppe_set_chapv2(PasswordHashHash, NTResponse, IsServer);
 }
 
 #endif /* MPPE */
@@ -945,38 +826,6 @@ ChapMS2(u_char *rchallenge, u_char *PeerChallenge,
 #endif
 }
 
-#ifdef MPPE
-/*
- * Set MPPE options from plugins.
- */
-void
-set_mppe_enc_types(int policy, int types)
-{
-    /* Early exit for unknown policies. */
-    if (policy != MPPE_ENC_POL_ENC_ALLOWED ||
-       policy != MPPE_ENC_POL_ENC_REQUIRED)
-       return;
-
-    /* Don't modify MPPE if it's optional and wasn't already configured. */
-    if (policy == MPPE_ENC_POL_ENC_ALLOWED && !ccp_wantoptions[0].mppe)
-       return;
-
-    /*
-     * Disable undesirable encryption types.  Note that we don't ENABLE
-     * any encryption types, to avoid overriding manual configuration.
-     */
-    switch(types) {
-       case MPPE_ENC_TYPES_RC4_40:
-           ccp_wantoptions[0].mppe &= ~MPPE_OPT_128;   /* disable 128-bit */
-           break;
-       case MPPE_ENC_TYPES_RC4_128:
-           ccp_wantoptions[0].mppe &= ~MPPE_OPT_40;    /* disable 40-bit */
-           break;
-       default:
-           break;
-    }
-}
-#endif /* MPPE */
 
 static struct chap_digest_type chapms_digest = {
        CHAP_MICROSOFT,         /* code */
@@ -996,6 +845,7 @@ static struct chap_digest_type chapms2_digest = {
        chapms_handle_failure,
 };
 
+#ifndef UNIT_TEST
 void
 chapms_init(void)
 {
@@ -1003,5 +853,96 @@ chapms_init(void)
        chap_register_digest(&chapms2_digest);
        add_options(chapms_option_list);
 }
+#else
+
+#include <time.h>
+
+int debug = 1;
+int error_count = 0;
+int unsuccess = 0;
+
+void random_bytes(unsigned char *bytes, int len)
+{
+    int i = 0;
+    srand(time(NULL));
+    while (i < len) {
+        bytes[i++] = (unsigned char) rand();
+    }
+}
+
+
+int test_chap_v1(void) {
+    char *secret = "TestPassword";
+
+    unsigned char challenge[8] = {
+        0x6c, 0x8d, 0x4b, 0xa1, 0x2b, 0x5c, 0x13, 0xc3
+    };
+    unsigned char response[MS_CHAP_RESPONSE_LEN] = {
+    };
+    unsigned char result[MS_CHAP_RESPONSE_LEN] = {
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+
+        0x91, 0x09, 0x61, 0x5a, 0x0c, 0xac, 0xac, 0x55,
+        0x1f, 0x60, 0xe2, 0x9c, 0x00, 0xac, 0x24, 0xda,
+        0x6e, 0xa5, 0x7b, 0xdb, 0x1d, 0x6a, 0x17, 0xc5,
+        0x01
+    };
+
+    ChapMS(challenge, secret, strlen(secret), response);
+    return memcmp(response, result, MS_CHAP_RESPONSE_LEN);
+}
+
+int test_chap_v2(void) {
+    char *secret = "clientPass";
+    char *name = "User";
+
+    char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
+    char *saresult = "407A5589115FD0D6209F510FE9C04566932CDA56";
+
+    unsigned char authenticator[16] = {
+        0x5B, 0x5D, 0x7C, 0x7D, 0x7B, 0x3F, 0x2F, 0x3E,
+        0x3C, 0x2C, 0x60, 0x21, 0x32, 0x26, 0x26, 0x28
+    };
+    unsigned char peerchallenge[16] = {
+        0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A,
+        0x28, 0x29, 0x5F, 0x2B, 0x3A, 0x33, 0x7C, 0x7E
+    };
+    unsigned char result[MS_CHAP_NTRESP_LEN] = {
+        0x82, 0x30, 0x9E, 0xCD, 0x8D, 0x70, 0x8B, 0x5E,
+        0xA0, 0x8F, 0xAA, 0x39, 0x81, 0xCD, 0x83, 0x54,
+        0x42, 0x33, 0x11, 0x4A, 0x3D, 0x85, 0xD6, 0xDF
+    };
+
+    unsigned char response[MS_CHAP2_RESPONSE_LEN] = {
+    };
+
+       ChapMS2(authenticator, peerchallenge, name,
+               secret, strlen(secret), response,
+               (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR);
+
+    return memcmp(&response[MS_CHAP2_NTRESP], result, MS_CHAP2_NTRESP_LEN) ||
+        strncmp(saresponse, saresult, MS_AUTH_RESPONSE_LENGTH);
+}
+
+int main(int argc, char *argv[]) {
+
+    if (test_chap_v1()) {
+        printf("CHAPv1 failed\n");
+        return -1;
+    }
+
+    if (test_chap_v2()) {
+        printf("CHAPv2 failed\n");
+        return -1;
+    }
+
+    printf("Success\n");
+    return 0;
+}
+
+#endif  /* UNIT_TEST */
+
 
 #endif /* CHAPMS */
index 005eb63bc6dfb38987d977d78e50f5b9535402e0..c1c5ed846f5f5004f086de610a32ede41dc5a121 100644 (file)
@@ -30,6 +30,8 @@
  * $Id: chap_ms.h,v 1.13 2004/11/15 22:13:26 paulus Exp $
  */
 
+#include "pppdconf.h"
+
 #ifndef __CHAPMS_INCLUDE__
 
 #define MD4_SIGNATURE_SIZE     16      /* 16 bytes in a MD4 message digest */
@@ -38,6 +40,7 @@
 #define MS_CHAP_RESPONSE_LEN   49      /* Response length for MS-CHAP */
 #define MS_CHAP2_RESPONSE_LEN  49      /* Response length for MS-CHAPv2 */
 #define MS_AUTH_RESPONSE_LENGTH        40      /* MS-CHAPv2 authenticator response, */
+#define MS_AUTH_NTRESP_LEN      24  /* Length of NT-response field */
                                        /* as ASCII */
 
 /* E=eeeeeeeeee error codes for MS-CHAP failure messages. */
 #define MS_CHAP2_NTRESP_LEN    24
 #define MS_CHAP2_FLAGS         48
 
-#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;
-
-/* These values are the RADIUS attribute values--see RFC 2548. */
-#define MPPE_ENC_POL_ENC_ALLOWED 1
-#define MPPE_ENC_POL_ENC_REQUIRED 2
-#define MPPE_ENC_TYPES_RC4_40 2
-#define MPPE_ENC_TYPES_RC4_128 4
-
-/* used by plugins (using above values) */
-extern void set_mppe_enc_types(int, int);
-#endif
-
 /* Are we the authenticator or authenticatee?  For MS-CHAPv2 key derivation. */
 #define MS_CHAP2_AUTHENTICATEE 0
 #define MS_CHAP2_AUTHENTICATOR 1
@@ -90,11 +77,6 @@ extern void set_mppe_enc_types(int, int);
 void ChapMS (u_char *, char *, int, u_char *);
 void ChapMS2 (u_char *, u_char *, char *, char *, int,
              u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int);
-#ifdef MPPE
-void mppe_set_keys (u_char *, u_char[MD4_SIGNATURE_SIZE]);
-void mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
-                   u_char NTResponse[24], int IsServer);
-#endif
 
 void   ChallengeHash (u_char[16], u_char *, char *, u_char[8]);
 
index 289c9f8fdd57959588e65835d16cc3adf7950c6a..0943e8a381ad5ce8ee2b12b3438708357f0c63d1 100644 (file)
 
 #define RCSID  "$Id: demand.c,v 1.20 2005/08/25 12:14:18 paulus Exp $"
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
index 5740f308a89ae6c2e645222474a2ba6497cde9e7..b9bab842bbf2c290f7b635bfb38ad8e8e522cf36 100644 (file)
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <string.h>
 #include <strings.h>
 #include <unistd.h>
 #include <fcntl.h>
 
 #include <openssl/conf.h>
+#ifndef OPENSSL_NO_ENGINE
 #include <openssl/engine.h>
+#endif
+#include <openssl/ssl.h>
 #include <openssl/hmac.h>
 #include <openssl/err.h>
 #include <openssl/ui.h>
 #include <openssl/x509v3.h>
+#include <openssl/pkcs12.h>
 
 #include "pppd.h"
+#include "tls.h"
 #include "eap.h"
 #include "eap-tls.h"
 #include "fsm.h"
 #include "lcp.h"
+#include "chap_ms.h"
+#include "mppe.h"
 #include "pathnames.h"
 
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#define SSL3_RT_HEADER  0x100
+#endif
+
 typedef struct pw_cb_data
 {
     const void *password;
     const char *prompt_info;
 } PW_CB_DATA;
 
+#ifndef OPENSSL_NO_ENGINE
 /* 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;
+#endif
 
 /* TLSv1.3 do we have a session ticket ? */
 static int have_session_ticket = 0;
 
-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);
 int ssl_new_session_cb(SSL *s, SSL_SESSION *sess);
 
-X509 *get_X509_from_file(char *filename);
-int ssl_cmp_certs(char *filename, X509 * a); 
-
 #ifdef MPPE
-
 #define EAPTLS_MPPE_KEY_LEN     32
 
-/*
- *  OpenSSL 1.1+ introduced a generic TLS_method()
- *  For older releases we substitute the appropriate method
- */
-
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-
-#define TLS_method SSLv23_method
-
-#define SSL3_RT_HEADER  0x100
-
-#ifndef SSL_CTX_set_max_proto_version
-/** Mimics SSL_CTX_set_max_proto_version for OpenSSL < 1.1 */
-static inline int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, long tls_ver_max)
-{
-    long sslopt = 0;
-
-    if (tls_ver_max < TLS1_VERSION)
-    {
-        sslopt |= SSL_OP_NO_TLSv1;
-    }
-#ifdef SSL_OP_NO_TLSv1_1
-    if (tls_ver_max < TLS1_1_VERSION)
-    {
-        sslopt |= SSL_OP_NO_TLSv1_1;
-    }
-#endif
-#ifdef SSL_OP_NO_TLSv1_2
-    if (tls_ver_max < TLS1_2_VERSION)
-    {
-        sslopt |= SSL_OP_NO_TLSv1_2;
-    }
-#endif
-    SSL_CTX_set_options(ctx, sslopt);
-
-    return 1;
-}
-#endif /* SSL_CTX_set_max_proto_version */
-
-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
-
-
 /*
  *  Generate keys according to RFC 2716 and add to reply
  */
@@ -159,37 +129,16 @@ void eaptls_gen_mppe_keys(struct eaptls_session *ets, int client)
      */
     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) );
+        mppe_set_keys(out, out + EAPTLS_MPPE_KEY_LEN, EAPTLS_MPPE_KEY_LEN);
     }
     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_set_keys(out + EAPTLS_MPPE_KEY_LEN, out, EAPTLS_MPPE_KEY_LEN);
     }
-
-    mppe_keys_set = 1;
 }
 
 #endif /* MPPE */
 
-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)
@@ -219,20 +168,23 @@ CONF *eaptls_ssl_load_config( void )
     }
 
     dbglog( "Loading OpenSSL built-ins" );
+#ifndef OPENSSL_NO_ENGINE
     ENGINE_load_builtin_engines();
+#endif
     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();
+        tls_log_sslerr();
         config = NULL;
     }
 
     return config;
 }
 
+#ifndef OPENSSL_NO_ENGINE
 ENGINE *eaptls_ssl_load_engine( char *engine_name )
 {
     ENGINE      *e = NULL;
@@ -252,7 +204,7 @@ ENGINE *eaptls_ssl_load_engine( char *engine_name )
              || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0))
             {
                 warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name );
-                log_ssl_errors();
+                tls_log_sslerr();
                 ENGINE_free(e);
                 e = NULL;
             }
@@ -269,7 +221,7 @@ ENGINE *eaptls_ssl_load_engine( char *engine_name )
         if(!ENGINE_set_default(e, ENGINE_METHOD_ALL))
         {
             warn( "EAP-TLS: Cannot use that engine" );
-            log_ssl_errors();
+            tls_log_sslerr();
             ENGINE_free(e);
             e = NULL;
         }
@@ -277,90 +229,103 @@ ENGINE *eaptls_ssl_load_engine( char *engine_name )
 
     return e;
 }
+#endif
+
+
+#ifndef OPENSSL_NO_ENGINE
+static int eaptls_UI_writer(UI *ui, UI_STRING *uis)
+{
+    PW_CB_DATA* cb_data = (PW_CB_DATA*)UI_get0_user_data(ui);
+    UI_set_result(ui, uis, cb_data->password);
+    return 1;
+}
 
+static int eaptls_UI_stub(UI* ui) {
+    return 1;
+}
 
+static int eaptls_UI_reader(UI *ui, UI_STRING *uis) {
+    return 1;
+}
+#endif
 
 /*
  * 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 *capath,
-            char *certfile, char *peer_certfile, char *privkeyfile)
+            char *certfile, char *privkeyfile, char *pkcs12)
 {
+#ifndef OPENSSL_NO_ENGINE
     char        *cert_engine_name = NULL;
-    char        *cert_identifier = NULL;
     char        *pkey_engine_name = NULL;
-    char        *pkey_identifier = NULL;
+    char        *idx;
+#endif
     SSL_CTX     *ctx;
     SSL         *ssl;
-    X509_STORE  *certstore;
-    X509_LOOKUP *lookup;
     X509        *tmp;
+    X509        *cert = NULL;
+    PKCS12      *p12 = NULL;
+    EVP_PKEY    *pkey = NULL;
+    STACK_OF(X509) *chain = NULL;
+    BIO         *input;
     int          ret;
-#if defined(TLS1_2_VERSION)
-    long         tls_version = TLS1_2_VERSION; 
-#elif defined(TLS1_1_VERSION)
-    long         tls_version = TLS1_1_VERSION; 
-#else
-    long         tls_version = TLS1_VERSION; 
-#endif
+    int          reason;
 
     /*
      * Without these can't continue 
      */
-    if (!(cacertfile[0] || capath[0]))
+    if (!pkcs12[0]) 
     {
-        error("EAP-TLS: CA certificate file or path missing");
-        return NULL;
-    }
+        if (!(cacertfile[0] || capath[0]))
+        {
+            error("EAP-TLS: CA certificate file or path missing");
+            return NULL;
+        }
 
-    if (!certfile[0])
-    {
-        error("EAP-TLS: Certificate missing");
-        return NULL;
-    }
+        if (!certfile[0])
+        {
+            error("EAP-TLS: Certificate missing");
+            return NULL;
+        }
 
-    if (!privkeyfile[0])
-    {
-        error("EAP-TLS: Private key missing");
-        return NULL;
+        if (!privkeyfile[0])
+        {
+            error("EAP-TLS: Private key missing");
+            return NULL;
+        }
     }
 
-    SSL_library_init();
-    SSL_load_error_strings();
+    tls_init();
 
+#ifndef OPENSSL_NO_ENGINE
     /* load the openssl config file only once and load it before triggering
        the loading of a global openssl config file via SSL_CTX_new()
      */
     if (!ssl_config)
         ssl_config = eaptls_ssl_load_config();
+#endif
 
-    ctx = SSL_CTX_new(TLS_method());
-
+    ctx = SSL_CTX_new(tls_method());
     if (!ctx) {
         error("EAP-TLS: Cannot initialize SSL CTX context");
         goto fail;
     }
 
+#ifndef OPENSSL_NO_ENGINE
     /* 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 )
+    if ( (idx = index( certfile, ':' )) != NULL )
     {
-        cert_identifier = index( certfile, ':' );
-
-        if (cert_identifier)
-        {
-            cert_engine_name = certfile;
-            *cert_identifier = '\0';
-            cert_identifier++;
+        cert_engine_name = strdup( certfile );
+        cert_engine_name[idx - certfile] = 0;
 
-            dbglog( "Found certificate engine '%s'", cert_engine_name );
-            dbglog( "Found certificate identifier '%s'", cert_identifier );
-        }
+        dbglog( "Using engine '%s' for certificate, URI: '%s'",
+                cert_engine_name, certfile );
     }
 
     /* if the privatekey filename is of the form engine:id. e.g.
@@ -369,39 +334,33 @@ SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath,
        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 )
+    if ( (idx = index( privkeyfile, ':' )) != NULL )
     {
-        pkey_identifier = index( privkeyfile, ':' );
-
-        if (pkey_identifier)
-        {
-            pkey_engine_name = privkeyfile;
-            *pkey_identifier = '\0';
-            pkey_identifier++;
+        pkey_engine_name = strdup( privkeyfile );
+        pkey_engine_name[idx - privkeyfile] = 0;
 
-            dbglog( "Found privatekey engine '%s'", pkey_engine_name );
-            dbglog( "Found privatekey identifier '%s'", pkey_identifier );
-        }
+        dbglog( "Using engine '%s' for private key, URI: '%s'",
+                pkey_engine_name, privkeyfile );
     }
 
-    if (cert_identifier && pkey_identifier)
+    if (cert_engine_name && pkey_engine_name)
     {
-        if (strlen( cert_identifier ) == 0)
+        if (strlen( certfile ) - strlen( cert_engine_name ) == 1)
         {
-            if (strlen( pkey_identifier ) == 0)
+            if (strlen( privkeyfile ) - strlen( pkey_engine_name ) == 1)
                 error( "EAP-TLS: both the certificate and privatekey identifiers are missing!" );
             else
             {
                 dbglog( "Substituting privatekey identifier for certificate identifier" );
-                cert_identifier = pkey_identifier;
+                certfile = privkeyfile;
             }
         }
         else
         {
-            if (strlen( pkey_identifier ) == 0)
+            if (strlen( privkeyfile ) - strlen( pkey_engine_name ) == 1)
             {
                 dbglog( "Substituting certificate identifier for privatekey identifier" );
-                pkey_identifier = cert_identifier;
+                privkeyfile = certfile;
             }
         }
     }
@@ -418,22 +377,24 @@ SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath,
             pkey_engine = eaptls_ssl_load_engine( pkey_engine_name );
     }
 
-    SSL_CTX_set_default_passwd_cb (ctx, password_callback);
+    if (cert_engine_name)
+        free(cert_engine_name);
 
-    if (strlen(cacertfile) == 0) cacertfile = NULL;
-    if (strlen(capath) == 0)     capath = NULL;
+    if (pkey_engine_name)
+        free(pkey_engine_name);
 
-    if (!SSL_CTX_load_verify_locations(ctx, cacertfile, capath))
-    {
-        error("EAP-TLS: Cannot load verify locations");
-        if (cacertfile) dbglog("CA certificate file = [%s]", cacertfile);
-        if (capath) dbglog("CA certificate path = [%s]", capath);
+#endif
+
+    SSL_CTX_set_default_passwd_cb (ctx, password_callback);
+
+    if (tls_set_ca(ctx, capath, cacertfile) != 0) {
         goto fail;
     }
 
     if (init_server)
         SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(cacertfile));
 
+#ifndef OPENSSL_NO_ENGINE
     if (cert_engine)
     {
         struct
@@ -442,40 +403,87 @@ SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath,
             X509 *cert;
         } cert_info;
 
-        cert_info.s_slot_cert_id = cert_identifier;
+        cert_info.s_slot_cert_id = certfile;
         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 );
+            error( "EAP-TLS: Error loading certificate with URI '%s' from engine", certfile );
             goto fail;
         }
 
         if (cert_info.cert)
         {
-            dbglog( "Got the certificate, adding it to SSL context" );
+            dbglog( "Got the certificate" );
             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)
+            cert = cert_info.cert;
+        }
+        else
+        {
+            warn("EAP-TLS: Cannot load key with URI: '%s'", certfile );
+            tls_log_sslerr();
+        }
+    }
+    else
+#endif
+    {
+        if (pkcs12[0])
+        {
+            input = BIO_new_file(pkcs12, "r");
+            if (input == NULL)
+            {
+                error("EAP-TLS: Cannot open `%s' PKCS12 for input", pkcs12);
+                goto fail;
+            }
+
+            p12 = d2i_PKCS12_bio(input, NULL);
+            BIO_free(input);
+            if (!p12)
+            {
+                error("EAP-TLS: Cannot load PKCS12 certificate");
+                goto fail;
+            }
+
+            if (PKCS12_parse(p12, passwd, &pkey, &cert, &chain) != 1)
             {
-                error("EAP-TLS: Cannot use PKCS11 certificate %s", cert_identifier);
+                error("EAP-TLS: Cannot parse PKCS12 certificate, invalid password");
+                PKCS12_free(p12);
                 goto fail;
             }
+
+            PKCS12_free(p12);
         }
-        else
+        else 
         {
-            warn("EAP-TLS: Cannot load PKCS11 key %s", cert_identifier);
-            log_ssl_errors();
+            if (!SSL_CTX_use_certificate_chain_file(ctx, certfile))
+            {
+                error( "EAP-TLS: Cannot load certificate %s", certfile );
+                goto fail;
+            }
         }
     }
-    else
+
+    if (cert)
     {
-        if (!SSL_CTX_use_certificate_chain_file(ctx, certfile))
+        if (!SSL_CTX_use_certificate(ctx, cert))
         {
-            error( "EAP-TLS: Cannot use public certificate %s", certfile );
+            error("EAP-TLS: Cannot use load certificate");
             goto fail;
         }
-    }
 
+        if (chain)
+        {
+            int i;
+            for (i = 0; i < sk_X509_num(chain); i++)
+            {
+                if (!SSL_CTX_add_extra_chain_cert(ctx, sk_X509_value(chain, i)))
+                {
+                    error("EAP-TLS: Cannot add extra chain certificate");
+                    goto fail;
+                }
+            }
+        }
+    }
 
     /*
      *  Check the Before and After dates of the certificate
@@ -504,86 +512,70 @@ SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath,
     }
     SSL_free(ssl);
 
+#ifndef OPENSSL_NO_ENGINE
     if (pkey_engine)
     {
-        EVP_PKEY   *pkey = NULL;
         PW_CB_DATA  cb_data;
 
         cb_data.password = passwd;
-        cb_data.prompt_info = pkey_identifier;
+        cb_data.prompt_info = privkeyfile;
 
         if (passwd[0] != 0)
         {
             UI_METHOD* transfer_pin = UI_create_method("transfer_pin");
 
-            int writer (UI *ui, UI_STRING *uis)
-            {
-                PW_CB_DATA* cb_data = (PW_CB_DATA*)UI_get0_user_data(ui);
-                UI_set_result(ui, uis, cb_data->password);
-                return 1;
-            };
-            int stub (UI* ui) {return 1;};
-            int stub_reader (UI *ui, UI_STRING *uis) {return 1;};
-
-            UI_method_set_writer(transfer_pin,  writer);
-            UI_method_set_opener(transfer_pin,  stub);
-            UI_method_set_closer(transfer_pin,  stub);
-            UI_method_set_flusher(transfer_pin, stub);
-            UI_method_set_reader(transfer_pin,  stub_reader);
-
-            dbglog( "Using our private key '%s' in engine", pkey_identifier );
-            pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, transfer_pin, &cb_data);
+            UI_method_set_writer(transfer_pin,  eaptls_UI_writer);
+            UI_method_set_opener(transfer_pin,  eaptls_UI_stub);
+            UI_method_set_closer(transfer_pin,  eaptls_UI_stub);
+            UI_method_set_flusher(transfer_pin, eaptls_UI_stub);
+            UI_method_set_reader(transfer_pin,  eaptls_UI_reader);
+
+            dbglog( "Using our private key URI: '%s' in engine", privkeyfile );
+            pkey = ENGINE_load_private_key(pkey_engine, privkeyfile, transfer_pin, &cb_data);
 
             if (transfer_pin) UI_destroy_method(transfer_pin);
         }
         else {
-            dbglog( "Loading private key '%s' from engine", pkey_identifier );
-            pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, NULL, NULL);
+            dbglog( "Loading private key URI: '%s' from engine", privkeyfile );
+            pkey = ENGINE_load_private_key(pkey_engine, privkeyfile, NULL, NULL);
         }
-        if (pkey)
+    }
+    else 
+#endif
+    {
+        if (!pkey)
         {
-            dbglog( "Got the private key, adding it to SSL context" );
-            if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0)
+            input = BIO_new_file(privkeyfile, "r");
+            if (!input)
             {
-                error("EAP-TLS: Cannot use PKCS11 key %s", pkey_identifier);
+                error("EAP-TLS: Could not open private key, %s", privkeyfile);
+                goto fail;
+            }
+
+            pkey = PEM_read_bio_PrivateKey(input, NULL, password_callback, NULL);
+            BIO_free(input);
+            if (!pkey)
+            {
+                error("EAP-TLS: Cannot load private key, %s", privkeyfile);
                 goto fail;
             }
-        }
-        else
-        {
-            warn("EAP-TLS: Cannot load PKCS11 key %s", pkey_identifier);
-            log_ssl_errors();
         }
     }
-    else
+
+    if (SSL_CTX_use_PrivateKey(ctx, pkey) != 1)
     {
-        if (!SSL_CTX_use_PrivateKey_file(ctx, privkeyfile, SSL_FILETYPE_PEM))
-        { 
-            error("EAP-TLS: Cannot use private key %s", privkeyfile);
-            goto fail;
-        }
+        error("EAP-TLS: Cannot use private key");
+        goto fail;
     }
 
-    if (SSL_CTX_check_private_key(ctx) != 1) {
-        error("EAP-TLS: Private key %s fails security check", privkeyfile);
+    if (SSL_CTX_check_private_key(ctx) != 1)
+    {
+        error("EAP-TLS: Private key fails security check");
         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
-    );
-
-    /* OpenSSL 1.1.1+ does not include RC4 ciphers by default.
-     * This causes totally obsolete WinXP clients to fail. If you really
-     * need ppp+EAP-TLS+openssl 1.1.1+WinXP then enable RC4 cipers and
-     * make sure that you use an OpenSSL that supports them
-
-    SSL_CTX_set_cipher_list(ctx, "RC4");
-     */
-
+    /* Configure the default options */
+    tls_set_opts(ctx);
 
     /* Set up a SSL Session cache with a callback. This is needed for TLSv1.3+.
      * During the initial handshake the server signals to the client early on
@@ -595,100 +587,33 @@ SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath,
     SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE);
     SSL_CTX_sess_set_new_cb(ctx, ssl_new_session_cb);
 
-    /* As EAP-TLS+TLSv1.3 is highly experimental we offer the user a chance to override */
-    if (max_tls_version)
-    {
-        if (strncmp(max_tls_version, "1.0", 3) == 0)
-            tls_version = TLS1_VERSION;
-        else if (strncmp(max_tls_version, "1.1", 3) == 0)
-            tls_version = TLS1_1_VERSION;
-        else if (strncmp(max_tls_version, "1.2", 3) == 0)
-#ifdef TLS1_2_VERSION
-            tls_version = TLS1_2_VERSION;
-#else
-        {
-            warn("TLSv1.2 not available. Defaulting to TLSv1.1");
-            tls_version = TLS_1_1_VERSION;
-        }
-#endif
-        else if (strncmp(max_tls_version, "1.3", 3) == 0)
-#ifdef TLS1_3_VERSION
-            tls_version = TLS1_3_VERSION;
-#else
-            warn("TLSv1.3 not available.");
-#endif
-    }
-
-    dbglog("EAP-TLS: Setting max protocol version to 0x%X", tls_version);
-    SSL_CTX_set_max_proto_version(ctx, tls_version);
-
-    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");
+    /* Configure the maximum SSL version */
+    tls_set_version(ctx, max_tls_version);
 
-            goto fail;
-        }
-
-        X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM);
-        X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
+    /* Configure the callback */
+    if (tls_set_verify(ctx, 5)) {
+        goto fail;
     }
 
-    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;
-        }
+    /* Configure CRL check (if any) */
+    if (tls_set_crl(ctx, crl_dir, 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;
-        }
+    return ctx;
 
-        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);
+fail:
 
-    }
+    if (cert)
+        X509_free(cert);
 
-    /*
-     * 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);
-    }
+    if (pkey)
+        EVP_PKEY_free(pkey);
 
-    return ctx;
+    if (chain)
+        sk_X509_pop_free(chain, X509_free);
 
-fail:
-    log_ssl_errors();
+    tls_log_sslerr();
     SSL_CTX_free(ctx);
     return NULL;
 }
@@ -726,6 +651,8 @@ int eaptls_init_ssl_server(eap_state * esp)
     char cacertfile[MAXWORDLEN];
     char capath[MAXWORDLEN];
     char pkfile[MAXWORDLEN];
+    char pkcs12[MAXWORDLEN];
+
     /*
      * Allocate new eaptls session 
      */
@@ -739,12 +666,10 @@ int eaptls_init_ssl_server(eap_state * esp)
         return 0;
     }
 
-    strlcpy(ets->peer, esp->es_server.ea_peer, MAXWORDLEN-1);
-
     dbglog( "getting eaptls secret" );
     if (!get_eaptls_secret(esp->es_unit, esp->es_server.ea_peer,
                    esp->es_server.ea_name, clicertfile,
-                   servcertfile, cacertfile, capath, pkfile, 1)) {
+                   servcertfile, cacertfile, capath, pkfile, pkcs12, 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;
@@ -752,13 +677,17 @@ int eaptls_init_ssl_server(eap_state * esp)
 
     ets->mtu = eaptls_get_mtu(esp->es_unit);
 
-    ets->ctx = eaptls_init_ssl(1, cacertfile, capath, servcertfile, clicertfile, pkfile);
+    ets->ctx = eaptls_init_ssl(1, cacertfile, capath, servcertfile, pkfile, pkcs12);
     if (!ets->ctx)
         goto fail;
 
     if (!(ets->ssl = SSL_new(ets->ctx)))
         goto fail;
 
+    if (tls_set_verify_info(ets->ssl, esp->es_server.ea_peer,
+            clicertfile, 0, &ets->info))
+        goto fail;
+
     /*
      * Set auto-retry to avoid timeouts on BIO_read
      */
@@ -774,12 +703,6 @@ int eaptls_init_ssl_server(eap_state * esp)
     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->tls_v13 = 0;
@@ -788,16 +711,6 @@ int eaptls_init_ssl_server(eap_state * esp)
     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])
-        strlcpy(&ets->peercertfile[0], clicertfile, MAXWORDLEN);
-    else
-        ets->peercertfile[0] = 0;
-
     return 1;
 
 fail:
@@ -816,6 +729,7 @@ int eaptls_init_ssl_client(eap_state * esp)
     char cacertfile[MAXWORDLEN];
     char capath[MAXWORDLEN];
     char pkfile[MAXWORDLEN];
+    char pkcs12[MAXWORDLEN];
 
     /*
      * Allocate new eaptls session 
@@ -824,37 +738,30 @@ int eaptls_init_ssl_client(eap_state * esp)
     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)
-        strlcpy(ets->peer, esp->es_client.ea_peer, MAXWORDLEN-1);
-    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, capath, pkfile, 0)) {
+                   esp->es_client.ea_peer, clicertfile,
+                   servcertfile, cacertfile, capath, pkfile, pkcs12, 0)) {
         error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"",
-                esp->es_client.ea_name, ets->peer );
+                esp->es_client.ea_name, esp->es_client.ea_peer);
         return 0;
     }
 
     dbglog( "calling eaptls_init_ssl" );
-    ets->ctx = eaptls_init_ssl(0, cacertfile, capath, clicertfile, servcertfile, pkfile);
+    ets->ctx = eaptls_init_ssl(0, cacertfile, capath, clicertfile, pkfile, pkcs12);
     if (!ets->ctx)
         goto fail;
 
     ets->ssl = SSL_new(ets->ctx);
-
     if (!ets->ssl)
         goto fail;
 
+    if (tls_set_verify_info(ets->ssl, esp->es_client.ea_peer,
+            servcertfile, 0, &ets->info))
+        goto fail;
+
     /*
      * Initialize the BIOs we use to read/write to ssl engine 
      */
@@ -865,13 +772,6 @@ int eaptls_init_ssl_client(eap_state * esp)
 
     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->tls_v13 = 0;
@@ -880,17 +780,6 @@ int eaptls_init_ssl_client(eap_state * esp)
     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])
-        strlcpy(ets->peercertfile, servcertfile, MAXWORDLEN);
-    else
-        ets->peercertfile[0] = 0;
-
     return 1;
 
 fail:
@@ -908,6 +797,9 @@ void eaptls_free_session(struct eaptls_session *ets)
     if (ets->ctx)
         SSL_CTX_free(ets->ctx);
 
+    if (ets->info)
+        tls_free_verify_info(&ets->info);
+
     free(ets);
 }
 
@@ -1017,7 +909,7 @@ int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len)
         }
 
         if (BIO_write(ets->into_ssl, ets->data, ets->datalen) == -1)
-            log_ssl_errors();
+            tls_log_sslerr();
 
         SSL_read(ets->ssl, dummy, 65536);
 
@@ -1132,133 +1024,6 @@ void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp)
     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 ok, X509_STORE_CTX * ctx)
-{
-    char subject[256];
-    char cn_str[256];
-    X509 *peer_cert;
-    int err, depth;
-    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 ok;
-        }
-
-        /*
-         * 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 ok;
-}
-
-/*
- * 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
index cdbc9e4e4f9e90cf6139ea39b1eb13e75e0f581c..9c56687858aeece748575f2a96648483debb2ddd 100644 (file)
@@ -30,6 +30,8 @@
  *
  */
 
+#include "pppdconf.h"
+
 #ifndef __EAP_TLS_H__
 #define __EAP_TLS_H__
 
@@ -44,6 +46,8 @@
 
 #define EAP_TLS_MAX_LEN         65536  /* max eap tls packet size */
 
+struct tls_info;
+
 struct eaptls_session
 {
     u_char *data;               /* buffered data */
@@ -56,7 +60,6 @@ struct eaptls_session
     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;
@@ -65,11 +68,12 @@ struct eaptls_session
     char rtx[EAP_TLS_MAX_LEN];  /* retransmission buffer */
     int rtx_len;
     int mtu;                    /* unit mtu */
+    struct tls_info *info;
 };
 
 
 SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath,
-            char *certfile, char *peer_certfile, char *privkeyfile);
+            char *certfile, char *privkeyfile, char *pkcs12);
 int eaptls_init_ssl_server(eap_state * esp);
 int eaptls_init_ssl_client(eap_state * esp);
 void eaptls_free_session(struct eaptls_session *ets);
@@ -82,14 +86,9 @@ 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 *capath, char *pkfile, int am_server);
+              char *capath, char *pkfile, char *pkcs12, 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, int client);
 #endif
 
index 79146557bd32116975874f9c68cd222647a7d1f3..54c3d42b85fe82edce41c3571e3a6af937b8dbae 100644 (file)
  * Implemented EAP-TLS authentication
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include "pathnames.h"
 #include "md5.h"
 #include "eap.h"
-
-#ifdef CHAPMS
-#include "chap_ms.h"
-#endif
+#ifdef USE_PEAP
+#include "peap.h"
+#endif /* USE_PEAP */
 
 #ifdef USE_SRP
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
 #include <t_pwd.h>
 #include <t_server.h>
 #include <t_client.h>
 #ifdef USE_EAPTLS
 #include "eap-tls.h"
 #endif /* USE_EAPTLS */
+
 #ifdef CHAPMS
-#include "magic.h"
 #include "chap_ms.h"
 #include "chap-new.h"
+
+extern int chapms_strip_domain;
 #endif /* CHAPMS */
 
 eap_state eap_states[NUM_PPP];         /* EAP state; one for each unit */
@@ -223,7 +231,8 @@ eap_init(int unit)
        esp->es_client.ea_using_eaptls = 0;
 #endif /* USE_EAPTLS */
 #ifdef CHAPMS
-        esp->es_client.digest = chap_find_digest(CHAP_MICROSOFT_V2);
+       esp->es_client.digest = chap_find_digest(CHAP_MICROSOFT_V2);
+       esp->es_server.digest = chap_find_digest(CHAP_MICROSOFT_V2);
 #endif
 }
 
@@ -553,7 +562,7 @@ eap_figure_next_state(eap_state *esp, int status)
                        tpw.pebuf.name = esp->es_server.ea_peer;
                        tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf,
                            cp);
-                       tpw.pebuf.password.data = tpw.pwbuf;
+                       tpw.pebuf.password.data = (char*) tpw.pwbuf;
                        tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf,
                            cp2);
                        tpw.pebuf.salt.data = tpw.saltbuf;
@@ -719,92 +728,6 @@ eap_figure_next_state(eap_state *esp, int status)
 }
 
 #if CHAPMS
-static int
-eap_chapms2_verify_response(int id, char *name,
-                           unsigned char *secret, int secret_len,
-                           unsigned char *challenge, unsigned char *response,
-                           char *message, int message_space)
-{
-       unsigned char md[MS_CHAP2_RESPONSE_LEN];
-       char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
-       int challenge_len, response_len;
-
-       challenge_len = *challenge++;   /* skip length, is 16 */
-       response_len = *response++;
-       if (response_len != MS_CHAP2_RESPONSE_LEN)
-               goto bad;       /* not even the right length */
-
-       /* Generate the expected response and our mutual auth. */
-       ChapMS2(challenge, &response[MS_CHAP2_PEER_CHALLENGE], name,
-               (char *)secret, secret_len, md,
-               (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR);
-
-       /* compare MDs and send the appropriate status */
-       /*
-        * Per RFC 2759, success message must be formatted as
-        *     "S=<auth_string> M=<message>"
-        * where
-        *     <auth_string> is the Authenticator Response (mutual auth)
-        *     <message> is a text message
-        *
-        * However, some versions of Windows (win98 tested) do not know
-        * about the M=<message> part (required per RFC 2759) and flag
-        * it as an error (reported incorrectly as an encryption error
-        * to the user).  Since the RFC requires it, and it can be
-        * useful information, we supply it if the peer is a conforming
-        * system.  Luckily (?), win98 sets the Flags field to 0x04
-        * (contrary to RFC requirements) so we can use that to
-        * distinguish between conforming and non-conforming systems.
-        *
-        * Special thanks to Alex Swiridov <say@real.kharkov.ua> for
-        * help debugging this.
-        */
-       if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP],
-                  MS_CHAP2_NTRESP_LEN) == 0) {
-               if (response[MS_CHAP2_FLAGS])
-                       slprintf(message, message_space, "S=%s", saresponse);
-               else
-                       slprintf(message, message_space, "S=%s M=%s",
-                                saresponse, "Access granted");
-               return 1;
-       }
-
- bad:
-       /*
-        * Failure message must be formatted as
-        *     "E=e R=r C=c V=v M=m"
-        * where
-        *     e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE)
-        *     r = retry (we use 1, ok to retry)
-        *     c = challenge to use for next response, we reuse previous
-        *     v = Change Password version supported, we use 0
-        *     m = text message
-        *
-        * The M=m part is only for MS-CHAPv2.  Neither win2k nor
-        * win98 (others untested) display the message to the user anyway.
-        * They also both ignore the E=e code.
-        *
-        * Note that it's safe to reuse the same challenge as we don't
-        * actually accept another response based on the error message
-        * (and no clients try to resend a response anyway).
-        *
-        * Basically, this whole bit is useless code, even the small
-        * implementation here is only because of overspecification.
-        */
-       slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s",
-                challenge_len, challenge, "Access denied");
-       return 0;
-}
-
-static struct chap_digest_type eap_chapms2_digest = {
-       CHAP_MICROSOFT_V2,      /* code */
-       NULL, /* chapms2_generate_challenge, */
-       eap_chapms2_verify_response,
-       NULL, /* chapms2_make_response, */
-       NULL, /* chapms2_check_success, */
-       NULL, /* chapms_handle_failure, */
-};
-
 /*
  * eap_chap_verify_response - check whether the peer's response matches
  * what we think it should be.  Returns 1 if it does (authentication
@@ -961,10 +884,9 @@ eap_send_request(eap_state *esp)
 
 #ifdef CHAPMS
        case eapMSCHAPv2Chall:
-               challen = 0x10;
+               esp->es_server.digest->generate_challenge(esp->es_challenge);
+               challen = esp->es_challenge[0];
                esp->es_challen = challen;
-               esp->es_challenge[0] = challen;
-               random_bytes(&esp->es_challenge[1], challen);
 
                PUTCHAR(EAPT_MSCHAPV2, outp);
                PUTCHAR(CHAP_CHALLENGE, outp);
@@ -2297,6 +2219,28 @@ eap_request(eap_state *esp, u_char *inp, int id, int len)
 
            break;
 #endif /* CHAPMS */
+#ifdef USE_PEAP
+       case EAPT_PEAP:
+
+               /* Initialize the PEAP context (if not already initialized) */
+               if (!esp->ea_peap) {
+                       rhostname[0] = '\0';
+                       if (explicit_remote || (remote_name[0] != '\0')) {
+                               strlcpy(rhostname, remote_name, sizeof (rhostname));
+                       }
+                       if (peap_init(&esp->ea_peap, rhostname)) {
+                               eap_send_nak(esp, id, EAPT_TLS);
+                               break;
+                       }
+               }
+
+               /* Process the PEAP packet */
+               if (peap_process(esp, id, inp, len)) {
+                       eap_send_nak(esp, id, EAPT_TLS);
+               }
+
+               break;
+#endif /* USE_PEAP */
 
        default:
                info("EAP: unknown authentication type %d; Naking", typenum);
@@ -2341,8 +2285,6 @@ eap_response(eap_state *esp, u_char *inp, int id, int len)
        struct t_num A;
        SHA1_CTX ctxt;
        u_char dig[SHA_DIGESTSIZE];
-       SHA1_CTX ctxt;
-       u_char dig[SHA_DIGESTSIZE];
 #endif /* USE_SRP */
 
 #ifdef USE_EAPTLS
@@ -2500,6 +2442,12 @@ eap_response(eap_state *esp, u_char *inp, int id, int len)
 #ifdef CHAPMS
                case EAPT_MSCHAPV2:
                        info("EAP: peer proposes MSCHAPv2");
+                       /* If MSCHAPv2 digest was not found, NAK the packet */
+                       if (!esp->es_server.digest) {
+                               error("EAP MSCHAPv2 not supported");
+                               eap_send_nak(esp, id, EAPT_SRP);
+                               break;
+                       }
                        esp->es_server.ea_state = eapMSCHAPv2Chall;
                        break;
 #endif /* CHAPMS */
@@ -2629,6 +2577,14 @@ eap_response(eap_state *esp, u_char *inp, int id, int len)
                                        (remote_name[0] != '\0' && vallen == len))
                                strlcpy(rhostname, remote_name, sizeof (rhostname));
 
+                       /* strip the MS domain name */
+                       if (chapms_strip_domain && strrchr(rhostname, '\\')) {
+                               char tmp[MAXNAMELEN+1];
+
+                               strcpy(tmp, strrchr(rhostname, '\\') + 1);
+                               strcpy(rhostname, tmp);
+                       }
+
                        if (chap_verify_hook)
                                chap_verifier = chap_verify_hook;
                        else
@@ -2638,7 +2594,7 @@ eap_response(eap_state *esp, u_char *inp, int id, int len)
                        if ((*chap_verifier)(rhostname,
                                                esp->es_server.ea_name,
                                                id,
-                                               &eap_chapms2_digest,
+                                               esp->es_server.digest,
                                                esp->es_challenge,
                                                inp - 1,
                                                response_message,
@@ -2838,6 +2794,10 @@ eap_success(eap_state *esp, u_char *inp, int id, int len)
                PRINTMSG(inp, len);
        }
 
+#ifdef USE_PEAP
+       peap_finish(&esp->ea_peap);
+#endif
+
        esp->es_client.ea_state = eapOpen;
        auth_withpeer_success(esp->es_unit, PPP_EAP, 0);
 }
@@ -2872,6 +2832,11 @@ eap_failure(eap_state *esp, u_char *inp, int id, int len)
        esp->es_client.ea_state = eapBadAuth;
 
        error("EAP: peer reports authentication failure");
+
+#ifdef USE_PEAP
+       peap_finish(&esp->ea_peap);
+#endif
+
        auth_withpeer_fail(esp->es_unit, PPP_EAP);
 }
 
@@ -3095,6 +3060,7 @@ eap_printpkt(u_char *inp, int inlen,
                        break;
 #endif /* USE_EAPTLS */
 
+#ifdef USE_SRP
                case EAPT_SRP:
                        if (len < 3)
                                goto truncated;
@@ -3182,6 +3148,7 @@ eap_printpkt(u_char *inp, int inlen,
                                break;
                        }
                        break;
+#endif  /* USE_SRP */
                }
                break;
 
@@ -3307,6 +3274,7 @@ eap_printpkt(u_char *inp, int inlen,
                        break;
 #endif /* CHAPMS */
 
+#ifdef USE_SRP
                case EAPT_SRP:
                        if (len < 1)
                                goto truncated;
@@ -3351,6 +3319,7 @@ eap_printpkt(u_char *inp, int inlen,
                                break;
                        }
                        break;
+#endif  /* USE_SRP */
                }
                break;
 
index 046eb1cf8436b3c91a77340c7dd25ea0d2f6b819..5d582bc6e2db60ad61ec194ec55347674dcffa8e 100644 (file)
@@ -20,6 +20,8 @@
  * $Id: eap.h,v 1.2 2003/06/11 23:56:26 paulus Exp $
  */
 
+#include "pppdconf.h"
+
 #ifndef PPP_EAP_H
 #define        PPP_EAP_H
 
@@ -167,6 +169,9 @@ typedef struct eap_state {
        int es_unit;                    /* Interface unit number */
        struct eap_auth es_client;      /* Client (authenticatee) data */
        struct eap_auth es_server;      /* Server (authenticator) data */
+#ifdef USE_PEAP
+       struct peap_state *ea_peap;     /* Client PEAP (authenticator) data */
+#endif
        int es_savedtime;               /* Saved timeout */
        int es_rechallenge;             /* EAP rechallenge interval */
        int es_lwrechallenge;           /* SRP lightweight rechallenge inter */
index 1ecd7be0d79e64007085e51763bee6b3c3f7fa6d..9570f389561ffc7daec9d0df7c8872baff8199ab 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <string.h>
 
 #include "pppd.h"
index df6e3ca1abf2b46804999eaad19addddf6d0f8ed..162dace7e07915c62cc39198eb56be2b146dfe03 100644 (file)
@@ -30,6 +30,7 @@
  *
  * $Id: ecp.h,v 1.2 2003/01/10 07:12:36 fcusack Exp $
  */
+#include "pppdconf.h"
 
 typedef struct ecp_options {
     bool required;             /* Is ECP required? */
index 98caf9447408d6ea4741d49f3c4e065852373bf6..7978c06c204d887e6bdce9a7ea8cb2f5fcca68ee 100644 (file)
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "pppd.h"
 
 
index c48d689eda7b0dcf40df2e0bd83c7199d66705b0..aa83e1a092b8abf28a31eb14fd85c1e5dba3eea5 100644 (file)
@@ -34,6 +34,8 @@
  *
  */
 
+#include "pppdconf.h"
+
 #ifndef __EUI64_H__
 #define __EUI64_H__
 
index 96d20e86e98db3160de9eda59033d578d8c4b6fe..17cb76f8fd11e2cd53943ff598c57e0273419dd3 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 /*
  * TODO:
  * Randomize fsm id on link/init.
index 75a36d52fe94e9172a0578ef5491a06e2fb26344..d23725c9e7eccb31620870c2063fd3896e83ac12 100644 (file)
@@ -42,6 +42,8 @@
  * $Id: fsm.h,v 1.10 2004/11/13 02:28:15 paulus Exp $
  */
 
+#include "pppdconf.h"
+
 /*
  * Packet header = Code, id, length.
  */
index 6e0d5f66f57c86b5572b315cb434a65166caabd2..0dc251e503d725f4bec5f7f81953fafcc0f04168 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 /*
  * TODO:
  */
@@ -682,8 +686,9 @@ ipcp_resetci(fsm *f)
     ipcp_options *go = &ipcp_gotoptions[f->unit];
     ipcp_options *ao = &ipcp_allowoptions[f->unit];
 
-    wo->req_addr = (wo->neg_addr || wo->old_addrs) &&
-       (ao->neg_addr || ao->old_addrs);
+    wo->req_addr = ((wo->neg_addr || wo->old_addrs) &&
+       (ao->neg_addr || ao->old_addrs)) ||
+       (wo->hisaddr && !wo->accept_remote);
     if (wo->ouraddr == 0)
        wo->accept_local = 1;
     if (wo->hisaddr == 0)
@@ -1000,6 +1005,7 @@ bad:
 static int
 ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
 {
+    ipcp_options *wo = &ipcp_wantoptions[f->unit];
     ipcp_options *go = &ipcp_gotoptions[f->unit];
     u_char cimaxslotindex, cicflag;
     u_char citype, cilen, *next;
@@ -1204,7 +1210,7 @@ ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
            GETLONG(l, p);
            ciaddr1 = htonl(l);
            if (ciaddr1 && go->accept_local)
-               try.ouraddr = ciaddr1;
+               try.ouraddr = wo->old_addrs ? ciaddr1 : 0;
            GETLONG(l, p);
            ciaddr2 = htonl(l);
            if (ciaddr2 && go->accept_remote)
@@ -1219,7 +1225,7 @@ ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
            ciaddr1 = htonl(l);
            if (ciaddr1 && go->accept_local)
                try.ouraddr = ciaddr1;
-           if (try.ouraddr != 0)
+           if (try.ouraddr != 0 && wo->neg_addr)
                try.neg_addr = 1;
            no.neg_addr = 1;
            break;
@@ -1511,7 +1517,7 @@ ipcp_reqci(fsm *f, u_char *inp,   int *len, int reject_if_disagree)
            if (ciaddr2 != wo->ouraddr) {
                if (ciaddr2 == 0 || !wo->accept_local) {
                    orc = CONFNAK;
-                   if (!reject_if_disagree) {
+                   if (!reject_if_disagree && wo->old_addrs) {
                        DECPTR(sizeof(u_int32_t), p);
                        tl = ntohl(wo->ouraddr);
                        PUTLONG(tl, p);
@@ -1688,7 +1694,8 @@ endswitch:
      * option safely.
      */
     if (rc != CONFREJ && !ho->neg_addr && !ho->old_addrs &&
-       wo->req_addr && !reject_if_disagree && !noremoteip) {
+       wo->req_addr && !reject_if_disagree &&
+       ((wo->hisaddr && !wo->accept_remote) || !noremoteip)) {
        if (rc == CONFACK) {
            rc = CONFNAK;
            ucp = inp;                  /* reset pointer */
@@ -1800,6 +1807,12 @@ ipcp_up(fsm *f)
     /*
      * We must have a non-zero IP address for both ends of the link.
      */
+
+    if (wo->hisaddr && !wo->accept_remote && (!(ho->neg_addr || ho->old_addrs) || ho->hisaddr != wo->hisaddr)) {
+       error("Peer refused to agree to his IP address");
+       ipcp_close(f->unit, "Refused his IP address");
+       return;
+    }
     if (!ho->neg_addr && !ho->old_addrs)
        ho->hisaddr = wo->hisaddr;
 
@@ -1870,9 +1883,10 @@ ipcp_up(fsm *f)
                wo->ouraddr = go->ouraddr;
            } else
                script_unsetenv("OLDIPLOCAL");
-           if (ho->hisaddr != wo->hisaddr && wo->hisaddr != 0) {
+           if (ho->hisaddr != wo->hisaddr) {
                warn("Remote IP address changed to %I", ho->hisaddr);
-               script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0);
+               if (wo->hisaddr != 0)
+                   script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0);
                wo->hisaddr = ho->hisaddr;
            } else
                script_unsetenv("OLDIPREMOTE");
index 2ec8190cd53bde1a163997bfb757b71cf9c94b7e..90336c4013cd1aaddb27409db28e9cef7c21f8a9 100644 (file)
@@ -39,6 +39,7 @@
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#include "pppdconf.h"
 
 /*
  * Options.
index 431cb62211bff1d28de4ca8151c070199a615877..8ab440a95f683015bcc2226c8a759173369c203c 100644 (file)
  *   since SVR4 && (SNI || __USLC__) didn't work properly)
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -239,9 +243,9 @@ static option_t ipv6cp_option_list[] = {
     { "-ipv6", o_bool, &ipv6cp_protent.enabled_flag,
       "Disable IPv6 and IPv6CP", OPT_PRIOSUB | OPT_ALIAS },
 
-    { "ipv6cp-accept-local", o_bool, &ipv6cp_allowoptions[0].accept_local,
+    { "ipv6cp-accept-local", o_bool, &ipv6cp_wantoptions[0].accept_local,
       "Accept peer's interface identifier for us", 1 },
-    { "ipv6cp-accept-remote", o_bool, &ipv6cp_allowoptions[0].accept_remote,
+    { "ipv6cp-accept-remote", o_bool, &ipv6cp_wantoptions[0].accept_remote,
       "Accept peer's interface identifier for itself", 1 },
 
     { "defaultroute6", o_bool, &ipv6cp_wantoptions[0].default_route,
@@ -528,7 +532,8 @@ ipv6cp_resetci(fsm *f)
     
     if (!wo->opt_local) {
        wo->accept_local = 1;
-       eui64_magic_nz(wo->ourid);
+       if (!demand)
+           eui64_magic_nz(wo->ourid);
     }
     if (!wo->opt_remote)
        wo->accept_remote = 1;
@@ -719,7 +724,9 @@ ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
     NAKCIIFACEID(CI_IFACEID, neg_ifaceid,
                 if (treat_as_reject) {
                     try.neg_ifaceid = 0;
-                } else if (go->accept_local) {
+                } else if (go->accept_local && !eui64_iszero(ifaceid) && !eui64_equals(ifaceid, go->hisid)) {
+                    try.ourid = ifaceid;
+                } else if (eui64_iszero(ifaceid) && !go->opt_local) {
                     while (eui64_iszero(ifaceid) || 
                            eui64_equals(ifaceid, go->hisid)) /* bad luck */
                         eui64_magic(ifaceid);
@@ -771,11 +778,15 @@ ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
                goto bad;
            try.neg_ifaceid = 1;
            eui64_get(ifaceid, p);
-           if (go->accept_local) {
+           if (go->accept_local && !eui64_iszero(ifaceid) && !eui64_equals(ifaceid, go->hisid)) {
+               try.ourid = ifaceid;
+           } else if (eui64_iszero(ifaceid) && !go->opt_local) {
                while (eui64_iszero(ifaceid) || 
                       eui64_equals(ifaceid, go->hisid)) /* bad luck */
                    eui64_magic(ifaceid);
                try.ourid = ifaceid;
+           } else {
+               try.neg_ifaceid = 0;
            }
            no.neg_ifaceid = 1;
            break;
@@ -942,8 +953,7 @@ ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree)
                break;
            }
            if (!eui64_iszero(wo->hisid) && !wo->accept_remote &&
-               !eui64_equals(ifaceid, wo->hisid) && 
-               eui64_iszero(go->hisid)) {
+               !eui64_equals(ifaceid, wo->hisid)) {
                    
                orc = CONFNAK;
                ifaceid = wo->hisid;
@@ -955,9 +965,17 @@ ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree)
                orc = CONFNAK;
                if (eui64_iszero(go->hisid))    /* first time, try option */
                    ifaceid = wo->hisid;
-               while (eui64_iszero(ifaceid) || 
-                      eui64_equals(ifaceid, go->ourid)) /* bad luck */
-                   eui64_magic(ifaceid);
+               if (eui64_equals(ifaceid, go->ourid)) /* bad luck */
+                   eui64_zero(ifaceid);
+               if (eui64_iszero(ifaceid)) {
+                   if (wo->opt_remote)
+                       ifaceid = wo->hisid;
+                   else {
+                       while (eui64_iszero(ifaceid) ||
+                              eui64_equals(ifaceid, go->ourid)) /* bad luck */
+                           eui64_magic(ifaceid);
+                   }
+               }
                go->hisid = ifaceid;
                DECPTR(sizeof(ifaceid), p);
                eui64_put(ifaceid, p);
@@ -1069,7 +1087,7 @@ ether_to_eui64(eui64_t *p_eui64)
 {
     u_char addr[6];
 
-    if (get_if_hwaddr(addr, devnam) < 0 || get_first_ether_hwaddr(addr) < 0) {
+    if (get_if_hwaddr(addr, devnam) < 0 && get_first_ether_hwaddr(addr) < 0) {
         error("ipv6cp: no persistent id can be found");
         return 0;
     }
@@ -1106,7 +1124,7 @@ ipv6_check_options(void)
      * Persistent link-local id is only used when user has not explicitly
      * configure/hard-code the id
      */
-    if ((wo->use_persistent) && (!wo->opt_local) && (!wo->opt_remote)) {
+    if ((wo->use_persistent) && (!wo->opt_local)) {
 
        /* 
         * On systems where there are no Ethernet interfaces used, there
@@ -1140,11 +1158,6 @@ ipv6_check_options(void)
                wo->opt_remote = 1;
        }
     }
-
-    if (demand && (eui64_iszero(wo->ourid) || eui64_iszero(wo->hisid))) {
-       option_error("local/remote LL address required for demand-dialling\n");
-       exit(EXIT_OPTION_ERROR);
-    }
 }
 
 
@@ -1157,6 +1170,15 @@ ipv6_demand_conf(int u)
 {
     ipv6cp_options *wo = &ipv6cp_wantoptions[u];
 
+    if (eui64_iszero(wo->hisid)) {
+       /* make up an arbitrary identifier for the peer */
+       eui64_magic_nz(wo->hisid);
+    }
+    if (eui64_iszero(wo->ourid)) {
+       /* make up an arbitrary identifier for us */
+       eui64_magic_nz(wo->ourid);
+    }
+
     if (!sif6up(u))
        return 0;
     if (!sif6addr(u, wo->ourid, wo->hisid))
@@ -1171,7 +1193,6 @@ ipv6_demand_conf(int u)
        if (sif6defaultroute(u, wo->ourid, wo->hisid))
            default_route_set[u] = 1;
 
-    notice("ipv6_demand_conf");
     notice("local  LL address %s", llv6_ntoa(wo->ourid));
     notice("remote LL address %s", llv6_ntoa(wo->hisid));
 
@@ -1196,6 +1217,12 @@ ipv6cp_up(fsm *f)
     /*
      * We must have a non-zero LL address for both ends of the link.
      */
+
+    if (!eui64_iszero(wo->hisid) && !wo->accept_remote && (!ho->neg_ifaceid || !eui64_equals(ho->hisid, wo->hisid))) {
+       error("Peer refused to agree to his interface identifier");
+       ipv6cp_close(f->unit, "Refused his interface identifier");
+       return;
+    }
     if (!ho->neg_ifaceid)
        ho->hisid = wo->hisid;
 
@@ -1238,7 +1265,7 @@ ipv6cp_up(fsm *f)
            if (! eui64_equals(ho->hisid, wo->hisid))
                warn("Remote LL address changed to %s", 
                     llv6_ntoa(ho->hisid));
-           ipv6cp_clear_addrs(f->unit, go->ourid, ho->hisid);
+           ipv6cp_clear_addrs(f->unit, wo->ourid, wo->hisid);
 
            /* Set the interface to the new addresses */
            if (!sif6addr(f->unit, go->ourid, ho->hisid)) {
index 19bc01362f8b9a69d032ffb1be15cac89abca4e7..5e1db6ba510f65d6eb6dae0bb130de5927c0cadc 100644 (file)
@@ -33,6 +33,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
  */
+#include "pppdconf.h"
 
 /*  Original version, based on RFC2023 :
 
index d39b14c4848106ca26840fa58dc6b1f2c63f387a..000608deda07bb0878d51a8d3ea613a8a4bf43af 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #ifdef IPX_CHANGE
 
 /*
index 8a69232a8b06f658d3e90566391ee4fc8e007567..6112e757e9fc93ff7f1968fe9bdb5c4176c82d35 100644 (file)
@@ -39,6 +39,7 @@
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#include "pppdconf.h"
 
 /*
  * Options.
index ac5d5ce6488416afefde82633d969c7bc352a502..8a18e9516e0e121f019dc184fd6adabbb2b690c5 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
index 984f86892fdd0f1969fae60f4bda78c861a5c731..768442d17464d7f33f53c1eca2b403fbec13d972 100644 (file)
@@ -39,6 +39,7 @@
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#include "pppdconf.h"
 
 /*
  * Options.
index 8e08e47ef5bb0ed528fe3fcfb269069e596af8f4..6a5a7eb28ee67cac69db337c3f833b5c0d42c45f 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
index d6094db867b1e3c93c2b8cb035d290576ea024fa..b864b7bc8ddb8b4dab7eb86eea7ab4d63d01920f 100644 (file)
@@ -39,6 +39,7 @@
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#include "pppdconf.h"
 
 void magic_init (void);        /* Initialize the magic number generator */
 u_int32_t magic (void);        /* Returns the next magic number */
index 87a5d29217bb48103440c3af6e467f75854e49dd..b1ac8b4fd68087d54c1e6b9a6eeda87ca5130bc5 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdio.h>
 #include <ctype.h>
 #include <stdlib.h>
 
 
 /* interface vars */
-char ifname[MAXIFNAMELEN];     /* Interface name */
+char ifname[IFNAMSIZ];         /* Interface name */
 int ifunit;                    /* Interface unit number */
 
 struct channel *the_channel;
@@ -749,6 +753,7 @@ void
 detach(void)
 {
     int pid;
+    int ret;
     char numbuf[16];
     int pipefd[2];
 
@@ -770,7 +775,10 @@ detach(void)
        exit(0);                /* parent dies */
     }
     setsid();
-    chdir("/");
+    ret = chdir("/");
+    if (ret != 0) {
+        fatal("Could not change directory to '/', %m");
+    }
     dup2(fd_devnull, 0);
     dup2(fd_devnull, 1);
     dup2(fd_devnull, 2);
@@ -1409,8 +1417,12 @@ hup(int sig)
        /* Send the signal to the [dis]connector process(es) also */
        kill_my_pg(sig);
     notify(sigreceived, sig);
-    if (waiting)
+    if (waiting) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-result"
        write(sigpipe[1], &sig, sizeof(sig));
+#pragma GCC diagnostic pop
+    }
 }
 
 
@@ -1429,8 +1441,12 @@ term(int sig)
        /* Send the signal to the [dis]connector process(es) also */
        kill_my_pg(sig);
     notify(sigreceived, sig);
-    if (waiting)
+    if (waiting) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-result"
        write(sigpipe[1], &sig, sizeof(sig));
+#pragma GCC diagnostic pop
+    }
 }
 
 
@@ -1442,8 +1458,12 @@ static void
 chld(int sig)
 {
     got_sigchld = 1;
-    if (waiting)
+    if (waiting) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-result"
        write(sigpipe[1], &sig, sizeof(sig));
+#pragma GCC diagnostic pop
+    }
 }
 
 
@@ -1475,8 +1495,12 @@ static void
 open_ccp(int sig)
 {
     got_sigusr2 = 1;
-    if (waiting)
+    if (waiting) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-result"
        write(sigpipe[1], &sig, sizeof(sig));
+#pragma GCC diagnostic pop
+    }
 }
 
 
@@ -1638,6 +1662,7 @@ device_script(char *program, int in, int out, int dont_wait)
     int pid;
     int status = -1;
     int errfd;
+    int ret;
 
     if (log_to_fd >= 0)
        errfd = log_to_fd;
@@ -1672,12 +1697,15 @@ device_script(char *program, int in, int out, int dont_wait)
     }
 
     /* here we are executing in the child */
-
-    setgid(getgid());
-    setuid(uid);
-    if (getuid() != uid) {
-       fprintf(stderr, "pppd: setuid failed\n");
-       exit(1);
+    ret = setgid(getgid());
+    if (ret != 0) {
+        perror("pppd: setgid failed\n");
+        exit(1);
+    }
+    ret = setuid(uid);
+    if (ret != 0 || getuid() != uid) {
+        perror("pppd: setuid failed\n");
+        exit(1);
     }
     update_system_environment();
     execl("/bin/sh", "sh", "-c", program, (char *)0);
@@ -1738,7 +1766,7 @@ update_script_environment(void)
 pid_t
 run_program(char *prog, char **args, int must_exist, void (*done)(void *), void *arg, int wait)
 {
-    int pid, status;
+    int pid, status, ret;
     struct stat sbuf;
 
     /*
@@ -1778,9 +1806,18 @@ run_program(char *prog, char **args, int must_exist, void (*done)(void *), void
     /* Leave the current location */
     (void) setsid();   /* No controlling tty. */
     (void) umask (S_IRWXG|S_IRWXO);
-    (void) chdir ("/");        /* no current directory. */
-    setuid(0);         /* set real UID = root */
-    setgid(getegid());
+    ret = chdir ("/"); /* no current directory. */
+    if (ret != 0) {
+        fatal("Failed to change directory to '/', %m");
+    }
+    ret = setuid(0);           /* set real UID = root */
+    if (ret != 0) {
+        fatal("Failed to set uid, %m");
+    }
+    ret = setgid(getegid());
+    if (ret != 0) {
+        fatal("failed to set gid, %m");
+    }
 
 #ifdef BSD
     /* Force the priority back to zero if pppd is running higher. */
index 42a9b2e75d6ee09764e83e6fc99dc5f161e86ea5..88f3413c544951e77e9e60f587320c59ca52032e 100644 (file)
@@ -30,6 +30,9 @@
 /* Implementation notes:
 ** This implementation assumes that ints are 32-bit quantities.
 */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
 #define TRUE  1
 #define FALSE 0
index b6fc3f561faa670f0ac1087e49242dfc832dba8a..d67daeb820b3982fbaee9aae7cc95fae07b77e60 100644 (file)
@@ -7,6 +7,16 @@
 ** (C) 1990 RSA Data Security, Inc.                                  **
 ** ********************************************************************
 */
+#include "pppdconf.h"
+
+#ifndef __MD4_INCLUDE__
+#define __MD4_INCLUDE__
+#ifndef USE_MD4
+#include <openssl/md4.h>
+#define MD4Init MD4_Init
+#define MD4Update MD4_Update
+#define MD4Final MD4_Final
+#else
 
 /* MDstruct is the data structure for a message digest computation.
 */
@@ -53,3 +63,5 @@ extern void MD4Final(unsigned char *, MD4_CTX *);
 /*
 ** End of md4.h
 ****************************(cut)***********************************/
+#endif  /* USE_MD4 */
+#endif  /* __MD4_INCLUDE__ */
index f7988e64141aa42b7f635cea9624967ef2f988c2..9fb3397b6fb98c32a980cb35b2847b5a4de17bf4 100644 (file)
  ***********************************************************************
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <string.h>
 #include "md5.h"
 
index 71e8b00e2dde9e481384b43866c9b0e091ac3408..662eb4126085c6f48ada54d41cea54ba7b2fd3e9 100644 (file)
  ** documentation and/or software.                                    **
  ***********************************************************************
  */
+#include "pppdconf.h"
 
 #ifndef __MD5_INCLUDE__
+#define __MD5_INCLUDE__
+#ifndef USE_MD5
+#include <openssl/md5.h>
+#else
 
 /* typedef a 32-bit type */
 #ifdef _LP64
@@ -61,5 +66,5 @@ void MD5_Init (MD5_CTX *mdContext);
 void MD5_Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen);
 void MD5_Final (unsigned char hash[], MD5_CTX *mdContext);
 
-#define __MD5_INCLUDE__
+#endif /* USE_MD5 */
 #endif /* __MD5_INCLUDE__ */
diff --git a/pppd/mppe.c b/pppd/mppe.c
new file mode 100644 (file)
index 0000000..f1b7abf
--- /dev/null
@@ -0,0 +1,256 @@
+/* * mppe.c - MPPE key implementation
+ *
+ * Copyright (c) 2020 Eivind Naess. All rights reserved.
+ * Copyright (c) 2008 Paul Mackerras. 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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+
+#include "pppd.h"
+#include "fsm.h"
+#include "md4.h"
+#include "sha1.h"
+#include "ccp.h"
+#include "chap_ms.h"
+#include "mppe.h"
+
+u_char mppe_send_key[MPPE_MAX_KEY_SIZE];
+u_char mppe_recv_key[MPPE_MAX_KEY_SIZE];
+int mppe_keys_set = 0;
+
+void
+mppe_set_keys(u_char *send_key, u_char *recv_key, int keylen)
+{
+       int length = keylen;
+       if (length > MPPE_MAX_KEY_SIZE)
+               length = MPPE_MAX_KEY_SIZE;
+       
+       if (send_key) {
+           BCOPY(send_key, mppe_send_key, length);
+           BZERO(send_key, keylen);
+       }
+
+       if (recv_key) {
+           BCOPY(recv_key, mppe_recv_key, length);
+           BZERO(recv_key, keylen);
+       }
+
+       mppe_keys_set = length;
+}
+
+bool
+mppe_keys_isset()
+{
+       return !!mppe_keys_set;
+}
+
+int
+mppe_get_recv_key(u_char *recv_key, int length)
+{
+       if (mppe_keys_isset()) {
+               if (length > mppe_keys_set)
+                       length = mppe_keys_set;
+               BCOPY(mppe_recv_key, recv_key, length);
+               return length;
+       }
+       return 0;
+}
+
+int
+mppe_get_send_key(u_char *send_key, int length)
+{
+       if (mppe_keys_isset()) {
+               if (length > mppe_keys_set)
+                       length = mppe_keys_set;
+               BCOPY(mppe_send_key, send_key, length);
+               return length;
+       }
+       return 0;
+}
+
+void
+mppe_clear_keys(void)
+{
+       mppe_keys_set = 0;
+       BZERO(mppe_send_key, sizeof(mppe_send_key));
+       BZERO(mppe_recv_key, sizeof(mppe_recv_key));
+}
+
+/*
+ * Set mppe_xxxx_key from the NTPasswordHashHash.
+ * RFC 2548 (RADIUS support) requires us to export this function (ugh).
+ */
+void
+mppe_set_chapv1(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE])
+{
+    SHA1_CTX   sha1Context;
+    u_char     Digest[SHA1_SIGNATURE_SIZE];
+
+    SHA1_Init(&sha1Context);
+    SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
+    SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
+    SHA1_Update(&sha1Context, rchallenge, 8);
+    SHA1_Final(Digest, &sha1Context);
+
+    /* Same key in both directions. */
+    mppe_set_keys(Digest, Digest, sizeof(Digest));
+}
+
+/*
+ * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079)
+ *
+ * This helper function used in the Winbind module, which gets the
+ * NTHashHash from the server.
+ */
+void
+mppe_set_chapv2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
+              u_char NTResponse[MS_AUTH_NTRESP_LEN], int IsServer)
+{
+    SHA1_CTX   sha1Context;
+    u_char     MasterKey[SHA1_SIGNATURE_SIZE];
+    u_char     SendKey[SHA1_SIGNATURE_SIZE];
+    u_char     RecvKey[SHA1_SIGNATURE_SIZE];
+
+    u_char SHApad1[40] =
+       { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+    u_char SHApad2[40] =
+       { 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
+         0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
+         0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2,
+         0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 };
+
+    /* "This is the MPPE Master Key" */
+    u_char Magic1[27] =
+       { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
+         0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
+         0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 };
+    /* "On the client side, this is the send key; "
+       "on the server side, it is the receive key." */
+    u_char Magic2[84] =
+       { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
+         0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
+         0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
+         0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79,
+         0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
+         0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65,
+         0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
+         0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
+         0x6b, 0x65, 0x79, 0x2e };
+    /* "On the client side, this is the receive key; "
+       "on the server side, it is the send key." */
+    u_char Magic3[84] =
+       { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69,
+         0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20,
+         0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68,
+         0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20,
+         0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68,
+         0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73,
+         0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73,
+         0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20,
+         0x6b, 0x65, 0x79, 0x2e };
+    u_char *s;
+
+    SHA1_Init(&sha1Context);
+    SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE);
+    SHA1_Update(&sha1Context, NTResponse, 24);
+    SHA1_Update(&sha1Context, Magic1, sizeof(Magic1));
+    SHA1_Final(MasterKey, &sha1Context);
+
+    /*
+     * generate send key
+     */
+    if (IsServer)
+       s = Magic3;
+    else
+       s = Magic2;
+    SHA1_Init(&sha1Context);
+    SHA1_Update(&sha1Context, MasterKey, 16);
+    SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1));
+    SHA1_Update(&sha1Context, s, 84);
+    SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2));
+    SHA1_Final(SendKey, &sha1Context);
+
+    /*
+     * generate recv key
+     */
+    if (IsServer)
+       s = Magic2;
+    else
+       s = Magic3;
+    SHA1_Init(&sha1Context);
+    SHA1_Update(&sha1Context, MasterKey, 16);
+    SHA1_Update(&sha1Context, SHApad1, sizeof(SHApad1));
+    SHA1_Update(&sha1Context, s, 84);
+    SHA1_Update(&sha1Context, SHApad2, sizeof(SHApad2));
+    SHA1_Final(RecvKey, &sha1Context);
+
+    mppe_set_keys(SendKey, RecvKey, SHA1_SIGNATURE_SIZE);
+}
+
+#ifndef UNIT_TEST
+
+/*
+ * Set MPPE options from plugins.
+ */
+void
+mppe_set_enc_types(int policy, int types)
+{
+    /* Early exit for unknown policies. */
+    if (policy != MPPE_ENC_POL_ENC_ALLOWED &&
+       policy != MPPE_ENC_POL_ENC_REQUIRED)
+       return;
+
+    /* Don't modify MPPE if it's optional and wasn't already configured. */
+    if (policy == MPPE_ENC_POL_ENC_ALLOWED && !ccp_wantoptions[0].mppe)
+       return;
+
+    /*
+     * Disable undesirable encryption types.  Note that we don't ENABLE
+     * any encryption types, to avoid overriding manual configuration.
+     */
+    switch(types) {
+       case MPPE_ENC_TYPES_RC4_40:
+           ccp_wantoptions[0].mppe &= ~MPPE_OPT_128;   /* disable 128-bit */
+           break;
+       case MPPE_ENC_TYPES_RC4_128:
+           ccp_wantoptions[0].mppe &= ~MPPE_OPT_40;    /* disable 40-bit */
+           break;
+       default:
+           break;
+    }
+}
+
+#endif
index 5eb3b37a99d65966e0ead25e9265a7db7f11a2bc..2684a7f6fe85801b44eb978faa5a88567a040ba5 100644 (file)
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#include "pppdconf.h"
+
+#ifndef __MPPE_H__
+#define __MPPE_H__
 
 #define MPPE_PAD               4       /* MPPE growth per frame */
-#define MPPE_MAX_KEY_LEN       16      /* largest key length (128-bit) */
+#define MPPE_MAX_KEY_SIZE      32      /* Largest key length */
+#define MPPE_MAX_KEY_LEN       16      /* Largest key size accepted by the kernel */
 
 /* option bits for ccp_options.mppe */
 #define MPPE_OPT_40            0x01    /* 40 bit */
        if (ptr[3] & ~MPPE_ALL_BITS)            \
            opts |= MPPE_OPT_UNKNOWN;           \
     } while (/* CONSTCOND */ 0)
+
+
+#if MPPE
+
+/*
+ * NOTE:
+ *   Access to these variables directly is discuraged. Please
+ *   change your code to use below accessor functions.
+ */
+
+/* The key material generated which is used for MPPE send key */
+extern u_char mppe_send_key[MPPE_MAX_KEY_SIZE];
+/* The key material generated which is used for MPPE recv key */
+extern u_char mppe_recv_key[MPPE_MAX_KEY_SIZE];
+/* Keys are set if value is non-zero */
+extern int mppe_keys_set;
+
+/* These values are the RADIUS attribute values--see RFC 2548. */
+#define MPPE_ENC_POL_ENC_ALLOWED 1
+#define MPPE_ENC_POL_ENC_REQUIRED 2
+#define MPPE_ENC_TYPES_RC4_40 2
+#define MPPE_ENC_TYPES_RC4_128 4
+
+/* used by plugins (using above values) */
+void mppe_set_enc_types (int policy, int types);
+
+/*
+ * Set the MPPE send and recv keys. NULL values for keys are ignored
+ *   and input values are cleared to avoid leaving them on the stack
+ */
+void mppe_set_keys(u_char *send_key, u_char *recv_key, int keylen);
+
+/*
+ * Get the MPPE recv key
+ */
+int mppe_get_recv_key(u_char *recv_key, int length);
+
+/*
+ * Get the MPPE send key
+ */
+int mppe_get_send_key(u_char *send_key, int length);
+
+/*
+ * Clear the MPPE keys
+ */
+void mppe_clear_keys(void);
+
+/*
+ * Check if the MPPE keys are set
+ */
+bool mppe_keys_isset(void);
+
+/*
+ * Set mppe_xxxx_key from NT Password Hash Hash (MSCHAPv1), see RFC3079
+ */
+void mppe_set_chapv1(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE]);
+
+/*
+ * Set the mppe_xxxx_key from MS-CHAP-v2 credentials, see RFC3079
+ */
+void mppe_set_chapv2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE],
+                   u_char NTResponse[MS_AUTH_NTRESP_LEN], int IsServer);
+
+#endif  // #ifdef MPPE
+#endif  // #ifdef __MPPE_H__
index ddd848c3270bcba9c8dbeda4c6324fbc2151989d..6f17cf87eeb10df66e68430cab87b476c1bf6c25 100644 (file)
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <string.h>
 #include <ctype.h>
 #include <stdlib.h>
index f8d6c001e195d5b64d671b535f58e2f9be7d3cb5..f3f5e25d6e7e9fb4b9ea5d70532c102e6a60826e 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <ctype.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -117,7 +121,7 @@ int connect_delay = 1000;   /* wait this many ms after connect script */
 int    req_unit = -1;          /* requested interface unit */
 char   path_ipup[MAXPATHLEN];  /* pathname of ip-up script */
 char   path_ipdown[MAXPATHLEN];/* pathname of ip-down script */
-char   req_ifname[MAXIFNAMELEN];       /* requested interface name */
+char   req_ifname[IFNAMSIZ];   /* requested interface name */
 bool   multilink = 0;          /* Enable multilink operation */
 char   *bundle_name = NULL;    /* bundle name for multilink */
 bool   dump_options;           /* print out option values */
@@ -295,7 +299,7 @@ option_t general_options[] = {
 
     { "ifname", o_string, req_ifname,
       "Set PPP interface name",
-      OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXIFNAMELEN },
+      OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, IFNAMSIZ },
 
     { "dump", o_bool, &dump_options,
       "Print out option values after parsing all options", 1 },
index 30df079b0aafd733e01c9040a4c9e80b3f389122..1ecdb82b80b1de7bc6085016dbd3bcc0f3e3fd01 100644 (file)
@@ -1,2 +1 @@
-#define VERSION                "2.4.9"
 #define DATE           "5 January 2021"
index 524d608ce12c5cefed20ceafff035738434e2d31..e68d91a15f067385d215764feb233f34adab0b6f 100644 (file)
@@ -1,16 +1,35 @@
 /*
  * define path names
  */
+#include "pppdconf.h"
 
 #ifdef HAVE_PATHS_H
 #include <paths.h>
+#endif /* HAVE_PATHS_H */
 
-#else /* HAVE_PATHS_H */
-#ifndef _PATH_VARRUN
-#define _PATH_VARRUN   "/etc/ppp/"
-#endif
+#ifndef _PATH_DEVNULL
 #define _PATH_DEVNULL  "/dev/null"
-#endif /* HAVE_PATHS_H */
+#endif
+
+#ifdef PPPD_RUNTIME_DIR
+#undef  _PATH_VARRUN
+#define _PATH_VARRUN   PPPD_RUNTIME_DIR "/"
+#endif
+
+#ifdef PPPD_LOGFILE_DIR
+#undef  _PATH_VARLOG
+#define _PATH_VARLOG    PPPD_LOGFILE_DIR
+#endif
+
+#ifdef PPPD_PLUGIN_DIR
+#define _PATH_PLUGIN    PPPD_PLUGIN_DIR
+#else
+#ifdef __STDC__
+#define _PATH_PLUGIN   DESTDIR "/lib/pppd/" VERSION
+#else  /* __STDC__ */
+#define _PATH_PLUGIN   "/usr/lib/pppd"
+#endif /* __STDC__ */
+#endif /* PPPD_PLUGIN_DIR */
 
 #ifndef _ROOT_PATH
 #define _ROOT_PATH
@@ -33,7 +52,7 @@
 #define _PATH_AUTHUP    _ROOT_PATH "/etc/ppp/auth-up"
 #define _PATH_AUTHDOWN  _ROOT_PATH "/etc/ppp/auth-down"
 #define _PATH_TTYOPT    _ROOT_PATH "/etc/ppp/options."
-#define _PATH_CONNERRS  _ROOT_PATH "/etc/ppp/connect-errors"
+#define _PATH_CONNERRS  _ROOT_PATH _PATH_VARLOG "/connect-errors"
 #define _PATH_PEERFILES         _ROOT_PATH "/etc/ppp/peers/"
 #define _PATH_RESOLV    _ROOT_PATH "/etc/ppp/resolv.conf"
 
 #ifdef __STDC__
 #define _PATH_PPPDB    _ROOT_PATH _PATH_VARRUN "pppd2.tdb"
 #else /* __STDC__ */
-#ifdef HAVE_PATHS_H
-#define _PATH_PPPDB    "/var/run/pppd2.tdb"
-#else
-#define _PATH_PPPDB    "/etc/ppp/pppd2.tdb"
-#endif
-#endif /* __STDC__ */
-
-#ifdef PLUGIN
-#ifdef __STDC__
-#define _PATH_PLUGIN   DESTDIR "/lib/pppd/" VERSION
-#else /* __STDC__ */
-#define _PATH_PLUGIN   "/usr/lib/pppd"
+#define _PATH_PPPDB    _PPP_VARRUN "pppd2.tdb"
 #endif /* __STDC__ */
 
-#endif /* PLUGIN */
diff --git a/pppd/peap.c b/pppd/peap.c
new file mode 100644 (file)
index 0000000..fb9af3e
--- /dev/null
@@ -0,0 +1,768 @@
+/*
+ * Copyright (c) 2011 Rustam Kovhaev. All rights reserved.
+ * Copyright (c) 2021 Eivind Næss. 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.
+ *
+ * NOTES:
+ *
+ * PEAP has 2 phases,
+ * 1 - Outer EAP, where TLS session gets established
+ * 2 - Inner EAP, where inside TLS session with EAP MSCHAPV2 auth, or any other auth
+ *
+ * And so protocols encapsulation looks like this:
+ * Outer EAP -> TLS -> Inner EAP -> MSCHAPV2
+ * PEAP can compress an inner EAP packet prior to encapsulating it within
+ * the Data field of a PEAP packet by removing its Code, Identifier,
+ * and Length fields, and Microsoft PEAP server/client always does that
+ *
+ * Current implementation does not support:
+ * a) Fast reconnect
+ * b) Inner EAP fragmentation
+ * c) Any other auth other than MSCHAPV2
+ *
+ * For details on the PEAP protocol, look to Microsoft:
+ *    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-peap
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <openssl/opensslv.h>
+#include <openssl/ssl.h>
+#include <openssl/hmac.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <net/ppp_defs.h>
+
+#include "pppd.h"
+#include "eap.h"
+#include "tls.h"
+#include "chap-new.h"
+#include "chap_ms.h"
+#include "mppe.h"
+#include "peap.h"
+
+#ifdef UNIT_TEST
+#define novm(x)
+#endif
+
+struct peap_state {
+       SSL_CTX *ctx;
+       SSL *ssl;
+       BIO *in_bio;
+       BIO *out_bio;
+
+       int phase;
+       int written, read;
+       u_char *in_buf;
+       u_char *out_buf;
+
+       u_char ipmk[PEAP_TLV_IPMK_LEN];
+       u_char tk[PEAP_TLV_TK_LEN];
+       u_char nonce[PEAP_TLV_NONCE_LEN];
+       struct tls_info *info;
+#ifdef CHAPMS
+       struct chap_digest_type *chap;
+#endif
+};
+
+/*
+ * K = Key, S = Seed, LEN = output length
+ * PRF+(K, S, LEN) = T1 | T2 | ... |Tn
+ * Where:
+ * T1 = HMAC-SHA1 (K, S | 0x01 | 0x00 | 0x00)
+ * T2 = HMAC-SHA1 (K, T1 | S | 0x02 | 0x00 | 0x00)
+ * ...
+ * Tn = HMAC-SHA1 (K, Tn-1 | S | n | 0x00 | 0x00)
+ * As shown, PRF+ is computed in iterations. The number of iterations (n)
+ * depends on the output length (LEN).
+ */
+static void peap_prfplus(u_char *seed, size_t seed_len, u_char *key, size_t key_len, u_char *out_buf, size_t pfr_len)
+{
+       int pos;
+       u_char *buf, *hash;
+       size_t max_iter, i, j, k;
+       u_int len;
+
+       max_iter = (pfr_len + SHA_DIGEST_LENGTH - 1) / SHA_DIGEST_LENGTH;
+       buf = malloc(seed_len + max_iter * SHA_DIGEST_LENGTH);
+       if (!buf)
+               novm("pfr buffer");
+       hash = malloc(pfr_len + SHA_DIGEST_LENGTH);
+       if (!hash)
+               novm("hash buffer");
+
+       for (i = 0; i < max_iter; i++) {
+               j = 0;
+               k = 0;
+
+               if (i > 0)
+                       j = SHA_DIGEST_LENGTH;
+               for (k = 0; k < seed_len; k++)
+                       buf[j + k] = seed[k];
+               pos = j + k;
+               buf[pos] = i + 1;
+               pos++;
+               buf[pos] = 0x00;
+               pos++;
+               buf[pos] = 0x00;
+               pos++;
+               if (!HMAC(EVP_sha1(), key, key_len, buf, pos, (hash + i * SHA_DIGEST_LENGTH), &len))
+                       fatal("HMAC() failed");
+               for (j = 0; j < SHA_DIGEST_LENGTH; j++)
+                       buf[j] = hash[i * SHA_DIGEST_LENGTH + j];
+       }
+       BCOPY(hash, out_buf, pfr_len);
+       free(hash);
+       free(buf);
+}
+
+static void generate_cmk(u_char *ipmk, u_char *tempkey, u_char *nonce, u_char *tlv_response_out, int client)
+{
+       const char *label = PEAP_TLV_IPMK_SEED_LABEL;
+       u_char data_tlv[PEAP_TLV_DATA_LEN] = {0};
+       u_char isk[PEAP_TLV_ISK_LEN] = {0};
+       u_char ipmkseed[PEAP_TLV_IPMKSEED_LEN] = {0};
+       u_char cmk[PEAP_TLV_CMK_LEN] = {0};
+       u_char buf[PEAP_TLV_CMK_LEN + PEAP_TLV_IPMK_LEN] = {0};
+       u_char compound_mac[PEAP_TLV_COMP_MAC_LEN] = {0};
+       u_int len;
+
+       /* format outgoing CB TLV response packet */
+       data_tlv[1] = PEAP_TLV_TYPE;
+       data_tlv[3] = PEAP_TLV_LENGTH_FIELD;
+       if (client)
+               data_tlv[7] = PEAP_TLV_SUBTYPE_RESPONSE;
+       else
+               data_tlv[7] = PEAP_TLV_SUBTYPE_REQUEST;
+       BCOPY(nonce, (data_tlv + PEAP_TLV_HEADERLEN), PEAP_TLV_NONCE_LEN);
+       data_tlv[60] = EAPT_PEAP;
+
+#ifdef MPPE
+       mppe_get_send_key(isk, MPPE_MAX_KEY_LEN);
+       mppe_get_recv_key(isk + MPPE_MAX_KEY_LEN, MPPE_MAX_KEY_LEN);
+#endif
+
+       BCOPY(label, ipmkseed, strlen(label));
+       BCOPY(isk, ipmkseed + strlen(label), PEAP_TLV_ISK_LEN);
+       peap_prfplus(ipmkseed, PEAP_TLV_IPMKSEED_LEN,
+                       tempkey, PEAP_TLV_TEMPKEY_LEN, buf, PEAP_TLV_CMK_LEN + PEAP_TLV_IPMK_LEN);
+
+       BCOPY(buf, ipmk, PEAP_TLV_IPMK_LEN);
+       BCOPY(buf + PEAP_TLV_IPMK_LEN, cmk, PEAP_TLV_CMK_LEN);
+       if (!HMAC(EVP_sha1(), cmk, PEAP_TLV_CMK_LEN, data_tlv, PEAP_TLV_DATA_LEN, compound_mac, &len))
+               fatal("HMAC() failed");
+       BCOPY(compound_mac, data_tlv + PEAP_TLV_HEADERLEN + PEAP_TLV_NONCE_LEN, PEAP_TLV_COMP_MAC_LEN);
+       /* do not copy last byte to response packet */
+       BCOPY(data_tlv, tlv_response_out, PEAP_TLV_DATA_LEN - 1);
+}
+
+static void verify_compound_mac(struct peap_state *psm, u_char *in_buf)
+{
+       u_char nonce[PEAP_TLV_NONCE_LEN] = {0};
+       u_char out_buf[PEAP_TLV_LEN] = {0};
+
+       BCOPY(in_buf, nonce, PEAP_TLV_NONCE_LEN);
+       generate_cmk(psm->ipmk, psm->tk, nonce, out_buf, 0);
+       if (memcmp((in_buf + PEAP_TLV_NONCE_LEN), (out_buf + PEAP_TLV_HEADERLEN + PEAP_TLV_NONCE_LEN), PEAP_TLV_CMK_LEN))
+                       fatal("server's CMK does not match client's CMK, potential MiTM");
+}
+
+#ifdef MPPE
+#define PEAP_MPPE_KEY_LEN 32
+
+static void generate_mppe_keys(u_char *ipmk, int client)
+{
+       const char *label = PEAP_TLV_CSK_SEED_LABEL;
+       u_char csk[PEAP_TLV_CSK_LEN] = {0};
+       size_t len;
+
+       dbglog("PEAP CB: generate mppe keys");
+       len = strlen(label);
+       len++; /* CSK requires NULL byte in seed */
+       peap_prfplus((u_char *)label, len, ipmk, PEAP_TLV_IPMK_LEN, csk, PEAP_TLV_CSK_LEN);
+
+       /*
+        * The first 64 bytes of the CSK are split into two MPPE keys, as follows.
+        *
+        * +-----------------------+------------------------+
+        * | First 32 bytes of CSK | Second 32 bytes of CSK |
+        * +-----------------------+------------------------+
+        * | MS-MPPE-Send-Key      | MS-MPPE-Recv-Key       |
+        * +-----------------------+------------------------+
+        */
+       if (client) {
+               mppe_set_keys(csk, csk + PEAP_MPPE_KEY_LEN, PEAP_MPPE_KEY_LEN);
+       } else {
+               mppe_set_keys(csk + PEAP_MPPE_KEY_LEN, csk, PEAP_MPPE_KEY_LEN);
+       }
+}
+
+#endif
+
+#ifndef UNIT_TEST
+
+static void peap_ack(eap_state *esp, u_char id)
+{
+       u_char *outp;
+
+       outp = outpacket_buf;
+       MAKEHEADER(outp, PPP_EAP);
+       PUTCHAR(EAP_RESPONSE, outp);
+       PUTCHAR(id, outp);
+       esp->es_client.ea_id = id;
+       PUTSHORT(PEAP_HEADERLEN, outp);
+       PUTCHAR(EAPT_PEAP, outp);
+       PUTCHAR(PEAP_FLAGS_ACK, outp);
+       output(esp->es_unit, outpacket_buf, PPP_HDRLEN + PEAP_HEADERLEN);
+}
+
+static void peap_response(eap_state *esp, u_char id, u_char *buf, int len)
+{
+       struct peap_state *psm = esp->ea_peap;
+       u_char *outp;
+       int peap_len;
+
+       outp = outpacket_buf;
+       MAKEHEADER(outp, PPP_EAP);
+       PUTCHAR(EAP_RESPONSE, outp);
+       PUTCHAR(id, outp);
+       esp->es_client.ea_id = id;
+
+       if (psm->phase == PEAP_PHASE_1)
+               peap_len = PEAP_HEADERLEN + PEAP_FRAGMENT_LENGTH_FIELD + len;
+       else
+               peap_len = PEAP_HEADERLEN + len;
+
+       PUTSHORT(peap_len, outp);
+       PUTCHAR(EAPT_PEAP, outp);
+
+       if (psm->phase == PEAP_PHASE_1) {
+               PUTCHAR(PEAP_L_FLAG_SET, outp);
+               PUTLONG(len, outp);
+       } else
+               PUTCHAR(PEAP_NO_FLAGS, outp);
+
+       BCOPY(buf, outp, len);
+       output(esp->es_unit, outpacket_buf, PPP_HDRLEN + peap_len);
+}
+
+void peap_do_inner_eap(u_char *in_buf, int in_len, eap_state *esp, int id,
+               u_char *out_buf, int *out_len)
+{
+       struct peap_state *psm = esp->ea_peap;
+       int used = 0;
+       int typenum;
+       int secret_len;
+       char secret[MAXSECRETLEN + 1];
+       char rhostname[MAXWORDLEN];
+       u_char *outp = out_buf;
+
+       dbglog("PEAP: EAP (in): %.*B", in_len, in_buf);
+
+       if (*(in_buf + EAP_HEADERLEN) == PEAP_CAPABILITIES_TYPE &&
+                       in_len  == (EAP_HEADERLEN + PEAP_CAPABILITIES_LEN)) {
+               /* use original packet as template for response */
+               BCOPY(in_buf, outp, EAP_HEADERLEN + PEAP_CAPABILITIES_LEN);
+               PUTCHAR(EAP_RESPONSE, outp);
+               PUTCHAR(id, outp);
+               /* change last byte to 0 to disable fragmentation */
+               *(outp + PEAP_CAPABILITIES_LEN + 1) = 0x00;
+               used = EAP_HEADERLEN + PEAP_CAPABILITIES_LEN;
+               goto done;
+       }
+       if (*(in_buf + EAP_HEADERLEN + PEAP_TLV_HEADERLEN) == PEAP_TLV_TYPE &&
+                       in_len == PEAP_TLV_LEN) {
+               /* PEAP TLV message, do cryptobinding */
+               SSL_export_keying_material(psm->ssl, psm->tk, PEAP_TLV_TK_LEN,
+                               PEAP_TLV_TK_SEED_LABEL, strlen(PEAP_TLV_TK_SEED_LABEL), NULL, 0, 0);
+               /* verify server's CMK */
+               verify_compound_mac(psm, in_buf + EAP_HEADERLEN + PEAP_TLV_RESULT_LEN + PEAP_TLV_HEADERLEN);
+               /* generate client's CMK with new nonce */
+               PUTCHAR(EAP_RESPONSE, outp);
+               PUTCHAR(id, outp);
+               PUTSHORT(PEAP_TLV_LEN, outp);
+               BCOPY(in_buf + EAP_HEADERLEN, outp, PEAP_TLV_RESULT_LEN);
+               outp = outp + PEAP_TLV_RESULT_LEN;
+               RAND_bytes(psm->nonce, PEAP_TLV_NONCE_LEN);
+               generate_cmk(psm->ipmk, psm->tk, psm->nonce, outp, 1);
+#ifdef MPPE
+               /* set mppe keys */
+               generate_mppe_keys(psm->ipmk, 1);
+#endif
+               used = PEAP_TLV_LEN;
+               goto done;
+       }
+
+       GETCHAR(typenum, in_buf);
+       in_len--;
+
+       switch (typenum) {
+       case EAPT_IDENTITY:
+               /* Respond with our identity to the peer */
+               PUTCHAR(EAPT_IDENTITY, outp);
+               BCOPY(esp->es_client.ea_name, outp,
+                               esp->es_client.ea_namelen);
+               used += (esp->es_client.ea_namelen + 1);
+               break;
+
+       case EAPT_TLS:
+               /* Send NAK to EAP_TLS request */
+               PUTCHAR(EAPT_NAK, outp);
+               PUTCHAR(EAPT_MSCHAPV2, outp);
+               used += 2;
+               break;
+
+#if CHAPMS
+       case EAPT_MSCHAPV2: {
+
+               // Must have at least 4 more bytes to process CHAP header
+               if (in_len < 4) {
+                       error("PEAP: received invalid MSCHAPv2 packet, too short");
+                       break;
+               }
+
+               u_char opcode;
+               GETCHAR(opcode, in_buf);
+
+               u_char chap_id;
+               GETCHAR(chap_id, in_buf);
+
+               short mssize;
+               GETSHORT(mssize, in_buf);
+
+               // Validate the CHAP packet (including header)
+               if (in_len != mssize) {
+                       error("PEAP: received invalid MSCHAPv2 packet, invalid length");
+                       break;
+               }
+               in_len -= 4;
+
+               switch (opcode) {
+               case CHAP_CHALLENGE: {
+
+                       u_char *challenge = in_buf;     // VLEN + VALUE
+                       u_char vsize;
+
+                       GETCHAR(vsize, in_buf);
+                       in_len -= 1;
+
+                       if (vsize != MS_CHAP2_PEER_CHAL_LEN || in_len < MS_CHAP2_PEER_CHAL_LEN) {
+                               error("PEAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize);
+                               goto done;
+                       }
+
+                       INCPTR(MS_CHAP2_PEER_CHAL_LEN, in_buf);
+                       in_len -= MS_CHAP2_PEER_CHAL_LEN;
+
+                       // Copy the provided remote host name
+                       rhostname[0] = '\0';
+                       if (in_len > 0) {
+                               if (in_len >= sizeof(rhostname)) {
+                                       dbglog("PEAP: trimming really long peer name down");
+                                       in_len = sizeof(rhostname) - 1;
+                               }
+                               BCOPY(in_buf, rhostname, in_len);
+                               rhostname[in_len] = '\0';
+                       }
+
+                       // In case the remote doesn't give us his name, or user explictly specified remotename is config
+                       if (explicit_remote || (remote_name[0] != '\0' && in_len == 0))
+                               strlcpy(rhostname, remote_name, sizeof(rhostname));
+
+                       // Get the scrert for authenticating ourselves with the specified host
+                       if (get_secret(esp->es_unit, esp->es_client.ea_name,
+                                               rhostname, secret, &secret_len, 0)) {
+
+                               u_char response[MS_CHAP2_RESPONSE_LEN+1];
+                               u_char user_len = esp->es_client.ea_namelen;
+                               char *user = esp->es_client.ea_name;
+
+                               psm->chap->make_response(response, chap_id, user,
+                                               challenge, secret, secret_len, NULL);
+
+                               PUTCHAR(EAPT_MSCHAPV2, outp);
+                               PUTCHAR(CHAP_RESPONSE, outp);
+                               PUTCHAR(chap_id, outp);
+                               PUTCHAR(0, outp);
+                               PUTCHAR(5 + user_len + MS_CHAP2_RESPONSE_LEN, outp);
+                               BCOPY(response, outp, MS_CHAP2_RESPONSE_LEN+1); // VLEN + VALUE
+                               INCPTR(MS_CHAP2_RESPONSE_LEN+1, outp);
+                               BCOPY(user, outp, user_len);
+                               used = 5 + user_len + MS_CHAP2_RESPONSE_LEN + 1;
+
+                       } else {
+                               dbglog("PEAP: no CHAP secret for auth to %q", rhostname);
+                               PUTCHAR(EAPT_NAK, outp);
+                               ++used;
+                       }
+                       break;
+               }
+               case CHAP_SUCCESS: {
+
+                       u_char status = CHAP_FAILURE;
+                       if (psm->chap->check_success(chap_id, in_buf, in_len)) {
+                               info("Chap authentication succeeded! %.*v", in_len, in_buf);
+                               status = CHAP_SUCCESS;
+                       }
+
+                       PUTCHAR(EAPT_MSCHAPV2, outp);
+                       PUTCHAR(status, outp);
+                       used += 2;
+                       break;
+               }
+               case CHAP_FAILURE: {
+
+                       psm->chap->handle_failure(in_buf, in_len);
+                       PUTCHAR(EAPT_MSCHAPV2, outp);
+                       PUTCHAR(status, outp);
+                       used += 2;
+                       break;
+               }
+               default:
+                       break;
+               }
+               break;
+       }       // EAPT_MSCHAPv2
+#endif
+       default:
+
+               /* send compressed EAP NAK for any unknown packet */
+               PUTCHAR(EAPT_NAK, outp);
+               ++used;
+       }
+
+done:
+
+       dbglog("PEAP: EAP (out): %.*B", used, psm->out_buf);
+       *out_len = used;
+}
+
+int peap_init(struct peap_state **ctx, const char *rhostname)
+{
+       const SSL_METHOD *method;
+
+       if (!ctx)
+               return -1;
+
+       tls_init();
+
+       struct peap_state *psm = malloc(sizeof(*psm));
+       if (!psm)
+               novm("peap psm struct");
+       psm->in_buf = malloc(TLS_RECORD_MAX_SIZE);
+       if (!psm->in_buf)
+               novm("peap tls buffer");
+       psm->out_buf = malloc(TLS_RECORD_MAX_SIZE);
+       if (!psm->out_buf)
+               novm("peap tls buffer");
+       method = tls_method();
+       if (!method)
+               novm("TLS_method() failed");
+       psm->ctx = SSL_CTX_new(method);
+       if (!psm->ctx)
+               novm("SSL_CTX_new() failed");
+
+       /* Configure the default options */
+       tls_set_opts(psm->ctx);
+
+       /* Configure the max TLS version */
+       tls_set_version(psm->ctx, max_tls_version);
+
+       /* Configure the peer certificate callback */
+       tls_set_verify(psm->ctx, 5);
+
+       /* Configure CA locations */
+       if (tls_set_ca(psm->ctx, ca_path, cacert_file)) {
+               fatal("Could not set CA verify locations");
+       }
+
+       /* Configure CRL check (if any) */
+       if (tls_set_crl(psm->ctx, crl_dir, crl_file)) {
+               fatal("Could not set CRL verify locations");
+       }
+
+       psm->out_bio = BIO_new(BIO_s_mem());
+       psm->in_bio = BIO_new(BIO_s_mem());
+       BIO_set_mem_eof_return(psm->out_bio, -1);
+       BIO_set_mem_eof_return(psm->in_bio, -1);
+       psm->ssl = SSL_new(psm->ctx);
+       SSL_set_bio(psm->ssl, psm->in_bio, psm->out_bio);
+       SSL_set_connect_state(psm->ssl);
+       psm->phase = PEAP_PHASE_1;
+       tls_set_verify_info(psm->ssl, explicit_remote ? rhostname : NULL, NULL, 1, &psm->info);
+       psm->chap = chap_find_digest(CHAP_MICROSOFT_V2);
+       *ctx = psm;
+       return 0;
+}
+
+void peap_finish(struct peap_state **psm) {
+
+       if (psm && *psm) {
+               struct peap_state *tmp = *psm;
+
+               if (tmp->ssl)
+                       SSL_free(tmp->ssl);
+
+               if (tmp->ctx)
+                       SSL_CTX_free(tmp->ctx);
+
+               if (tmp->info)
+                       tls_free_verify_info(&tmp->info);
+
+               // NOTE: BIO and memory is freed as a part of SSL_free()
+
+               free(*psm);
+               *psm = NULL;
+       }
+}
+
+int peap_process(eap_state *esp, u_char id, u_char *inp, int len)
+{
+       int ret;
+       int out_len;
+
+       struct peap_state *psm = esp->ea_peap;
+
+       if (esp->es_client.ea_id == id) {
+               info("PEAP: retransmits are not supported..");
+               return -1;
+       }
+
+       switch (*inp) {
+       case PEAP_S_FLAG_SET:
+               dbglog("PEAP: S bit is set, starting PEAP phase 1");
+               ret = SSL_do_handshake(psm->ssl);
+               if (ret != 1) {
+                       ret = SSL_get_error(psm->ssl, ret);
+                       if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
+                               fatal("SSL_do_handshake(): %s", ERR_error_string(ret, NULL));
+
+               }
+               psm->read = BIO_read(psm->out_bio, psm->out_buf, TLS_RECORD_MAX_SIZE);
+               peap_response(esp, id, psm->out_buf, psm->read);
+               break;
+
+       case PEAP_LM_FLAG_SET:
+               dbglog("PEAP TLS: LM bits are set, need to get more TLS fragments");
+               inp = inp + PEAP_FRAGMENT_LENGTH_FIELD + PEAP_FLAGS_FIELD;
+               psm->written = BIO_write(psm->in_bio, inp, len - PEAP_FRAGMENT_LENGTH_FIELD - PEAP_FLAGS_FIELD);
+               peap_ack(esp, id);
+               break;
+
+       case PEAP_M_FLAG_SET:
+               dbglog("PEAP TLS: M bit is set, need to get more TLS fragments");
+               inp = inp + PEAP_FLAGS_FIELD;
+               psm->written = BIO_write(psm->in_bio, inp, len - PEAP_FLAGS_FIELD);
+               peap_ack(esp, id);
+               break;
+
+       case PEAP_L_FLAG_SET:
+       case PEAP_NO_FLAGS:
+               if (*inp == PEAP_L_FLAG_SET) {
+                       dbglog("PEAP TLS: L bit is set");
+                       inp = inp + PEAP_FRAGMENT_LENGTH_FIELD + PEAP_FLAGS_FIELD;
+                       psm->written = BIO_write(psm->in_bio, inp, len - PEAP_FRAGMENT_LENGTH_FIELD - PEAP_FLAGS_FIELD);
+               } else {
+                       dbglog("PEAP TLS: all bits are off");
+                       inp = inp + PEAP_FLAGS_FIELD;
+                       psm->written = BIO_write(psm->in_bio, inp, len - PEAP_FLAGS_FIELD);
+               }
+
+               if (psm->phase == PEAP_PHASE_1) {
+                       dbglog("PEAP TLS: continue handshake");
+                       ret = SSL_do_handshake(psm->ssl);
+                       if (ret != 1) {
+                               ret = SSL_get_error(psm->ssl, ret);
+                               if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
+                                       fatal("SSL_do_handshake(): %s", ERR_error_string(ret, NULL));
+                       }
+                       if (SSL_is_init_finished(psm->ssl))
+                               psm->phase = PEAP_PHASE_2;
+                       if (BIO_ctrl_pending(psm->out_bio) == 0) {
+                               peap_ack(esp, id);
+                               break;
+                       }
+                       psm->read = 0;
+                       psm->read = BIO_read(psm->out_bio, psm->out_buf,
+                                       TLS_RECORD_MAX_SIZE);
+                       peap_response(esp, id, psm->out_buf, psm->read);
+                       break;
+               }
+               psm->read = SSL_read(psm->ssl, psm->in_buf,
+                               TLS_RECORD_MAX_SIZE);
+               out_len = TLS_RECORD_MAX_SIZE;
+               peap_do_inner_eap(psm->in_buf, psm->read, esp, id,
+                               psm->out_buf, &out_len);
+               if (out_len > 0) {
+                       psm->written = SSL_write(psm->ssl, psm->out_buf, out_len);
+                       psm->read = BIO_read(psm->out_bio, psm->out_buf,
+                               TLS_RECORD_MAX_SIZE);
+                       peap_response(esp, id, psm->out_buf, psm->read);
+               }
+               break;
+       }
+       return 0;
+}
+
+#else
+
+u_char outpacket_buf[255];
+int debug = 1;
+int error_count = 0;
+int unsuccess = 0;
+
+/**
+ * Using the example in MS-PEAP, section 4.4.1.
+ *     see https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-peap/5308642b-90c9-4cc4-beec-fb367325c0f9
+ */
+int test_cmk(u_char *ipmk) {
+       u_char nonce[PEAP_TLV_NONCE_LEN] = {
+               0x6C, 0x6B, 0xA3, 0x87, 0x84, 0x23, 0x74, 0x57,
+               0xCC, 0xC9, 0x0B, 0x1A, 0x90, 0x8C, 0xBD, 0xF4,
+               0x71, 0x1B, 0x69, 0x99, 0x4D, 0x0C, 0xFE, 0x8D,
+               0x3D, 0xB4, 0x4E, 0xCB, 0xCD, 0xAD, 0x37, 0xE9
+       };
+
+       u_char tmpkey[PEAP_TLV_TEMPKEY_LEN] = {
+               0x73, 0x8B, 0xB5, 0xF4, 0x62, 0xD5, 0x8E, 0x7E,
+               0xD8, 0x44, 0xE1, 0xF0, 0x0D, 0x0E, 0xBE, 0x50,
+               0xC5, 0x0A, 0x20, 0x50, 0xDE, 0x11, 0x99, 0x77,
+               0x10, 0xD6, 0x5F, 0x45, 0xFB, 0x5F, 0xBA, 0xB7,
+               0xE3, 0x18, 0x1E, 0x92, 0x4F, 0x42, 0x97, 0x38,
+               // 0xDE, 0x40, 0xC8, 0x46, 0xCD, 0xF5, 0x0B, 0xCB,
+               // 0xF9, 0xCE, 0xDB, 0x1E, 0x85, 0x1D, 0x22, 0x52,
+               // 0x45, 0x3B, 0xDF, 0x63
+       };
+
+       u_char expected[60] = {
+               0x00, 0x0C, 0x00, 0x38, 0x00, 0x00, 0x00, 0x01,
+               0x6C, 0x6B, 0xA3, 0x87, 0x84, 0x23, 0x74, 0x57,
+               0xCC, 0xC9, 0x0B, 0x1A, 0x90, 0x8C, 0xBD, 0xF4,
+               0x71, 0x1B, 0x69, 0x99, 0x4D, 0x0C, 0xFE, 0x8D,
+               0x3D, 0xB4, 0x4E, 0xCB, 0xCD, 0xAD, 0x37, 0xE9,
+               0x42, 0xE0, 0x86, 0x07, 0x1D, 0x1C, 0x8B, 0x8C,
+               0x8E, 0x45, 0x8F, 0x70, 0x21, 0xF0, 0x6A, 0x6E,
+               0xAB, 0x16, 0xB6, 0x46
+       };
+
+       u_char inner_mppe_keys[32] = {
+               0x67, 0x3E, 0x96, 0x14, 0x01, 0xBE, 0xFB, 0xA5,
+               0x60, 0x71, 0x7B, 0x3B, 0x5D, 0xDD, 0x40, 0x38,
+               0x65, 0x67, 0xF9, 0xF4, 0x16, 0xFD, 0x3E, 0x9D,
+               0xFC, 0x71, 0x16, 0x3B, 0xDF, 0xF2, 0xFA, 0x95
+       };
+
+       u_char response[60] = {};
+
+       // Set the inner MPPE keys (e.g. from CHAPv2)
+       mppe_set_keys(inner_mppe_keys, inner_mppe_keys + 16, 16);
+
+       // Generate and compare the response
+       generate_cmk(ipmk, tmpkey, nonce, response, 1);
+       if (memcmp(expected, response, sizeof(response)) != 0) {
+               dbglog("Failed CMK key generation\n");
+               dbglog("%.*B", sizeof(response), response);
+               dbglog("%.*B", sizeof(expected), expected);
+               return -1;
+       }
+
+       return 0;
+}
+
+int test_mppe(u_char *ipmk) {
+       u_char outer_mppe_send_key[MPPE_MAX_KEY_SIZE] = {
+               0x6A, 0x02, 0xD7, 0x82, 0x20, 0x1B, 0xC7, 0x13,
+               0x8B, 0xF8, 0xEF, 0xF7, 0x33, 0xB4, 0x96, 0x97,
+               0x0D, 0x7C, 0xAB, 0x30, 0x0A, 0xC9, 0x57, 0x72,
+               0x78, 0xE1, 0xDD, 0xD5, 0xAE, 0xF7, 0x66, 0x97
+       };
+
+       u_char outer_mppe_recv_key[MPPE_MAX_KEY_SIZE] = {
+               0x17, 0x52, 0xD4, 0xE5, 0x84, 0xA1, 0xC8, 0x95,
+               0x03, 0x9B, 0x4D, 0x05, 0xE3, 0xBC, 0x9A, 0x84,
+               0x84, 0xDD, 0xC2, 0xAA, 0x6E, 0x2C, 0xE1, 0x62,
+               0x76, 0x5C, 0x40, 0x68, 0xBF, 0xF6, 0x5A, 0x45
+       };
+
+       u_char result[MPPE_MAX_KEY_SIZE];
+       int len;
+
+       mppe_clear_keys();
+
+       generate_mppe_keys(ipmk, 1);
+
+       len = mppe_get_recv_key(result, sizeof(result));
+       if (len != sizeof(result)) {
+               dbglog("Invalid length of resulting MPPE recv key");
+               return -1;
+       }
+
+       if (memcmp(result, outer_mppe_recv_key, len) != 0) {
+               dbglog("Invalid result for outer mppe recv key");
+               return -1;
+       }
+
+       len = mppe_get_send_key(result, sizeof(result));
+       if (len != sizeof(result)) {
+               dbglog("Invalid length of resulting MPPE send key");
+               return -1;
+       }
+
+       if (memcmp(result, outer_mppe_send_key, len) != 0) {
+               dbglog("Invalid result for outer mppe send key");
+               return -1;
+       }
+
+       return 0;
+}
+
+int main(int argc, char *argv[])
+{
+        u_char ipmk[PEAP_TLV_IPMK_LEN] = {
+               0x3A, 0x91, 0x1C, 0x25, 0x54, 0x73, 0xE8, 0x3E,
+               0x9A, 0x0C, 0xC3, 0x33, 0xAE, 0x1F, 0x8A, 0x35,
+               0xCD, 0xC7, 0x41, 0x63, 0xE7, 0xF6, 0x0F, 0x6C,
+               0x65, 0xEF, 0x71, 0xC2, 0x64, 0x42, 0xAA, 0xAC,
+               0xA2, 0xB6, 0xF1, 0xEB, 0x4F, 0x25, 0xEC, 0xA3,
+       };
+       int ret = -1;
+
+       ret = test_cmk(ipmk);
+       if (ret != 0) {
+               return -1;
+       }
+
+       ret = test_mppe(ipmk);
+       if (ret != 0) {
+               return -1;
+       }
+
+       return 0;
+}
+
+#endif
diff --git a/pppd/peap.h b/pppd/peap.h
new file mode 100644 (file)
index 0000000..49e28e8
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2011 Rustam Kovhaev. All rights reserved.
+ * Copyright (c) 2021 Eivind Næss. 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 PPP_PEAP_H
+#define        PPP_PEAP_H
+
+#define        PEAP_PHASE_1                    1
+#define        PEAP_PHASE_2                    2
+
+#define        PEAP_HEADERLEN                  6
+#define        PEAP_FRAGMENT_LENGTH_FIELD      4
+#define        PEAP_FLAGS_FIELD                1
+#define        PEAP_FLAGS_ACK                  0
+
+#define PEAP_CAPABILITIES_TYPE         254
+#define PEAP_CAPABILITIES_LEN          12
+
+#define PEAP_TLV_TYPE                  12
+#define PEAP_TLV_LENGTH_FIELD          56
+#define PEAP_TLV_SUBTYPE_REQUEST       0
+#define PEAP_TLV_SUBTYPE_RESPONSE      1
+#define PEAP_TLV_HEADERLEN             8
+#define PEAP_TLV_RESULT_LEN            7
+#define PEAP_TLV_LEN                   71
+
+/*
+ * Microsoft PEAP client/server never exchange
+ * outer TLVs during PEAP authentication
+ */
+#define        PEAP_TLV_DATA_LEN               61
+
+#define        PEAP_TLV_TK_LEN                 60
+#define        PEAP_TLV_ISK_LEN                32
+#define        PEAP_TLV_IPMKSEED_LEN           59
+#define        PEAP_TLV_TEMPKEY_LEN            40
+#define        PEAP_TLV_IPMK_LEN               40
+#define        PEAP_TLV_CMK_LEN                20
+#define        PEAP_TLV_NONCE_LEN              32
+#define        PEAP_TLV_COMP_MAC_LEN           20
+#define        PEAP_TLV_CSK_LEN                128
+#define        PEAP_TLV_TK_SEED_LABEL          "client EAP encryption"
+#define        PEAP_TLV_IPMK_SEED_LABEL        "Inner Methods Compound Keys"
+#define        PEAP_TLV_CSK_SEED_LABEL         "Session Key Generating Function"
+
+#define        PEAP_S_FLAG_SET                 0x20
+#define        PEAP_L_FLAG_SET                 0x80
+#define        PEAP_LM_FLAG_SET                0xC0
+#define        PEAP_M_FLAG_SET                 0x40
+#define        PEAP_NO_FLAGS                   0x00
+
+#define        EAP_TLS_KEY_LEN                 0x40
+#define        TLS_RECORD_MAX_SIZE             0x4000
+
+struct peap_state;
+
+/**
+ * Initialize the PEAP structure
+ */
+int peap_init(struct peap_state** psm, const char *remote_name);
+
+/**
+ * Process a PEAP packet
+ */
+int peap_process(eap_state *esp, u_char id, u_char *inp, int len);
+
+/**
+ * Clean up the PEAP structure
+ */
+void peap_finish(struct peap_state **psm);
+
+#endif /* PPP_PEAP_H */
diff --git a/pppd/plugins/Makefile.am b/pppd/plugins/Makefile.am
new file mode 100644 (file)
index 0000000..cfc9164
--- /dev/null
@@ -0,0 +1,25 @@
+pppd_plugin_LTLIBRARIES = minconn.la passprompt.la passwordfd.la winbind.la
+pppd_plugindir = $(PPPD_PLUGIN_DIR)
+
+PLUGIN_CPPFLAGS = -I${top_srcdir}/include -I${top_srcdir}/pppd
+PLUGIN_LDFLAGS = -module -avoid-version
+
+minconn_la_CPPFLAGS = $(PLUGIN_CPPFLAGS)
+minconn_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+minconn_la_SOURCES = minconn.c
+
+passprompt_la_CPPFLAGS = $(PLUGIN_CPPFLAGS)
+passprompt_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+passprompt_la_SOURCES = passprompt.c
+
+passwordfd_la_CPPFLAGS = $(PLUGIN_CPPFLAGS)
+passwordfd_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+passwordfd_la_SOURCES = passwordfd.c
+
+winbind_la_CPPFLAGS = $(PLUGIN_CPPFLAGS)
+winbind_la_LDFLAGS = $(PLUGIN_LDFLAGS)
+winbind_la_SOURCES = winbind.c
+
+if !SUNOS
+SUBDIRS = pppoe pppoatm pppol2tp radius
+endif
diff --git a/pppd/plugins/Makefile.linux b/pppd/plugins/Makefile.linux
deleted file mode 100644 (file)
index 6403e3d..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-CROSS_COMPILE=@CROSS_COMPILE@
-CC=$(CROSS_COMPILE)@CC@
-COPTS=@CFLAGS@
-
-DESTDIR = $(INSTROOT)@DESTDIR@
-BINDIR = $(DESTDIR)/sbin
-MANDIR = $(DESTDIR)/share/man/man8
-LIBDIR = $(DESTDIR)/lib/pppd/$(VERSION)
-
-CFLAGS = $(COPTS) -I.. -I../../include -fPIC
-LDFLAGS_SHARED = -shared
-INSTALL        = install
-
-# EAP-TLS
-CFLAGS += -DUSE_EAPTLS=1
-
-SUBDIRS := pppoe pppoatm pppol2tp
-# Uncomment the next line to include the radius authentication plugin
-SUBDIRS += radius
-PLUGINS := minconn.so passprompt.so passwordfd.so winbind.so
-
-# This setting should match the one in ../Makefile.linux
-MPPE=y
-
-ifdef MPPE
-CFLAGS   += -DMPPE=1
-endif
-
-# include dependencies if present
-ifeq (.depend,$(wildcard .depend))
-include .depend
-endif
-
-all:   $(PLUGINS)
-       for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d all || exit $$?; done
-
-%.so: %.c
-       $(CC) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) $(CFLAGS) $^
-
-VERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../patchlevel.h)
-
-install: $(PLUGINS)
-       $(INSTALL) -d $(LIBDIR)
-       $(INSTALL) $? $(LIBDIR)
-       for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d install || exit $$?; done
-
-clean:
-       rm -f *.o *.so *.a
-       for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d clean || exit $$?; done
-
-depend:
-       $(CPP) -M $(CFLAGS) *.c >.depend
-       for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d depend || exit $$?; done
diff --git a/pppd/plugins/Makefile.sol2 b/pppd/plugins/Makefile.sol2
deleted file mode 100644 (file)
index bc7d85d..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Makefile for plugins on Solaris 2
-#
-# $Id: Makefile.sol2,v 1.3 2002/09/07 05:15:25 carlsonj Exp $
-#
-
-include ../../Makedefs.com
-
-CFLAGS = -c -O -I.. -I../../include $(COPTS)
-LDFLAGS        = -G 
-
-all:   minconn.so
-
-minconn.so: minconn.o
-       ld -o $@ $(LDFLAGS) -h $@ minconn.o
-
-minconn.o: minconn.c
-       $(CC) $(CFLAGS) -c $? 
-
-passprompt.so: passprompt.o
-       ld -o $@ $(LDFLAGS) -h $@ passprompt.o
-
-passprompt.o: passprompt.c
-       $(CC) $(CFLAGS) -c $?
-
-clean:
-       rm -f *.o *.so
index c12216a0a7d81d55a86e424b74a3756682cbf194..40855ee1673637f565b6b19913bfd8b02f7958ba 100644 (file)
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stddef.h>
 #include <time.h>
 #include "pppd.h"
index ab9f390c2d1c968c8054b60e1e5da7cc81eb5e00..743c087b47805ea002b026dd7cf36a6b2ef5afb4 100644 (file)
@@ -8,6 +8,11 @@
  *  as published by the Free Software Foundation; either version
  *  2 of the License, or (at your option) any later version.
  */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <errno.h>
 #include <unistd.h>
 #include <sys/wait.h>
@@ -30,7 +35,7 @@ static int promptpass(char *user, char *passwd)
 {
     int p[2];
     pid_t kid;
-    int readgood, wstat;
+    int readgood, wstat, ret;
     ssize_t red;
 
     if (promptprog_refused || promptprog[0] == 0 || access(promptprog, X_OK) < 0)
@@ -55,8 +60,14 @@ static int promptpass(char *user, char *passwd)
        sys_close();
        closelog();
        close(p[0]);
-       seteuid(getuid());
-       setegid(getgid());
+       ret = seteuid(getuid());
+       if (ret != 0) {
+               warn("Couldn't set effective user id");
+       }
+       ret = setegid(getgid());
+       if (ret != 0) {
+               warn("Couldn't set effective user id");
+       }
        argv[0] = promptprog;
        argv[1] = user;
        argv[2] = remote_name;
index c3f9793e41a01b141da91d7a5370e04dec51af83..84fd72e3b9b6994a43d112410de3312744cdf3bc 100644 (file)
@@ -7,6 +7,10 @@
  *  with pap- and chap-secrets files.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
diff --git a/pppd/plugins/pppoatm/Makefile.am b/pppd/plugins/pppoatm/Makefile.am
new file mode 100644 (file)
index 0000000..66119c9
--- /dev/null
@@ -0,0 +1,18 @@
+pppd_plugin_LTLIBRARIES = pppoatm.la
+pppd_plugindir = $(PPPD_PLUGIN_DIR)
+
+noinst_HEADERS = \
+    atm.h \
+    atmres.h \
+    atmsap.h
+
+pppoatm_la_CPPFLAGS = -I${top_srcdir}/include -I${top_srcdir}/pppd
+pppoatm_la_LDFLAGS = -module -avoid-version
+pppoatm_la_SOURCES = pppoatm.c
+
+if WITH_LIBATM
+pppoatm_la_LIBADD = -latm
+else
+pppoatm_la_SOURCES += text2qos.c text2atm.c misc.c ans.c
+pppoatm_la_LIBADD = -lresolv
+endif
diff --git a/pppd/plugins/pppoatm/Makefile.linux b/pppd/plugins/pppoatm/Makefile.linux
deleted file mode 100644 (file)
index 970eee1..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-#***********************************************************************
-CROSS_COMPILE=@CROSS_COMPILE@
-CC=$(CROSS_COMPILE)@CC@
-COPTS=@CFLAGS@
-
-DESTDIR = $(INSTROOT)@DESTDIR@
-LIBDIR = $(DESTDIR)/lib/pppd/$(VERSION)
-
-VERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../../patchlevel.h)
-
-CFLAGS = $(COPTS) -I../.. -I../../../include -fPIC
-LDFLAGS_SHARED = -shared
-INSTALL        = install
-
-PLUGIN := pppoatm.so
-PLUGIN_OBJS := pppoatm.o 
-
-#*******
-# Do we have the ATM libraries installed? Set HAVE_LIBATM to use them,
-# or leave it unset to build the few routines we actually _use_ into
-# the plugin directly.
-#
-#HAVE_LIBATM=yes
-
-ifdef HAVE_LIBATM
-LIBS := -latm
-else
-CFLAGS += -I.
-PLUGIN_OBJS += text2qos.o text2atm.o misc.o ans.o
-LIBS := -lresolv
-endif
-
-#*********
-all: $(PLUGIN)
-
-$(PLUGIN): $(PLUGIN_OBJS)
-       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(LDFLAGS_SHARED) $^ $(LIBS)
-
-install: all
-       $(INSTALL) -d -m 755 $(LIBDIR)
-       $(INSTALL) -c -m 755 $(PLUGIN) $(LIBDIR)
-
-clean:
-       rm -f *.o *.so
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $<
index 5a3ecd61b6a2c278781ad94151c6e92458b4f77b..09cd0b8bfb0142524d12c15971f8e13844e7e6b0 100644 (file)
  *  as published by the Free Software Foundation; either version
  *  2 of the License, or (at your option) any later version.
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <unistd.h>
 #include <string.h>
 #include <stdlib.h>
@@ -183,15 +187,15 @@ void plugin_init(void)
 }
 
 struct channel pppoa_channel = {
-    options: pppoa_options,
-    process_extra_options: NULL,
-    check_options: NULL,
-    connect: &connect_pppoatm,
-    disconnect: &disconnect_pppoatm,
-    establish_ppp: &generic_establish_ppp,
-    disestablish_ppp: &generic_disestablish_ppp,
-    send_config: NULL,
-    recv_config: NULL,
-    close: NULL,
-    cleanup: NULL
+    .options = pppoa_options,
+    .process_extra_options = NULL,
+    .check_options = NULL,
+    .connect = &connect_pppoatm,
+    .disconnect = &disconnect_pppoatm,
+    .establish_ppp = &generic_establish_ppp,
+    .disestablish_ppp = &generic_disestablish_ppp,
+    .send_config = NULL,
+    .recv_config = NULL,
+    .close = NULL,
+    .cleanup = NULL
 };
diff --git a/pppd/plugins/pppoe/Makefile.am b/pppd/plugins/pppoe/Makefile.am
new file mode 100644 (file)
index 0000000..e3c01cd
--- /dev/null
@@ -0,0 +1,14 @@
+pppd_plugin_LTLIBRARIES = pppoe.la 
+pppd_plugindir = $(PPPD_PLUGIN_DIR)
+sbin_PROGRAMS = pppoe-discovery
+dist_man8_MANS = pppoe-discovery.8
+
+noinst_HEADERS = \
+    pppoe.h
+
+pppoe_la_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/include
+pppoe_la_LDFLAGS = -module -avoid-version
+pppoe_la_SOURCES = plugin.c discovery.c if.c common.c
+
+pppoe_discovery_CPPFLAGS = -I${top_srcdir} -I${top_srcdir}/include
+pppoe_discovery_SOURCES = pppoe-discovery.c debug.c
diff --git a/pppd/plugins/pppoe/Makefile.linux b/pppd/plugins/pppoe/Makefile.linux
deleted file mode 100644 (file)
index b969871..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#***********************************************************************
-#
-# Makefile
-#
-# Makefile for Roaring Penguin's Linux PPPoE plugin.
-# Modified for integration with pppd sources by Paul Mackerras.
-#
-# Copyright (C) 2001 Roaring Penguin Software Inc.
-#
-# This program may be distributed according to the terms of the GNU
-# General Public License, version 2 or (at your option) any later version.
-#
-#***********************************************************************
-
-CROSS_COMPILE=@CROSS_COMPILE@
-CC=$(CROSS_COMPILE)@CC@
-COPTS=@CFLAGS@
-
-DESTDIR = $(INSTROOT)@DESTDIR@
-BINDIR = $(DESTDIR)/sbin
-MANDIR = $(DESTDIR)/share/man/man8
-LIBDIR = $(DESTDIR)/lib/pppd/$(PPPDVERSION)
-
-PPPDVERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../../patchlevel.h)
-
-INSTALL        = install
-LN_S   = ln -sf
-
-CFLAGS=$(COPTS) -I../../../include
-all: pppoe.so pppoe-discovery
-
-pppoe-discovery: pppoe-discovery.o debug.o
-       $(CC) $(LDFLAGS) -o pppoe-discovery pppoe-discovery.o debug.o
-
-pppoe-discovery.o: pppoe-discovery.c
-       $(CC) $(CFLAGS) -I../../.. -c -o pppoe-discovery.o pppoe-discovery.c
-
-debug.o: debug.c
-       $(CC) $(CFLAGS) -I../../.. -c -o debug.o debug.c
-
-pppoe.so: plugin.o discovery.o if.o common.o
-       $(CC) $(LDFLAGS) -o pppoe.so -shared plugin.o discovery.o if.o common.o
-
-install: all
-       $(INSTALL) -d -m 755 $(LIBDIR)
-       $(INSTALL) -c -m 755 pppoe.so $(LIBDIR)
-       # Symlink for backward compatibility
-       $(LN_S) pppoe.so $(LIBDIR)/rp-pppoe.so
-       $(INSTALL) -d -m 755 $(BINDIR)
-       $(INSTALL) -c -m 755 pppoe-discovery $(BINDIR)
-       $(INSTALL) -c -m 644 pppoe-discovery.8 $(MANDIR)
-
-clean:
-       rm -f *.o *.so pppoe-discovery
-
-plugin.o: plugin.c
-       $(CC) $(CFLAGS) -I../../.. -c -o plugin.o -fPIC plugin.c
-
-discovery.o: discovery.c
-       $(CC) $(CFLAGS) -I../../.. -c -o discovery.o -fPIC discovery.c
-
-if.o: if.c
-       $(CC) $(CFLAGS) -I../../.. -c -o if.o -fPIC if.c
-
-common.o: common.c
-       $(CC) $(CFLAGS) -I../../.. -c -o common.o -fPIC common.c
-
index 9ea7fd609c8774aafbaf2cbe9bb6a6d86679b516..64bed1af6ca63df5de7344bbdc85c8ea262f22e8 100644 (file)
 static char const RCSID[] =
 "$Id: common.c,v 1.3 2008/06/09 08:34:23 paulus Exp $";
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #define _GNU_SOURCE 1
 #include "pppoe.h"
 #include "pppd/pppd.h"
@@ -132,7 +136,7 @@ sendPADT(PPPoEConnection *conn, char const *msg)
        size_t elen = strlen(msg);
        err.type = htons(TAG_GENERIC_ERROR);
        err.length = htons(elen);
-       strcpy(err.payload, msg);
+       strcpy((char*) err.payload, msg);
        memcpy(cursor, &err, elen + TAG_HDR_SIZE);
        cursor += elen + TAG_HDR_SIZE;
        plen += elen + TAG_HDR_SIZE;
diff --git a/pppd/plugins/pppoe/config.h b/pppd/plugins/pppoe/config.h
deleted file mode 100644 (file)
index a708859..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/* config.h.  Generated automatically by configure.  */
-/* config.h.in.  Generated automatically from configure.in by autoheader.  */
-
-/* Define to empty if the keyword does not work.  */
-/* #undef const */
-
-/* Define if you have <sys/wait.h> that is POSIX.1 compatible.  */
-#define HAVE_SYS_WAIT_H 1
-
-/* Define to `int' if <sys/types.h> doesn't define.  */
-/* #undef pid_t */
-
-/* Define as the return type of signal handlers (int or void).  */
-#define RETSIGTYPE void
-
-/* Define if the setvbuf function takes the buffering type as its second
-   argument and the buffer pointer as the third, as on System V
-   before release 3.  */
-/* #undef SETVBUF_REVERSED */
-
-/* Define if you have the ANSI C header files.  */
-#define STDC_HEADERS 1
-
-/* Define if you can safely include both <sys/time.h> and <time.h>.  */
-#define TIME_WITH_SYS_TIME 1
-
-/* Define if your <sys/time.h> declares struct tm.  */
-/* #undef TM_IN_SYS_TIME */
-
-#define HAVE_STRUCT_SOCKADDR_LL 1
-
-/* The number of bytes in a unsigned int.  */
-#define SIZEOF_UNSIGNED_INT 4
-
-/* The number of bytes in a unsigned long.  */
-#define SIZEOF_UNSIGNED_LONG 4
-
-/* The number of bytes in a unsigned short.  */
-#define SIZEOF_UNSIGNED_SHORT 2
-
-/* Define if you have the select function.  */
-#define HAVE_SELECT 1
-
-/* Define if you have the socket function.  */
-#define HAVE_SOCKET 1
-
-/* Define if you have the strerror function.  */
-#define HAVE_STRERROR 1
-
-/* Define if you have the strtol function.  */
-#define HAVE_STRTOL 1
-
-/* Define if you have the <asm/types.h> header file.  */
-#define HAVE_ASM_TYPES_H 1
-
-/* Define if you have the <fcntl.h> header file.  */
-#define HAVE_FCNTL_H 1
-
-/* Define if you have the <getopt.h> header file.  */
-#define HAVE_GETOPT_H 1
-
-/* Define if you have the <linux/if_ether.h> header file.  */
-#define HAVE_LINUX_IF_ETHER_H 1
-
-/* Define if you have kernel-mode PPPoE in Linux file.  */
-#define HAVE_LINUX_KERNEL_PPPOE 1
-
-/* Define if you have the <linux/if_packet.h> header file.  */
-#define HAVE_LINUX_IF_PACKET_H 1
-
-/* Define if you have the <linux/if_pppox.h> header file.  */
-#define HAVE_LINUX_IF_PPPOX_H 1
-
-/* Define if you have the <net/bpf.h> header file.  */
-#define HAVE_NET_BPF_H 1
-
-/* Define if you have the <net/if_arp.h> header file.  */
-#define HAVE_NET_IF_ARP_H 1
-
-/* Define if you have the <net/ethernet.h> header file.  */
-#define HAVE_NET_ETHERNET_H 1
-
-/* Define if you have the <net/if.h> header file.  */
-#define HAVE_NET_IF_H 1
-
-/* Define if you have the <linux/if.h> header file.  */
-#define HAVE_LINUX_IF_H 1
-
-/* Define if you have the <net/if_dl.h> header file.  */
-/* #undef HAVE_NET_IF_DL_H */
-
-/* Define if you have the <net/if_ether.h> header file.  */
-/* #undef HAVE_NET_IF_ETHER_H */
-
-/* Define if you have the <net/if_types.h> header file.  */
-/* #undef HAVE_NET_IF_TYPES_H */
-
-/* Define if you have the <netinet/if_ether.h> header file.  */
-#define HAVE_NETINET_IF_ETHER_H 1
-
-/* Define if you have the <netpacket/packet.h> header file.  */
-#define HAVE_NETPACKET_PACKET_H 1
-
-/* Define if you have the <sys/dlpi.h> header file.  */
-/* #undef HAVE_SYS_DLPI_H */
-
-/* Define if you have the <sys/ioctl.h> header file.  */
-#define HAVE_SYS_IOCTL_H 1
-
-/* Define if you have the <sys/param.h> header file.  */
-#define HAVE_SYS_PARAM_H 1
-
-/* Define if you have the <sys/socket.h> header file.  */
-#define HAVE_SYS_SOCKET_H 1
-
-/* Define if you have the <sys/time.h> header file.  */
-#define HAVE_SYS_TIME_H 1
-
-/* Define if you have the <sys/uio.h> header file.  */
-#define HAVE_SYS_UIO_H 1
-
-/* Define if you have the <syslog.h> header file.  */
-#define HAVE_SYSLOG_H 1
-
-/* Define if you have the <unistd.h> header file.  */
-#define HAVE_UNISTD_H 1
-
-/* Define if you have the N_HDLC line discipline in linux/termios.h */
-#define HAVE_N_HDLC 1
index a6e698161a8189b1b644ce244294fdd35e6fff49..3478b5f81e27cd210283cbaa0bc89f0dadd6f270 100644 (file)
 static char const RCSID[] =
 "$Id: debug.c,v 1.2 2008/06/09 08:34:23 paulus Exp $";
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include "pppoe.h"
 #include <sys/time.h>
 #include <time.h>
index 23089df550771f2a795c1e54b8d197b6bdc5e492..bd281bdb863b1a6be44e6c9530f99e7b6f05997e 100644 (file)
 static char const RCSID[] =
 "$Id: discovery.c,v 1.6 2008/06/15 04:35:50 paulus Exp $";
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #define _GNU_SOURCE 1
 #include "pppoe.h"
 #include "pppd/pppd.h"
index 225dd567c2e7486c5ef3998c108ac5e8bb18afce..3dfea8c0fa20347c0c0a78c35cb386d6989b974b 100644 (file)
 static char const RCSID[] =
 "$Id: if.c,v 1.2 2008/06/09 08:34:23 paulus Exp $";
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #define _GNU_SOURCE 1
 #include "pppoe.h"
 #include "pppd/pppd.h"
index de9b8166ce7bb1e982aaaacdf5f1049c3d225471..8bcd1f8d0306d372997647d0e5c9221836057919 100644 (file)
 static char const RCSID[] =
 "$Id: plugin.c,v 1.17 2008/06/15 04:35:50 paulus Exp $";
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #define _GNU_SOURCE 1
 #include "pppoe.h"
 
index e41d2863cb9bafe0e85eb321f8bd7421ad91c758..96d6333edddfd451d710dcbf78d42ecc2ee5a7e8 100644 (file)
@@ -9,6 +9,10 @@
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
index 4e1972002ed80e17d5790c0f07c1d82bb2fb1d85..5d96f0cf0c88ee197cc8732d90dce4186cf87b52 100644 (file)
@@ -13,8 +13,6 @@
 *
 ***********************************************************************/
 
-#include "config.h"
-
 #include <stdio.h>             /* For FILE */
 #include <sys/types.h>         /* For pid_t */
 #include <ctype.h>
diff --git a/pppd/plugins/pppol2tp/Makefile.am b/pppd/plugins/pppol2tp/Makefile.am
new file mode 100644 (file)
index 0000000..999f35b
--- /dev/null
@@ -0,0 +1,13 @@
+pppd_plugin_LTLIBRARIES = pppol2tp.la openl2tp.la
+pppd_plugindir = $(PPPD_PLUGIN_DIR)
+
+noinst_HEADERS = \
+    l2tp_event.h
+
+pppol2tp_la_CPPFLAGS = -I${top_srcdir}/include -I${top_srcdir}/pppd
+pppol2tp_la_LDFLAGS = -module -avoid-version
+pppol2tp_la_SOURCES = pppol2tp.c
+
+openl2tp_la_CPPFLAGS = -I${top_srcdir}/include -I${top_srcdir}/pppd
+openl2tp_la_LDFLAGS = -module -avoid-version
+openl2tp_la_SOURCES = openl2tp.c
diff --git a/pppd/plugins/pppol2tp/Makefile.linux b/pppd/plugins/pppol2tp/Makefile.linux
deleted file mode 100644 (file)
index 1aa1c0b..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#***********************************************************************
-CROSS_COMPILE=@CROSS_COMPILE@
-CC=$(CROSS_COMPILE)@CC@
-COPTS=@CFLAGS@
-
-DESTDIR = $(INSTROOT)/@DESTDIR@
-LIBDIR = $(DESTDIR)/lib/pppd/$(VERSION)
-
-VERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../../patchlevel.h)
-
-CFLAGS = $(COPTS) -I. -I../.. -I../../../include -fPIC
-LDFLAGS_SHARED = -shared
-INSTALL        = install
-
-PLUGINS := pppol2tp.so openl2tp.so
-
-all: $(PLUGINS)
-
-%.so: %.o
-       $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(LDFLAGS_SHARED) $^ $(LIBS)
-
-install: all
-       $(INSTALL) -d -m 755 $(LIBDIR)
-       $(INSTALL) -c -m 755 $(PLUGINS) $(LIBDIR)
-
-clean:
-       rm -f *.o *.so
-
-%.o: %.c
-       $(CC) $(CFLAGS) -c -o $@ $<
index 85ff0b56cdc5b839382a2f970034419c6bcb7756..0f9db6d5ecc34e268206d1b55d4205881172b0fa 100644 (file)
 
 /* pppd plugin for interfacing to openl2tpd */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <unistd.h>
 #include <string.h>
 #include <stdlib.h>
index 1be0ad25b67cb1e0dca3a6ce4832c766ecd996fe..ed2d7c7942a11db2ac6eb8152d0ad87507bf2886 100644 (file)
  *  as published by the Free Software Foundation; either version
  *  2 of the License, or (at your option) any later version.
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <unistd.h>
 #include <string.h>
 #include <stdlib.h>
@@ -121,10 +125,10 @@ static int setdevname_pppol2tp(char **argv)
                char buffer[128];
                struct sockaddr pppol2tp;
        } s;
-       int len = sizeof(s);
+       socklen_t len = sizeof(s);
        char **a;
        int tmp;
-       int tmp_len = sizeof(tmp);
+       socklen_t tmp_len = sizeof(tmp);
 
        if (device_got_set)
                return 0;
@@ -203,8 +207,8 @@ static void send_config_pppol2tp(int mtu,
        int on = 1;
        int fd;
        char reorderto[16];
-       char tid[8];
-       char sid[8];
+       char tid[12];
+       char sid[12];
 
        if (pppol2tp_ifname[0]) {
                struct ifreq ifr;
@@ -237,10 +241,10 @@ static void send_config_pppol2tp(int mtu,
                sprintf(&reorderto[0], "%d ", pppol2tp_reorder_timeout);
        tid[0] = '\0';
        if (pppol2tp_tunnel_id > 0)
-               sprintf(&tid[0], "%hu ", pppol2tp_tunnel_id);
+               sprintf(&tid[0], "%u ", pppol2tp_tunnel_id);
        sid[0] = '\0';
        if (pppol2tp_session_id > 0)
-               sprintf(&sid[0], "%hu ", pppol2tp_session_id);
+               sprintf(&sid[0], "%u ", pppol2tp_session_id);
 
        dbglog("PPPoL2TP options: %s%s%s%s%s%s%s%s%sdebugmask %d",
               pppol2tp_recv_seq ? "recvseq " : "",
@@ -510,15 +514,15 @@ void plugin_init(void)
 }
 
 struct channel pppol2tp_channel = {
-    options: pppol2tp_options,
-    process_extra_options: NULL,
-    check_options: &pppol2tp_check_options,
-    connect: &connect_pppol2tp,
-    disconnect: &disconnect_pppol2tp,
-    establish_ppp: &generic_establish_ppp,
-    disestablish_ppp: &generic_disestablish_ppp,
-    send_config: &send_config_pppol2tp,
-    recv_config: &recv_config_pppol2tp,
-    close: NULL,
-    cleanup: NULL
+    .options = pppol2tp_options,
+    .process_extra_options = NULL,
+    .check_options = &pppol2tp_check_options,
+    .connect = &connect_pppol2tp,
+    .disconnect = &disconnect_pppol2tp,
+    .establish_ppp = &generic_establish_ppp,
+    .disestablish_ppp = &generic_disestablish_ppp,
+    .send_config = &send_config_pppol2tp,
+    .recv_config = &recv_config_pppol2tp,
+    .close = NULL,
+    .cleanup = NULL
 };
diff --git a/pppd/plugins/radius/Makefile.am b/pppd/plugins/radius/Makefile.am
new file mode 100644 (file)
index 0000000..c3cff23
--- /dev/null
@@ -0,0 +1,64 @@
+pppd_plugin_LTLIBRARIES = radius.la radattr.la radrealms.la
+pppd_plugindir = $(PPPD_PLUGIN_DIR)
+
+noinst_LTLIBRARIES = libradiusclient.la
+dist_man8_MANS = pppd-radius.8 pppd-radattr.8
+noinst_HEADERS = \
+    includes.h \
+    options.h \
+    pathnames.h \
+    radiusclient.h
+
+EXTRA_FILES = \
+    COPYRIGHT
+
+EXTRA_ETC = \
+    etc/dictionary \
+    etc/dictionary.ascend \
+    etc/dictionary.compat \
+    etc/dictionary.merit \
+    etc/dictionary.microsoft \
+    etc/issue \
+    etc/port-id-map \
+    etc/radiusclient.conf \
+    etc/radiusclient.conf.in \
+    etc/realms \
+    etc/servers
+
+RADIUS_CPPFLAGS = -I${top_srcdir}/include -I${top_srcdir}/pppd -DRC_LOG_FACILITY=LOG_DAEMON
+RADIUS_LDFLAGS = -module -avoid-version $(LDFLAGS)
+
+radius_la_CPPFLAGS = $(RADIUS_CPPFLAGS)
+radius_la_LDFLAGS = $(RADIUS_LDFLAGS)
+radius_la_SOURCES = radius.c
+radius_la_LIBADD = libradiusclient.la
+if WITH_OPENSSL
+radius_la_LIBADD += $(OPENSSL_LIBS)
+endif
+
+radattr_la_CPPFLAGS = $(RADIUS_CPPFLAGS)
+radattr_la_LDFLAGS = $(RADIUS_LDFLAGS)
+radattr_la_SOURCES = radattr.c
+
+radrealms_la_CPPFLAGS = $(RADIUS_CPPFLAGS)
+radrealms_la_LDFLAGS = $(RADIUS_LDFLAGS)
+radrealms_la_SOURCES = radrealms.c
+
+libradiusclient_la_SOURCES = \
+    avpair.c buildreq.c config.c dict.c ip_util.c \
+       clientid.c sendserver.c lock.c util.c
+libradiusclient_la_CPPFLAGS = $(RADIUS_CPPFLAGS)
+
+if !WITH_OPENSSL
+libradiusclient_la_SOURCES += md5.c
+else
+if OPENSSL_HAVE_MD5
+libradiusclient_la_SOURCES += md5.c
+else
+libradiusclient_la_CPPFLAGS += $(OPENSSL_INCLUDES)
+endif
+endif
+
+EXTRA_DIST = \
+    $(EXTRA_FILES) \
+    $(EXTRA_ETC)
diff --git a/pppd/plugins/radius/Makefile.linux b/pppd/plugins/radius/Makefile.linux
deleted file mode 100644 (file)
index 489aef2..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-# Makefile for RADIUS plugin
-#
-# Copyright 2002 Roaring Penguin Software Inc.
-#
-
-CROSS_COMPILE=@CROSS_COMPILE@
-CC=$(CROSS_COMPILE)@CC@
-COPTS=@CFLAGS@
-
-DESTDIR = $(INSTROOT)@DESTDIR@
-MANDIR = $(DESTDIR)/share/man/man8
-LIBDIR = $(DESTDIR)/lib/pppd/$(VERSION)
-
-VERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../../patchlevel.h)
-
-INSTALL        = install
-
-PLUGIN=radius.so radattr.so radrealms.so
-CFLAGS = $(COPTS) -I. -I../.. -I../../../include -fPIC -DRC_LOG_FACILITY=LOG_DAEMON
-
-# Uncomment the next line to include support for Microsoft's
-# MS-CHAP authentication protocol.
-CHAPMS=y
-# Uncomment the next line to include support for MPPE.
-MPPE=y
-# Uncomment the next lint to include support for traffic limiting
-MAXOCTETS=y
-
-ifdef CHAPMS
-CFLAGS += -DCHAPMS=1
-ifdef MPPE
-CFLAGS += -DMPPE=1
-endif
-endif
-ifdef MAXOCTETS
-CFLAGS += -DMAXOCTETS=1
-endif
-
-all: $(PLUGIN)
-
-install: all
-       $(INSTALL) -d -m 755 $(LIBDIR)
-       $(INSTALL) -c -m 755 radius.so $(LIBDIR)
-       $(INSTALL) -c -m 755 radattr.so $(LIBDIR)
-       $(INSTALL) -c -m 755 radrealms.so $(LIBDIR)
-       $(INSTALL) -c -m 444 pppd-radius.8 $(MANDIR)
-       $(INSTALL) -c -m 444 pppd-radattr.8 $(MANDIR)
-
-radius.so: radius.o libradiusclient.a
-       $(CC) $(LDFLAGS) -o radius.so -shared radius.o libradiusclient.a
-
-radattr.so: radattr.o
-       $(CC) $(LDFLAGS) -o radattr.so -shared radattr.o
-
-radrealms.so: radrealms.o
-       $(CC) $(LDFLAGS) -o radrealms.so -shared radrealms.o
-
-CLIENTOBJS = avpair.o buildreq.o config.o dict.o ip_util.o \
-       clientid.o sendserver.o lock.o util.o md5.o
-libradiusclient.a: $(CLIENTOBJS)
-       $(AR) rv $@ $?
-
-clean:
-       rm -f *.o *.so *.a
-
-distclean:
-       rm -f *.o *.so *.a
-
-dist-clean: distclean
index d548b47b1d23bd5ecc4c56b6ad2081a2068463dc..0dc9a85d13a6be0b4e8e939961e754e5a7ce2b00 100644 (file)
@@ -76,7 +76,7 @@ int rc_avpair_assign (VALUE_PAIR *vp, void *pval, int len)
                                vp->strvalue[len] = '\0';
                                vp->lvalue = len;
                        } else {
-                       strncpy (vp->strvalue, (char *) pval, AUTH_STRING_LEN);
+                       strncpy ((char*) vp->strvalue, (char *) pval, AUTH_STRING_LEN);
                        vp->lvalue = strlen((char *) pval);
                        }
 
@@ -161,7 +161,7 @@ VALUE_PAIR *rc_avpair_gen (AUTH_HDR *auth)
        DICT_ATTR      *attr;
        VALUE_PAIR     *vp;
        VALUE_PAIR     *pair;
-       unsigned char   hex[3];         /* For hex string conversion. */
+       char            hex[3];         /* For hex string conversion. */
        char            buffer[512];
 
        /*
@@ -600,7 +600,7 @@ int rc_avpair_parse (char *buffer, VALUE_PAIR **first_pair)
                        {
 
                            case PW_TYPE_STRING:
-                               strcpy (pair->strvalue, valstr);
+                               strcpy ((char*) pair->strvalue, valstr);
                                pair->lvalue = strlen(valstr);
                                break;
 
@@ -725,7 +725,7 @@ int rc_avpair_tostr (VALUE_PAIR *pair, char *name, int ln, char *value, int lv)
                        }
                        else
                        {
-                               strncat(value, ptr, 1);
+                               strncat(value, (char*) ptr, 1);
                                lv--;
                                if (lv < 0) break;
                        }
index 3edd5ea92e1c0e0a864975670f5fa57b8aa87aa0..562790aa7887ea8d174021cce062a85abbcf843c 100644 (file)
@@ -94,7 +94,7 @@ unsigned char rc_get_seqnbr(void)
 {
        FILE *sf;
        int tries = 1;
-       int seq_nbr, pos;
+       int seq_nbr, pos, ret;
        char *seqfile = rc_conf_str("seqfile");
 
        if ((sf = fopen(seqfile, "a+")) == NULL)
@@ -135,7 +135,10 @@ unsigned char rc_get_seqnbr(void)
        }
 
        rewind(sf);
-       ftruncate(fileno(sf),0);
+       ret = ftruncate(fileno(sf),0);
+       if (ret != 0) {
+               error("rc_get_seqnbr: couldn't truncate sequence file, %m");
+       }
        fprintf(sf,"%d\n", (seq_nbr+1) & UCHAR_MAX);
 
        fflush(sf); /* fflush because a process may read it between the do_unlock and fclose */
index 871cea060cb0e68cbccd99957ca1e800b55b0e8c..47c172cccf00234b9bcc135a63a14e9a30c7006b 100644 (file)
@@ -525,7 +525,6 @@ int rc_find_server (char *server_name, UINT4 *ip_addr, char *secret)
        if (result == 0)
        {
                memset (buffer, '\0', sizeof (buffer));
-               memset (secret, '\0', sizeof (secret));
                error("rc_find_server: couldn't find RADIUS server %s in %s",
                      server_name, rc_conf_str("servers"));
                return (-1);
index 3b2add2ae4e7cbc7fe84b67b83a3722d4b8e6f73..6f2657d719ae4a3806c7e67eb85207640b171050 100644 (file)
@@ -150,7 +150,7 @@ int rc_read_dictionary (char *filename)
                        {
                                type = PW_TYPE_INTEGER;
                        }
-                       else if (strcmp (typestr, "ipaddr") == 0)
+                       else if (strcmp (typestr, "ipaddr") == 0 || strcmp (typestr, "ipv4addr") == 0)
                        {
                                type = PW_TYPE_IPADDR;
                        }
index 1fe7daa551613049a783135beaabf8147b60e035..f6a787424afc4fc304f605fb02467b4d055d9700 100644 (file)
 static char const RCSID[] =
 "$Id: radattr.c,v 1.2 2004/10/28 00:24:40 paulus Exp $";
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include "pppd.h"
 #include "radiusclient.h"
 #include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 
 extern void (*radius_attributes_hook)(VALUE_PAIR *);
 static void print_attributes(VALUE_PAIR *);
@@ -71,9 +77,12 @@ print_attributes(VALUE_PAIR *vp)
     char name[2048];
     char value[2048];
     int cnt = 0;
+    mode_t old_umask;
 
     slprintf(fname, sizeof(fname), "/var/run/radattr.%s", ifname);
+    old_umask = umask(077);
     fp = fopen(fname, "w");
+    umask(old_umask);
     if (!fp) {
        warn("radattr plugin: Could not open %s for writing: %m", fname);
        return;
index c5798316719af431a6f1dc6926845bde76b95b88..254ed904184f150330a0696a532f83a23a8d8f08 100644 (file)
 static char const RCSID[] =
 "$Id: radius.c,v 1.32 2008/05/26 09:18:08 paulus Exp $";
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include "pppd.h"
 #include "chap-new.h"
 #ifdef CHAPMS
 #include "chap_ms.h"
 #ifdef MPPE
+#include "mppe.h"
 #include "md5.h"
 #endif
 #endif
@@ -107,7 +112,6 @@ static int radius_setmppekeys2(VALUE_PAIR *vp, REQUEST_INFO *req_info);
 #endif
 
 struct radius_state {
-    int accounting_started;
     int initialized;
     int client_port;
     int choose_ip;
@@ -202,7 +206,7 @@ add_avp(char **argv)
 *  1 -- we are ALWAYS willing to supply a secret. :-)
 * %DESCRIPTION:
 * Tells pppd that we will try to authenticate the peer, and not to
-* worry about looking in /etc/ppp/*-secrets
+* worry about looking in *-secrets file(s)
 ***********************************************************************/
 static int
 radius_secret_check(void)
@@ -593,11 +597,11 @@ radius_setparams(VALUE_PAIR *vp, char *msg, REQUEST_INFO *req_info,
                break;
            case PW_FILTER_ID:
                /* packet filter, will be handled via ip-(up|down) script */
-               script_setenv("RADIUS_FILTER_ID", vp->strvalue, 1);
+               script_setenv("RADIUS_FILTER_ID", (char*) vp->strvalue, 1);
                break;
            case PW_FRAMED_ROUTE:
                /* route, will be handled via ip-(up|down) script */
-               script_setenv("RADIUS_FRAMED_ROUTE", vp->strvalue, 1);
+               script_setenv("RADIUS_FRAMED_ROUTE", (char*) vp->strvalue, 1);
                break;
            case PW_IDLE_TIMEOUT:
                /* idle parameter */
@@ -661,12 +665,12 @@ radius_setparams(VALUE_PAIR *vp, char *msg, REQUEST_INFO *req_info,
 #ifdef CHAPMS
            switch (vp->attribute) {
            case PW_MS_CHAP2_SUCCESS:
-               if ((vp->lvalue != 43) || strncmp(vp->strvalue + 1, "S=", 2)) {
+               if ((vp->lvalue != 43) || strncmp((char*) vp->strvalue + 1, "S=", 2)) {
                    slprintf(msg,BUF_LEN,"RADIUS: bad MS-CHAP2-Success packet");
                    return -1;
                }
                if (message != NULL)
-                   strlcpy(message, vp->strvalue + 1, message_space);
+                   strlcpy(message, (char*) vp->strvalue + 1, message_space);
                ms_chap2_success = 1;
                break;
 
@@ -743,11 +747,12 @@ radius_setparams(VALUE_PAIR *vp, char *msg, REQUEST_INFO *req_info,
      * Note that if the policy value was '0' we don't set the key!
      */
     if (mppe_enc_policy && mppe_enc_keys) {
-       mppe_keys_set = 1;
        /* Set/modify allowed encryption types. */
        if (mppe_enc_types)
-           set_mppe_enc_types(mppe_enc_policy, mppe_enc_types);
+           mppe_set_enc_types(mppe_enc_policy, mppe_enc_types);
+       return 0;
     }
+    mppe_clear_keys();
 #endif
 
     return 0;
@@ -803,7 +808,7 @@ radius_setmppekeys(VALUE_PAIR *vp, REQUEST_INFO *req_info,
      * the NAS (us) doesn't need; we only need the start key.  So we have
      * to generate the start key, sigh.  NB: We do not support the LM-Key.
      */
-    mppe_set_keys(challenge, &plain[8]);
+    mppe_set_chapv1(challenge, &plain[8]);
 
     return 0;    
 }
@@ -855,7 +860,7 @@ radius_setmppekeys2(VALUE_PAIR *vp, REQUEST_INFO *req_info)
     for (i = 0; i < 16; i++)
        plain[i] ^= buf[i];
 
-    if (plain[0] != sizeof(mppe_send_key) /* 16 */) {
+    if (plain[0] != 16) {
        error("RADIUS: Incorrect key length (%d) for MS-MPPE-%s-Key attribute",
              (int) plain[0], type);
        return -1;
@@ -869,9 +874,9 @@ radius_setmppekeys2(VALUE_PAIR *vp, REQUEST_INFO *req_info)
     plain[16] ^= buf[0]; /* only need the first byte */
 
     if (vp->attribute == PW_MS_MPPE_SEND_KEY)
-       memcpy(mppe_send_key, plain + 1, 16);
+       mppe_set_keys(plain + 1, NULL, 16);
     else
-       memcpy(mppe_recv_key, plain + 1, 16);
+       mppe_set_keys(NULL, plain + 1, 16);
 
     return 0;
 }
@@ -955,12 +960,11 @@ radius_acct_start(void)
        /* RADIUS server could be down so make this a warning */
        syslog(LOG_WARNING,
                "Accounting START failed for %s", rstate.user);
-    } else {
-       rstate.accounting_started = 1;
-       /* Kick off periodic accounting reports */
-       if (rstate.acct_interim_interval) {
-           TIMEOUT(radius_acct_interim, NULL, rstate.acct_interim_interval);
-       }
+    }
+
+    /* Kick off periodic accounting reports */
+    if (rstate.acct_interim_interval) {
+       TIMEOUT(radius_acct_interim, NULL, rstate.acct_interim_interval);
     }
 }
 
@@ -986,14 +990,9 @@ radius_acct_stop(void)
        return;
     }
 
-    if (!rstate.accounting_started) {
-       return;
-    }
-
     if (rstate.acct_interim_interval)
        UNTIMEOUT(radius_acct_interim, NULL);
 
-    rstate.accounting_started = 0;
     rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id,
                   0, VENDOR_NONE);
 
@@ -1138,10 +1137,6 @@ radius_acct_interim(void *ignored)
        return;
     }
 
-    if (!rstate.accounting_started) {
-       return;
-    }
-
     rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id,
                   0, VENDOR_NONE);
 
index cd006fd0894cae2cae87ec303daf1256839cbe87..a3b9a513bb53ab93a59e25e7d01e4b4930d3cf99 100644 (file)
 static char const RCSID[] =
     "$Id: radrealms.c,v 1.2 2004/11/14 07:26:26 paulus Exp $";
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include "pppd.h"
 #include "radiusclient.h"
 #include <stdio.h>
index 0c0ef30f8d37f41309cc395a9d3fad5153130f08..f6012868e2dbbbcb6de5f3a4806088d0c9f761a9 100644 (file)
@@ -104,7 +104,7 @@ static int rc_pack_list (VALUE_PAIR *vp, char *secret, AUTH_HDR *auth)
                    memcpy ((char *) passbuf, vp->strvalue, (size_t) length);
 
                    secretlen = strlen (secret);
-                   vector = (char *)auth->vector;
+                   vector = auth->vector;
                    for(i = 0; i < padded_length; i += AUTH_VECTOR_LEN) {
                        /* Calculate the MD5 digest*/
                        strcpy ((char *) md5buf, secret);
@@ -200,10 +200,10 @@ int rc_send_server (SEND_DATA *data, char *msg, REQUEST_INFO *info)
        AUTH_HDR       *auth, *recv_auth;
        UINT4           auth_ipaddr;
        char           *server_name;    /* Name of server to query */
-       int             salen;
+       socklen_t       salen;
        int             result;
        int             total_length;
-       int             length;
+       socklen_t       length;
        int             retry_max;
        int             secretlen;
        char            secret[MAX_SECRET_LENGTH + 1];
@@ -228,6 +228,7 @@ int rc_send_server (SEND_DATA *data, char *msg, REQUEST_INFO *info)
        {
                if (rc_find_server (server_name, &auth_ipaddr, secret) != 0)
                {
+                       memset (secret, '\0', sizeof (secret));
                        return (ERROR_RC);
                }
        }
@@ -272,7 +273,7 @@ int rc_send_server (SEND_DATA *data, char *msg, REQUEST_INFO *info)
                memset((char *) auth->vector, 0, AUTH_VECTOR_LEN);
                secretlen = strlen (secret);
                memcpy ((char *) auth + total_length, secret, secretlen);
-               rc_md5_calc (vector, (char *) auth, total_length + secretlen);
+               rc_md5_calc (vector, (unsigned char *) auth, total_length + secretlen);
                memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
        }
        else
@@ -362,7 +363,7 @@ int rc_send_server (SEND_DATA *data, char *msg, REQUEST_INFO *info)
        {
                if ((vp = rc_avpair_get(vp, PW_REPLY_MESSAGE)))
                {
-                       strcat(msg, vp->strvalue);
+                       strcat(msg, (char*) vp->strvalue);
                        strcat(msg, "\n");
                        vp = vp->next;
                }
@@ -428,7 +429,7 @@ static int rc_check_reply (AUTH_HDR *auth, int bufferlen, char *secret,
        memcpy ((char *) reply_digest, (char *) auth->vector, AUTH_VECTOR_LEN);
        memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
        memcpy ((char *) auth + totallen, secret, secretlen);
-       rc_md5_calc (calc_digest, (char *) auth, totallen + secretlen);
+       rc_md5_calc (calc_digest, (unsigned char *) auth, totallen + secretlen);
 
 #ifdef DIGEST_DEBUG
        {
index 740131e8377c51f326b1f465ca94a12526563712..4065724926ae44a1a1433a2b0ef25e01e9ec35bc 100644 (file)
@@ -75,10 +75,10 @@ rc_mksid (void)
 {
   static char buf[32];
   static unsigned short int cnt = 0;
-  slprintf(buf, sizeof(buf), "%08lX%04X%02hX",
+  snprintf(buf, sizeof(buf), "%08lX%04X%02hX",
           (unsigned long int) time (NULL),
           (unsigned int) getpid (),
-          cnt & 0xFF);
+          (unsigned short) (cnt & 0xFF));
   cnt++;
   return buf;
 }
index 0c395c34711af6cef39d3ac01e3603f7205ebbc5..76db234737e93876f38d97171ab3877aea19c729 100644 (file)
 *
 ***********************************************************************/
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include "pppd.h"
 #include "chap-new.h"
 #include "chap_ms.h"
-#ifdef MPPE
-#include "md5.h"
-#endif
 #include "fsm.h"
 #include "ipcp.h"
+#include "mppe.h"
 #include <syslog.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -165,7 +167,7 @@ plugin_init(void)
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
-size_t strhex_to_str(char *p, size_t len, const char *strhex)
+size_t strhex_to_str(unsigned char *p, size_t len, const char *strhex)
 {
        size_t i;
        size_t num_chars = 0;
@@ -297,15 +299,20 @@ unsigned int run_ntlm_auth(const char *username,
        if (forkret == 0) {
                /* child process */
                uid_t uid;
+               gid_t gid;
 
                close(child_out[0]);
                close(child_in[1]);
 
                /* run winbind as the user that invoked pppd */
-               setgid(getgid());
+               gid = getgid();
+               if (setgid(gid) == -1 || getgid() != gid) {
+                       fatal("pppd/winbind: could not setgid to %d: %m", gid);
+               }
                uid = getuid();
-               if (setuid(uid) == -1 || getuid() != uid)
+               if (setuid(uid) == -1 || getuid() != uid) {
                        fatal("pppd/winbind: could not setuid to %d: %m", uid);
+               }
                execl("/bin/sh", "sh", "-c", ntlm_auth, NULL);  
                fatal("pppd/winbind: could not exec /bin/sh: %m");
        }
@@ -520,7 +527,7 @@ winbind_chap_verify(char *user, char *ourname, int id,
        char *domain;
        char *username;
        char *p;
-       char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
+       unsigned char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
 
        /* The first byte of each of these strings contains their length */
        challenge_len = *challenge++;
@@ -583,7 +590,9 @@ winbind_chap_verify(char *user, char *ourname, int id,
                                  nt_response, nt_response_size,
                                  session_key,
                                  &error_string) == AUTHENTICATED) {
-                       mppe_set_keys(challenge, session_key);
+#ifdef MPPE
+                       mppe_set_chapv1(challenge, session_key);
+#endif
                        slprintf(message, message_space, "Access granted");
                        return AUTHENTICATED;
                        
@@ -628,8 +637,10 @@ winbind_chap_verify(char *user, char *ourname, int id,
                                &response[MS_CHAP2_NTRESP],
                                &response[MS_CHAP2_PEER_CHALLENGE],
                                challenge, user, saresponse);
-                       mppe_set_keys2(session_key, &response[MS_CHAP2_NTRESP],
+#ifdef MPPE
+                       mppe_set_chapv2(session_key, &response[MS_CHAP2_NTRESP],
                                       MS_CHAP2_AUTHENTICATOR);
+#endif
                        if (response[MS_CHAP2_FLAGS]) {
                                slprintf(message, message_space, "S=%s", saresponse);
                        } else {
index 193f8fdf5528f78feba38dd41a5bc674ae0b01db..a954d62516b94569490814227307e2564c8b2cd1 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <errno.h>
+
 #include "pppd.h"
 #include "pppcrypt.h"
 
index 364940e39f79e269cc169aada4b8b167b10dd3b1..79676ca902342c7b07bb92231ef2f6ab21a19ec5 100644 (file)
@@ -29,6 +29,7 @@
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#include "pppdconf.h"
 
 #ifndef PPPCRYPT_H
 #define        PPPCRYPT_H
@@ -38,7 +39,7 @@
 #endif
 
 #ifndef USE_CRYPT
-#include <des.h>
+#include <openssl/des.h>
 #endif
 
 extern bool    DesSetkey(u_char *);
index b5790d9b3d1e6f3af6cf55db4eafbe63dd83da05..7417a36ed2632ae4172a2776b1c4d574c62f8d2e 100644 (file)
@@ -55,8 +55,8 @@ non-privileged user.
 .I speed
 An option that is a decimal number is taken as the desired baud rate
 for the serial device.  On systems such as
-4.4BSD and NetBSD, any speed can be specified.  Other systems
-(e.g. Linux, SunOS) only support the commonly-used baud rates.
+Linux, 4.4BSD and NetBSD, any speed can be specified.  Other systems
+(e.g. SunOS) only support the commonly-used baud rates.
 .TP
 .B asyncmap \fImap
 This option sets the Async-Control-Character-Map (ACCM) for this end
@@ -127,12 +127,6 @@ is no other default route with the same metric.  With the default
 value of -1, the route is only added if there is no default route at
 all.
 .TP
-.B defaultroute6
-Add a default IPv6 route to the system routing tables, using the peer as
-the gateway, when IPv6CP negotiation is successfully completed.
-This entry is removed when the PPP connection is broken.  This option
-is privileged if the \fInodefaultroute6\fR option has been specified.
-.TP
 .B replacedefaultroute
 This option is a flag to the defaultroute option. If defaultroute is
 set and this flag is also set, pppd replaces an existing default route
@@ -266,10 +260,16 @@ 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
+(EAP-TLS, or PEAP) 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.
+and \fBkey\fR options.  Either \fIca\fR, or \fIcapath\fR options are required
+for PEAP. EAP-TLS may also use the entry in eaptls-client or eaptls-server
+for a CA certificate associated with a particular peer.
+.TP
+.B capath \fIpath
+(EAP-TLS, or PEAP) Specify a location that contains public CA certificates.
+Either \fIca\fR, or \fIcapath\fR options are required for PEAP.
 .TP
 .B cdtrcts
 Use a non-standard hardware flow control (i.e. DTR/CTS) to control
@@ -326,15 +326,15 @@ negotiation by sending its first LCP packet.  The default value is
 or \fBpty\fR option is used.
 .TP
 .B crl \fIfilename
-(EAP-TLS) Use the file \fIfilename\fR as the Certificate Revocation List
+(EAP-TLS, or PEAP) 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
+mandatory for setting up a 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
+(EAP-TLS, or PEAP) 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.
+This option is not mandatory for setting up a TLS connection.
 Also see the \fBcrl\fR option.
 .TP
 .B debug
@@ -354,6 +354,17 @@ Disable MRU [Maximum Receive Unit] negotiation.  With this option,
 pppd will use the default MRU value of 1500 bytes for both the
 transmit and receive direction.
 .TP
+.B defaultroute6
+Add a default IPv6 route to the system routing tables, using the peer as
+the gateway, when IPv6CP negotiation is successfully completed.
+This entry is removed when the PPP connection is broken.  This option
+is privileged if the \fInodefaultroute6\fR option has been specified.
+\fBWARNING: Do not enable this option by default\fR.  IPv6 routing tables
+are managed by kernel (as apposite to IPv4) and IPv6 default route is
+configured by kernel automatically too based on ICMPv6 Router Advertisement
+packets.  This option may conflict with kernel IPv6 route setup and should
+be used only for broken IPv6 networks.
+.TP
 .B deflate \fInr,nt
 Request that the peer compress packets that it sends, using the
 Deflate scheme, with a maximum window size of \fI2**nr\fR bytes, and
@@ -493,6 +504,18 @@ to send configure-Rejects instead to \fIn\fR (default 10).
 Set the maximum number of IPCP terminate-request transmissions to
 \fIn\fR (default 3).
 .TP
+.B ipcp\-no\-address
+Disable negotiation of addresses via IP-Address IPCP option.
+.TP
+.B ipcp\-no\-addresses
+Disable negotiation of addresses via old-style deprecated IP-Addresses
+IPCP option. pppd by default try to use new-style IP-Address IPCP option.
+If new-style is not supported by peer or is disabled by \fBipcp\-no\-address\fR
+option then pppd fallbacks to old-style deprecated IP-Addresses IPCP option.
+When both new-style and old-style are disabled by both \fBipcp\-no\-address\fR
+and \fBipcp\-no\-addresses\fR options then negotiation of IP addresses
+is completely disabled.
+.TP
 .B ipcp\-restart \fIn
 Set the IPCP restart interval (retransmission timeout) to \fIn\fR
 seconds (default 3).
@@ -707,6 +730,11 @@ network control protocol comes up).
 Terminate after \fIn\fR consecutive failed connection attempts.  A
 value of 0 means no limit.  The default value is 10.
 .TP
+.B max-tls-version \fIstring
+(EAP-TLS, or PEAP) Configures the max allowed TLS version used during
+negotiation with a peer.  The default value for this is \fI1.2\fR.  Values
+allowed for this option is \fI1.0.\fR, \fI1.1\fR, \fI1.2\fR, \fI1.3\fR.
+.TP
 .B modem
 Use the modem control lines.  This option is the default.  With this
 option, pppd will wait for the CD (Carrier Detect) signal from the
@@ -924,6 +952,9 @@ situation, the ppp interface can be used for routing by creating
 device routes, but the peer itself cannot be addressed directly for IP
 traffic.
 .TP
+.B nosendip
+Don't send our local IP address to peer during IP address negotiation.
+.TP
 .B notty
 Normally, pppd requires a terminal device.  With this option, pppd
 will allocate itself a pseudo-tty master/slave pair and use the slave
@@ -1153,6 +1184,16 @@ The device used by pppd with this option must have sync support.
 Currently supports Microgate SyncLink adapters
 under Linux and FreeBSD 2.2.8 and later.
 .TP
+.B tls-verify-method \fIstring
+(EAP-TLS, or PEAP) Match the value specified for \fIremotename\fR to that that
+of the X509 certificates subject name, common name, or suffix of the common
+name.  Respective values allowed for this option is: \fInone\fR, \fIsubject\fR,
+\fIname\fR, or \fIsuffix\fR.  The default value for this option is \fIname\fR.
+.TP
+.B tls-verify-key-usage
+(EAP-TLS, or PEAP) Enables examination of peer certificate's purpose, and
+extended key usage attributes.
+.TP
 .B unit \fInum
 Sets the ppp unit number (for a ppp0 or ppp1 etc interface name) for outbound
 connections.  If the unit is already in use a dynamically allocated number will
@@ -1760,6 +1801,14 @@ IPCP has come up.
 The IP address for the remote end of the link.  This is only set when
 IPCP has come up.
 .TP
+.B LLLOCAL
+The Link-Local IPv6 address for the local end of the link.  This is only
+set when IPV6CP has come up.
+.TP
+.B LLREMOTE
+The Link-Local IPv6 address for the remote end of the link.  This is only
+set when IPV6CP has come up.
+.TP
 .B PEERNAME
 The authenticated name of the peer.  This is only set if the peer
 authenticates itself.
index 612902f55d0d6ceef0646980d7941b7571526e14..ab8f674dda5e3901acab82d35b766e921fcbf4ac 100644 (file)
@@ -42,6 +42,8 @@
  * $Id: pppd.h,v 1.96 2008/06/23 11:47:18 paulus Exp $
  */
 
+#include "pppdconf.h"
+
 /*
  * TODO:
  */
@@ -58,6 +60,7 @@
 #include <sys/types.h>         /* for u_int32_t, if defined */
 #include <sys/time.h>          /* for struct timeval */
 #include <net/ppp_defs.h>
+#include <net/if.h>
 #include "patchlevel.h"
 
 #ifdef INET6
@@ -73,8 +76,6 @@
 #define MAXARGS                1       /* max # args to a command */
 #define MAXNAMELEN     256     /* max length of hostname or name for auth */
 #define MAXSECRETLEN   256     /* max length of password or secret */
-#define MAXIFNAMELEN   32      /* max length of interface name; or use IFNAMSIZ, can we
-                                  always include net/if.h? */
 
 /*
  * If PPP_DRV_NAME is not defined, use the default "ppp" as the device name.
@@ -327,7 +328,7 @@ extern int  max_data_rate;  /* max bytes/sec through charshunt */
 extern int     req_unit;       /* interface unit number to use */
 extern char    path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
 extern char    path_ipdown[MAXPATHLEN]; /* pathname of ip-down script */
-extern char    req_ifname[MAXIFNAMELEN]; /* interface name to use */
+extern char    req_ifname[IFNAMSIZ]; /* interface name to use */
 extern bool    multilink;      /* enable multilink operation */
 extern bool    noendpoint;     /* don't send or accept endpt. discrim. */
 extern char    *bundle_name;   /* bundle name for multilink */
@@ -335,10 +336,25 @@ extern bool       dump_options;   /* print out option values */
 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;
+#if defined(USE_EAPTLS) || defined(USE_PEAP)
+
+#define TLS_VERIFY_NONE     "none"
+#define TLS_VERIFY_NAME     "name"
+#define TLS_VERIFY_SUBJECT  "subject"
+#define TLS_VERIFY_SUFFIX   "suffix"
+
+extern char *crl_dir;
+extern char *crl_file;
+extern char *ca_path;
+extern char *cacert_file;
+
 extern char *max_tls_version;
+extern bool tls_verify_key_usage;
+extern char *tls_verify_method;
+#endif /* USE_EAPTLS || USE_PEAP */
+
+#ifdef USE_EAPTLS
+extern char *pkcs12_file;
 #endif /* USE_EAPTLS */
 
 #ifdef MAXOCTETS
diff --git a/pppd/pppd.pc.in b/pppd/pppd.pc.in
new file mode 100644 (file)
index 0000000..20ef104
--- /dev/null
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+plugindir=@PPPD_PLUGIN_DIR@
+
+Name: pppd
+Description: Point-to-Point Protocol (PPP) daemon
+Version: @PACKAGE_VERSION@
+Cflags: -I${includedir}
diff --git a/pppd/pppdconf.h.in b/pppd/pppdconf.h.in
new file mode 100644 (file)
index 0000000..a1eea0e
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * This file is generated by configure and sets the features enabled
+ *   in pppd when configured.
+ */
+
+/* "Have Microsoft CHAP support" */
+#undef CHAPMS
+
+/* "Have Microsoft MPPE support" */
+#undef MPPE
+
+/* "Have multilink support" */
+#undef HAVE_MULTILINK
+
+/* "Have IPX Control Protocol" */
+#undef IPX_CHANGE
+
+/* "Have packet activity filter support" */
+#undef PPP_FILTER
+
+/* "Have support for loadable plugins" */
+#undef PLUGIN
+
+/* "Limit sessions by maximum number of octets" */
+#undef MAXOCTETS
+
+/* Have Microsoft Callback Protocol support */
+#undef CBCP_SUPPORT
+
+/* "Include Trivial Database support" */
+#undef USE_TDB
+
+/* "Have IPv6 support" */
+#undef INET6
+
+/* "Support for Pluggable Authentication Modules" */
+#undef USE_PAM
+
+/* "Have EAP-SRP authentication support" */
+#undef USE_SRP
+
+/* "Have EAP-TLS authentication support" */
+#undef USE_EAPTLS
+
+/* "Have PEAP authentication support" */
+#undef USE_PEAP
+
+/* Use included des included with pppd */
+#undef USE_CRYPT
+
+/* Use included md4 included with pppd */
+#undef USE_MD4
+
+/* Use included md5 included with pppd */
+#undef USE_MD5
+
+/* Use included sha included with pppd */
+#undef USE_SHA
+
+/* Version number of package */
+#undef VERSION
index 2f1c83e5552cd3afd59813e82d6b8bdf3de6294b..3d1fb6d7ccc1f912e1454eacdd10e20f2a22626d 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <pwd.h>
+
+#ifdef HAVE_CRYPT_H
 #include <crypt.h>
-#ifdef HAS_SHADOW
+#endif
+
+#ifdef HAVE_SHADOW_H
 #include <shadow.h>
 #endif
+
 #include <time.h>
 #include <utmp.h>
 #include <fcntl.h>
@@ -171,11 +180,11 @@ session_start(const int flags, const char *user, const char *passwd, const char
 #else /* #ifdef USE_PAM */
     struct passwd *pw;
     char *cbuf;
-#ifdef HAS_SHADOW
+#ifdef HAVE_SHADOW_H
     struct spwd *spwd;
     struct spwd *getspnam();
     long now = 0;
-#endif /* #ifdef HAS_SHADOW */
+#endif /* #ifdef HAVE_SHADOW_H */
 #endif /* #ifdef USE_PAM */
 
     SET_MSG(msg, SUCCESS_MSG);
@@ -305,7 +314,7 @@ session_start(const int flags, const char *user, const char *passwd, const char
        if (pw == NULL)
            return SESSION_FAILED;
 
-#ifdef HAS_SHADOW
+#ifdef HAVE_SHADOW_H
 
        spwd = getspnam(user);
        endspent();
@@ -336,15 +345,17 @@ session_start(const int flags, const char *user, const char *passwd, const char
        /* We have a valid shadow entry, keep the password */
        pw->pw_passwd = spwd->sp_pwdp;
 
-#endif /* #ifdef HAS_SHADOW */
+#endif /* #ifdef HAVE_SHADOW_H */
 
        /*
         * If no passwd, don't let them login if we're authenticating.
         */
         if (pw->pw_passwd == NULL || strlen(pw->pw_passwd) < 2)
             return SESSION_FAILED;
+#ifdef HAVE_CRYPT_H
        cbuf = crypt(passwd, pw->pw_passwd);
        if (!cbuf || strcmp(cbuf, pw->pw_passwd) != 0)
+#endif
             return SESSION_FAILED;
     }
 
index bee8c4124eafb425fd85ec01c485a92ec6504ba0..0047db6646ffe5042b7ab9389211e65db58d12c2 100644 (file)
@@ -27,6 +27,7 @@
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
+#include "pppdconf.h"
 
 #ifndef __SESSION_H
 #define __SESSION_H
index 4e51cee506c237ce2385ad3ed94003e31c9f1914..efb37bec40fe5b3ba0f0c456028cc887532f47eb 100644 (file)
  * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 /* #define SHA1HANDSOFF * Copies data before messing with it. */
 
 #include <string.h>
index 83f64df25843ac6f8bbd1bfe686a00c09ff8716a..e7e557308ee8e1f446c4295cc09d1c84bfda5e75 100644 (file)
@@ -1,12 +1,17 @@
 /* sha1.h */
 
-/* If OpenSSL is in use, then use that version of SHA-1 */
-#ifdef OPENSSL
-#include <t_sha.h>
-#define __SHA1_INCLUDE_
-#endif
+#include "pppdconf.h"
 
 #ifndef __SHA1_INCLUDE_
+#define __SHA1_INCLUDE_
+
+#ifndef USE_SHA
+#include <openssl/sha.h>
+
+#define SHA1_CTX SHA_CTX
+#define SHA1_SIGNATURE_SIZE SHA_DIGEST_LENGTH
+
+#else
 
 #ifndef SHA1_SIGNATURE_SIZE
 #ifdef SHA_DIGESTSIZE
@@ -26,6 +31,5 @@ extern void SHA1_Init(SHA1_CTX *);
 extern void SHA1_Update(SHA1_CTX *, const unsigned char *, unsigned int);
 extern void SHA1_Final(unsigned char[SHA1_SIGNATURE_SIZE], SHA1_CTX *);
 
-#define __SHA1_INCLUDE_
+#endif /* USE_SHA */
 #endif /* __SHA1_INCLUDE_ */
-
index 4df7e47592542cc126dbbda6437150e6835ddeae..56abae4fc19f7c95b359290d92f5568e7e48c84a 100644 (file)
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <unistd.h>
index 967fe37457fb9a69b754c3ef50fc860d729a7963..38e7bcc6cdc3b2be41b312881bd746420acf5d97 100644 (file)
@@ -1,10 +1,8 @@
+#include "pppdconf.h"
+
 #ifndef __SPINLOCK_H__
 #define __SPINLOCK_H__
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #include "tdb.h"
 
 #ifdef USE_SPINLOCKS
index 8c0e297e856084417fe488825c4a7edfb79a60bb..d59c1d3a3d267d9264555c10de86fbd94f144865 100644 (file)
  * The default modulus/generator can be requested as index 0.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
index 85033d97124fc0c49e2b274b80277aefc8e7893e..1e00366ba2914f5c1fba36fabd98e17edecaef72 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <string.h>
 #include <time.h>
 #include <memory.h>
+#ifdef HAVE_UTMP_H
 #include <utmp.h>
+#endif
 #include <mntent.h>
 #include <signal.h>
 #include <fcntl.h>
 #include <ctype.h>
-#include <termios.h>
 #include <unistd.h>
 
 /* This is in netdevice.h. However, this compile will fail miserably if
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
 #include <linux/if_addr.h>
+/* glibc versions prior to 2.24 do not define SOL_NETLINK */
+#ifndef SOL_NETLINK
+#define SOL_NETLINK 270
+#endif
+/* linux kernel versions prior to 4.3 do not define/support NETLINK_CAP_ACK */
+#ifndef NETLINK_CAP_ACK
+#define NETLINK_CAP_ACK 10
+#endif
 #endif
 
 #include "pppd.h"
 #include <sys/locks.h>
 #endif
 
+/*
+ * Instead of system header file <termios.h> use local "termios_linux.h" header
+ * file as it provides additional support for arbitrary baud rates via BOTHER.
+ */
+#include "termios_linux.h"
+
 #ifdef INET6
 #ifndef _LINUX_IN6_H
 /*
@@ -164,9 +183,9 @@ struct in6_ifreq {
 #endif
 
 #define IN6_LLADDR_FROM_EUI64(sin6, eui64) do {                        \
-       memset(&sin6.s6_addr, 0, sizeof(struct in6_addr));      \
-       sin6.s6_addr16[0] = htons(0xfe80);                      \
-       eui64_copy(eui64, sin6.s6_addr32[2]);                   \
+       memset(&(sin6).s6_addr, 0, sizeof(struct in6_addr));    \
+       (sin6).s6_addr16[0] = htons(0xfe80);                    \
+       eui64_copy(eui64, (sin6).s6_addr32[2]);                 \
        } while (0)
 
 static const eui64_t nulleui64;
@@ -668,11 +687,11 @@ static int make_ppp_unit(void)
 
        if (x == 0 && req_ifname[0] != '\0') {
                struct ifreq ifr;
-               char t[MAXIFNAMELEN];
+               char t[IFNAMSIZ];
                memset(&ifr, 0, sizeof(struct ifreq));
                slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit);
-               strlcpy(ifr.ifr_name, t, IF_NAMESIZE);
-               strlcpy(ifr.ifr_newname, req_ifname, IF_NAMESIZE);
+               strlcpy(ifr.ifr_name, t, IFNAMSIZ);
+               strlcpy(ifr.ifr_newname, req_ifname, IFNAMSIZ);
                x = ioctl(sock_fd, SIOCSIFNAME, &ifr);
                if (x < 0)
                    error("Couldn't rename interface %s to %s: %m", t, req_ifname);
@@ -890,6 +909,12 @@ struct speed {
 #ifdef B460800
     { 460800, B460800 },
 #endif
+#ifdef B500000
+    { 500000, B500000 },
+#endif
+#ifdef B576000
+    { 576000, B576000 },
+#endif
 #ifdef B921600
     { 921600, B921600 },
 #endif
@@ -934,7 +959,6 @@ static int translate_speed (int bps)
            if (bps == speedp->speed_int)
                return speedp->speed_val;
        }
-       warn("speed %d not supported", bps);
     }
     return 0;
 }
@@ -1013,26 +1037,53 @@ void set_up_tty(int tty_fd, int local)
     if (stop_bits >= 2)
        tios.c_cflag |= CSTOPB;
 
-    speed = translate_speed(inspeed);
-    if (speed) {
-       cfsetospeed (&tios, speed);
-       cfsetispeed (&tios, speed);
+    if (inspeed) {
+       speed = translate_speed(inspeed);
+       if (speed) {
+           cfsetospeed (&tios, speed);
+           cfsetispeed (&tios, speed);
+           speed = cfgetospeed(&tios);
+           baud_rate = baud_rate_of(speed);
+       } else {
+#ifdef BOTHER
+           tios.c_cflag &= ~CBAUD;
+           tios.c_cflag |= BOTHER;
+           tios.c_ospeed = inspeed;
+#ifdef IBSHIFT
+           /* B0 sets input baudrate to the output baudrate */
+           tios.c_cflag &= ~(CBAUD << IBSHIFT);
+           tios.c_cflag |= B0 << IBSHIFT;
+           tios.c_ispeed = inspeed;
+#endif
+           baud_rate = inspeed;
+#else
+           baud_rate = 0;
+#endif
+       }
+    }
+    else {
+       speed = cfgetospeed(&tios);
+       baud_rate = baud_rate_of(speed);
+#ifdef BOTHER
+       if (!baud_rate)
+           baud_rate = tios.c_ospeed;
+#endif
     }
+
 /*
- * We can't proceed if the serial port speed is B0,
+ * We can't proceed if the serial port baud rate is unknown,
  * since that implies that the serial port is disabled.
  */
-    else {
-       speed = cfgetospeed(&tios);
-       if (speed == B0)
+    if (!baud_rate) {
+       if (inspeed)
+           fatal("speed %d not supported", inspeed);
+       else
            fatal("Baud rate for %s is 0; need explicit baud rate", devnam);
     }
 
     while (tcsetattr(tty_fd, TCSAFLUSH, &tios) < 0 && !ok_error(errno))
        if (errno != EINTR)
            fatal("tcsetattr: %m (line %d)", __LINE__);
-
-    baud_rate    = baud_rate_of(speed);
     restore_term = 1;
 }
 
@@ -2824,133 +2875,143 @@ int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
 }
 
 #ifdef INET6
-static int append_peer_ipv6_address(unsigned int iface, struct in6_addr *local_addr, struct in6_addr *remote_addr)
-{
-    struct msghdr msg;
-    struct sockaddr_nl sa;
+/********************************************************************
+ *
+ * sif6addr_rtnetlink - Config the interface with both IPv6 link-local addresses via rtnetlink
+ */
+static int sif6addr_rtnetlink(unsigned int iface, eui64_t our_eui64, eui64_t his_eui64)
+{
+    struct {
+        struct nlmsghdr nlh;
+        struct ifaddrmsg ifa;
+        struct {
+            struct rtattr rta;
+            struct in6_addr addr;
+        } addrs[2];
+    } nlreq;
+    struct {
+        struct nlmsghdr nlh;
+        struct nlmsgerr nlerr;
+    } nlresp;
+    struct sockaddr_nl nladdr;
     struct iovec iov;
-    struct nlmsghdr *nlmsg;
-    struct ifaddrmsg *ifa;
-    struct rtattr *local_rta;
-    struct rtattr *remote_rta;
-    char buf[NLMSG_LENGTH(sizeof(*ifa) + RTA_LENGTH(sizeof(*local_addr)) + RTA_LENGTH(sizeof(*remote_addr)))];
-    ssize_t nlmsg_len;
-    struct nlmsgerr *errmsg;
+    struct msghdr msg;
+    ssize_t nlresplen;
     int one;
     int fd;
 
     fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-    if (fd < 0)
+    if (fd < 0) {
+        error("sif6addr_rtnetlink: socket(NETLINK_ROUTE): %m (line %d)", __LINE__);
         return 0;
+    }
 
-    /* do not ask for error message content */
+    /*
+     * Tell kernel to not send to us payload of acknowledgment error message.
+     * NETLINK_CAP_ACK option is supported since Linux kernel version 4.3 and
+     * older kernel versions always send full payload in acknowledgment netlink
+     * message. We ignore payload of this message as we need only error code,
+     * to check if our set remote peer address request succeeded or failed.
+     * So ignore return value from the following setsockopt() call as setting
+     * option NETLINK_CAP_ACK means for us just a kernel hint / optimization.
+     */
     one = 1;
     setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &one, sizeof(one));
 
-    memset(&sa, 0, sizeof(sa));
-    sa.nl_family = AF_NETLINK;
-    sa.nl_pid = 0;
-    sa.nl_groups = 0;
+    memset(&nladdr, 0, sizeof(nladdr));
+    nladdr.nl_family = AF_NETLINK;
 
-    if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
+    if (bind(fd, (struct sockaddr *)&nladdr, sizeof(nladdr)) < 0) {
+        error("sif6addr_rtnetlink: bind(AF_NETLINK): %m (line %d)", __LINE__);
         close(fd);
         return 0;
     }
 
-    memset(buf, 0, sizeof(buf));
-
-    nlmsg = (struct nlmsghdr *)buf;
-    nlmsg->nlmsg_len = NLMSG_LENGTH(sizeof(*ifa) + RTA_LENGTH(sizeof(*local_addr)) + RTA_LENGTH(sizeof(*remote_addr)));
-    nlmsg->nlmsg_type = RTM_NEWADDR;
-    nlmsg->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE;
-    nlmsg->nlmsg_seq = 1;
-    nlmsg->nlmsg_pid = 0;
-
-    ifa = NLMSG_DATA(nlmsg);
-    ifa->ifa_family = AF_INET6;
-    ifa->ifa_prefixlen = 128;
-    ifa->ifa_flags = 0;
-    ifa->ifa_scope = RT_SCOPE_UNIVERSE;
-    ifa->ifa_index = iface;
-
-    local_rta = IFA_RTA(ifa);
-    local_rta->rta_len = RTA_LENGTH(sizeof(*local_addr));
-    local_rta->rta_type = IFA_LOCAL;
-    memcpy(RTA_DATA(local_rta), local_addr, sizeof(*local_addr));
-
-    remote_rta = (struct rtattr *)((char *)local_rta + local_rta->rta_len);
-    remote_rta->rta_len = RTA_LENGTH(sizeof(*remote_addr));
-    remote_rta->rta_type = IFA_ADDRESS;
-    memcpy(RTA_DATA(remote_rta), remote_addr, sizeof(*remote_addr));
-
-    memset(&sa, 0, sizeof(sa));
-    sa.nl_family = AF_NETLINK;
-    sa.nl_pid = 0;
-    sa.nl_groups = 0;
+    memset(&nlreq, 0, sizeof(nlreq));
+    nlreq.nlh.nlmsg_len = sizeof(nlreq);
+    nlreq.nlh.nlmsg_type = RTM_NEWADDR;
+    nlreq.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE;
+    nlreq.ifa.ifa_family = AF_INET6;
+    nlreq.ifa.ifa_prefixlen = 128;
+    nlreq.ifa.ifa_flags = IFA_F_NODAD | IFA_F_PERMANENT;
+    nlreq.ifa.ifa_scope = RT_SCOPE_LINK;
+    nlreq.ifa.ifa_index = iface;
+    nlreq.addrs[0].rta.rta_len = sizeof(nlreq.addrs[0]);
+    nlreq.addrs[0].rta.rta_type = IFA_LOCAL;
+    IN6_LLADDR_FROM_EUI64(nlreq.addrs[0].addr, our_eui64);
+    nlreq.addrs[1].rta.rta_len = sizeof(nlreq.addrs[1]);
+    nlreq.addrs[1].rta.rta_type = IFA_ADDRESS;
+    IN6_LLADDR_FROM_EUI64(nlreq.addrs[1].addr, his_eui64);
+
+    memset(&nladdr, 0, sizeof(nladdr));
+    nladdr.nl_family = AF_NETLINK;
 
     memset(&iov, 0, sizeof(iov));
-    iov.iov_base = nlmsg;
-    iov.iov_len = nlmsg->nlmsg_len;
+    iov.iov_base = &nlreq;
+    iov.iov_len = sizeof(nlreq);
 
     memset(&msg, 0, sizeof(msg));
-    msg.msg_name = &sa;
-    msg.msg_namelen = sizeof(sa);
+    msg.msg_name = &nladdr;
+    msg.msg_namelen = sizeof(nladdr);
     msg.msg_iov = &iov;
     msg.msg_iovlen = 1;
-    msg.msg_control = NULL;
-    msg.msg_controllen = 0;
-    msg.msg_flags = 0;
 
     if (sendmsg(fd, &msg, 0) < 0) {
+        error("sif6addr_rtnetlink: sendmsg(RTM_NEWADDR/NLM_F_CREATE): %m (line %d)", __LINE__);
         close(fd);
         return 0;
     }
 
     memset(&iov, 0, sizeof(iov));
-    iov.iov_base = buf;
-    iov.iov_len = sizeof(buf);
+    iov.iov_base = &nlresp;
+    iov.iov_len = sizeof(nlresp);
 
     memset(&msg, 0, sizeof(msg));
-    msg.msg_name = NULL;
-    msg.msg_namelen = 0;
+    msg.msg_name = &nladdr;
+    msg.msg_namelen = sizeof(nladdr);
     msg.msg_iov = &iov;
     msg.msg_iovlen = 1;
-    msg.msg_control = NULL;
-    msg.msg_controllen = 0;
-    msg.msg_flags = 0;
 
-    nlmsg_len = recvmsg(fd, &msg, 0);
-    close(fd);
+    nlresplen = recvmsg(fd, &msg, 0);
 
-    if (nlmsg_len < 0)
+    if (nlresplen < 0) {
+        error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): %m (line %d)", __LINE__);
+        close(fd);
         return 0;
+    }
 
-    if ((size_t)nlmsg_len < sizeof(*nlmsg)) {
-        errno = EINVAL;
+    close(fd);
+
+    if (nladdr.nl_family != AF_NETLINK) {
+        error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): Not a netlink packet (line %d)", __LINE__);
         return 0;
     }
 
-    nlmsg = (struct nlmsghdr *)buf;
+    if ((size_t)nlresplen != sizeof(nlresp) || nlresp.nlh.nlmsg_len < sizeof(nlresp)) {
+        error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): Acknowledgment netlink packet too short (line %d)", __LINE__);
+        return 0;
+    }
 
     /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */
-    if (nlmsg->nlmsg_type != NLMSG_ERROR) {
-        errno = EINVAL;
+    if (nlresp.nlh.nlmsg_type != NLMSG_ERROR) {
+        error("sif6addr_rtnetlink: recvmsg(NLM_F_ACK): Not an acknowledgment netlink packet (line %d)", __LINE__);
         return 0;
     }
 
-    if ((size_t)nlmsg_len < NLMSG_LENGTH(sizeof(*errmsg))) {
-        errno = EINVAL;
+    /* error == 0 indicates success, negative value is errno code */
+    if (nlresp.nlerr.error != 0) {
+        /*
+         * Linux kernel versions prior 3.11 do not support setting IPv6 peer
+         * addresses and error response is expected. On older kernel versions
+         * do not show this error message. On error pppd tries to fallback to
+         * the old IOCTL method.
+         */
+        if (kernel_version >= KVERSION(3,11,0))
+            error("sif6addr_rtnetlink: %s (line %d)", strerror(-nlresp.nlerr.error), __LINE__);
         return 0;
     }
 
-    errmsg = NLMSG_DATA(nlmsg);
-
-    /* error == 0 indicates success */
-    if (errmsg->error == 0)
-        return 1;
-
-    errno = -errmsg->error;
-    return 0;
+    return 1;
 }
 
 /********************************************************************
@@ -2962,7 +3023,7 @@ int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
     struct in6_ifreq ifr6;
     struct ifreq ifr;
     struct in6_rtmsg rt6;
-    struct in6_addr remote_addr;
+    int ret;
 
     if (sock6_fd < 0) {
        errno = -sock6_fd;
@@ -2976,27 +3037,34 @@ int sif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
        return 0;
     }
 
-    /* Local interface */
-    memset(&ifr6, 0, sizeof(ifr6));
-    IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
-    ifr6.ifr6_ifindex = ifr.ifr_ifindex;
-    ifr6.ifr6_prefixlen = 128;
-
-    if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
-       error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
-       return 0;
+    if (kernel_version >= KVERSION(2,1,16)) {
+        /* Set both local address and remote peer address (with route for it) via rtnetlink */
+        ret = sif6addr_rtnetlink(ifr.ifr_ifindex, our_eui64, his_eui64);
+    } else {
+        ret = 0;
     }
 
-    if (kernel_version >= KVERSION(2,1,16)) {
-        /* Set remote peer address (and route for it) */
-        IN6_LLADDR_FROM_EUI64(remote_addr, his_eui64);
-        if (!append_peer_ipv6_address(ifr.ifr_ifindex, &ifr6.ifr6_addr, &remote_addr)) {
-            error("sif6addr: setting remote peer address failed: %m");
+    /*
+     * Linux kernel versions prior 3.11 do not support setting IPv6 peer address
+     * via rtnetlink. So if sif6addr_rtnetlink() fails then try old IOCTL method.
+     */
+    if (!ret) {
+        /* Local interface */
+        memset(&ifr6, 0, sizeof(ifr6));
+        IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64);
+        ifr6.ifr6_ifindex = ifr.ifr_ifindex;
+        ifr6.ifr6_prefixlen = 128;
+
+        if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) {
+            error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__);
             return 0;
         }
-    }
 
-    if (kernel_version < KVERSION(2,1,16)) {
+        /*
+         * Linux kernel does not provide AF_INET6 ioctl SIOCSIFDSTADDR for
+         * setting remote peer host address, so set only route to remote host.
+         */
+
         /* Route to remote host */
         memset(&rt6, 0, sizeof(rt6));
         IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64);
@@ -3062,7 +3130,7 @@ int cif6addr (int unit, eui64_t our_eui64, eui64_t his_eui64)
 int
 get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
 {
-    int i, mfd, sfd = -1;
+    int i, mfd, ret, sfd = -1;
     char pty_name[16];
     struct termios tios;
 
@@ -3100,8 +3168,14 @@ get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid)
                pty_name[5] = 't';
                sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
                if (sfd >= 0) {
-                   fchown(sfd, uid, -1);
-                   fchmod(sfd, S_IRUSR | S_IWUSR);
+                   ret = fchown(sfd, uid, -1);
+                   if (ret != 0) {
+                       warn("Couldn't change ownership of %s, %m", pty_name);
+                   }
+                   ret = fchmod(sfd, S_IRUSR | S_IWUSR);
+                   if (ret != 0) {
+                       warn("Couldn't change permissions of %s, %m", pty_name);
+                   }
                    break;
                }
                close(mfd);
index 58ad21afca7337050ab42b6eeb7c6e5c08fa792b..809b506a3640d34879fd8d9be303912bc81b5caa 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <limits.h>
 #include <stdio.h>
 #include <stddef.h>
 #include <sys/ethernet.h>
 #endif
 
+#ifdef PPP_FILTER
+#include <pcap.h>
+#endif
+
 #include "pppd.h"
 #include "fsm.h"
 #include "lcp.h"
@@ -1636,33 +1644,6 @@ get_ppp_stats(int u, struct pppd_stats *stats)
     return 1;
 }
 
-#if 0
-/*
- * set_filters - transfer the pass and active filters to the kernel.
- */
-int
-set_filters(struct bpf_program *pass, struct bpf_program *active)
-{
-    int ret = 1;
-
-    if (pass->bf_len > 0) {
-       if (strioctl(pppfd, PPPIO_PASSFILT, pass,
-                    sizeof(struct bpf_program), 0) < 0) {
-           error("Couldn't set pass-filter in kernel: %m");
-           ret = 0;
-       }
-    }
-    if (active->bf_len > 0) {
-       if (strioctl(pppfd, PPPIO_ACTIVEFILT, active,
-                    sizeof(struct bpf_program), 0) < 0) {
-           error("Couldn't set active-filter in kernel: %m");
-           ret = 0;
-       }
-    }
-    return ret;
-}
-#endif
-
 /*
  * ccp_fatal_error - returns 1 if decompression was disabled as a
  * result of an error detected after decompression of a packet,
index bdc58288da023b489983b994b1cc53b126de6e97..8a563f88b9a62b8aedc2ea504f8f8b22afdddb95 100644 (file)
  * right time.  Probably too hard -- the process just doesn't know.
  */ 
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdlib.h>
 #include <stdio.h>
 #include <fcntl.h>
index 153b6e99232b32f08d0b6f2deabecfc150e57620..418bd8d9d3496d4b4ef90223e908f98abf463eba 100644 (file)
@@ -1,3 +1,5 @@
+#include "pppdconf.h"
+
 #ifndef __TDB_H__
 #define __TDB_H__
 
diff --git a/pppd/termios_linux.h b/pppd/termios_linux.h
new file mode 100644 (file)
index 0000000..9c79d16
--- /dev/null
@@ -0,0 +1,194 @@
+/* SPDX-License-Identifier: GPL-2.0+ OR BSD-4-Clause OR BSD-3-Clause OR BSD-2-Clause */
+/*
+ * termios fuctions to support arbitrary baudrates (on Linux)
+ *
+ * Copyright (c) 2021 Pali RohĂ¡r <pali@kernel.org>
+ * Copyright (c) 2021 Marek BehĂºn <kabel@kernel.org>
+ */
+
+#ifndef _TERMIOS_LINUX_H_
+#define _TERMIOS_LINUX_H_
+
+/*
+ * We need to use raw TCGETS2/TCSETS2 or TCGETS/TCSETS ioctls with the BOTHER
+ * flag in struct termios2/termios, defined in Linux headers <asm/ioctls.h>
+ * and <asm/termbits.h>. Since these headers conflict with glibc's header file
+ * <termios.h>, it is not possible to use libc's termios functions and we need
+ * to reimplement them via ioctl() calls.
+ *
+ * An arbitrary baudrate is supported when the macro BOTHER is defined. The
+ * baudrate value itself is then stored into the c_ospeed and c_ispeed members.
+ * If ioctls TCGETS2/TCSETS2 are defined and supported then these fields are
+ * present in struct termios2, otherwise these fields are present in struct
+ * termios.
+ *
+ * Note that the Bnnn constants from <termios.h> need not be compatible with
+ * Bnnn constants from <asm/termbits.h>.
+ */
+
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <asm/ioctls.h>
+#include <asm/termbits.h>
+
+#if defined(BOTHER) && defined(TCGETS2)
+#define termios termios2
+#endif
+
+static inline int tcgetattr(int fd, struct termios *t)
+{
+#if defined(BOTHER) && defined(TCGETS2)
+       return ioctl(fd, TCGETS2, t);
+#else
+       return ioctl(fd, TCGETS, t);
+#endif
+}
+
+static inline int tcsetattr(int fd, int a, const struct termios *t)
+{
+       int cmd;
+
+       switch (a) {
+#if defined(BOTHER) && defined(TCGETS2)
+       case TCSANOW:
+               cmd = TCSETS2;
+               break;
+       case TCSADRAIN:
+               cmd = TCSETSW2;
+               break;
+       case TCSAFLUSH:
+               cmd = TCSETSF2;
+               break;
+#else
+       case TCSANOW:
+               cmd = TCSETS;
+               break;
+       case TCSADRAIN:
+               cmd = TCSETSW;
+               break;
+       case TCSAFLUSH:
+               cmd = TCSETSF;
+               break;
+#endif
+       default:
+               errno = EINVAL;
+               return -1;
+       }
+
+       return ioctl(fd, cmd, t);
+}
+
+static inline int tcdrain(int fd)
+{
+       return ioctl(fd, TCSBRK, 1);
+}
+
+static inline int tcflush(int fd, int q)
+{
+       return ioctl(fd, TCFLSH, q);
+}
+
+static inline int tcsendbreak(int fd, int d)
+{
+#ifdef TCSBRKP
+       return ioctl(fd, TCSBRKP, d);
+#else
+       return ioctl(fd, TCSBRK, 0);
+#endif
+}
+
+static inline int tcflow(int fd, int a)
+{
+       return ioctl(fd, TCXONC, a);
+}
+
+static inline pid_t tcgetsid(int fd)
+{
+       pid_t sid;
+
+       if (ioctl(fd, TIOCGSID, &sid) < 0)
+               return (pid_t)-1;
+
+       return sid;
+}
+
+static inline speed_t cfgetospeed(const struct termios *t)
+{
+       return t->c_cflag & CBAUD;
+}
+
+static inline int cfsetospeed(struct termios *t, speed_t s)
+{
+       if (s & ~CBAUD) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       t->c_cflag &= ~CBAUD;
+       t->c_cflag |= s;
+
+       return 0;
+}
+
+#ifdef IBSHIFT
+static inline speed_t cfgetispeed(const struct termios *t)
+{
+       speed_t s = (t->c_cflag >> IBSHIFT) & CBAUD;
+
+       if (s == B0)
+               return cfgetospeed(t);
+       else
+               return s;
+}
+
+static inline int cfsetispeed(struct termios *t, speed_t s)
+{
+       if (s == 0)
+               s = B0;
+
+       if (s & ~CBAUD) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       t->c_cflag &= ~(CBAUD << IBSHIFT);
+       t->c_cflag |= s << IBSHIFT;
+
+       return 0;
+}
+#else /* !IBSHIFT */
+static inline speed_t cfgetispeed(const struct termios *t)
+{
+       return cfgetospeed(t);
+}
+
+static inline int cfsetispeed(struct termios *t, speed_t s)
+{
+       return cfsetospeed(t, s);
+}
+#endif /* !IBSHIFT */
+
+static inline int cfsetspeed(struct termios *t, speed_t s)
+{
+       if (cfsetospeed(t, s))
+               return -1;
+#ifdef IBSHIFT
+       if (cfsetispeed(t, s))
+               return -1;
+#endif
+
+       return 0;
+}
+
+static void cfmakeraw(struct termios *t)
+{
+       t->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR |
+                       ICRNL | IXON);
+       t->c_oflag &= ~OPOST;
+       t->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
+       t->c_cflag &= ~(CSIZE | PARENB);
+       t->c_cflag |= CS8;
+}
+
+#endif /* _TERMIOS_LINUX_H_ */
diff --git a/pppd/tls.c b/pppd/tls.c
new file mode 100644 (file)
index 0000000..28c2e57
--- /dev/null
@@ -0,0 +1,447 @@
+/*
+ * Copyright (c) 2021 Eivind Næss. 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 <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+
+#include "pppd.h"
+#include "tls.h"
+
+/**
+ * Structure used in verifying the peer certificate
+ */
+struct tls_info
+{
+    char *peer_name;
+    X509 *peer_cert;
+    bool client;
+};
+
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+/*
+ *  OpenSSL 1.1+ introduced a generic TLS_method()
+ *  For older releases we substitute the appropriate method
+ */
+#define TLS_method SSLv23_method
+
+#ifndef SSL_CTX_set_max_proto_version
+/** Mimics SSL_CTX_set_max_proto_version for OpenSSL < 1.1 */
+static inline int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, long tls_ver_max)
+{
+    long sslopt = 0;
+
+    if (tls_ver_max < TLS1_VERSION)
+    {
+        sslopt |= SSL_OP_NO_TLSv1;
+    }
+#ifdef SSL_OP_NO_TLSv1_1
+    if (tls_ver_max < TLS1_1_VERSION)
+    {
+        sslopt |= SSL_OP_NO_TLSv1_1;
+    }
+#endif
+#ifdef SSL_OP_NO_TLSv1_2
+    if (tls_ver_max < TLS1_2_VERSION)
+    {
+        sslopt |= SSL_OP_NO_TLSv1_2;
+    }
+#endif
+    SSL_CTX_set_options(ctx, sslopt);
+
+    return 1;
+}
+#endif /* SSL_CTX_set_max_proto_version */
+
+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+
+
+/*
+ * 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.
+ */
+static int tls_verify_callback(int ok, X509_STORE_CTX *ctx)
+{
+    char subject[256];
+    char cn_str[256];
+    X509 *peer_cert;
+    int err, depth;
+    SSL *ssl;
+    struct tls_info *inf;
+    char *ptr1 = NULL, *ptr2 = NULL;
+
+    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());
+
+    inf = (struct tls_info*) SSL_get_ex_data(ssl, 0);
+    if (inf == NULL) {
+        error("Error: SSL_get_ex_data returned NULL");
+        return 0;
+    }
+
+    tls_log_sslerr();
+
+    if (!depth) 
+    {
+        /* Verify certificate based on certificate type and extended key usage */
+        if (tls_verify_key_usage) {
+            int purpose = inf->client ? X509_PURPOSE_SSL_SERVER : X509_PURPOSE_SSL_CLIENT ;
+            if (X509_check_purpose(peer_cert, purpose, 0) == 0) {
+                error("Certificate verification error: nsCertType mismatch");
+                return 0;
+            }
+
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+            int flags = inf->client ? XKU_SSL_SERVER : XKU_SSL_CLIENT;
+            if (!(X509_get_extended_key_usage(peer_cert) & flags)) {
+                error("Certificate verification error: invalid extended key usage");
+                return 0;
+            }
+#endif
+            info("Certificate key usage: OK");
+        }
+
+        /*
+         * If acting as client and the name of the server wasn't specified
+         * explicitely, we can't verify the server authenticity 
+         */
+        if (!tls_verify_method)
+            tls_verify_method = TLS_VERIFY_NONE;
+
+        if (!inf->peer_name || !strcmp(TLS_VERIFY_NONE, tls_verify_method)) {
+            warn("Certificate verication disabled or no peer name was specified");
+            return ok;
+        }
+
+        /* 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);
+
+        /* Verify based on subject name */
+        ptr1 = inf->peer_name;
+        if (!strcmp(TLS_VERIFY_SUBJECT, tls_verify_method)) {
+            ptr2 = subject;
+        }
+
+        /* Verify based on common name (default) */
+        if (strlen(tls_verify_method) == 0 ||
+            !strcmp(TLS_VERIFY_NAME, tls_verify_method)) {
+            ptr2 = cn_str;
+        }
+
+        /* Match the suffix of common name */
+        if (!strcmp(TLS_VERIFY_SUFFIX, tls_verify_method)) {
+            int len = strlen(ptr1);
+            int off = strlen(cn_str) - len;
+            ptr2 = cn_str;
+            if (off > 0) {
+                ptr2 = cn_str + off;
+            }
+        }
+
+        if (strcmp(ptr1, ptr2)) {
+            error("Certificate verification error: CN (%s) != %s", ptr1, ptr2);
+            return 0;
+        }
+
+        if (inf->peer_cert) { 
+            if (X509_cmp(inf->peer_cert, peer_cert) != 0) {
+                error("Peer certificate doesn't match stored certificate");
+                return 0;
+            }
+        }
+
+        info("Certificate CN: %s, peer name %s", cn_str, inf->peer_name);
+    }
+
+    return ok;
+}
+
+int tls_init()
+{
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+    SSL_library_init();
+    SSL_load_error_strings();
+#endif
+    return 0;
+}
+
+int tls_set_verify(SSL_CTX *ctx, int depth) 
+{
+    SSL_CTX_set_verify_depth(ctx, depth);
+    SSL_CTX_set_verify(ctx,
+               SSL_VERIFY_PEER |
+               SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+               &tls_verify_callback);
+    return 0;
+}
+
+int tls_set_verify_info(SSL *ssl, const char *peer_name, const char *peer_cert, 
+        bool client, struct tls_info **out)
+{
+    if (out != NULL) {
+        struct tls_info *tmp = calloc(sizeof(struct tls_info), 1);
+        if (!tmp) {
+            fatal("Allocation error");
+        }
+
+        tmp->client = client;
+        if (peer_name) {
+            tmp->peer_name = strdup(peer_name);
+        }
+
+        if (peer_cert && strlen(peer_cert) > 0) {
+            FILE *fp = fopen(peer_cert, "r");
+            if (fp) {
+                tmp->peer_cert = PEM_read_X509(fp, NULL, NULL, NULL);
+                fclose(fp);
+            }
+
+            if (!tmp->peer_cert) {
+                error("EAP-TLS: Error loading client certificate from file %s",
+                     peer_cert);
+                tls_free_verify_info(&tmp);
+                return -1;
+            }
+        }
+
+        SSL_set_ex_data(ssl, 0, tmp);
+        *out = tmp;
+        return 0;
+    }
+
+    return -1;
+}
+
+void tls_free_verify_info(struct tls_info **in) {
+    if (in && *in) {
+        struct tls_info *tmp = *in;
+        if (tmp->peer_name) {
+            free(tmp->peer_name);
+        }
+        if (tmp->peer_cert) {
+            X509_free(tmp->peer_cert);
+        }
+        free(tmp);
+        *in = NULL;
+    }
+}
+
+const SSL_METHOD* tls_method() {
+    return TLS_method();
+}
+
+int tls_set_version(SSL_CTX *ctx, const char *max_version)
+{
+#if defined(TLS1_2_VERSION)
+    long tls_version = TLS1_2_VERSION; 
+#elif defined(TLS1_1_VERSION)
+    long tls_version = TLS1_1_VERSION; 
+#else
+    long tls_version = TLS1_VERSION; 
+#endif
+
+    /* As EAP-TLS+TLSv1.3 is highly experimental we offer the user a chance to override */
+    if (max_version) {
+        if (strncmp(max_version, "1.0", 3) == 0) {
+            tls_version = TLS1_VERSION;
+        }
+        else if (strncmp(max_version, "1.1", 3) == 0) {
+            tls_version = TLS1_1_VERSION;
+        }
+        else if (strncmp(max_version, "1.2", 3) == 0) {
+#ifdef TLS1_2_VERSION
+            tls_version = TLS1_2_VERSION;
+#else
+            warn("TLSv1.2 not available. Defaulting to TLSv1.1");
+            tls_version = TLS_1_1_VERSION;
+#endif
+        }
+        else if (strncmp(max_version, "1.3", 3) == 0) {
+#ifdef TLS1_3_VERSION
+            tls_version = TLS1_3_VERSION;
+#else
+            warn("TLSv1.3 not available.");
+#endif
+        }
+    }
+
+    dbglog("Setting max protocol version to 0x%X", tls_version);
+    if (!SSL_CTX_set_max_proto_version(ctx, tls_version)) {
+        error("Could not set max protocol version");
+        return -1;
+    }
+
+    return 0;
+}
+
+int tls_set_opts(SSL_CTX *ctx) {
+    
+    /* 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_OP_NO_COMPRESSION
+    );
+
+    /* OpenSSL 1.1.1+ does not include RC4 ciphers by default.
+     * This causes totally obsolete WinXP clients to fail. If you really
+     * need ppp+EAP-TLS+openssl 1.1.1+WinXP then enable RC4 cipers and
+     * make sure that you use an OpenSSL that supports them
+
+    SSL_CTX_set_cipher_list(ctx, "RC4");
+    */
+    return 0;
+}
+
+int tls_set_crl(SSL_CTX *ctx, const char *crl_dir, const char *crl_file) 
+{
+    X509_STORE  *certstore = NULL;
+    X509_LOOKUP *lookup = NULL;
+    FILE *fp = NULL;
+    int status = -1;
+
+    if (crl_dir) {
+        if (!(certstore = SSL_CTX_get_cert_store(ctx))) {
+            error("Failed to get certificate store");
+            goto done;
+        }
+
+        if (!(lookup =
+             X509_STORE_add_lookup(certstore, X509_LOOKUP_hash_dir()))) {
+            error("Store lookup for CRL failed");
+            goto done;
+        }
+
+        X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM);
+        X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
+    }
+
+    if (crl_file) {
+        X509_CRL *crl = NULL;
+
+        fp = fopen(crl_file, "r");
+        if (!fp) {
+            error("Cannot open CRL file '%s'", crl_file);
+            goto done;
+        }
+
+        crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL);
+        if (!crl) {
+            error("Cannot read CRL file '%s'", crl_file);
+            goto done;
+        }
+
+        if (!(certstore = SSL_CTX_get_cert_store(ctx))) {
+            error("Failed to get certificate store");
+            goto done;
+        }
+        if (!X509_STORE_add_crl(certstore, crl)) {
+            error("Cannot add CRL to certificate store");
+            goto done;
+        }
+        X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK);
+    }
+
+    status = 0;
+
+done: 
+
+    if (fp != NULL) {
+        fclose(fp);
+    }
+
+    return status;
+}
+
+int tls_set_ca(SSL_CTX *ctx, const char *ca_dir, const char *ca_file) 
+{
+    if (ca_file && strlen(ca_file) == 0) {
+        ca_file = NULL;
+    }
+
+    if (ca_dir && strlen(ca_dir) == 0) {
+        ca_dir = NULL;
+    }
+
+    if (!SSL_CTX_load_verify_locations(ctx, ca_file, ca_dir)) {
+
+        error("Cannot load verify locations");
+        if (ca_file) {
+            dbglog("CA certificate file = [%s]", ca_file);
+        }
+
+        if (ca_dir) {
+            dbglog("CA certificate path = [%s]", ca_dir);
+        }
+
+        return -1;
+    }
+
+    return 0;
+}
+
+void tls_log_sslerr( 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();
+    }
+}
+
diff --git a/pppd/tls.h b/pppd/tls.h
new file mode 100644 (file)
index 0000000..39fdef7
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2021 Eivind Næss. 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 TLS_H
+#define TLS_H
+
+/**
+ * Structure used in verifying the peer certificate
+ */
+struct tls_info;
+
+/**
+ * Initialize the SSL library
+ */
+int tls_init();
+
+/**
+ * Get the SSL_METHOD
+ */
+const SSL_METHOD* tls_method();
+
+/**
+ * Configure the SSL options
+ */
+int tls_set_opts(SSL_CTX *ctx);
+
+/**
+ * Configure the SSL context's max TLS version
+ */
+int tls_set_version(SSL_CTX *ctx, const char *max_version);
+
+/** 
+ * Configure the SSL context's verify callback
+ */
+int tls_set_verify(SSL_CTX *ctx, int depth);
+
+/**
+ * Configure the SSL verify information
+ */
+int tls_set_verify_info(SSL *ssl, const char *peer_name, const char *peer_cert_file, 
+        bool client, struct tls_info **out);
+
+/**
+ * Free the tls_info structure and it's members
+ */
+void tls_free_verify_info(struct tls_info **in);
+
+/**
+ * Configure the SSL context's CRL details
+ */
+int tls_set_crl(SSL_CTX *ctx, const char *crl_dir, const char *crl_file);
+
+/**
+ * Configure the SSL context's CA verify locations
+ */
+int tls_set_ca(SSL_CTX *ctx, const char *ca_dir, const char *ca_file);
+
+/**
+ * Log all errors from ssl library
+ */
+void tls_log_sslerr( void );
+
+#endif /* TLS_H */
index 852cee700ac2d6811a9dfad81665defd1566238d..7e208badaff078c20c3ed8345c12778c769f5fbf 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdio.h>
 #include <ctype.h>
 #include <stdlib.h>
@@ -905,7 +909,7 @@ open_socket(char *dest)
 static int
 start_charshunt(int ifd, int ofd)
 {
-    int cpid;
+    int cpid, ret;
 
     cpid = safe_fork(ifd, ofd, (log_to_fd >= 0? log_to_fd: 2));
     if (cpid == -1) {
@@ -919,10 +923,14 @@ start_charshunt(int ifd, int ofd)
            log_to_fd = -1;
        else if (log_to_fd >= 0)
            log_to_fd = 2;
-       setgid(getgid());
-       setuid(uid);
-       if (getuid() != uid)
-           fatal("setuid failed");
+       ret = setgid(getgid());
+       if (ret != 0) {
+               fatal("setgid failed, %m");
+       }
+       ret = setuid(uid);
+       if (ret != 0 || getuid() != uid) {
+               fatal("setuid failed, %m");
+       }
        charshunt(0, 1, record_file);
        exit(0);
     }
index 0ae02888281d9eb069763442a862def2025e6b93..1fcff0904b1d9961814db0a8341b4940e8001201 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 /*
  * TODO:
  */
index 99b007fe816abb547842479716078b3984991080..709cd6294ffd2bf216799da3284518bea0238a2c 100644 (file)
@@ -1,3 +1,5 @@
+#include "pppdconf.h"
+
 /*
  * upap.h - User/Password Authentication Protocol definitions.
  *
index 7228279ec000517a07bb15a6342141a77423203d..e75bb9c8eecd21279a999c18f8c0bc4f132ef1e3 100644 (file)
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdarg.h>
 #include <stdio.h>
 #include <ctype.h>
@@ -137,6 +141,7 @@ vslprintf(char *buf, int buflen, char *fmt, va_list args)
     int c, i, n;
     int width, prec, fillch;
     int base, len, neg, quoted;
+    long lval = 0;
     unsigned long val = 0;
     char *str, *f, *buf0;
     unsigned char *p;
@@ -202,11 +207,12 @@ vslprintf(char *buf, int buflen, char *fmt, va_list args)
            c = *fmt++;
            switch (c) {
            case 'd':
-               val = va_arg(args, long);
-               if (val < 0) {
+               lval = va_arg(args, long);
+               if (lval < 0) {
                    neg = 1;
-                   val = -val;
-               }
+                   val = -lval;
+               } else
+                   val = lval;
                base = 10;
                break;
            case 'u':
@@ -323,6 +329,7 @@ vslprintf(char *buf, int buflen, char *fmt, va_list args)
                    OUTCHAR(c);
            }
            continue;
+#ifndef UNIT_TEST
        case 'P':               /* print PPP packet */
            bufinfo.ptr = buf;
            bufinfo.len = buflen + 1;
@@ -332,6 +339,7 @@ vslprintf(char *buf, int buflen, char *fmt, va_list args)
            buf = bufinfo.ptr;
            buflen = bufinfo.len - 1;
            continue;
+#endif
        case 'B':
            p = va_arg(args, unsigned char *);
            for (n = prec; n > 0; --n) {
@@ -426,6 +434,7 @@ log_packet(u_char *p, int len, char *prefix, int level)
 }
 #endif /* unused */
 
+#ifndef UNIT_TEST
 /*
  * format_packet - make a readable representation of a packet,
  * calling `printer(arg, format, ...)' to output it.
@@ -471,6 +480,7 @@ format_packet(u_char *p, int len, printer_func printer, void *arg)
     else
        printer(arg, "%.*B", len, p);
 }
+#endif  /* UNIT_TEST */
 
 /*
  * init_pr_log, end_pr_log - initialize and finish use of pr_log.
@@ -597,6 +607,7 @@ logit(int level, char *fmt, va_list args)
     log_write(level, buf);
 }
 
+#ifndef UNIT_TEST
 static void
 log_write(int level, char *buf)
 {
@@ -611,6 +622,13 @@ log_write(int level, char *buf)
            log_to_fd = -1;
     }
 }
+#else
+static void
+log_write(int level, char *buf)
+{
+    printf("<%d>: %s\n", level, buf);
+}
+#endif
 
 /*
  * fatal - log an error message and die horribly.
@@ -625,7 +643,11 @@ fatal(char *fmt, ...)
     logit(LOG_ERR, fmt, pvar);
     va_end(pvar);
 
+#ifndef UNIT_TEST
     die(1);                    /* as promised */
+#else
+    exit(-1);
+#endif
 }
 
 /*
@@ -729,6 +751,8 @@ dump_packet(const char *tag, unsigned char *p, int len)
     dbglog("%s %P", tag, p, len);
 }
 
+
+#ifndef UNIT_TEST
 /*
  * complete_read - read a full `count' bytes from fd,
  * unless end-of-file or an error other than EINTR is encountered.
@@ -754,6 +778,7 @@ complete_read(int fd, void *buf, size_t count)
        }
        return done;
 }
+#endif
 
 /* Procedures for locking the serial device using a lock file. */
 #ifndef LOCK_DIR
@@ -794,7 +819,7 @@ lock(char *dev)
 #else /* LOCKLIB */
 
     char lock_buffer[12];
-    int fd, pid, n;
+    int fd, pid, n, siz;
 
 #ifdef SVR4
     struct stat sbuf;
@@ -881,11 +906,16 @@ lock(char *dev)
 
     pid = getpid();
 #ifndef LOCK_BINARY
+    siz = 11;
     slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid);
-    write (fd, lock_buffer, 11);
+    n = write (fd, lock_buffer, siz);
 #else
-    write(fd, &pid, sizeof (pid));
+    siz = sizeof (pid);
+    n = write(fd, &pid, siz);
 #endif
+    if (n != siz) {
+       error("Could not write pid to lock file when locking");
+    }
     close(fd);
     return 0;
 
@@ -909,7 +939,7 @@ relock(int pid)
     return -1;
 #else /* LOCKLIB */
 
-    int fd;
+    int fd, n, siz;
     char lock_buffer[12];
 
     if (lock_file[0] == 0)
@@ -922,11 +952,16 @@ relock(int pid)
     }
 
 #ifndef LOCK_BINARY
+    siz = 11;
     slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid);
-    write (fd, lock_buffer, 11);
+    n = write (fd, lock_buffer, siz);
 #else
-    write(fd, &pid, sizeof(pid));
+    siz = sizeof(pid);
+    n = write(fd, &pid, siz);
 #endif /* LOCK_BINARY */
+    if (n != siz) {
+       error("Could not write pid to lock file when locking");
+    }
     close(fd);
     return 0;
 
diff --git a/pppdump/Makefile.am b/pppdump/Makefile.am
new file mode 100644 (file)
index 0000000..2df7e0e
--- /dev/null
@@ -0,0 +1,9 @@
+sbin_PROGRAMS = pppdump
+dist_man8_MANS = pppdump.8
+
+pppdump_SOURCES = pppdump.c bsd-comp.c deflate.c zlib.c
+pppdump_CFLAGS = -I${top_srcdir}/include/net
+
+noinst_HEADERS = \
+    ppp-comp.h \
+    zlib.h
diff --git a/pppdump/Makefile.linux b/pppdump/Makefile.linux
deleted file mode 100644 (file)
index a94187f..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-CROSS_COMPILE=@CROSS_COMPILE@
-CC=$(CROSS_COMPILE)@CC@
-COPTS=@CFLAGS@
-
-DESTDIR = $(INSTROOT)@DESTDIR@
-BINDIR = $(DESTDIR)/sbin
-MANDIR = $(DESTDIR)/share/man/man8
-
-CFLAGS = $(COPTS) -I../include/net
-OBJS = pppdump.o bsd-comp.o deflate.o zlib.o
-
-INSTALL= install
-
-all:   pppdump
-
-pppdump: $(OBJS)
-       $(CC) $(LDFLAGS) -o pppdump $(OBJS)
-
-clean:
-       rm -f pppdump $(OBJS) *~
-
-install:
-       mkdir -p $(BINDIR) $(MANDIR)
-       $(INSTALL) -c pppdump $(BINDIR)
-       $(INSTALL) -c -m 444 pppdump.8 $(MANDIR)
diff --git a/pppdump/Makefile.sol2 b/pppdump/Makefile.sol2
deleted file mode 100644 (file)
index e9196f6..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# pppdump Makefile for SVR4 systems
-# $Id: Makefile.sol2,v 1.4 2002/09/07 05:15:25 carlsonj Exp $
-#
-
-include ../Makedefs.com
-
-CFLAGS= $(COPTS) -I../include/net
-OBJS = pppdump.o bsd-comp.o deflate.o zlib.o
-
-all:   pppdump
-
-pppdump: $(OBJS)
-       $(CC) -o pppdump $(OBJS)
-
-clean:
-       rm -f $(OBJS) pppdump *~
-
-install:
-       $(INSTALL) -f $(BINDIR) pppdump
-       $(INSTALL) -m 444 -f $(MANDIR)/man8 pppdump.8
diff --git a/pppstats/Makefile.am b/pppstats/Makefile.am
new file mode 100644 (file)
index 0000000..d7d74e0
--- /dev/null
@@ -0,0 +1,14 @@
+sbin_PROGRAMS = pppstats
+dist_man8_MANS = pppstats.8
+
+pppstats_SOURCES = pppstats.c
+pppstats_CFLAGS =
+pppstats_CPPFLAGS =
+
+if LINUX
+pppstats_CFLAGS += -I${top_srcdir}/include
+endif
+
+if SUNOS
+pppstats_CPPFLAGS += -DSTREAMS
+endif
diff --git a/pppstats/Makefile.linux b/pppstats/Makefile.linux
deleted file mode 100644 (file)
index ddfe0cc..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# pppstats makefile
-#
-CROSS_COMPILE=@CROSS_COMPILE@
-CC=$(CROSS_COMPILE)@CC@
-COPTS=@CFLAGS@
-
-DESTDIR = $(INSTROOT)@DESTDIR@
-BINDIR = $(DESTDIR)/sbin
-MANDIR = $(DESTDIR)/share/man/man8
-
-PPPSTATSRCS = pppstats.c
-PPPSTATOBJS = pppstats.o
-
-COMPILE_FLAGS = -I../include
-LIBS =
-
-INSTALL= install
-
-CFLAGS = $(COPTS) $(COMPILE_FLAGS)
-
-all: pppstats
-
-install: pppstats
-       -mkdir -p $(MANDIR)
-       $(INSTALL) -c pppstats $(BINDIR)
-       $(INSTALL) -c -m 444 pppstats.8 $(MANDIR)
-
-pppstats: $(PPPSTATSRCS)
-       $(CC) $(CFLAGS) $(LDFLAGS) -o pppstats pppstats.c $(LIBS)
-
-clean:
-       rm -f pppstats *~ #* core
-
-depend:
-       cpp -M $(CFLAGS) $(PPPSTATSRCS) >.depend
-#      makedepend $(CFLAGS) $(PPPSTATSRCS)
diff --git a/pppstats/Makefile.sol2 b/pppstats/Makefile.sol2
deleted file mode 100644 (file)
index e0093a5..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# pppstats Makefile for SVR4 systems
-# $Id: Makefile.sol2,v 1.10 2002/09/07 05:15:25 carlsonj Exp $
-#
-
-include ../Makedefs.com
-
-CFLAGS = -DSTREAMS -I../include $(COPTS)
-
-all: pppstats
-
-pppstats: pppstats.c
-       $(CC) $(CFLAGS) -o pppstats pppstats.c
-
-install: pppstats
-       $(INSTALL) -f $(BINDIR) pppstats
-       $(INSTALL) -m 444 -f $(MANDIR)/man8 pppstats.8
-
-clean:
-       rm -f pppstats *~ core
index 92ebc2a4e007284f2a050f5b007cf5ac378a7dd8..cbea00b6d71268a1838ffd11428618c217a19cdc 100644 (file)
@@ -235,7 +235,7 @@ strioctl(int fd, int cmd, char *ptr, int ilen, int olen)
 static void
 get_ppp_stats(struct ppp_stats *curp)
 {
-    if (strioctl(s, PPPIO_GETSTAT, curp, 0, sizeof(*curp)) < 0) {
+    if (strioctl(s, PPPIO_GETSTAT, (char*) curp, 0, sizeof(*curp)) < 0) {
        fprintf(stderr, "%s: ", progname);
        if (errno == EINVAL)
            fprintf(stderr, "kernel support missing\n");
@@ -248,7 +248,7 @@ get_ppp_stats(struct ppp_stats *curp)
 static void
 get_ppp_cstats(struct ppp_comp_stats *csp)
 {
-    if (strioctl(s, PPPIO_GETCSTAT, csp, 0, sizeof(*csp)) < 0) {
+    if (strioctl(s, PPPIO_GETCSTAT, (char*) csp, 0, sizeof(*csp)) < 0) {
        fprintf(stderr, "%s: ", progname);
        if (errno == ENOTTY) {
            fprintf(stderr, "no kernel compression support\n");
@@ -539,7 +539,7 @@ main(int argc, char *argv[])
        perror(dev);
        exit(1);
     }
-    if (strioctl(s, PPPIO_ATTACH, &unit, sizeof(int), 0) < 0) {
+    if (strioctl(s, PPPIO_ATTACH, (char*) &unit, sizeof(int), 0) < 0) {
        fprintf(stderr, "%s: ppp%d is not available\n", progname, unit);
        exit(1);
     }
index 8d0a3f963774ac8c90c992915baab6ad55a17121..35852c5ae62c6b7aa939c76a34d6e61c5371db5d 100644 (file)
@@ -32,6 +32,12 @@ noipdefault
 # enable this on a server that already has a permanent default route
 #nodefaultroute
 
+# Default IPv6 route is automatically configured by kernel based on
+# received ICMPv6 Router Advertisement packets.
+# pppd should not touch default IPv6 route to prevent breaking IPv6 setup.
+# Enabling defaultroute6 is needed only for broken IPv6 setup.
+nodefaultroute6
+
 # 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
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
new file mode 100644 (file)
index 0000000..0fadd48
--- /dev/null
@@ -0,0 +1,32 @@
+EXTRA_CHATCHAT = \
+    chatchat/chatchat.c \
+    chatchat/README
+
+EXTRA_SCRIPTS = \
+    autopppd \
+    callback \
+    chatchat \
+    ip-down.local.add \
+    ip-up.local.add \
+    ipv6-down.sample \
+    ipv6-up.sample \
+    options-rsh-loc \
+    options-rsh-rem \
+    options-ssh-loc \
+    options-ssh-rem \
+    plog \
+    poff \
+    pon \
+    pon.1 \
+    ppp-off \
+    ppp-on \
+    ppp-on-dialer \
+    ppp-on-rsh \
+    ppp-on-ssh \
+    README \
+    redialer \
+    secure-card
+
+EXTRA_DIST= \
+    $(EXTRA_CHATCHAT) \
+    $(EXTRA_SCRIPTS)