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: |
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: |
with:
run: |
pkg update
- pkg install gcc
- ./configure
+ pkg install gcc automake autoconf libtool
+ ./autogen.sh CFLAGS="-Wno-deprecated-declarations"
make
+ make install
--- /dev/null
+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 }}"
*.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
--- /dev/null
+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>
+
--- /dev/null
+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.
--- /dev/null
+2021-07-11 Eivind Naess <eivnaes@yahoo.com>
+
+ Introduction of Autotools to pppd project
+
--- /dev/null
+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)
--- /dev/null
+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.
+
+
+
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
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>
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
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).
--- /dev/null
+#!/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 $@
+)
+
--- /dev/null
+sbin_PROGRAMS = chat
+dist_man8_MANS = chat.8
+
+chat_SOURCES = chat.c
+chat_CPPFLAGS = -DTERMIOS -DSIGTYPE=void -UNO_SLEEP -DFNDELAY=O_NDELAY
+++ /dev/null
-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 *~
+++ /dev/null
-#
-# 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
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);
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);
/*
* 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) {
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) {
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) {
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;
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) {
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) {
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;
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) {
if (verbose)
msgf("timeout set to %d seconds", timeout);
- return;
+ return 0;
}
/*
if (!put_string(s))
fatal(1, "Failed");
+
+ return 0;
}
int get_char(void)
* 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' */
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;
}
/*
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 */
--- /dev/null
+EXTRA_ZLIB = \
+ zlib.c \
+ zlib.h
+
+EXTRA_DIST = \
+ $(EXTRA_ZLIB)
+++ /dev/null
-#!/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
--- /dev/null
+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}
+"
--- /dev/null
+SUBDIRS = pppgetpass
--- /dev/null
+pppgetpass.vt
+pppgetpass.gtk
--- /dev/null
+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
+++ /dev/null
-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
--- /dev/null
+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)
+++ /dev/null
-# 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
--- /dev/null
+# 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}")
+])
+
--- /dev/null
+# ===========================================================================
+# 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 ])
+])
--- /dev/null
+# 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"
+])
+
--- /dev/null
+# 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}")
+])
+
--- /dev/null
+# 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}")
+])
+
--- /dev/null
+# 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}")
+])
+
--- /dev/null
+# 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
--- /dev/null
+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)
--- /dev/null
+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)
+
+++ /dev/null
-#
-# 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
+++ /dev/null
-#
-# 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
#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>
#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
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. */
"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 }
};
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;
}
}
if ((cacert_file || ca_path) && cert_file && privkey_file)
return 1;
+ if (pkcs12_file)
+ return 1;
filename = _PATH_EAPTLSCLIFILE;
f = fopen(filename, "r");
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;
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 )
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);
* 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>
#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 */
* 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
/*
}
/* 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");
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;
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! */
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
*
* $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? */
#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"
* 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);
#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"
*/
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;
}
/*
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);
* 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).
*/
#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]);
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 */
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
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);
#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)
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);
}
/*
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 */
#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 */
chapms_handle_failure,
};
+#ifndef UNIT_TEST
void
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 */
* $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 */
#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
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]);
#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>
*
*/
+#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
*/
*/
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)
}
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;
|| !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;
}
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;
}
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.
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;
}
}
}
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
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
}
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
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;
}
char cacertfile[MAXWORDLEN];
char capath[MAXWORDLEN];
char pkfile[MAXWORDLEN];
+ char pkcs12[MAXWORDLEN];
+
/*
* Allocate new eaptls session
*/
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;
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
*/
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;
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:
char cacertfile[MAXWORDLEN];
char capath[MAXWORDLEN];
char pkfile[MAXWORDLEN];
+ char pkcs12[MAXWORDLEN];
/*
* Allocate new eaptls session
if (!esp->es_client.ea_session)
fatal("Allocation error");
ets = esp->es_client.ea_session;
-
- /*
- * If available, copy server name in ets; it will be used in cert
- * verify
- */
- if (esp->es_client.ea_peer)
- 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
*/
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;
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:
if (ets->ctx)
SSL_CTX_free(ets->ctx);
+ if (ets->info)
+ tls_free_verify_info(&ets->info);
+
free(ets);
}
}
if (BIO_write(ets->into_ssl, ets->data, ets->datalen) == -1)
- log_ssl_errors();
+ tls_log_sslerr();
SSL_read(ets->ssl, dummy, 65536);
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
*
*/
+#include "pppdconf.h"
+
#ifndef __EAP_TLS_H__
#define __EAP_TLS_H__
#define EAP_TLS_MAX_LEN 65536 /* max eap tls packet size */
+struct tls_info;
+
struct eaptls_session
{
u_char *data; /* buffered data */
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;
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);
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
* 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 */
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
}
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;
}
#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
#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);
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);
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
#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 */
(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
if ((*chap_verifier)(rhostname,
esp->es_server.ea_name,
id,
- &eap_chapms2_digest,
+ esp->es_server.digest,
esp->es_challenge,
inp - 1,
response_message,
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);
}
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);
}
break;
#endif /* USE_EAPTLS */
+#ifdef USE_SRP
case EAPT_SRP:
if (len < 3)
goto truncated;
break;
}
break;
+#endif /* USE_SRP */
}
break;
break;
#endif /* CHAPMS */
+#ifdef USE_SRP
case EAPT_SRP:
if (len < 1)
goto truncated;
break;
}
break;
+#endif /* USE_SRP */
}
break;
* $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
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 */
* 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"
*
* $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? */
*
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include "pppd.h"
*
*/
+#include "pppdconf.h"
+
#ifndef __EUI64_H__
#define __EUI64_H__
* 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.
* $Id: fsm.h,v 1.10 2004/11/13 02:28:15 paulus Exp $
*/
+#include "pppdconf.h"
+
/*
* Packet header = Code, id, length.
*/
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
/*
* TODO:
*/
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)
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;
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)
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;
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);
* 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 */
/*
* 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;
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");
* 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.
* 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>
{ "-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,
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;
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);
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;
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;
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);
{
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;
}
* 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
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);
- }
}
{
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))
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));
/*
* 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;
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)) {
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
*/
+#include "pppdconf.h"
/* Original version, based on RFC2023 :
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#ifdef IPX_CHANGE
/*
* 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.
* 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>
* 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.
* 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>
* 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 */
* 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;
detach(void)
{
int pid;
+ int ret;
char numbuf[16];
int pipefd[2];
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);
/* 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
+ }
}
/* 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
+ }
}
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
+ }
}
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
+ }
}
int pid;
int status = -1;
int errfd;
+ int ret;
if (log_to_fd >= 0)
errfd = log_to_fd;
}
/* 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);
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;
/*
/* 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. */
/* 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
** (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.
*/
/*
** End of md4.h
****************************(cut)***********************************/
+#endif /* USE_MD4 */
+#endif /* __MD4_INCLUDE__ */
***********************************************************************
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <string.h>
#include "md5.h"
** 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
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__ */
--- /dev/null
+/* * 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
* 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__
* 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>
* 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>
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 */
{ "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 },
-#define VERSION "2.4.9"
#define DATE "5 January 2021"
/*
* 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
#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 */
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+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
+++ /dev/null
-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
+++ /dev/null
-#
-# 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
* 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"
* 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>
{
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)
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;
* with pap- and chap-secrets files.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#include <stdio.h>
#include <errno.h>
#include <string.h>
--- /dev/null
+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
+++ /dev/null
-#***********************************************************************
-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 $@ $<
* 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>
}
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
};
--- /dev/null
+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
+++ /dev/null
-#***********************************************************************
-#
-# 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
-
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"
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;
+++ /dev/null
-/* 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
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>
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"
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"
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"
*
*/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
*
***********************************************************************/
-#include "config.h"
-
#include <stdio.h> /* For FILE */
#include <sys/types.h> /* For pid_t */
#include <ctype.h>
--- /dev/null
+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
+++ /dev/null
-#***********************************************************************
-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 $@ $<
/* pppd plugin for interfacing to openl2tpd */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
* 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>
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;
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;
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 " : "",
}
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
};
--- /dev/null
+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)
+++ /dev/null
-# 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
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);
}
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];
/*
{
case PW_TYPE_STRING:
- strcpy (pair->strvalue, valstr);
+ strcpy ((char*) pair->strvalue, valstr);
pair->lvalue = strlen(valstr);
break;
}
else
{
- strncat(value, ptr, 1);
+ strncat(value, (char*) ptr, 1);
lv--;
if (lv < 0) break;
}
{
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)
}
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 */
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);
{
type = PW_TYPE_INTEGER;
}
- else if (strcmp (typestr, "ipaddr") == 0)
+ else if (strcmp (typestr, "ipaddr") == 0 || strcmp (typestr, "ipv4addr") == 0)
{
type = PW_TYPE_IPADDR;
}
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 *);
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;
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
#endif
struct radius_state {
- int accounting_started;
int initialized;
int client_port;
int choose_ip;
* 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)
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 */
#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;
* 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;
* 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;
}
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;
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;
}
/* 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);
}
}
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);
return;
}
- if (!rstate.accounting_started) {
- return;
- }
-
rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id,
0, VENDOR_NONE);
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>
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);
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];
{
if (rc_find_server (server_name, &auth_ipaddr, secret) != 0)
{
+ memset (secret, '\0', sizeof (secret));
return (ERROR_RC);
}
}
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
{
if ((vp = rc_avpair_get(vp, PW_REPLY_MESSAGE)))
{
- strcat(msg, vp->strvalue);
+ strcat(msg, (char*) vp->strvalue);
strcat(msg, "\n");
vp = vp->next;
}
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
{
{
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;
}
*
***********************************************************************/
+#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>
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;
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");
}
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++;
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;
&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 {
* 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"
* 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
#endif
#ifndef USE_CRYPT
-#include <des.h>
+#include <openssl/des.h>
#endif
extern bool DesSetkey(u_char *);
.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
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
\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
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
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
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).
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
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
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
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.
* $Id: pppd.h,v 1.96 2008/06/23 11:47:18 paulus Exp $
*/
+#include "pppdconf.h"
+
/*
* TODO:
*/
#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
#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.
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 */
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
--- /dev/null
+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}
--- /dev/null
+/*
+ * 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
* 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>
#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);
if (pw == NULL)
return SESSION_FAILED;
-#ifdef HAS_SHADOW
+#ifdef HAVE_SHADOW_H
spwd = getspnam(user);
endspent();
/* 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;
}
* 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
* 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
/* #define SHA1HANDSOFF * Copies data before messing with it. */
#include <string.h>
/* 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
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_ */
-
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>
+#include "pppdconf.h"
+
#ifndef __SPINLOCK_H__
#define __SPINLOCK_H__
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#include "tdb.h"
#ifdef USE_SPINLOCKS
* 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>
* 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
/*
#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;
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);
#ifdef B460800
{ 460800, B460800 },
#endif
+#ifdef B500000
+ { 500000, B500000 },
+#endif
+#ifdef B576000
+ { 576000, B576000 },
+#endif
#ifdef B921600
{ 921600, B921600 },
#endif
if (bps == speedp->speed_int)
return speedp->speed_val;
}
- warn("speed %d not supported", bps);
}
return 0;
}
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;
}
}
#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;
}
/********************************************************************
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;
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);
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;
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);
* 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"
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,
* 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>
+#include "pppdconf.h"
+
#ifndef __TDB_H__
#define __TDB_H__
--- /dev/null
+/* 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_ */
--- /dev/null
+/*
+ * 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();
+ }
+}
+
--- /dev/null
+/*
+ * 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 */
* 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>
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) {
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);
}
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
/*
* TODO:
*/
+#include "pppdconf.h"
+
/*
* upap.h - User/Password Authentication Protocol definitions.
*
* 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>
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;
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':
OUTCHAR(c);
}
continue;
+#ifndef UNIT_TEST
case 'P': /* print PPP packet */
bufinfo.ptr = buf;
bufinfo.len = buflen + 1;
buf = bufinfo.ptr;
buflen = bufinfo.len - 1;
continue;
+#endif
case 'B':
p = va_arg(args, unsigned char *);
for (n = prec; n > 0; --n) {
}
#endif /* unused */
+#ifndef UNIT_TEST
/*
* format_packet - make a readable representation of a packet,
* calling `printer(arg, format, ...)' to output it.
else
printer(arg, "%.*B", len, p);
}
+#endif /* UNIT_TEST */
/*
* init_pr_log, end_pr_log - initialize and finish use of pr_log.
log_write(level, buf);
}
+#ifndef UNIT_TEST
static void
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.
logit(LOG_ERR, fmt, pvar);
va_end(pvar);
+#ifndef UNIT_TEST
die(1); /* as promised */
+#else
+ exit(-1);
+#endif
}
/*
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.
}
return done;
}
+#endif
/* Procedures for locking the serial device using a lock file. */
#ifndef LOCK_DIR
#else /* LOCKLIB */
char lock_buffer[12];
- int fd, pid, n;
+ int fd, pid, n, siz;
#ifdef SVR4
struct stat sbuf;
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;
return -1;
#else /* LOCKLIB */
- int fd;
+ int fd, n, siz;
char lock_buffer[12];
if (lock_file[0] == 0)
}
#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;
--- /dev/null
+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
+++ /dev/null
-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)
+++ /dev/null
-#
-# 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
--- /dev/null
+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
+++ /dev/null
-#
-# 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)
+++ /dev/null
-#
-# 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
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");
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");
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);
}
# 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
--- /dev/null
+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)