diff -Nru ppp-2.4.7/chat/chat.c ppp-2.4.9/chat/chat.c --- ppp-2.4.7/chat/chat.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/chat/chat.c 2021-01-05 00:06:37.000000000 +0100 @@ -82,14 +82,6 @@ * */ -#ifndef __STDC__ -#define const -#endif - -#ifndef lint -static const char rcsid[] = "$Id: chat.c,v 1.30 2004/01/17 05:47:55 carlsonj Exp $"; -#endif - #include #include #include @@ -102,6 +94,7 @@ #include #include #include +#include #ifndef TERMIO #undef TERMIOS @@ -121,20 +114,6 @@ #define SIGTYPE void #endif -#undef __P -#undef __V - -#ifdef __STDC__ -#include -#define __V(x) x -#define __P(x) x -#else -#include -#define __V(x) (va_alist) va_dcl -#define __P(x) () -#define const -#endif - #ifndef O_NONBLOCK #define O_NONBLOCK O_NDELAY #endif @@ -209,43 +188,41 @@ int say_next = 0, hup_next = 0; -void *dup_mem __P((void *b, size_t c)); -void *copy_of __P((char *s)); -char *grow __P((char *s, char **p, size_t len)); -void usage __P((void)); -void msgf __P((const char *fmt, ...)); -void fatal __P((int code, const char *fmt, ...)); -SIGTYPE sigalrm __P((int signo)); -SIGTYPE sigint __P((int signo)); -SIGTYPE sigterm __P((int signo)); -SIGTYPE sighup __P((int signo)); -void unalarm __P((void)); -void init __P((void)); -void set_tty_parameters __P((void)); -void echo_stderr __P((int)); -void break_sequence __P((void)); -void terminate __P((int status)); -void do_file __P((char *chat_file)); -int get_string __P((register char *string)); -int put_string __P((register char *s)); -int write_char __P((int c)); -int put_char __P((int c)); -int get_char __P((void)); -void chat_send __P((register char *s)); -char *character __P((int c)); -void chat_expect __P((register char *s)); -char *clean __P((register char *s, int sending)); -void break_sequence __P((void)); -void terminate __P((int status)); -void pack_array __P((char **array, int end)); -char *expect_strtok __P((char *, char *)); -int vfmtmsg __P((char *, int, const char *, va_list)); /* vsprintf++ */ - -int main __P((int, char *[])); - -void *dup_mem(b, c) -void *b; -size_t c; +void *dup_mem (void *b, size_t c); +void *copy_of (char *s); +char *grow (char *s, char **p, size_t len); +void usage (void); +void msgf (const char *fmt, ...); +void fatal (int code, const char *fmt, ...); +SIGTYPE sigalrm (int signo); +SIGTYPE sigint (int signo); +SIGTYPE sigterm (int signo); +SIGTYPE sighup (int signo); +void unalarm (void); +void init (void); +void set_tty_parameters (void); +void echo_stderr (int); +void break_sequence (void); +void terminate (int status); +void do_file (char *chat_file); +int get_string (register char *string); +int put_string (register char *s); +int write_char (int c); +int put_char (int c); +int get_char (void); +void chat_send (register char *s); +char *character (int c); +void chat_expect (register char *s); +char *clean (register char *s, int sending); +void break_sequence (void); +void terminate (int status); +void pack_array (char **array, int end); +char *expect_strtok (char *, char *); +int vfmtmsg (char *, int, const char *, va_list); /* vsprintf++ */ + +int main (int, char *[]); + +void *dup_mem(void *b, size_t c) { void *ans = malloc (c); if (!ans) @@ -255,17 +232,13 @@ return ans; } -void *copy_of (s) -char *s; +void *copy_of (char *s) { return dup_mem (s, strlen (s) + 1); } /* grow a char buffer and keep a pointer offset */ -char *grow(s, p, len) -char *s; -char **p; -size_t len; +char *grow(char *s, char **p, size_t len) { size_t l = *p - s; /* save p as distance into s */ @@ -284,9 +257,7 @@ * Perform a UUCP-dialer-like chat script on stdin and stdout. */ int -main(argc, argv) - int argc; - char **argv; +main(int argc, char **argv) { int option; char *arg; @@ -413,8 +384,7 @@ * Process a chat script when read from a file. */ -void do_file (chat_file) -char *chat_file; +void do_file (char *chat_file) { int linect, sendflg; char *sp, *arg, quote; @@ -482,7 +452,7 @@ /* * We got an error parsing the command line. */ -void usage() +void usage(void) { fprintf(stderr, "\ Usage: %s [-e] [-E] [-v] [-V] [-t timeout] [-r report-file]\n\ @@ -495,55 +465,42 @@ /* * Send a message to syslog and/or stderr. */ -void msgf __V((const char *fmt, ...)) +void msgf(const char *fmt, ...) { va_list args; -#ifdef __STDC__ va_start(args, fmt); -#else - char *fmt; - va_start(args); - fmt = va_arg(args, char *); -#endif vfmtmsg(line, sizeof(line), fmt, args); if (to_log) syslog(LOG_INFO, "%s", line); if (to_stderr) fprintf(stderr, "%s\n", line); + va_end(args); } /* * Print an error message and terminate. */ -void fatal __V((int code, const char *fmt, ...)) +void fatal(int code, const char *fmt, ...) { va_list args; -#ifdef __STDC__ va_start(args, fmt); -#else - int code; - char *fmt; - va_start(args); - code = va_arg(args, int); - fmt = va_arg(args, char *); -#endif vfmtmsg(line, sizeof(line), fmt, args); if (to_log) syslog(LOG_ERR, "%s", line); if (to_stderr) fprintf(stderr, "%s\n", line); + va_end(args); terminate(code); } int alarmed = 0; -SIGTYPE sigalrm(signo) -int signo; +SIGTYPE sigalrm(int signo) { int flags; @@ -561,7 +518,7 @@ msgf("alarm"); } -void unalarm() +void unalarm(void) { int flags; @@ -572,25 +529,22 @@ fatal(2, "Can't set file mode flags on stdin: %m"); } -SIGTYPE sigint(signo) -int signo; +SIGTYPE sigint(int signo) { fatal(2, "SIGINT"); } -SIGTYPE sigterm(signo) -int signo; +SIGTYPE sigterm(int signo) { fatal(2, "SIGTERM"); } -SIGTYPE sighup(signo) -int signo; +SIGTYPE sighup(int signo) { fatal(2, "SIGHUP"); } -void init() +void init(void) { signal(SIGINT, sigint); signal(SIGTERM, sigterm); @@ -602,7 +556,7 @@ alarmed = 0; } -void set_tty_parameters() +void set_tty_parameters(void) { #if defined(get_term_param) term_parms t; @@ -626,15 +580,14 @@ #endif } -void break_sequence() +void break_sequence(void) { #ifdef TERMIOS tcsendbreak (0, 0); #endif } -void terminate(status) -int status; +void terminate(int status) { static int terminating = 0; @@ -681,9 +634,8 @@ /* * 'Clean up' this string. */ -char *clean(s, sending) -register char *s; -int sending; /* set to 1 when sending (putting) this string. */ +char *clean(register char *s, + int sending) /* set to 1 when sending (putting) this string. */ { char cur_chr; char *s1, *p, *phchar; @@ -868,8 +820,7 @@ * A modified version of 'strtok'. This version skips \ sequences. */ -char *expect_strtok (s, term) - char *s, *term; +char *expect_strtok (char *s, char *term) { static char *str = ""; int escape_flag = 0; @@ -923,8 +874,7 @@ * Process the expect string */ -void chat_expect (s) -char *s; +void chat_expect (char *s) { char *expect; char *reply; @@ -1012,8 +962,7 @@ * the data. */ -char *character(c) -int c; +char *character(int c) { static char string[10]; char *meta; @@ -1034,8 +983,7 @@ /* * process the reply string */ -void chat_send (s) -register char *s; +void chat_send (register char *s) { char file_data[STR_LEN]; @@ -1225,7 +1173,7 @@ fatal(1, "Failed"); } -int get_char() +int get_char(void) { int status; char c; @@ -1250,8 +1198,7 @@ } } -int put_char(c) -int c; +int put_char(int c) { int status; char ch = c; @@ -1278,8 +1225,7 @@ } } -int write_char (c) -int c; +int write_char(int c) { if (alarmed || put_char(c) < 0) { alarm(0); @@ -1296,8 +1242,7 @@ return (1); } -int put_string (s) -register char *s; +int put_string(register char *s) { quiet = 0; s = clean(s, 1); @@ -1351,8 +1296,7 @@ * When called with -1, a '\n' character is generated when * the cursor is not at the beginning of a line. */ -void echo_stderr(n) -int n; +void echo_stderr(int n) { static int need_lf; char *s; @@ -1379,8 +1323,7 @@ /* * 'Wait for' this string to appear on this file descriptor. */ -int get_string(string) -register char *string; +int get_string(register char *string) { char temp[STR_LEN]; int c, printed = 0, len, minlen; @@ -1548,9 +1491,8 @@ extern int select(); -int -usleep( usec ) /* returns 0 if ok, else -1 */ - long usec; /* delay in microseconds */ +/* returns 0 if ok, else -1 */ +int usleep(long usec) /* delay in microseconds */ { static struct { /* `timeval' */ long tv_sec; /* seconds */ @@ -1564,10 +1506,9 @@ } #endif -void -pack_array (array, end) - char **array; /* The address of the array of string pointers */ - int end; /* The index of the next free entry before CLR_ */ +void pack_array ( + char **array, /* The address of the array of string pointers */ + int end) /* The index of the next free entry before CLR_ */ { int i, j; @@ -1593,11 +1534,7 @@ #define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) int -vfmtmsg(buf, buflen, fmt, args) - char *buf; - int buflen; - const char *fmt; - va_list args; +vfmtmsg(char *buf, int buflen, const char *fmt, va_list args) { int c, i, n; int width, prec, fillch; diff -Nru ppp-2.4.7/chat/Makefile.linux ppp-2.4.9/chat/Makefile.linux --- ppp-2.4.7/chat/Makefile.linux 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/chat/Makefile.linux 2021-01-05 00:06:37.000000000 +0100 @@ -1,4 +1,6 @@ -# $Id: Makefile.linux,v 1.15 2006/06/04 05:07:46 paulus Exp $ +CROSS_COMPILE=@CROSS_COMPILE@ +CC=$(CROSS_COMPILE)@CC@ +COPTS=@CFLAGS@ DESTDIR = $(INSTROOT)@DESTDIR@ BINDIR = $(DESTDIR)/sbin @@ -10,7 +12,6 @@ CDEF4= -DFNDELAY=O_NDELAY # Old name value CDEFS= $(CDEF1) $(CDEF2) $(CDEF3) $(CDEF4) -COPTS= -O2 -g -pipe CFLAGS= $(COPTS) $(CDEFS) INSTALL= install @@ -18,14 +19,14 @@ all: chat chat: chat.o - $(CC) -o 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) -s -c chat $(BINDIR) + $(INSTALL) -c chat $(BINDIR) $(INSTALL) -c -m 644 chat.8 $(MANDIR) clean: diff -Nru ppp-2.4.7/configure ppp-2.4.9/configure --- ppp-2.4.7/configure 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/configure 2021-01-05 00:06:37.000000000 +0100 @@ -5,25 +5,25 @@ DESTDIR=/usr/local SYSCONF=/etc -# if [ -d /NextApps ]; then -# system="NeXTStep" -# else - system=`uname -s` - release=`uname -r` - arch=`uname -m` -# fi +# 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";; + state="known"; + CFLAGS="-O2 -g -pipe";; SunOS) karch=`/usr/bin/isainfo -k` case $release in -# [0-3]*) state="ancient";; -# 4*) state="known"; ksrc="sunos4"; makext="sunos4";; 5.[7-9]*|5.[1-9][0-9]*) state="known"; ksrc="solaris"; makext="sol2"; case "$karch" in amd64) archvariant='-64x';; @@ -72,57 +72,6 @@ fi;; NetBSD|FreeBSD|ULTRIX|OSF1|NeXTStep|SINIX-?|UNIX_SV|UNIX_System_V) state="notincluded";; -# NetBSD) -# makext="bsd"; -# case $release in -# 0.*) state="ancient";; -# 1.0*) state="ancient";; -# 1.1*) state="known"; ksrc="netbsd-1.1";; -# 1.2*) state="known"; ksrc="netbsd-1.2"; makext="netbsd-1.2";; -# 1.[3-9]*|[2-9]*) -# state="late"; ksrc="netbsd-1.2";; -# esac;; -# ULTRIX) -# makext="ultrix"; -# case $release in -# [0-3]*) state="ancient";; -# 4.[01]*) state="early"; ksrc="ultrix";; -# 4.[234]) state="known"; ksrc="ultrix";; -# esac;; -# OSF1) -# makext="osf"; -# case $release in -# V1.*) state="neolithic"; ksrc="osf1";; -# V[23].*) state="neolithic"; ksrc="osf1";; -# V4.*) state="known"; ksrc="osf1";; -# V[5-9]*) state="late"; ksrc="osf1";; -# esac;; -# FreeBSD) -# makext="bsd"; -# case $release in -# 1.*) state="known"; ksrc="freebsd-old";; -# 2.[01]*) state="known"; ksrc="freebsd-2.0";; -# 2.2.[2-7]*) state="late"; ksrc="freebsd-2.0";; -# 2.2.8*) state="known"; ksrc="freebsd-2.2.8";; -# 3.[0-1]*) state="known"; ksrc="freebsd-3.0";; -# esac;; -# NeXTStep) -# makext="NeXT"; -# ksrc="NeXT"; -# state="known";; -# SINIX-?) -# case $release in -# 5.4[01]) state=known; ksrc=svr4; makext=svr4;; -# 5.4[2-9]) state=late; ksrc=svr4; makext=svr4;; -# esac;; -# # Intel SVR4 systems come with a bug in the uname program. Unless -# # your provider fixed the bug, or you get a fix for it, uname -S will -# # overwrite the system name with the node name! -# UNIX_SV|UNIX_System_V|`uname -n`) -# case $release in -# 4.0) state=known; ksrc=svr4; makext=svr4;; -# 4.2) state=late; ksrc=svr4; makext=svr4;; -# esac;; esac if [ -d "$ksrc" ]; then :; else @@ -131,22 +80,6 @@ fi case $state in - neolithic) - echo "This is a newer release on an outdated OS ($system)." - echo " This software may or may not work on this OS." - echo " You may want to download an older version of PPP for this OS.";; - ancient) - echo "This is an old release of a supported OS ($system)." - echo "This software cannot be used as-is on this system," - echo "but you may be able to port it. Good luck!" - exit;; - early) - echo "This is an old release of a supported OS ($system)." - echo "This software should install and run on this system," - echo "but it hasn't been tested.";; - late) - echo "This is a newer release of $system than is supported by" - echo "this software. It may or may not work.";; unknown) echo "This software has not been ported to $system. Sorry.";; notincluded) @@ -176,8 +109,11 @@ ;; esac case $arg in - --prefix) DESTDIR=$val ;; - --sysconfdir) SYSCONF=$val ;; + --prefix) DESTDIR=$val ;; + --sysconfdir) SYSCONF=$val ;; + --cross_compile) CROSS_COMPILE=$val ;; + --cc) CC=$val ;; + --cflags) CFLAGS=$val ;; esac done @@ -185,7 +121,9 @@ rm -f $2 if [ -f $1 ]; then echo " $2 <= $1" - sed -e "s,@DESTDIR@,$DESTDIR,g" -e "s,@SYSCONF@,$SYSCONF,g" $1 >$2 + sed -e "s,@DESTDIR@,$DESTDIR,g" -e "s,@SYSCONF@,$SYSCONF,g" \ + -e "s,@CROSS_COMPILE@,$CROSS_COMPILE,g" -e "s,@CC@,$CC,g" \ + -e "s,@CFLAGS@,$CFLAGS,g" $1 >$2 fi } @@ -193,7 +131,7 @@ 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/rp-pppoe \ + 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 diff -Nru ppp-2.4.7/debian/changelog ppp-2.4.9/debian/changelog --- ppp-2.4.7/debian/changelog 2021-02-25 06:59:12.000000000 +0100 +++ ppp-2.4.9/debian/changelog 2021-08-16 19:00:43.000000000 +0200 @@ -1,3 +1,129 @@ +ppp (2.4.9-1+1ubuntu1) impish; urgency=low + + * Merge from Debian unstable (LP: #1912168). Remaining changes: + - Stop producing udebs on i386 where we no longer have d-i or a kernel. + - debian/extra/ip-up.d/0000usepeerdns: Added NetworkManager check, which + lets the script exit when NetworkManager is in use + * Dropped changes as obsolete + - debian/patches/CVE-2020-8597.patch: fix bounds check in EAP code in + pppd/eap.c. + + -- Simon Chopin Mon, 16 Aug 2021 19:00:43 +0200 + +ppp (2.4.9-1+1) unstable; urgency=medium + + [ Samuel Thibault ] + * Use merge request URLs. + * Add comments from upstream for Nacked patches. + + [ Chris Boot ] + * New upstream release. + - Adds defaultroute6 option. (Closes: #477245) + - Adds defaultroute-metric option. (Closes: #578726) + - Accepts Windows Server 2019 malformed messages. (Closes: #968040) + - Fixes pppoe-discovery -U. (Closes: #961462) + * Remove patches merged upstream (lots!) and refresh the rest. + * d/ppp.symbols: update for the new version. + * d/rules: adjust for renamed pppoe plugin. + * d/ppp.lintian-overrides: update paths to plugins. + * d/ppp.postinst: remove left-in debugging aid (set -x). (Closes: #978732) + * Update d/watch to point at ftp.samba.org and add the signing key. + * Freshen up the ip{,v6}-{up,down} scripts. (Closes: #710946) + + [ Michael Biebl ] + * Stop using deprecated systemd-resolve tool. (Closes: #979255) + + [ наб ] + * Add /etc/ppp/ip-pre-up and corresponding /etc/ppp/ip-pre-up.d. + (Closes: #978396) + + -- Chris Boot Thu, 07 Jan 2021 00:10:29 +0000 + +ppp (2.4.8-1+2) unstable; urgency=medium + + * Clean up correctly after pppd-dns init script and systemd unit removal. + (Closes: #978427) + * Don't touch resolv.conf when systemd-resolved is running. + (Closes: #968589) + + [ Samuel Thibault ] + * Mark forwarded patches. + + -- Chris Boot Wed, 30 Dec 2020 13:49:46 +0000 + +ppp (2.4.8-1+1) unstable; urgency=medium + + [ Debian Janitor ] + * Use secure URI in Homepage field. + * Set upstream metadata fields: Bug-Database, Bug-Submit, Repository, + Repository-Browse. + * Update renamed lintian tag names in lintian overrides. + + [ Chris Boot ] + * d/control: + - Switch to debhelper compat level 13. + - Update Standards-Version to 4.5.1 (no changes requird). + * Clean up or ignore a handful of lintian complaints: + - Ignore possible-bashism-in-maintainer-script in ppp-udeb ($HOSTNAME is + set in the script). + - Do not use full path to pppoe-discovery. + - Remove 'echo' bashism (backslash substitution). + - Remove superfluous #DEBHELPER# tag. + - Install lintian overrides for ppp-udeb. + * d/rules: move generated changelog-from-README under debian/. + * Add debian/.gitignore file covering most files generated during build. + * Upload to unstable. + + -- Chris Boot Fri, 25 Dec 2020 19:26:26 +0000 + +ppp (2.4.8-1+1~exp1) experimental; urgency=medium + + * New upstream release. + * d/patches: + - Remove patches applied upstream. + - Refresh other patches to remove fuzz. + - Some patches required significant reworking: + - cifdefroute.dif (for replacedefaultroute) + - makefiles_cleanup + * d/ppp.symbols: + - adjust symbols for new release. + - add Build-Depends-Package metadata field. + * Switch to debhelper compat level 12. + - Remove d/compat. + - Replace Build-Depends on debhelper with debhelper-compat (= 12). + * Remove d/upstream/signing-key.asc. Upstream no loner supplied signed + tarballs. + * Fix various lintian complaints: + - d/rules: don't trigger ldconfig unnecessarily. + - d/rules: remove obsolete get-orig-source target. + - d/ppp.lintian-overrides: update version in plugins path. + - d/ppp.lintian-overrides: add new override for minconn.so. + * Remove pppd-dns init script and systemd unit, which have been broken since + ppp 2.4.5-1. + * Update pppoe-discovery(8) man page. + * Enable systemd notify integration. + * d/rules: don't set LDOPTS now that the makefiles use LDFLAGS correctly. + * Add patch to handle IPv6 RADIUS attributes. (Closes: #874620) + * d/ppp-udeb.postinst: + - Source /etc/network/interfaces.d snippets in /etc/network/interfaces file + generated by debian-installer udeb. (Closes: #889314) + - Prevent NetworkManager from managing the interface being used for PPPoE. + (Closes: #889323) + - Thanks to Алексей Шилин for the patches. + * Update Standards-Version to 4.5.0 (no changes requird). + * Add debian/salsa-ci.yml for GitLab CI, but disable reprotest which + currently fails when files need chowning (salsa-ci-team/pipeline#26). + * Import patches since upstream 2.4.8 release: + - radius: Prevent buffer overflow in rc_mksid (replaces + rc_mksid-no-buffer-overflow fixing #782450) + - pppd: Fix bounds check in EAP code (Closes: #950618; CVE-2020-8597) + - pppd: Ignore received EAP messages when not doing EAP + - Refresh eaptls-mppe.patch to remove fuzz. + * Add d/patches/multiarch-libc.patch: Use a compile test to detect crypt.h. + (Closes: #911359) + + -- Chris Boot Sat, 15 Feb 2020 16:42:26 +0000 + ppp (2.4.7-2+4.1ubuntu8) hirsute; urgency=medium * No-change rebuild to drop the udeb package. @@ -1769,3 +1895,4 @@ just removing selected files within. (Closes: #107910) -- Michael Beattie Sat, 29 Sep 2001 23:15:44 +1200 + diff -Nru ppp-2.4.7/debian/compat ppp-2.4.9/debian/compat --- ppp-2.4.7/debian/compat 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/compat 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -11 diff -Nru ppp-2.4.7/debian/control ppp-2.4.9/debian/control --- ppp-2.4.7/debian/control 2019-10-09 22:11:37.000000000 +0200 +++ ppp-2.4.9/debian/control 2021-08-16 18:58:24.000000000 +0200 @@ -1,17 +1,19 @@ Source: ppp Section: admin Priority: optional -Homepage: http://ppp.samba.org/ +Homepage: https://ppp.samba.org/ Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Chris Boot Uploaders: Marco d'Itri Build-Depends: - debhelper (>= 11~), + debhelper (>= 13~), + debhelper-compat (= 13), libpam0g-dev, libpcap0.8-dev, libssl-dev, + libsystemd-dev, zlib1g-dev, -Standards-Version: 4.1.3 +Standards-Version: 4.5.1 Vcs-Browser: https://salsa.debian.org/debian/ppp Vcs-Git: https://salsa.debian.org/debian/ppp.git Rules-Requires-Root: binary-targets @@ -21,7 +23,6 @@ Depends: libpam-modules, libpam-runtime, - lsb-base, procps, ${misc:Depends}, ${shlibs:Depends}, diff -Nru ppp-2.4.7/debian/extra/ip-down ppp-2.4.9/debian/extra/ip-down --- ppp-2.4.7/debian/extra/ip-down 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/extra/ip-down 2021-02-25 19:12:30.000000000 +0100 @@ -16,8 +16,8 @@ # $5 Peer IP number 12.34.56.99 # $6 Optional ``ipparam'' value foo -# The environment is cleared before executing this script -# so the path must be reset +# The environment is cleared before executing this script +# so the path must be reset. PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin export PATH @@ -32,13 +32,13 @@ # as an additional convenience, $PPP_TTYNAME is set to the tty name, # stripped of /dev/ (if present) for easier matching. -PPP_TTYNAME=`/usr/bin/basename "$2"` -export PPP_TTYNAME +PPP_TTYNAME=$(/usr/bin/basename "$2") +export PPP_TTYNAME # If /var/log/ppp-ipupdown.log exists use it for logging. if [ -e /var/log/ppp-ipupdown.log ]; then exec >> /var/log/ppp-ipupdown.log 2>&1 - echo $0 $@ + echo "$0" "$@" echo fi @@ -49,4 +49,3 @@ run-parts /etc/ppp/ip-down.d \ --arg="$1" --arg="$2" --arg="$3" --arg="$4" --arg="$5" --arg="$6" - diff -Nru ppp-2.4.7/debian/extra/ip-down.d/0000usepeerdns ppp-2.4.9/debian/extra/ip-down.d/0000usepeerdns --- ppp-2.4.7/debian/extra/ip-down.d/0000usepeerdns 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/extra/ip-down.d/0000usepeerdns 2021-02-25 19:12:30.000000000 +0100 @@ -3,6 +3,11 @@ # exit if the resolvconf package is installed [ -x /sbin/resolvconf ] && exit 0 +# exit if systemd-resolved is running +[ -e /run/systemd/system ] && \ + systemctl is-active --quiet systemd-resolved.service && + exit 0 + # follow any symlink to find the real file if [ -e /etc/resolv.conf ]; then REALRESOLVCONF=$(readlink --canonicalize /etc/resolv.conf) @@ -21,4 +26,3 @@ fi exit 0 - diff -Nru ppp-2.4.7/debian/extra/ip-pre-up ppp-2.4.9/debian/extra/ip-pre-up --- ppp-2.4.7/debian/extra/ip-pre-up 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/debian/extra/ip-pre-up 2021-01-07 01:10:29.000000000 +0100 @@ -0,0 +1,51 @@ +#!/bin/sh +# +# This script is run by the pppd after the link is established but before it's brought up. +# It uses run-parts to run scripts in /etc/ppp/ip-pre-up.d, so to delete default routes, +# configure the new interface etc. you should create script(s) there. +# +# Be aware that other packages may include /etc/ppp/ip-pre-up.d scripts (named +# after that package), so choose local script names with that in mind. +# +# This script is called with the following arguments: +# Arg Name Example +# $1 Interface name ppp0 +# $2 The tty ttyS1 +# $3 The link speed 38400 +# $4 Local IP number 12.34.56.78 +# $5 Peer IP number 12.34.56.99 +# $6 Optional ``ipparam'' value foo + +# The environment is cleared before executing this script +# so the path must be reset. +PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin +export PATH + +# These variables are for the use of the scripts run by run-parts +PPP_IFACE="$1" +PPP_TTY="$2" +PPP_SPEED="$3" +PPP_LOCAL="$4" +PPP_REMOTE="$5" +PPP_IPPARAM="$6" +export PPP_IFACE PPP_TTY PPP_SPEED PPP_LOCAL PPP_REMOTE PPP_IPPARAM + +# as an additional convenience, $PPP_TTYNAME is set to the tty name, +# stripped of /dev/ (if present) for easier matching. +PPP_TTYNAME=$(/usr/bin/basename "$2") +export PPP_TTYNAME + +# If /var/log/ppp-ipupdown.log exists use it for logging. +if [ -e /var/log/ppp-ipupdown.log ]; then + exec > /var/log/ppp-ipupdown.log 2>&1 + echo "$0" "$@" + echo +fi + +# This script can be used to override the .d files supplied by other packages. +if [ -x /etc/ppp/ip-pre-up.local ]; then + exec /etc/ppp/ip-pre-up.local "$@" +fi + +run-parts /etc/ppp/ip-pre-up.d \ + --arg="$1" --arg="$2" --arg="$3" --arg="$4" --arg="$5" --arg="$6" diff -Nru ppp-2.4.7/debian/extra/ip-up ppp-2.4.9/debian/extra/ip-up --- ppp-2.4.7/debian/extra/ip-up 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/extra/ip-up 2021-02-25 19:12:30.000000000 +0100 @@ -16,8 +16,8 @@ # $5 Peer IP number 12.34.56.99 # $6 Optional ``ipparam'' value foo -# The environment is cleared before executing this script -# so the path must be reset +# The environment is cleared before executing this script +# so the path must be reset. PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin export PATH @@ -32,13 +32,13 @@ # as an additional convenience, $PPP_TTYNAME is set to the tty name, # stripped of /dev/ (if present) for easier matching. -PPP_TTYNAME=`/usr/bin/basename "$2"` -export PPP_TTYNAME +PPP_TTYNAME=$(/usr/bin/basename "$2") +export PPP_TTYNAME # If /var/log/ppp-ipupdown.log exists use it for logging. if [ -e /var/log/ppp-ipupdown.log ]; then - exec > /var/log/ppp-ipupdown.log 2>&1 - echo $0 $@ + exec >> /var/log/ppp-ipupdown.log 2>&1 + echo "$0" "$@" echo fi @@ -54,6 +54,5 @@ if [ -e /var/run/ppp-quick ]; then rm /var/run/ppp-quick wait - kill $PPPD_PID + kill "$PPPD_PID" fi - diff -Nru ppp-2.4.7/debian/extra/ip-up.d/0000usepeerdns ppp-2.4.9/debian/extra/ip-up.d/0000usepeerdns --- ppp-2.4.7/debian/extra/ip-up.d/0000usepeerdns 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/extra/ip-up.d/0000usepeerdns 2021-08-16 18:53:23.000000000 +0200 @@ -13,6 +13,11 @@ ;; esac +# exit if systemd-resolved is running +[ -e /run/systemd/system ] && \ + systemctl is-active --quiet systemd-resolved.service && + exit 0 + # create the file if it does not exist if [ ! -e /etc/resolv.conf ]; then : > /etc/resolv.conf @@ -37,4 +42,3 @@ fi exit 0 - diff -Nru ppp-2.4.7/debian/extra/ipv6-down ppp-2.4.9/debian/extra/ipv6-down --- ppp-2.4.7/debian/extra/ipv6-down 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/extra/ipv6-down 2021-02-25 19:12:30.000000000 +0100 @@ -1,6 +1,11 @@ #!/bin/sh -# These variables are for the use of the scripts run by run-parts. +# The environment is cleared before executing this script +# so the path must be reset. +PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin +export PATH + +# These variables are for the use of the scripts run by run-parts PPP_IFACE="$1" PPP_TTY="$2" PPP_SPEED="$3" @@ -9,13 +14,11 @@ PPP_IPPARAM="$6" export PPP_IFACE PPP_TTY PPP_SPEED PPP_LOCAL PPP_REMOTE PPP_IPPARAM -# The environment is cleared before executing this script. -PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin -export PATH - # If /var/log/ppp-ipupdown.log exists use it for logging. if [ -e /var/log/ppp-ipupdown.log ]; then exec >> /var/log/ppp-ipupdown.log 2>&1 + echo "$0" "$@" + echo fi # This script can be used to override the .d files supplied by other packages. @@ -25,4 +28,3 @@ run-parts /etc/ppp/ipv6-down.d \ --arg="$1" --arg="$2" --arg="$3" --arg="$4" --arg="$5" --arg="$6" - diff -Nru ppp-2.4.7/debian/extra/ipv6-up ppp-2.4.9/debian/extra/ipv6-up --- ppp-2.4.7/debian/extra/ipv6-up 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/extra/ipv6-up 2021-02-25 19:12:30.000000000 +0100 @@ -1,6 +1,11 @@ #!/bin/sh -# These variables are for the use of the scripts run by run-parts. +# The environment is cleared before executing this script +# so the path must be reset. +PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin +export PATH + +# These variables are for the use of the scripts run by run-parts PPP_IFACE="$1" PPP_TTY="$2" PPP_SPEED="$3" @@ -9,13 +14,11 @@ PPP_IPPARAM="$6" export PPP_IFACE PPP_TTY PPP_SPEED PPP_LOCAL PPP_REMOTE PPP_IPPARAM -# The environment is cleared before executing this script. -PATH=/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin -export PATH - # If /var/log/ppp-ipupdown.log exists use it for logging. if [ -e /var/log/ppp-ipupdown.log ]; then exec >> /var/log/ppp-ipupdown.log 2>&1 + echo "$0" "$@" + echo fi # This script can be used to override the .d files supplied by other packages. @@ -30,6 +33,5 @@ if [ -e /var/run/ppp-quick ]; then rm /var/run/ppp-quick wait - kill $PPPD_PID + kill "$PPPD_PID" fi - diff -Nru ppp-2.4.7/debian/extra/pppoe-discovery.8 ppp-2.4.9/debian/extra/pppoe-discovery.8 --- ppp-2.4.7/debian/extra/pppoe-discovery.8 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/extra/pppoe-discovery.8 2021-02-25 19:12:30.000000000 +0100 @@ -1,7 +1,7 @@ .\" pppoe-discovery.8 written by .\" Ben Hutchings , based on pppoe.8. .\" Licenced under the GPL version 2 or later. -.TH PPPOE-DISCOVERY 8 "22 January 2006" +.TH PPPOE-DISCOVERY 8 "12 January 2019" .SH NAME pppoe\-discovery \- perform PPPoE discovery .SH SYNOPSIS @@ -39,12 +39,26 @@ .B \-U .RS Causes \fBpppoe\-discovery\fR to use the Host-Uniq tag in its discovery -packets. +packets. The value of the tag is derived from the process's PID number. This lets you run multiple instances of \fBpppoe\-discovery\fR and/or -\fBpppoe\fR without having their discovery packets interfere with one +\fBpppd\fR without having their discovery packets interfere with one another. You must supply this option to \fIall\fR instances that you intend to run simultaneously. +This option is mutually exclusive with \fB\-W\fR. +.RE +.TP +.BI \-W " value" +.RS +Causes \fBpppoe\-discovery\fR to use the Host-Uniq tag in its discovery +packets. The value of the tag is taken from the option argument, +encoded as a string of hexadecimal digits. +This lets you run multiple instances of \fBpppoe\-discovery\fR and/or +\fBpppd\fR without having their discovery packets interfere with one +another. +You must supply this option to \fIall\fR instances that you intend to +run simultaneously. +This option is mutually exclusive with \fB\-U\fR. .RE .TP .BI \-S " service_name" @@ -68,10 +82,26 @@ \fIboth\fR match. .RE .TP -.B \-A +.B \-Q +.RS +Causes \fBpppoe\-discovery\fR to avoid printing discovered access +concentrator names. +This can be useful in scripts, which can use the exit code of the +program to determine whether any matching access concentrators were +discovered. +.RE +.TP +.BI \-t " timeout" +.RS +Changes the discovery timeout for PADI requests, in seconds. +The default value is 5 seconds. +.RE +.TP +.BI \-a " attempts" .RS -This option is accepted for compatibility with \fBpppoe\fR, but has no -effect. +Changes the number of PADI discovery attempts made. +By default, 3 attempts are made to discover access concentrators before +giving up. .RE .TP .BR \-V " | " \-h diff -Nru ppp-2.4.7/debian/gbp.conf ppp-2.4.9/debian/gbp.conf --- ppp-2.4.7/debian/gbp.conf 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/debian/gbp.conf 2021-01-07 01:10:29.000000000 +0100 @@ -0,0 +1,2 @@ +[DEFAULT] +pristine-tar = False diff -Nru ppp-2.4.7/debian/NEWS ppp-2.4.9/debian/NEWS --- ppp-2.4.7/debian/NEWS 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/debian/NEWS 2021-01-07 01:10:29.000000000 +0100 @@ -0,0 +1,15 @@ +ppp (2.4.8-1+1~exp1) experimental; urgency=medium + + The pppd-dns init script and systemd unit have been removed. These were + intended to restore /etc/resolv.conf to how it was before pppd modified it, + for example when booting a system after a crash while pppd was running while + using the 'usepeerdns' option without resolvconf. This functionality has not + worked in a stable release since Debian Squeeze, released in July 2014. + + If you use 'usepeerdns' I strongly recommend using it with resolvconf, or + managing pppd with a tool such as NetworkManager instead. + + The usepeerdns functionality has *not* been removed, only the fallback + mechanism during boot which restores resolv.conf. + + -- Chris Boot Mon, 03 Feb 2020 12:05:07 +0100 diff -Nru ppp-2.4.7/debian/patches/0001-abort-on-errors-in-subdir-builds.patch ppp-2.4.9/debian/patches/0001-abort-on-errors-in-subdir-builds.patch --- ppp-2.4.7/debian/patches/0001-abort-on-errors-in-subdir-builds.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0001-abort-on-errors-in-subdir-builds.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,48 +0,0 @@ -From 5e90783d11a59268e05f4cfb29ce2343b13e8ab2 Mon Sep 17 00:00:00 2001 -From: Martin von Gagern -Date: Sat, 9 Aug 2014 22:44:45 -0400 -Subject: [PATCH 01/16] abort on errors in subdir builds - -The current recursive loops do not check the exit status of make -in subdirs which leads to `make` passing even when a subdir failed -to compile or install. - -URL: https://bugs.gentoo.org/334727 -Signed-off-by: Martin von Gagern -Signed-off-by: Mike Frysinger ---- - pppd/plugins/Makefile.linux | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/pppd/plugins/Makefile.linux b/pppd/plugins/Makefile.linux -index ab8cf50d9472..8a90e393a057 100644 ---- a/pppd/plugins/Makefile.linux -+++ b/pppd/plugins/Makefile.linux -@@ -27,7 +27,7 @@ include .depend - endif - - all: $(PLUGINS) -- for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d all; done -+ for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d all || exit $$?; done - - %.so: %.c - $(CC) -o $@ $(LDFLAGS) $(CFLAGS) $^ -@@ -37,12 +37,12 @@ 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; done -+ 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; done -+ 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; done -+ for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d depend || exit $$?; done --- -2.15.1 - diff -Nru ppp-2.4.7/debian/patches/0002-pppd-add-support-for-defaultroute-metric-option.patch ppp-2.4.9/debian/patches/0002-pppd-add-support-for-defaultroute-metric-option.patch --- ppp-2.4.7/debian/patches/0002-pppd-add-support-for-defaultroute-metric-option.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0002-pppd-add-support-for-defaultroute-metric-option.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,165 +0,0 @@ -From 35e5a569c988b1ff865b02a24d9a727a00db4da9 Mon Sep 17 00:00:00 2001 -From: Natanael Copa -Date: Tue, 3 Jun 2014 08:53:47 +0000 -Subject: [PATCH 02/16] pppd: add support for defaultroute-metric option - -This allows user to specify the 'metric' (or 'prio') for the default -route set by pppd. This is useful in multi-ISP setups where there -might be more than one default gateway. - -Signed-off-by: Natanael Copa ---- - pppd/options.c | 5 +++++ - pppd/pppd.8 | 6 ++++++ - pppd/sys-linux.c | 28 +++++++++++++++++++--------- - 3 files changed, 30 insertions(+), 9 deletions(-) - -diff --git a/pppd/options.c b/pppd/options.c -index 45fa742cd9ce..ca3f8750c8bb 100644 ---- a/pppd/options.c -+++ b/pppd/options.c -@@ -121,6 +121,7 @@ bool dryrun; /* print out option values and exit */ - char *domain; /* domain name set by domain option */ - int child_wait = 5; /* # seconds to wait for children at exit */ - struct userenv *userenv_list; /* user environment variables */ -+int dfl_route_metric = -1; /* metric of the default route to set over the PPP link */ - - #ifdef MAXOCTETS - unsigned int maxoctets = 0; /* default - no limit */ -@@ -299,6 +300,10 @@ option_t general_options[] = { - "Unset user environment variable", - OPT_A2PRINTER | OPT_NOPRINT, (void *)user_unsetprint }, - -+ { "defaultroute-metric", o_int, &dfl_route_metric, -+ "Metric to use for the default route (Linux only; -1 for default behavior)", -+ OPT_PRIV|OPT_LLIMIT|OPT_INITONLY, NULL, 0, -1 }, -+ - #ifdef HAVE_MULTILINK - { "multilink", o_bool, &multilink, - "Enable multilink operation", OPT_PRIO | 1 }, -diff --git a/pppd/pppd.8 b/pppd/pppd.8 -index e2768b135273..c508d277df3a 100644 ---- a/pppd/pppd.8 -+++ b/pppd/pppd.8 -@@ -121,6 +121,12 @@ the gateway, when IPCP negotiation is successfully completed. - This entry is removed when the PPP connection is broken. This option - is privileged if the \fInodefaultroute\fR option has been specified. - .TP -+.B defaultroute-metric -+Define the metric of the \fIdefaultroute\fR and only add it if there -+is no other default route with the same metric. With the default -+value of -1, the route is only added if there is no default route at -+all. -+.TP - .B disconnect \fIscript - Execute the command specified by \fIscript\fR, by passing it to a - shell, after -diff --git a/pppd/sys-linux.c b/pppd/sys-linux.c -index 72a7727c403f..37bdda4d7818 100644 ---- a/pppd/sys-linux.c -+++ b/pppd/sys-linux.c -@@ -232,7 +232,7 @@ static int baud_rate_of (int speed); - static void close_route_table (void); - static int open_route_table (void); - static int read_route_table (struct rtentry *rt); --static int defaultroute_exists (struct rtentry *rt); -+static int defaultroute_exists (struct rtentry *rt, int metric); - static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr, - char *name, int namelen); - static void decode_version (char *buf, int *version, int *mod, int *patch); -@@ -242,6 +242,8 @@ static int make_ppp_unit(void); - - extern u_char inpacket_buf[]; /* borrowed from main.c */ - -+extern int dfl_route_metric; -+ - /* - * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, - * if it exists. -@@ -1439,7 +1441,7 @@ static char *path_to_procfs(const char *tail) - FILE *route_fd = (FILE *) 0; - static char route_buffer[512]; - static int route_dev_col, route_dest_col, route_gw_col; --static int route_flags_col, route_mask_col; -+static int route_flags_col, route_metric_col, route_mask_col; - static int route_num_cols; - - static int open_route_table (void); -@@ -1482,6 +1484,7 @@ static int open_route_table (void) - route_dest_col = 1; - route_gw_col = 2; - route_flags_col = 3; -+ route_metric_col = 6; - route_mask_col = 7; - route_num_cols = 8; - -@@ -1542,6 +1545,7 @@ static int read_route_table(struct rtentry *rt) - SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16); - - rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16); -+ rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10); - rt->rt_dev = cols[route_dev_col]; - - return 1; -@@ -1550,9 +1554,10 @@ static int read_route_table(struct rtentry *rt) - /******************************************************************** - * - * defaultroute_exists - determine if there is a default route -+ * with the given metric (or negative for any) - */ - --static int defaultroute_exists (struct rtentry *rt) -+static int defaultroute_exists (struct rtentry *rt, int metric) - { - int result = 0; - -@@ -1565,7 +1570,8 @@ static int defaultroute_exists (struct rtentry *rt) - - if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0) - continue; -- if (SIN_ADDR(rt->rt_dst) == 0L) { -+ if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0 -+ || rt->rt_metric == metric)) { - result = 1; - break; - } -@@ -1612,13 +1618,13 @@ int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) - { - struct rtentry rt; - -- if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) { -+ if (defaultroute_exists(&rt, dfl_route_metric) && strcmp(rt.rt_dev, ifname) != 0) { - if (rt.rt_flags & RTF_GATEWAY) -- error("not replacing existing default route via %I", -- SIN_ADDR(rt.rt_gateway)); -+ error("not replacing existing default route via %I with metric %d", -+ SIN_ADDR(rt.rt_gateway), dfl_route_metric); - else -- error("not replacing existing default route through %s", -- rt.rt_dev); -+ error("not replacing existing default route through %s with metric %d", -+ rt.rt_dev, dfl_route_metric); - return 0; - } - -@@ -1626,6 +1632,7 @@ int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) - SET_SA_FAMILY (rt.rt_dst, AF_INET); - - rt.rt_dev = ifname; -+ rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */ - - if (kernel_version > KVERSION(2,1,0)) { - SET_SA_FAMILY (rt.rt_genmask, AF_INET); -@@ -1660,6 +1667,9 @@ int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) - - rt.rt_dev = ifname; - -+ rt.rt_dev = ifname; -+ rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */ -+ - if (kernel_version > KVERSION(2,1,0)) { - SET_SA_FAMILY (rt.rt_genmask, AF_INET); - SIN_ADDR(rt.rt_genmask) = 0L; --- -2.15.1 - diff -Nru ppp-2.4.7/debian/patches/0003-scripts-Avoid-killing-wrong-pppd.patch ppp-2.4.9/debian/patches/0003-scripts-Avoid-killing-wrong-pppd.patch --- ppp-2.4.7/debian/patches/0003-scripts-Avoid-killing-wrong-pppd.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0003-scripts-Avoid-killing-wrong-pppd.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,29 +0,0 @@ -From 67811a647d399db5d188a242827760615a0f86b5 Mon Sep 17 00:00:00 2001 -From: radaiming -Date: Sat, 13 Dec 2014 14:42:34 +0800 -Subject: [PATCH 03/16] scripts: Avoid killing wrong pppd - - poff could kill other pppd processes when there are many pppd - running on different serial port. - - Signed-off-by: Ming Dai ---- - scripts/poff | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/scripts/poff b/scripts/poff -index 3f55a7f40010..5b45d98a2b6a 100644 ---- a/scripts/poff -+++ b/scripts/poff -@@ -91,7 +91,7 @@ if test "$#" -eq 0 -o "$MODE" = "all" ; then - fi - - # There is an argument, so kill the pppd started on that provider. --PID=`ps axw | grep "[ /]pppd call $1" | awk '{print $1}'` -+PID=`ps axw | grep "[ /]pppd call $1" | grep -w "$1" | awk '{print $1}'` - if test -n "$PID" ; then - $KILL -$SIG $PID || { - echo "$0: $KILL failed. None ${DONE}." --- -2.15.1 - diff -Nru ppp-2.4.7/debian/patches/0004-pppd-Fix-sign-extension-when-displaying-bytes-in-oct.patch ppp-2.4.9/debian/patches/0004-pppd-Fix-sign-extension-when-displaying-bytes-in-oct.patch --- ppp-2.4.7/debian/patches/0004-pppd-Fix-sign-extension-when-displaying-bytes-in-oct.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0004-pppd-Fix-sign-extension-when-displaying-bytes-in-oct.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,30 +0,0 @@ -From 5e8c3cb256a7e86e3572a82a75d51c6850efdbdc Mon Sep 17 00:00:00 2001 -From: "Philip A. Prindeville" -Date: Fri, 19 Dec 2014 17:52:58 -0700 -Subject: [PATCH 04/16] pppd: Fix sign-extension when displaying bytes in octal - -print_string() displays characters as \\%.03o but without first -casting it from "char" to "unsigned char" so it gets sign-extended -to an int. This causes output like \37777777630 instead of \230. - -Signed-off-by: Philip A. Prindeville ---- - pppd/utils.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/pppd/utils.c b/pppd/utils.c -index 29bf970905d5..3ac1b60926d2 100644 ---- a/pppd/utils.c -+++ b/pppd/utils.c -@@ -625,7 +625,7 @@ print_string(p, len, printer, arg) - printer(arg, "\\t"); - break; - default: -- printer(arg, "\\%.3o", c); -+ printer(arg, "\\%.3o", (unsigned char) c); - } - } - } --- -2.15.1 - diff -Nru ppp-2.4.7/debian/patches/0005-Suppress-false-error-message-on-PPPoE-disconnect.patch ppp-2.4.9/debian/patches/0005-Suppress-false-error-message-on-PPPoE-disconnect.patch --- ppp-2.4.7/debian/patches/0005-Suppress-false-error-message-on-PPPoE-disconnect.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0005-Suppress-false-error-message-on-PPPoE-disconnect.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,33 +0,0 @@ -From 219aac3b53d0827549377f1bfe22853ee52d4405 Mon Sep 17 00:00:00 2001 -From: Simon Farnsworth -Date: Sun, 1 Mar 2015 11:49:06 +0000 -Subject: [PATCH 05/16] Suppress false error message on PPPoE disconnect - -Once the kernel handles PPPoE PADTs correctly[1], a PADT triggered -disconnect will result in EALREADY when pppd tries to clear the session ID. - -Simply ignore the error if, and only if, the error is EALREADY - -[1] https://patchwork.ozlabs.org/patch/444717/ - -Signed-off-by: Simon Farnsworth ---- - pppd/plugins/rp-pppoe/plugin.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/pppd/plugins/rp-pppoe/plugin.c b/pppd/plugins/rp-pppoe/plugin.c -index a8c2bb4f4a6a..da50cdf2b9d3 100644 ---- a/pppd/plugins/rp-pppoe/plugin.c -+++ b/pppd/plugins/rp-pppoe/plugin.c -@@ -270,7 +270,7 @@ PPPOEDisconnectDevice(void) - memcpy(sp.sa_addr.pppoe.dev, conn->ifName, IFNAMSIZ); - memcpy(sp.sa_addr.pppoe.remote, conn->peerEth, ETH_ALEN); - if (connect(conn->sessionSocket, (struct sockaddr *) &sp, -- sizeof(struct sockaddr_pppox)) < 0) -+ sizeof(struct sockaddr_pppox)) < 0 && errno != EALREADY) - error("Failed to disconnect PPPoE socket: %d %m", errno); - close(conn->sessionSocket); - /* don't send PADT?? */ --- -2.15.1 - diff -Nru ppp-2.4.7/debian/patches/0006-Send-PADT-on-PPPoE-disconnect.patch ppp-2.4.9/debian/patches/0006-Send-PADT-on-PPPoE-disconnect.patch --- ppp-2.4.7/debian/patches/0006-Send-PADT-on-PPPoE-disconnect.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0006-Send-PADT-on-PPPoE-disconnect.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,31 +0,0 @@ -From cd2c14f998c57bbe6a01dc5854f2763c0d7f31fb Mon Sep 17 00:00:00 2001 -From: Simon Farnsworth -Date: Sun, 1 Mar 2015 11:53:58 +0000 -Subject: [PATCH 06/16] Send PADT on PPPoE disconnect - -Once we've terminated the PPP session, there is no chance of a PPP layer -disconnect. Some PPPoE relays don't detect the PPP session going down, and -depend on a long timeout or a PPPoE PADT to terminate the session. - -Send a PADT on disconnect to work around these buggy relays. - -Signed-off-by: Simon Farnsworth ---- - pppd/plugins/rp-pppoe/plugin.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - ---- a/pppd/plugins/rp-pppoe/plugin.c -+++ b/pppd/plugins/rp-pppoe/plugin.c -@@ -273,9 +273,10 @@ - sizeof(struct sockaddr_pppox)) < 0 && errno != EALREADY) - error("Failed to disconnect PPPoE socket: %d %m", errno); - close(conn->sessionSocket); -- /* don't send PADT?? */ -- if (conn->discoverySocket >= 0) -+ if (conn->discoverySocket >= 0) { -+ sendPADT(conn, NULL); - close(conn->discoverySocket); -+ } - } - - static void diff -Nru ppp-2.4.7/debian/patches/0007-pppd-ipxcp-Prevent-buffer-overrun-on-remote-router-n.patch ppp-2.4.9/debian/patches/0007-pppd-ipxcp-Prevent-buffer-overrun-on-remote-router-n.patch --- ppp-2.4.7/debian/patches/0007-pppd-ipxcp-Prevent-buffer-overrun-on-remote-router-n.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0007-pppd-ipxcp-Prevent-buffer-overrun-on-remote-router-n.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,31 +0,0 @@ -From fe149de624f96629a7f46732055d8f718c74b856 Mon Sep 17 00:00:00 2001 -From: Paul Mackerras -Date: Fri, 14 Aug 2015 17:56:26 +1000 -Subject: [PATCH 07/16] pppd: ipxcp: Prevent buffer overrun on remote router - name - -This fixes an if condition to prevent a possible 1-byte overrun -on ipxcp_hisoptions[0].name. - -Reported-by: "Sabas Rosales, Blanca E" -Signed-off-by: Paul Mackerras ---- - pppd/ipxcp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/pppd/ipxcp.c b/pppd/ipxcp.c -index 7b2343e15537..aaff10f76200 100644 ---- a/pppd/ipxcp.c -+++ b/pppd/ipxcp.c -@@ -1194,7 +1194,7 @@ ipxcp_reqci(f, inp, len, reject_if_disagree) - case IPX_ROUTER_NAME: - if (cilen >= CILEN_NAME) { - int name_size = cilen - CILEN_NAME; -- if (name_size > sizeof (ho->name)) -+ if (name_size >= sizeof (ho->name)) - name_size = sizeof (ho->name) - 1; - memset (ho->name, 0, sizeof (ho->name)); - memcpy (ho->name, p, name_size); --- -2.15.1 - diff -Nru ppp-2.4.7/debian/patches/0008-pppd-Fix-ccp_options.mppe-type.patch ppp-2.4.9/debian/patches/0008-pppd-Fix-ccp_options.mppe-type.patch --- ppp-2.4.7/debian/patches/0008-pppd-Fix-ccp_options.mppe-type.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0008-pppd-Fix-ccp_options.mppe-type.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,30 +0,0 @@ -From 234edab99a6bb250cc9ecd384cca27b0c8b475ce Mon Sep 17 00:00:00 2001 -From: Sylvain Rochet -Date: Wed, 25 Mar 2015 00:25:18 +0100 -Subject: [PATCH 08/16] pppd: Fix ccp_options.mppe type - -This corrects the type of ccp_options.mppe; it is actually a bitfield of -MPPE_OPT_* and not a boolean. - -Signed-off-by: Sylvain Rochet -Signed-off-by: Paul Mackerras ---- - pppd/ccp.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/pppd/ccp.h b/pppd/ccp.h -index 6f4a2fee0a2c..76446db007c0 100644 ---- a/pppd/ccp.h -+++ b/pppd/ccp.h -@@ -37,7 +37,7 @@ typedef struct ccp_options { - bool predictor_2; /* do Predictor-2? */ - bool deflate_correct; /* use correct code for deflate? */ - bool deflate_draft; /* use draft RFC code for deflate? */ -- bool mppe; /* do MPPE? */ -+ u_char mppe; /* MPPE bitfield */ - u_short bsd_bits; /* # bits/code for BSD Compress */ - u_short deflate_size; /* lg(window size) for Deflate */ - short method; /* code for chosen compression method */ --- -2.15.1 - diff -Nru ppp-2.4.7/debian/patches/0009-pppd-Fix-ccp_cilen-calculated-size-if-both-deflate_c.patch ppp-2.4.9/debian/patches/0009-pppd-Fix-ccp_cilen-calculated-size-if-both-deflate_c.patch --- ppp-2.4.7/debian/patches/0009-pppd-Fix-ccp_cilen-calculated-size-if-both-deflate_c.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0009-pppd-Fix-ccp_cilen-calculated-size-if-both-deflate_c.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,33 +0,0 @@ -From 094cb8ae4c61db225e67fedadb4964f846dd0c27 Mon Sep 17 00:00:00 2001 -From: Sylvain Rochet -Date: Tue, 24 Mar 2015 21:21:40 +0100 -Subject: [PATCH 09/16] pppd: Fix ccp_cilen calculated size if both - deflate_correct and deflate_draft are enabled - -This fixes a bug where ccp_cilen() will return 4 bytes less than -necessary for the addci buffer if both deflate_correct and -deflate_draft are enabled. - -Signed-off-by: Sylvain Rochet -Signed-off-by: Paul Mackerras ---- - pppd/ccp.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/pppd/ccp.c b/pppd/ccp.c -index 5814f358eb44..7d7922afcfc0 100644 ---- a/pppd/ccp.c -+++ b/pppd/ccp.c -@@ -676,7 +676,8 @@ ccp_cilen(f) - ccp_options *go = &ccp_gotoptions[f->unit]; - - return (go->bsd_compress? CILEN_BSD_COMPRESS: 0) -- + (go->deflate? CILEN_DEFLATE: 0) -+ + (go->deflate && go->deflate_correct? CILEN_DEFLATE: 0) -+ + (go->deflate && go->deflate_draft? CILEN_DEFLATE: 0) - + (go->predictor_1? CILEN_PREDICTOR_1: 0) - + (go->predictor_2? CILEN_PREDICTOR_2: 0) - + (go->mppe? CILEN_MPPE: 0); --- -2.15.1 - diff -Nru ppp-2.4.7/debian/patches/0010-Fix-a-typo-in-comment.-Diff-from-Yuuichi-Someya.patch ppp-2.4.9/debian/patches/0010-Fix-a-typo-in-comment.-Diff-from-Yuuichi-Someya.patch --- ppp-2.4.7/debian/patches/0010-Fix-a-typo-in-comment.-Diff-from-Yuuichi-Someya.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0010-Fix-a-typo-in-comment.-Diff-from-Yuuichi-Someya.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,25 +0,0 @@ -From f831f27c309fb2f4dfca3336a9f144993e02c225 Mon Sep 17 00:00:00 2001 -From: YASUOKA Masahiko -Date: Wed, 16 Mar 2016 13:39:19 +0900 -Subject: [PATCH 10/16] Fix a typo in comment. Diff from Yuuichi Someya. - ---- - pppd/fsm.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/pppd/fsm.c b/pppd/fsm.c -index c200cc3a8438..e9bd34f0e8f4 100644 ---- a/pppd/fsm.c -+++ b/pppd/fsm.c -@@ -468,7 +468,7 @@ fsm_rconfreq(f, id, inp, len) - f->nakloops = 0; - - } else { -- /* we sent CONFACK or CONFREJ */ -+ /* we sent CONFNAK or CONFREJ */ - if (f->state != ACKRCVD) - f->state = REQSENT; - if( code == CONFNAK ) --- -2.15.1 - diff -Nru ppp-2.4.7/debian/patches/0011-plog-count-only-relevant-lines-from-syslog.patch ppp-2.4.9/debian/patches/0011-plog-count-only-relevant-lines-from-syslog.patch --- ppp-2.4.7/debian/patches/0011-plog-count-only-relevant-lines-from-syslog.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0011-plog-count-only-relevant-lines-from-syslog.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,24 +0,0 @@ -From 2ecc3c7ce01d01e514c8a514b16c45aec1d5613f Mon Sep 17 00:00:00 2001 -From: Dmitry Deshevoy -Date: Thu, 31 Mar 2016 23:39:32 +0400 -Subject: [PATCH 11/16] plog: count only relevant lines from syslog - -Closes paulusmack/ppp#42 ---- - scripts/plog | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/scripts/plog b/scripts/plog -index 84d2c7340cc6..7cb53346413d 100644 ---- a/scripts/plog -+++ b/scripts/plog -@@ -3,5 +3,5 @@ - if [ -s /var/log/ppp.log ]; then - exec tail "$@" /var/log/ppp.log - else -- exec tail "$@" /var/log/syslog | grep ' \(pppd\|chat\)\[' -+ exec grep ' \(pppd\|chat\)\[' /var/log/syslog | tail "$@" - fi --- -2.15.1 - diff -Nru ppp-2.4.7/debian/patches/0012-Change-include-from-sys-errno.h-to-errno.h.patch ppp-2.4.9/debian/patches/0012-Change-include-from-sys-errno.h-to-errno.h.patch --- ppp-2.4.7/debian/patches/0012-Change-include-from-sys-errno.h-to-errno.h.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0012-Change-include-from-sys-errno.h-to-errno.h.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,33 +0,0 @@ -From 56a4760236ee0a606075404c5704801feffa646c Mon Sep 17 00:00:00 2001 -From: Stefan Nickl -Date: Wed, 10 Aug 2016 21:32:21 +0200 -Subject: [PATCH 12/16] Change include from sys/errno.h to errno.h - -According to POSIX, the canonical location for errno.h is on the top level. - -Signed-off-by: Stefan Nickl ---- - pppd/sys-linux.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/pppd/sys-linux.c b/pppd/sys-linux.c -index b4a435d2a993..20b42ac3e80c 100644 ---- a/pppd/sys-linux.c -+++ b/pppd/sys-linux.c -@@ -73,12 +73,12 @@ - #include - #include - #include --#include - #include - #include - #include - #include - -+#include - #include - #include - #include --- -2.15.1 - diff -Nru ppp-2.4.7/debian/patches/0013-pppd-allow-use-of-arbitrary-interface-names.patch ppp-2.4.9/debian/patches/0013-pppd-allow-use-of-arbitrary-interface-names.patch --- ppp-2.4.7/debian/patches/0013-pppd-allow-use-of-arbitrary-interface-names.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0013-pppd-allow-use-of-arbitrary-interface-names.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,214 +0,0 @@ -From bbcdc4366bbee6c3f4e1ddda31e4eec8c1b3ccc2 Mon Sep 17 00:00:00 2001 -From: Paul Mackerras -Date: Tue, 23 Aug 2016 16:10:21 +1000 -Subject: [PATCH 13/16] pppd: allow use of arbitrary interface names - -This is a modified version of a patch from openSUSE that enables PPP interfaces -to be called arbitrary names, rather than simply pppX where X is the unit -number. - -The modifications from the stock openSUSE patch are: -- refresh patch on top of 018_ip-up_option.diff -- fix a printf format-string vulnerability in pppd/main.c:set_ifunit() -- clarify the pppd.8 manpage additions -- patch pppstats/pppstats.c to query renamed interfaces without complaint - -Origin: SUSE -Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=458646 -Forwarded: no -Reviewed-by: Chris Boot -Signed-off-by: Paul Mackerras ---- - pppd/main.c | 16 ++++++---------- - pppd/options.c | 5 +++++ - pppd/pppd.8 | 8 +++++++- - pppd/pppd.h | 11 +++++++++++ - pppd/sys-linux.c | 15 +++++++++++++++ - pppstats/pppstats.c | 12 ++++++------ - 6 files changed, 50 insertions(+), 17 deletions(-) - -diff --git a/pppd/main.c b/pppd/main.c -index 6d50d1bac1d9..f1986ed68d0b 100644 ---- a/pppd/main.c -+++ b/pppd/main.c -@@ -124,7 +124,7 @@ - static const char rcsid[] = RCSID; - - /* interface vars */ --char ifname[32]; /* Interface name */ -+char ifname[MAXIFNAMELEN]; /* Interface name */ - int ifunit; /* Interface unit number */ - - struct channel *the_channel; -@@ -298,13 +298,6 @@ struct protent *protocols[] = { - NULL - }; - --/* -- * If PPP_DRV_NAME is not defined, use the default "ppp" as the device name. -- */ --#if !defined(PPP_DRV_NAME) --#define PPP_DRV_NAME "ppp" --#endif /* !defined(PPP_DRV_NAME) */ -- - int - main(argc, argv) - int argc; -@@ -737,8 +730,11 @@ void - set_ifunit(iskey) - int iskey; - { -- info("Using interface %s%d", PPP_DRV_NAME, ifunit); -- slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit); -+ if (req_ifname[0] != '\0') -+ slprintf(ifname, sizeof(ifname), "%s", req_ifname); -+ else -+ slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit); -+ info("Using interface %s", ifname); - script_setenv("IFNAME", ifname, iskey); - if (iskey) { - create_pidfile(getpid()); /* write pid to file */ -diff --git a/pppd/options.c b/pppd/options.c -index c06a2b4ad8ed..177488ca6813 100644 ---- a/pppd/options.c -+++ b/pppd/options.c -@@ -114,6 +114,7 @@ char linkname[MAXPATHLEN]; /* logical name for link */ - bool tune_kernel; /* may alter kernel settings */ - int connect_delay = 1000; /* wait this many ms after connect script */ - int req_unit = -1; /* requested interface unit */ -+char req_ifname[MAXIFNAMELEN]; /* requested interface name */ - bool multilink = 0; /* Enable multilink operation */ - char *bundle_name = NULL; /* bundle name for multilink */ - bool dump_options; /* print out option values */ -@@ -284,6 +285,10 @@ option_t general_options[] = { - "PPP interface unit number to use if possible", - OPT_PRIO | OPT_LLIMIT, 0, 0 }, - -+ { "ifname", o_string, req_ifname, -+ "Set PPP interface name", -+ OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXIFNAMELEN }, -+ - { "dump", o_bool, &dump_options, - "Print out option values after parsing all options", 1 }, - { "dryrun", o_bool, &dryrun, -diff --git a/pppd/pppd.8 b/pppd/pppd.8 -index c508d277df3a..06e945fce998 100644 ---- a/pppd/pppd.8 -+++ b/pppd/pppd.8 -@@ -1079,7 +1079,13 @@ under Linux and FreeBSD 2.2.8 and later. - .TP - .B unit \fInum - Sets the ppp unit number (for a ppp0 or ppp1 etc interface name) for outbound --connections. -+connections. If the unit is already in use a dynamically allocated number will -+be used. -+.TP -+.B ifname \fIstring -+Set the ppp interface name for outbound connections. If the interface name is -+already in use, or if the name cannot be used for any other reason, pppd will -+terminate. - .TP - .B unset \fIname - Remove a variable from the environment variable for scripts that are -diff --git a/pppd/pppd.h b/pppd/pppd.h -index 247fa153739b..1a1bf0b99582 100644 ---- a/pppd/pppd.h -+++ b/pppd/pppd.h -@@ -80,6 +80,16 @@ - #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. -+ * Where should PPP_DRV_NAME come from? Do we include it here? -+ */ -+#if !defined(PPP_DRV_NAME) -+#define PPP_DRV_NAME "ppp" -+#endif /* !defined(PPP_DRV_NAME) */ - - /* - * Option descriptor structure. -@@ -318,6 +328,7 @@ extern bool tune_kernel; /* May alter kernel settings as necessary */ - extern int connect_delay; /* Time to delay after connect script */ - extern int max_data_rate; /* max bytes/sec through charshunt */ - extern int req_unit; /* interface unit number to use */ -+extern char req_ifname[MAXIFNAMELEN]; /* 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 */ -diff --git a/pppd/sys-linux.c b/pppd/sys-linux.c -index b4a435d2a993..b832031f7e26 100644 ---- a/pppd/sys-linux.c -+++ b/pppd/sys-linux.c -@@ -643,6 +643,21 @@ static int make_ppp_unit() - } - if (x < 0) - error("Couldn't create new ppp unit: %m"); -+ -+ if (x == 0 && req_ifname[0] != '\0') { -+ struct ifreq ifr; -+ char t[MAXIFNAMELEN]; -+ memset(&ifr, 0, sizeof(struct ifreq)); -+ slprintf(t, sizeof(t), "%s%d", PPP_DRV_NAME, ifunit); -+ strncpy(ifr.ifr_name, t, IF_NAMESIZE); -+ strncpy(ifr.ifr_newname, req_ifname, IF_NAMESIZE); -+ x = ioctl(sock_fd, SIOCSIFNAME, &ifr); -+ if (x < 0) -+ error("Couldn't rename interface %s to %s: %m", t, req_ifname); -+ else -+ info("Renamed interface %s to %s", t, req_ifname); -+ } -+ - return x; - } - -diff --git a/pppstats/pppstats.c b/pppstats/pppstats.c -index 6367988eb96b..46cb9c24942b 100644 ---- a/pppstats/pppstats.c -+++ b/pppstats/pppstats.c -@@ -88,7 +88,6 @@ int aflag; /* print absolute values, not deltas */ - int dflag; /* print data rates, not bytes */ - int interval, count; - int infinite; --int unit; - int s; /* socket or /dev/ppp file descriptor */ - int signalled; /* set if alarm goes off "early" */ - char *progname; -@@ -449,6 +448,7 @@ main(argc, argv) - { - int c; - #ifdef STREAMS -+ int unit; - char *dev; - #endif - -@@ -506,11 +506,6 @@ main(argc, argv) - if (argc > 0) - interface = argv[0]; - -- if (sscanf(interface, PPP_DRV_NAME "%d", &unit) != 1) { -- fprintf(stderr, "%s: invalid interface '%s' specified\n", -- progname, interface); -- } -- - #ifndef STREAMS - { - struct ifreq ifr; -@@ -535,6 +530,11 @@ main(argc, argv) - } - - #else /* STREAMS */ -+ if (sscanf(interface, PPP_DRV_NAME "%d", &unit) != 1) { -+ fprintf(stderr, "%s: invalid interface '%s' specified\n", -+ progname, interface); -+ } -+ - #ifdef __osf__ - dev = "/dev/streams/ppp"; - #else --- -2.15.1 - diff -Nru ppp-2.4.7/debian/patches/0014-pppd-Remove-unused-declaration-of-ttyname.patch ppp-2.4.9/debian/patches/0014-pppd-Remove-unused-declaration-of-ttyname.patch --- ppp-2.4.7/debian/patches/0014-pppd-Remove-unused-declaration-of-ttyname.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0014-pppd-Remove-unused-declaration-of-ttyname.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,25 +0,0 @@ -From 66ae569f1c6fb12df8a463c8beb9afc0c7e5f7f0 Mon Sep 17 00:00:00 2001 -From: George Burgess IV -Date: Fri, 9 Sep 2016 17:36:54 -0700 -Subject: [PATCH 14/16] pppd: Remove unused declaration of ttyname. - -Signed-off-by: George Burgess IV ---- - pppd/main.c | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/pppd/main.c b/pppd/main.c -index 6d50d1bac1d9..aef9e8477592 100644 ---- a/pppd/main.c -+++ b/pppd/main.c -@@ -257,7 +257,6 @@ static void cleanup_db __P((void)); - static void handle_events __P((void)); - void print_link_stats __P((void)); - --extern char *ttyname __P((int)); - extern char *getlogin __P((void)); - int main __P((int, char *[])); - --- -2.15.1 - diff -Nru ppp-2.4.7/debian/patches/0015-pppd-Provide-error-implementation-in-pppoe-discovery.patch ppp-2.4.9/debian/patches/0015-pppd-Provide-error-implementation-in-pppoe-discovery.patch --- ppp-2.4.7/debian/patches/0015-pppd-Provide-error-implementation-in-pppoe-discovery.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0015-pppd-Provide-error-implementation-in-pppoe-discovery.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,52 +0,0 @@ -From b7b97dea6eb042fae0dfaca39cbb190411e5fd31 Mon Sep 17 00:00:00 2001 -From: Stefan Nickl -Date: Wed, 10 Aug 2016 16:52:12 +0200 -Subject: [PATCH 15/16] pppd: Provide error() implementation in pppoe-discovery - -The pppoe-discovery program calls error() from the CHECK_ROOM macro -defined in pppoe.h. Since pppoe-discovery is a standalone program not -linked with the rest of pppd, the only way this could build is by -linking to glibc's proprietary error(3) function instead of the function -of the same name (but with different arguments) defined in pppd/utils.c. - -So with glibc this builds, but will probably crash when the assertion is -triggered. As the assertion is unlikely to fail, nobody has noticed. - -The build however fails with musl libc or uClibc since they don't -provide the doppelganger. - -Signed-off-by: Stefan Nickl ---- - pppd/plugins/rp-pppoe/pppoe-discovery.c | 9 +++++++++ - 1 file changed, 9 insertions(+) - -diff --git a/pppd/plugins/rp-pppoe/pppoe-discovery.c b/pppd/plugins/rp-pppoe/pppoe-discovery.c -index 3d3bf4eecc81..55037dffb023 100644 ---- a/pppd/plugins/rp-pppoe/pppoe-discovery.c -+++ b/pppd/plugins/rp-pppoe/pppoe-discovery.c -@@ -9,6 +9,7 @@ - * - */ - -+#include - #include - #include - #include -@@ -55,6 +56,14 @@ void die(int status) - exit(status); - } - -+void error(char *fmt, ...) -+{ -+ va_list pvar; -+ va_start(pvar, fmt); -+ vfprintf(stderr, fmt, pvar); -+ va_end(pvar); -+} -+ - /* Initialize frame types to RFC 2516 values. Some broken peers apparently - use different frame types... sigh... */ - --- -2.15.1 - diff -Nru ppp-2.4.7/debian/patches/0016-pppoe-include-netinet-in.h-before-linux-in.h.patch ppp-2.4.9/debian/patches/0016-pppoe-include-netinet-in.h-before-linux-in.h.patch --- ppp-2.4.7/debian/patches/0016-pppoe-include-netinet-in.h-before-linux-in.h.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/0016-pppoe-include-netinet-in.h-before-linux-in.h.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,49 +0,0 @@ -From 50a2997b256e0e0ef7a46fae133f56f60fce539c Mon Sep 17 00:00:00 2001 -From: Lubomir Rintel -Date: Mon, 9 Jan 2017 13:34:23 +0000 -Subject: [PATCH 16/16] pppoe: include netinet/in.h before linux/in.h - -This fixes builds with newer kernels. Basically, needs to be -included before otherwise the earlier, unaware of the latter, -tries to redefine symbols and structures. Also, doesn't work -alone anymore, since it pulls the headers in the wrong order, so we better -include early. ---- - pppd/plugins/rp-pppoe/pppoe.h | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/pppd/plugins/rp-pppoe/pppoe.h b/pppd/plugins/rp-pppoe/pppoe.h -index 9ab2eee3914c..c4aaa6e68856 100644 ---- a/pppd/plugins/rp-pppoe/pppoe.h -+++ b/pppd/plugins/rp-pppoe/pppoe.h -@@ -47,6 +47,10 @@ - #include - #endif - -+/* This has to be included before Linux 4.8's linux/in.h -+ * gets dragged in. */ -+#include -+ - /* Ugly header files on some Linux boxes... */ - #if defined(HAVE_LINUX_IF_H) - #include -@@ -84,8 +88,6 @@ typedef unsigned long UINT32_t; - #include - #endif - --#include -- - #ifdef HAVE_NETINET_IF_ETHER_H - #include - -@@ -98,7 +100,6 @@ typedef unsigned long UINT32_t; - #endif - - -- - /* Ethernet frame types according to RFC 2516 */ - #define ETH_PPPOE_DISCOVERY 0x8863 - #define ETH_PPPOE_SESSION 0x8864 --- -2.15.1 - diff -Nru ppp-2.4.7/debian/patches/018_ip-up_option.diff ppp-2.4.9/debian/patches/018_ip-up_option.diff --- ppp-2.4.7/debian/patches/018_ip-up_option.diff 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/018_ip-up_option.diff 1970-01-01 01:00:00.000000000 +0100 @@ -1,84 +0,0 @@ ---- a/pppd/ipcp.c -+++ b/pppd/ipcp.c -@@ -1984,7 +1984,7 @@ - */ - if (ipcp_script_state == s_down && ipcp_script_pid == 0) { - ipcp_script_state = s_up; -- ipcp_script(_PATH_IPUP, 0); -+ ipcp_script(path_ipup, 0); - } - } - -@@ -2034,7 +2034,7 @@ - /* Execute the ip-down script */ - if (ipcp_script_state == s_up && ipcp_script_pid == 0) { - ipcp_script_state = s_down; -- ipcp_script(_PATH_IPDOWN, 0); -+ ipcp_script(path_ipdown, 0); - } - } - -@@ -2097,13 +2097,13 @@ - case s_up: - if (ipcp_fsm[0].state != OPENED) { - ipcp_script_state = s_down; -- ipcp_script(_PATH_IPDOWN, 0); -+ ipcp_script(path_ipdown, 0); - } - break; - case s_down: - if (ipcp_fsm[0].state == OPENED) { - ipcp_script_state = s_up; -- ipcp_script(_PATH_IPUP, 0); -+ ipcp_script(path_ipup, 0); - } - break; - } ---- a/pppd/main.c -+++ b/pppd/main.c -@@ -308,6 +308,9 @@ - struct protent *protp; - char numbuf[16]; - -+ strlcpy(path_ipup, _PATH_IPUP, sizeof(path_ipup)); -+ strlcpy(path_ipdown, _PATH_IPDOWN, sizeof(path_ipdown)); -+ - link_stats_valid = 0; - new_phase(PHASE_INITIALIZE); - ---- a/pppd/options.c -+++ b/pppd/options.c -@@ -114,6 +114,8 @@ - bool tune_kernel; /* may alter kernel settings */ - int connect_delay = 1000; /* wait this many ms after connect script */ - int req_unit = -1; /* requested interface unit */ -+char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */ -+char path_ipdown[MAXPATHLEN];/* pathname of ip-down script */ - char req_ifname[MAXIFNAMELEN]; /* requested interface name */ - bool multilink = 0; /* Enable multilink operation */ - char *bundle_name = NULL; /* bundle name for multilink */ -@@ -304,6 +306,13 @@ - "Unset user environment variable", - OPT_A2PRINTER | OPT_NOPRINT, (void *)user_unsetprint }, - -+ { "ip-up-script", o_string, path_ipup, -+ "Set pathname of ip-up script", -+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN }, -+ { "ip-down-script", o_string, path_ipdown, -+ "Set pathname of ip-down script", -+ OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN }, -+ - #ifdef HAVE_MULTILINK - { "multilink", o_bool, &multilink, - "Enable multilink operation", OPT_PRIO | 1 }, ---- a/pppd/pppd.h -+++ b/pppd/pppd.h -@@ -328,6 +328,8 @@ - extern int connect_delay; /* Time to delay after connect script */ - extern int max_data_rate; /* max bytes/sec through charshunt */ - extern int req_unit; /* interface unit number to use */ -+extern char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */ -+extern char path_ipdown[MAXPATHLEN]; /* pathname of ip-down script */ - extern char req_ifname[MAXIFNAMELEN]; /* interface name to use */ - extern bool multilink; /* enable multilink operation */ - extern bool noendpoint; /* don't send or accept endpt. discrim. */ diff -Nru ppp-2.4.7/debian/patches/adaptive_echos ppp-2.4.9/debian/patches/adaptive_echos --- ppp-2.4.7/debian/patches/adaptive_echos 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/adaptive_echos 1970-01-01 01:00:00.000000000 +0100 @@ -1,56 +0,0 @@ ---- a/pppd/lcp.c -+++ b/pppd/lcp.c -@@ -73,6 +73,7 @@ static void lcp_delayed_up __P((void *)) - */ - int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ - int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ -+bool lcp_echo_adaptive = 0; /* request echo only if the link was idle */ - bool lax_recv = 0; /* accept control chars in asyncmap */ - bool noendpoint = 0; /* don't send/accept endpoint discriminator */ - -@@ -151,6 +152,8 @@ static option_t lcp_option_list[] = { - OPT_PRIO }, - { "lcp-echo-interval", o_int, &lcp_echo_interval, - "Set time in seconds between LCP echo requests", OPT_PRIO }, -+ { "lcp-echo-adaptive", o_bool, &lcp_echo_adaptive, -+ "Suppress LCP echo requests if traffic was received", 1 }, - { "lcp-restart", o_int, &lcp_fsm[0].timeouttime, - "Set time in seconds between LCP retransmissions", OPT_PRIO }, - { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits, -@@ -2331,6 +2334,22 @@ LcpSendEchoRequest (f) - } - } - -+ /* -+ * If adaptive echos have been enabled, only send the echo request if -+ * no traffic was received since the last one. -+ */ -+ if (lcp_echo_adaptive) { -+ static unsigned int last_pkts_in = 0; -+ -+ update_link_stats(f->unit); -+ link_stats_valid = 0; -+ -+ if (link_stats.pkts_in != last_pkts_in) { -+ last_pkts_in = link_stats.pkts_in; -+ return; -+ } -+ } -+ - /* - * Make and send the echo request frame. - */ ---- a/pppd/pppd.8 -+++ b/pppd/pppd.8 -@@ -557,6 +557,11 @@ to 1) if the \fIproxyarp\fR option is us - dynamic IP address option (i.e. set /proc/sys/net/ipv4/ip_dynaddr to - 1) in demand mode if the local address changes. - .TP -+.B lcp\-echo\-adaptive -+If this option is used with the \fIlcp\-echo\-failure\fR option then -+pppd will send LCP echo\-request frames only if no traffic was received -+from the peer since the last echo\-request was sent. -+.TP - .B lcp\-echo\-failure \fIn - If this option is given, pppd will presume the peer to be dead - if \fIn\fR LCP echo\-requests are sent without receiving a valid LCP diff -Nru ppp-2.4.7/debian/patches/cifdefroute.dif ppp-2.4.9/debian/patches/cifdefroute.dif --- ppp-2.4.7/debian/patches/cifdefroute.dif 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/cifdefroute.dif 1970-01-01 01:00:00.000000000 +0100 @@ -1,300 +0,0 @@ -Description: Add replacedefaultroute option - -Adds an option to pppd to control whether to replace existing default routes -when using the 'defaultroute' option. - -If defaultroute and replacedefaultroute are both set, pppd replaces an existing -default route with the new default route. The old default route is restored when -the connection is taken down. - -Origin: vendor, https://build.opensuse.org/source/network/ppp/ppp-2.4.2-cifdefroute.diff?rev=7a0fdeff0b29437dd7f4581c95c7255a -Forwarded: no -Reviewed-by: Chris Boot -Last-Update: 2014-01-26 - ---- a/pppd/ipcp.c -+++ b/pppd/ipcp.c -@@ -198,6 +198,16 @@ - "disable defaultroute option", OPT_ALIAS | OPT_A2CLR, - &ipcp_wantoptions[0].default_route }, - -+#ifdef __linux__ -+ { "replacedefaultroute", o_bool, -+ &ipcp_wantoptions[0].replace_default_route, -+ "Replace default route", 1 -+ }, -+ { "noreplacedefaultroute", o_bool, -+ &ipcp_allowoptions[0].replace_default_route, -+ "Never replace default route", OPT_A2COPY, -+ &ipcp_wantoptions[0].replace_default_route }, -+#endif - { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp, - "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp }, - { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, -@@ -271,7 +281,7 @@ - ip_active_pkt - }; - --static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t)); -+static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t, bool)); - static void ipcp_script __P((char *, int)); /* Run an up/down script */ - static void ipcp_script_done __P((void *)); - -@@ -1761,7 +1771,12 @@ - if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE)) - return 0; - if (wo->default_route) -+#ifndef __linux__ - if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr)) -+#else -+ if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr, -+ wo->replace_default_route)) -+#endif - default_route_set[u] = 1; - if (wo->proxy_arp) - if (sifproxyarp(u, wo->hisaddr)) -@@ -1849,7 +1864,8 @@ - */ - if (demand) { - if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) { -- ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr); -+ ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr, -+ wo->replace_default_route); - if (go->ouraddr != wo->ouraddr) { - warn("Local IP address changed to %I", go->ouraddr); - script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0); -@@ -1874,7 +1890,12 @@ - - /* assign a default route through the interface if required */ - if (ipcp_wantoptions[f->unit].default_route) -+#ifndef __linux__ - if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) -+#else -+ if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr, -+ wo->replace_default_route)) -+#endif - default_route_set[f->unit] = 1; - - /* Make a proxy ARP entry if requested. */ -@@ -1924,7 +1945,12 @@ - - /* assign a default route through the interface if required */ - if (ipcp_wantoptions[f->unit].default_route) -+#ifndef __linux__ - if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) -+#else -+ if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr, -+ wo->replace_default_route)) -+#endif - default_route_set[f->unit] = 1; - - /* Make a proxy ARP entry if requested. */ -@@ -2002,7 +2028,7 @@ - sifnpmode(f->unit, PPP_IP, NPMODE_DROP); - sifdown(f->unit); - ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr, -- ipcp_hisoptions[f->unit].hisaddr); -+ ipcp_hisoptions[f->unit].hisaddr, 0); - } - - /* Execute the ip-down script */ -@@ -2018,16 +2044,25 @@ - * proxy arp entries, etc. - */ - static void --ipcp_clear_addrs(unit, ouraddr, hisaddr) -+ipcp_clear_addrs(unit, ouraddr, hisaddr, replacedefaultroute) - int unit; - u_int32_t ouraddr; /* local address */ - u_int32_t hisaddr; /* remote address */ -+ bool replacedefaultroute; - { - if (proxy_arp_set[unit]) { - cifproxyarp(unit, hisaddr); - proxy_arp_set[unit] = 0; - } -- if (default_route_set[unit]) { -+ /* If replacedefaultroute, sifdefaultroute will be called soon -+ * with replacedefaultroute set and that will overwrite the current -+ * default route. This is the case only when doing demand, otherwise -+ * during demand, this cifdefaultroute would restore the old default -+ * route which is not what we want in this case. In the non-demand -+ * case, we'll delete the default route and restore the old if there -+ * is one saved by an sifdefaultroute with replacedefaultroute. -+ */ -+ if (!replacedefaultroute && default_route_set[unit]) { - cifdefaultroute(unit, ouraddr, hisaddr); - default_route_set[unit] = 0; - } ---- a/pppd/ipcp.h -+++ b/pppd/ipcp.h -@@ -70,6 +70,7 @@ - bool old_addrs; /* Use old (IP-Addresses) option? */ - bool req_addr; /* Ask peer to send IP address? */ - bool default_route; /* Assign default route through interface? */ -+ bool replace_default_route; /* Replace default route through interface? */ - bool proxy_arp; /* Make proxy ARP entry for peer? */ - bool neg_vj; /* Van Jacobson Compression? */ - bool old_vj; /* use old (short) form of VJ option? */ ---- a/pppd/pppd.8 -+++ b/pppd/pppd.8 -@@ -121,6 +121,11 @@ - This entry is removed when the PPP connection is broken. This option - is privileged if the \fInodefaultroute\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 -+with the new default route. -+.TP - .B disconnect \fIscript - Execute the command specified by \fIscript\fR, by passing it to a - shell, after -@@ -739,7 +744,12 @@ - .TP - .B nodefaultroute - Disable the \fIdefaultroute\fR option. The system administrator who --wishes to prevent users from creating default routes with pppd -+wishes to prevent users from adding a default route with pppd -+can do so by placing this option in the /etc/ppp/options file. -+.TP -+.B noreplacedefaultroute -+Disable the \fIreplacedefaultroute\fR option. The system administrator who -+wishes to prevent users from replacing a default route with pppd - can do so by placing this option in the /etc/ppp/options file. - .TP - .B nodeflate ---- a/pppd/pppd.h -+++ b/pppd/pppd.h -@@ -664,7 +664,11 @@ - int cif6addr __P((int, eui64_t, eui64_t)); - /* Remove an IPv6 address from i/f */ - #endif -+#ifndef __linux__ - int sifdefaultroute __P((int, u_int32_t, u_int32_t)); -+#else -+int sifdefaultroute __P((int, u_int32_t, u_int32_t, bool replace_default_rt)); -+#endif - /* Create default route through i/f */ - int cifdefaultroute __P((int, u_int32_t, u_int32_t)); - /* Delete default route through i/f */ ---- a/pppd/sys-linux.c -+++ b/pppd/sys-linux.c -@@ -207,6 +207,8 @@ - static int if_is_up; /* Interface has been marked up */ - static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */ - static int have_default_route; /* Gateway for default route added */ -+static struct rtentry old_def_rt; /* Old default route */ -+static int default_rt_repl_rest; /* replace and restore old default rt */ - static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ - static char proxy_arp_dev[16]; /* Device for proxy arp entry */ - static u_int32_t our_old_addr; /* for detecting address changes */ -@@ -1549,6 +1551,9 @@ - p = NULL; - } - -+ SET_SA_FAMILY (rt->rt_dst, AF_INET); -+ SET_SA_FAMILY (rt->rt_gateway, AF_INET); -+ - SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16); - SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16); - SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16); -@@ -1618,22 +1623,53 @@ - /******************************************************************** - * - * sifdefaultroute - assign a default route through the address given. -- */ -- --int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) --{ -- struct rtentry rt; -- -- if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) { -- if (rt.rt_flags & RTF_GATEWAY) -- error("not replacing existing default route via %I", -- SIN_ADDR(rt.rt_gateway)); -- else -- error("not replacing existing default route through %s", -- rt.rt_dev); -- return 0; -+ * -+ * If the global default_rt_repl_rest flag is set, then this function -+ * already replaced the original system defaultroute with some other -+ * route and it should just replace the current defaultroute with -+ * another one, without saving the current route. Use: demand mode, -+ * when pppd sets first a defaultroute it it's temporary ppp0 addresses -+ * and then changes the temporary addresses to the addresses for the real -+ * ppp connection when it has come up. -+ */ -+ -+int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace) -+{ -+ struct rtentry rt, tmp_rt; -+ struct rtentry *del_rt = NULL; -+ -+ if (default_rt_repl_rest) { -+ /* We have already reclaced the original defaultroute, if we -+ * are called again, we will delete the current default route -+ * and set the new default route in this function. -+ * - this is normally only the case the doing demand: */ -+ if (defaultroute_exists( &tmp_rt )) -+ del_rt = &tmp_rt; -+ } else if ( defaultroute_exists( &old_def_rt ) && -+ strcmp( old_def_rt.rt_dev, ifname ) != 0) { -+ /* We did not yet replace an existing default route, let's -+ * check if we should save and replace a default route: -+ */ -+ u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway); -+ -+ if (old_gateway != gateway) { -+ if (!replace) { -+ error("not replacing default route to %s [%I]", -+ old_def_rt.rt_dev, old_gateway); -+ return 0; -+ } else { -+ // we need to copy rt_dev because we need it permanent too: -+ char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1); -+ strcpy(tmp_dev, old_def_rt.rt_dev); -+ old_def_rt.rt_dev = tmp_dev; -+ -+ notice("replacing old default route to %s [%I]", -+ old_def_rt.rt_dev, old_gateway); -+ default_rt_repl_rest = 1; -+ del_rt = &old_def_rt; -+ } -+ } - } -- - memset (&rt, 0, sizeof (rt)); - SET_SA_FAMILY (rt.rt_dst, AF_INET); - -@@ -1650,6 +1686,12 @@ - error("default route ioctl(SIOCADDRT): %m"); - return 0; - } -+ if (default_rt_repl_rest && del_rt) -+ if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) { -+ if ( ! ok_error ( errno )) -+ error("del old default route ioctl(SIOCDELRT): %m(%d)", errno); -+ return 0; -+ } - - have_default_route = 1; - return 1; -@@ -1685,6 +1727,16 @@ - return 0; - } - } -+ if (default_rt_repl_rest) { -+ notice("restoring old default route to %s [%I]", -+ old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway)); -+ if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) { -+ if ( ! ok_error ( errno )) -+ error("restore default route ioctl(SIOCADDRT): %m(%d)", errno); -+ return 0; -+ } -+ default_rt_repl_rest = 0; -+ } - - return 1; - } diff -Nru ppp-2.4.7/debian/patches/close_dev_ppp ppp-2.4.9/debian/patches/close_dev_ppp --- ppp-2.4.7/debian/patches/close_dev_ppp 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/close_dev_ppp 1970-01-01 01:00:00.000000000 +0100 @@ -1,35 +0,0 @@ -be sure to close /dev/ppp when reconnecting - -From: Simon Peter -Subject: Bug#306261: pppd does not properly close /dev/ppp on persist - -When using the kernel PPPoE driver, pppd never -closes /dev/ppp when the link has come down. - -It opens superfluous fds to the device each time it re-opens the -connection, with the unclosed ones falsely reported always ready for -data by select(). - -This makes pppd eat up 100% CPU time after the first persist because of -the always instantly returning select() on the unclosed fds. - -The problem also occurs with the upstream version, but does not occur -when a pty/tty device is used for the ppp connection. - - ---- a/pppd/sys-linux.c -+++ b/pppd/sys-linux.c -@@ -453,6 +453,13 @@ int generic_establish_ppp (int fd) - if (new_style_driver) { - int flags; - -+ /* if a ppp_fd is already open, close it first */ -+ if(ppp_fd > 0) { -+ close(ppp_fd); -+ remove_fd(ppp_fd); -+ ppp_fd = -1; -+ } -+ - /* Open an instance of /dev/ppp and connect the channel to it */ - if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) { - error("Couldn't get channel number: %m"); diff -Nru ppp-2.4.7/debian/patches/eaptls-mppe.patch ppp-2.4.9/debian/patches/eaptls-mppe.patch --- ppp-2.4.7/debian/patches/eaptls-mppe.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/eaptls-mppe.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,3298 +0,0 @@ -Description: EAP-TLS authentication support for PPP -Origin: https://www.nikhef.nl/~janjust/ppp/download.html -Bug-Debian: https://bugs.debian.org/602503 -Bug-Ubuntu: https://launchpad.net/bugs/643417 -Forwarded: not-needed -Author: Jan Just Keijser -Last-Update: 2018-11-04 - -This patch is based on ppp-2.4.7-eaptls-mppe-1.102.patch, with the following -changes: - - - Patch refreshed to remove fuzz. - - Trailing spaces removed. - ---- /dev/null -+++ b/README.eap-tls -@@ -0,0 +1,291 @@ -+EAP-TLS authentication support for PPP -+====================================== -+ -+1. Intro -+ -+ The Extensible Authentication Protocol (EAP; RFC 3748) is a -+ security protocol that can be used with PPP. It provides a means -+ to plug in multiple optional authentication methods. -+ -+ Transport Level Security (TLS; RFC 5216) provides for mutual -+ authentication, integrity-protected ciphersuite negotiation and -+ key exchange between two endpoints. It also provides for optional -+ MPPE encryption. -+ -+ EAP-TLS (RFC 2716) incapsulates the TLS messages in EAP packets, -+ allowing TLS mutual authentication to be used as a generic EAP -+ mechanism. It also provides optional encryption using the MPPE -+ protocol. -+ -+ This patch provide EAP-TLS support to pppd. -+ This authentication method can be used in both client or server -+ mode. -+ -+2. Building -+ -+ To build pppd with EAP-TLS support, OpenSSL (http://www.openssl.org) -+ is required. Any version from 0.9.7 should work. -+ -+ Configure, compile, and install as usual. -+ -+3. Configuration -+ -+ On the client side there are two ways to configure EAP-TLS: -+ -+ 1. supply the appropriate 'ca', 'cert' and 'key' command-line parameters -+ -+ 2. edit the /etc/ppp/eaptls-client file. -+ Insert a line for each system with which you use EAP-TLS. -+ The line is composed of this fields separated by tab: -+ -+ - Client name -+ The name used by the client for authentication, can be * -+ - Server name -+ The name of the server, can be * -+ - Client certificate file -+ The file containing the certificate chain for the -+ client in PEM format -+ - Server certificate file -+ If you want to specify the certificate that the -+ server is allowed to use, put the certificate file name. -+ Else put a dash '-'. -+ - CA certificate file -+ The file containing the trusted CA certificates in PEM -+ format. -+ - Client private key file -+ The file containing the client private key in PEM format. -+ -+ -+ On the server side edit the /etc/ppp/eaptls-server file. -+ Insert a line for each system with which you use EAP-TLS. -+ The line is composed of this fields separated by tab: -+ -+ - Client name -+ The name used by the client for authentication, can be * -+ - Server name -+ The name of the server, can be * -+ - Client certificate file -+ If you want to specify the certificate that the -+ client is allowed to use, put the certificate file name. -+ Else put a dash '-'. -+ - Server certificate file -+ The file containing the certificate chain for the -+ server in PEM format -+ - CA certificate file -+ The file containing the trusted CA certificates in PEM format. -+ - Client private key file -+ The file containing the server private key in PEM format. -+ - addresses -+ A list of IP addresses the client is allowed to use. -+ -+ -+ OpenSSL engine support is included starting with v0.95 of this patch. -+ Currently the only engine tested is the 'pkcs11' engine (hardware token -+ support). To use the 'pksc11' engine: -+ - Use a special private key fileiname in the /etc/ppp/eaptls-client file: -+ : -+ e.g. -+ pkcs11:123456 -+ -+ - The certificate can also be loaded from the 'pkcs11' engine using -+ a special client certificate filename in the /etc/ppp/eaptls-client file: -+ : -+ e.g. -+ pkcs11:123456 -+ -+ - Create an /etc/ppp/openssl.cnf file to load the right OpenSSL engine prior -+ to starting 'pppd'. A sample openssl.cnf file is -+ -+ openssl_conf = openssl_def -+ -+ [ openssl_def ] -+ engines = engine_section -+ -+ [ engine_section ] -+ pkcs11 = pkcs11_section -+ -+ [ pkcs11_section ] -+ engine_id = pkcs11 -+ dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so -+ MODULE_PATH = /usr/lib64/libeTPkcs11.so -+ init = 0 -+ -+ - There are two ways to specify a password/PIN for the PKCS11 engine: -+ - inside the openssl.cnf file using -+ PIN = your-secret-pin -+ Note The keyword 'PIN' is case sensitive! -+ - Using the 'password' in the ppp options file. -+ From v0.97 of the eap-tls patch the password can also be supplied -+ using the appropriate 'eaptls_passwd_hook' (see plugins/passprompt.c -+ for an example). -+ -+ -+4. Options -+ -+ These pppd options are available: -+ -+ ca -+ Use the CA public certificate found in in PEM format -+ cert -+ Use the client public certificate found in in PEM format -+ or in engine:engine_id format -+ key -+ Use the client private key found in in PEM format -+ or in engine:engine_id format -+ crl -+ Use the Certificate Revocation List (CRL) file in PEM format. -+ crl-dir -+ Use CRL files from directory . It contains CRL files in PEM -+ format and each file contains a CRL. The files are looked up -+ by the issuer name hash value. Use the c_rehash utility -+ to create necessary links. -+ need-peer-eap -+ If the peer doesn't ask us to authenticate or doesn't use eap -+ to authenticate us, disconnect. -+ -+ Note: -+ password-encrypted certificates can be used as of v0.94 of this -+ patch. The password for the eap-tls.key file is specified using -+ the regular -+ password .... -+ statement in the ppp options file, or by using the appropriate -+ plugin which supplies a 'eaptls_passwd_hook' routine. -+ -+5. Connecting -+ -+ If you're setting up a pppd server, edit the EAP-TLS configuration file -+ as written above and then run pppd with the 'auth' option to authenticate -+ the client. The EAP-TLS method will be used if the other eap methods can't -+ be used (no secrets). -+ -+ If you're setting up a client, edit the configuration file and then run -+ pppd with 'remotename' option to specify the server name. Add the -+ 'need-peer-eap' option if you want to be sure the peer ask you to -+ authenticate (and to use eap) and to disconnect if it doesn't. -+ -+6. Example -+ -+ The following example can be used to connect a Linux client with the 'pptp' -+ package to a Linux server running the 'pptpd' (PoPToP) package. The server -+ was configured with a certificate with name (CN) 'pptp-server', the client -+ was configured with a certificate with name (CN) 'pptp-client', both -+ signed by the same Certificate Authority (CA). -+ -+ Server side: -+ - /etc/pptpd.conf file: -+ option /etc/ppp/options-pptpd-eaptls -+ localip 172.16.1.1 -+ remoteip 172.16.1.10-20 -+ - /etc/ppp/options-pptpd-eaptls file: -+ name pptp-server -+ lock -+ mtu 1500 -+ mru 1450 -+ auth -+ lcp-echo-failure 3 -+ lcp-echo-interval 5 -+ nodeflate -+ nobsdcomp -+ nopredictor1 -+ nopcomp -+ noaccomp -+ -+ require-eap -+ require-mppe-128 -+ -+ crl /home/janjust/ppp/keys/crl.pem -+ -+ debug -+ logfile /tmp/pppd.log -+ -+ - /etc/ppp/eaptls-server file: -+ * pptp-server - /etc/ppp/pptp-server.crt /etc/ppp/ca.crt /etc/ppp/pptp-server.key * -+ -+ - On the server, run -+ pptdp --conf /etc/pptpd.conf -+ -+ Client side: -+ - Run -+ pppd noauth require-eap require-mppe-128 \ -+ ipcp-accept-local ipcp-accept-remote noipdefault \ -+ cert /etc/ppp/keys/pptp-client.crt \ -+ key /etc/ppp/keys/pptp-client.key \ -+ ca /etc/ppp/keys/ca.crt \ -+ name pptp-client remotename pptp-server \ -+ debug logfile /tmp/pppd.log -+ pty "pptp pptp-server.example.com --nolaunchpppd" -+ -+ Check /var/log/messages and the files /tmp/pppd.log on both sides for debugging info. -+ -+7. Notes -+ -+ This is experimental code. -+ Send suggestions and comments to Jan Just Keijser -+ -+8. Changelog of ppp-<>-eaptls-mppe-* patches -+ -+v0.7 (22-Nov-2005) -+ - First version of the patch to include MPPE support -+ - ppp-2.4.3 only -+v0.9 (25-Jul-2006) -+ - Bug fixes -+ - First version for ppp-2.4.4 -+v0.91 (03-Sep-2006) -+ - Added missing #include for md5.h -+ - Last version for ppp-2.4.3 -+v0.92 (22-Apr-2008) -+ - Fix for openssl 0.9.8 issue with md5 function overload. -+v0.93 (14-Aug-2008) -+ - Make sure 'noauth' option can be used to bypass server certificate verification. -+v0.94 (15-Oct-2008) -+ - Added support for password-protected private keys by (ab)using the 'password' field. -+v0.95 (23-Dec-2009) -+ - First version with OpenSSL engine support. -+v0.96 (27-Jan-2010) -+ - Added fully functional support for OpenSSL engines (PKCS#11) -+ - First version for ppp-2.4.5 -+v0.97 (20-Apr-2010) -+ - Some bug fixes for v0.96 -+ - Added support for entering the password via a plugin. The sample plugin -+ .../pppd/plugins/passprompt.c has been extended with EAP-TLS support. -+ The "old" methods using the password option or the /etc/ppp/openssl.cnf file still work. -+ - Added support for specifying the client CA, certificate and private key on the command-line -+ or via the ppp config file. -+v0.98 (20-Apr-2010) -+ - Fix initialisation bug when using ca/cert/key command-line options. -+ - Last version for ppp-2.4.4 -+v0.99 (05-Oct-2010) -+ - Fix coredump when using multilink option. -+v0.991 (08-Aug-2011) -+ - Fix compilation issue with openssl 1.0. -+v0.992 (01-Dec-2011) -+ - Fix compilation issue with eaptls_check_hook and passwordfd plugin. -+v0.993 (24-Apr-2012) -+ - Fix compilation issue when EAP_TLS=n in pppd/Makefile. -+v0.994 (11-Jun-2012) -+ - Fix compilation issue on Ubuntu 11.10. -+v0.995 (27-May-2014) -+ - Add support for a CRL file using the command-line option 'crl' -+ (prior only 'crl-dir' was supported). -+ - Fix segfault when pkcs11 enginename was not specified correctly. -+ - Fix segfault when client was misconfigured. -+ - Disable SSL Session Ticket support as Windows 8 does not support this. -+v0.996 (28-May-2014) -+ - Fix minor bug where SessionTicket message was printed as 'Unknown SSL3 code 4' -+ - Add EAP-TLS-specific options to pppd.8 manual page. -+ - Updated README.eap-tls file with new options and provide an example. -+v0.997 (19-Jun-2014) -+ - Change SSL_OP_NO_TICKETS to SSL_OP_NO_TICKET -+ - Fix bug in initialisation code with fragmented packets. -+v0.998 (13-Mar-2015) -+ - Add fix for https://bugzilla.redhat.com/show_bug.cgi?id=1023620 -+v0.999 (11-May-2017) -+ - Add support for OpenSSL 1.1: the code will now compile against OpenSSL 1.0.x or 1.1.x. -+v1.101 (1-Jun-2018) -+ - Fix vulnerabilities CVE-2018-11574. -+v1.102 (2-Nov-2018) -+ - Add TLS 1.2 support. Windows 7/8 will connect using TLS 1.0, Windows 10 clients using TLS 1.2. -+ This works both when compiling against OpenSSL 1.0.1+ and 1.1+. -+ - Print warning when certificate is either not yet valid or has expired. -+ - Perform better peer certificate checks. -+ - Allow certificate chain files to be used. ---- /dev/null -+++ b/etc.ppp/eaptls-client -@@ -0,0 +1,10 @@ -+# Parameters for authentication using EAP-TLS (client) -+ -+# client name (can be *) -+# server name (can be *) -+# client certificate file (required) -+# server certificate file (optional, if unused put '-') -+# CA certificate file (required) -+# client private key file (required) -+ -+#client server /root/cert/client.crt - /root/cert/ca.crt /root/cert/client.key ---- /dev/null -+++ b/etc.ppp/eaptls-server -@@ -0,0 +1,11 @@ -+# Parameters for authentication using EAP-TLS (server) -+ -+# client name (can be *) -+# server name (can be *) -+# client certificate file (optional, if unused put '-') -+# server certificate file (required) -+# CA certificate file (required) -+# server private key file (required) -+# allowed addresses (required, can be *) -+ -+#client server - /root/cert/server.crt /root/cert/ca.crt /root/cert/server.key 192.168.1.0/24 ---- /dev/null -+++ b/etc.ppp/openssl.cnf -@@ -0,0 +1,14 @@ -+openssl_conf = openssl_def -+ -+[ openssl_def ] -+engines = engine_section -+ -+[ engine_section ] -+pkcs11 = pkcs11_section -+ -+[ pkcs11_section ] -+engine_id = pkcs11 -+dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so -+MODULE_PATH = /usr/lib64/libeTPkcs11.so -+init = 0 -+ ---- a/linux/Makefile.top -+++ b/linux/Makefile.top -@@ -26,7 +26,7 @@ - cd pppdump; $(MAKE) $(MFLAGS) install - - install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \ -- $(ETCDIR)/chap-secrets -+ $(ETCDIR)/chap-secrets $(ETCDIR)/eaptls-server $(ETCDIR)/eaptls-client - - install-devel: - cd pppd; $(MAKE) $(MFLAGS) install-devel -@@ -37,6 +37,10 @@ - $(INSTALL) -c -m 600 etc.ppp/pap-secrets $@ - $(ETCDIR)/chap-secrets: - $(INSTALL) -c -m 600 etc.ppp/chap-secrets $@ -+$(ETCDIR)/eaptls-server: -+ $(INSTALL) -c -m 600 etc.ppp/eaptls-server $@ -+$(ETCDIR)/eaptls-client: -+ $(INSTALL) -c -m 600 etc.ppp/eaptls-client $@ - - $(BINDIR): - $(INSTALL) -d -m 755 $@ ---- a/pppd/Makefile.linux -+++ b/pppd/Makefile.linux -@@ -76,6 +76,9 @@ - # Use libutil - USE_LIBUTIL=y - -+# Enable EAP-TLS authentication (requires libssl and libcrypto) -+USE_EAPTLS=y -+ - MAXOCTETS=y - - INCLUDE_DIRS= -I../include -@@ -116,6 +119,15 @@ - PPPDOBJS += sha1.o - endif - -+# EAP-TLS -+ifdef USE_EAPTLS -+CFLAGS += -DUSE_EAPTLS=1 -I/usr/kerberos/include -+LIBS += -lssl -lcrypto -+PPPDSRC += eap-tls.c -+HEADERS += eap-tls.h -+PPPDOBJS += eap-tls.o -+endif -+ - ifdef HAS_SHADOW - CFLAGS += -DHAS_SHADOW - #LIBS += -lshadow $(LIBS) ---- a/pppd/auth.c -+++ b/pppd/auth.c -@@ -109,6 +109,9 @@ - #include "upap.h" - #include "chap-new.h" - #include "eap.h" -+#ifdef USE_EAPTLS -+#include "eap-tls.h" -+#endif - #ifdef CBCP_SUPPORT - #include "cbcp.h" - #endif -@@ -183,6 +186,11 @@ - /* Hook for a plugin to get the CHAP password for authenticating us */ - int (*chap_passwd_hook) __P((char *user, char *passwd)) = NULL; - -+#ifdef USE_EAPTLS -+/* Hook for a plugin to get the EAP-TLS password for authenticating us */ -+int (*eaptls_passwd_hook) __P((char *user, char *passwd)) = NULL; -+#endif -+ - /* Hook for a plugin to say whether it is OK if the peer - refuses to authenticate. */ - int (*null_auth_hook) __P((struct wordlist **paddrs, -@@ -238,6 +246,14 @@ - bool explicit_user = 0; /* Set if "user" option supplied */ - bool explicit_passwd = 0; /* Set if "password" option supplied */ - char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ -+#ifdef USE_EAPTLS -+char *cacert_file = NULL; /* CA certificate file (pem format) */ -+char *cert_file = NULL; /* client certificate file (pem format) */ -+char *privkey_file = NULL; /* client private key file (pem format) */ -+char *crl_dir = NULL; /* directory containing CRL files */ -+char *crl_file = NULL; /* Certificate Revocation List (CRL) file (pem format) */ -+bool need_peer_eap = 0; /* Require peer to authenticate us */ -+#endif - - static char *uafname; /* name of most recent +ua file */ - -@@ -254,6 +270,19 @@ - static int have_chap_secret __P((char *, char *, int, int *)); - static int have_srp_secret __P((char *client, char *server, int need_ip, - int *lacks_ipp)); -+ -+#ifdef USE_EAPTLS -+static int have_eaptls_secret_server -+__P((char *client, char *server, int need_ip, int *lacks_ipp)); -+static int have_eaptls_secret_client __P((char *client, char *server)); -+static int scan_authfile_eaptls __P((FILE * f, char *client, char *server, -+ char *cli_cert, char *serv_cert, -+ char *ca_cert, char *pk, -+ struct wordlist ** addrs, -+ struct wordlist ** opts, -+ char *filename, int flags)); -+#endif -+ - static int ip_addr_check __P((u_int32_t, struct permitted_ip *)); - static int scan_authfile __P((FILE *, char *, char *, char *, - struct wordlist **, struct wordlist **, -@@ -401,6 +430,15 @@ - "Set telephone number(s) which are allowed to connect", - OPT_PRIV | OPT_A2LIST }, - -+#ifdef USE_EAPTLS -+ { "ca", o_string, &cacert_file, "EAP-TLS CA certificate in PEM format" }, -+ { "cert", o_string, &cert_file, "EAP-TLS client certificate in PEM format" }, -+ { "key", o_string, &privkey_file, "EAP-TLS client private key in PEM format" }, -+ { "crl-dir", o_string, &crl_dir, "Use CRLs in directory" }, -+ { "crl", o_string, &crl_file, "Use specific CRL file" }, -+ { "need-peer-eap", o_bool, &need_peer_eap, -+ "Require the peer to authenticate us", 1 }, -+#endif /* USE_EAPTLS */ - { NULL } - }; - -@@ -730,6 +768,9 @@ - lcp_options *wo = &lcp_wantoptions[unit]; - lcp_options *go = &lcp_gotoptions[unit]; - lcp_options *ho = &lcp_hisoptions[unit]; -+#ifdef USE_EAPTLS -+ lcp_options *ao = &lcp_allowoptions[unit]; -+#endif - int i; - struct protent *protp; - -@@ -764,6 +805,22 @@ - } - } - -+#ifdef USE_EAPTLS -+ if (need_peer_eap && !ao->neg_eap) { -+ warn("eap required to authenticate us but no suitable secrets"); -+ lcp_close(unit, "couldn't negotiate eap"); -+ status = EXIT_AUTH_TOPEER_FAILED; -+ return; -+ } -+ -+ if (need_peer_eap && !ho->neg_eap) { -+ warn("peer doesn't want to authenticate us with eap"); -+ lcp_close(unit, "couldn't negotiate eap"); -+ status = EXIT_PEER_AUTH_FAILED; -+ return; -+ } -+#endif -+ - new_phase(PHASE_AUTHENTICATE); - auth = 0; - if (go->neg_eap) { -@@ -1277,6 +1334,15 @@ - our_name, 1, &lacks_ip); - } - -+#ifdef USE_EAPTLS -+ if (!can_auth && wo->neg_eap) { -+ can_auth = -+ have_eaptls_secret_server((explicit_remote ? remote_name : -+ NULL), our_name, 1, &lacks_ip); -+ -+ } -+#endif -+ - if (auth_required && !can_auth && noauth_addrs == NULL) { - if (default_auth) { - option_error( -@@ -1331,7 +1397,11 @@ - passwd[0] != 0 || - (hadchap == 1 || (hadchap == -1 && have_chap_secret(user, - (explicit_remote? remote_name: NULL), 0, NULL))) || -- have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)); -+ have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL) -+#ifdef USE_EAPTLS -+ || have_eaptls_secret_client(user, (explicit_remote? remote_name: NULL)) -+#endif -+ ); - - hadchap = -1; - if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) -@@ -1346,8 +1416,14 @@ - !have_chap_secret((explicit_remote? remote_name: NULL), our_name, - 1, NULL))) && - !have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1, -- NULL)) -+ NULL) -+#ifdef USE_EAPTLS -+ && !have_eaptls_secret_server((explicit_remote? remote_name: NULL), -+ our_name, 1, NULL) -+#endif -+ ) - go->neg_eap = 0; -+ - } - - -@@ -1709,6 +1785,7 @@ - } - - -+ - /* - * get_secret - open the CHAP secret file and return the secret - * for authenticating the given client on the given server. -@@ -2361,3 +2438,335 @@ - - auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL, 0); - } -+ -+ -+#ifdef USE_EAPTLS -+static int -+have_eaptls_secret_server(client, server, need_ip, lacks_ipp) -+ char *client; -+ char *server; -+ int need_ip; -+ int *lacks_ipp; -+{ -+ FILE *f; -+ int ret; -+ char *filename; -+ struct wordlist *addrs; -+ char servcertfile[MAXWORDLEN]; -+ char clicertfile[MAXWORDLEN]; -+ char cacertfile[MAXWORDLEN]; -+ char pkfile[MAXWORDLEN]; -+ -+ filename = _PATH_EAPTLSSERVFILE; -+ f = fopen(filename, "r"); -+ if (f == NULL) -+ return 0; -+ -+ if (client != NULL && client[0] == 0) -+ client = NULL; -+ else if (server != NULL && server[0] == 0) -+ server = NULL; -+ -+ ret = -+ scan_authfile_eaptls(f, client, server, clicertfile, servcertfile, -+ cacertfile, pkfile, &addrs, NULL, filename, -+ 0); -+ -+ fclose(f); -+ -+/* -+ if (ret >= 0 && !eaptls_init_ssl(1, cacertfile, servcertfile, -+ clicertfile, pkfile)) -+ ret = -1; -+*/ -+ -+ if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { -+ if (lacks_ipp != 0) -+ *lacks_ipp = 1; -+ ret = -1; -+ } -+ if (addrs != 0) -+ free_wordlist(addrs); -+ -+ return ret >= 0; -+} -+ -+ -+static int -+have_eaptls_secret_client(client, server) -+ char *client; -+ char *server; -+{ -+ FILE *f; -+ int ret; -+ char *filename; -+ struct wordlist *addrs = NULL; -+ char servcertfile[MAXWORDLEN]; -+ char clicertfile[MAXWORDLEN]; -+ char cacertfile[MAXWORDLEN]; -+ char pkfile[MAXWORDLEN]; -+ -+ if (client != NULL && client[0] == 0) -+ client = NULL; -+ else if (server != NULL && server[0] == 0) -+ server = NULL; -+ -+ if (cacert_file && cert_file && privkey_file) -+ return 1; -+ -+ filename = _PATH_EAPTLSCLIFILE; -+ f = fopen(filename, "r"); -+ if (f == NULL) -+ return 0; -+ -+ ret = -+ scan_authfile_eaptls(f, client, server, clicertfile, servcertfile, -+ cacertfile, pkfile, &addrs, NULL, filename, -+ 0); -+ fclose(f); -+ -+/* -+ if (ret >= 0 && !eaptls_init_ssl(0, cacertfile, clicertfile, -+ servcertfile, pkfile)) -+ ret = -1; -+*/ -+ -+ if (addrs != 0) -+ free_wordlist(addrs); -+ -+ return ret >= 0; -+} -+ -+ -+static int -+scan_authfile_eaptls(f, client, server, cli_cert, serv_cert, ca_cert, pk, -+ addrs, opts, filename, flags) -+ FILE *f; -+ char *client; -+ char *server; -+ char *cli_cert; -+ char *serv_cert; -+ char *ca_cert; -+ char *pk; -+ struct wordlist **addrs; -+ struct wordlist **opts; -+ char *filename; -+ int flags; -+{ -+ int newline; -+ int got_flag, best_flag; -+ struct wordlist *ap, *addr_list, *alist, **app; -+ char word[MAXWORDLEN]; -+ -+ if (addrs != NULL) -+ *addrs = NULL; -+ if (opts != NULL) -+ *opts = NULL; -+ addr_list = NULL; -+ if (!getword(f, word, &newline, filename)) -+ return -1; /* file is empty??? */ -+ newline = 1; -+ best_flag = -1; -+ for (;;) { -+ /* -+ * Skip until we find a word at the start of a line. -+ */ -+ while (!newline && getword(f, word, &newline, filename)); -+ if (!newline) -+ break; /* got to end of file */ -+ -+ /* -+ * Got a client - check if it's a match or a wildcard. -+ */ -+ got_flag = 0; -+ if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) { -+ newline = 0; -+ continue; -+ } -+ if (!ISWILD(word)) -+ got_flag = NONWILD_CLIENT; -+ -+ /* -+ * Now get a server and check if it matches. -+ */ -+ if (!getword(f, word, &newline, filename)) -+ break; -+ if (newline) -+ continue; -+ if (!ISWILD(word)) { -+ if (server != NULL && strcmp(word, server) != 0) -+ continue; -+ got_flag |= NONWILD_SERVER; -+ } -+ -+ /* -+ * Got some sort of a match - see if it's better than what -+ * we have already. -+ */ -+ if (got_flag <= best_flag) -+ continue; -+ -+ /* -+ * Get the cli_cert -+ */ -+ if (!getword(f, word, &newline, filename)) -+ break; -+ if (newline) -+ continue; -+ if (strcmp(word, "-") != 0) { -+ strlcpy(cli_cert, word, MAXWORDLEN); -+ } else -+ cli_cert[0] = 0; -+ -+ /* -+ * Get serv_cert -+ */ -+ if (!getword(f, word, &newline, filename)) -+ break; -+ if (newline) -+ continue; -+ if (strcmp(word, "-") != 0) { -+ strlcpy(serv_cert, word, MAXWORDLEN); -+ } else -+ serv_cert[0] = 0; -+ -+ /* -+ * Get ca_cert -+ */ -+ if (!getword(f, word, &newline, filename)) -+ break; -+ if (newline) -+ continue; -+ strlcpy(ca_cert, word, MAXWORDLEN); -+ -+ /* -+ * Get pk -+ */ -+ if (!getword(f, word, &newline, filename)) -+ break; -+ if (newline) -+ continue; -+ strlcpy(pk, word, MAXWORDLEN); -+ -+ -+ /* -+ * Now read address authorization info and make a wordlist. -+ */ -+ app = &alist; -+ for (;;) { -+ if (!getword(f, word, &newline, filename) || newline) -+ break; -+ ap = (struct wordlist *) -+ malloc(sizeof(struct wordlist) + strlen(word) + 1); -+ if (ap == NULL) -+ novm("authorized addresses"); -+ ap->word = (char *) (ap + 1); -+ strcpy(ap->word, word); -+ *app = ap; -+ app = &ap->next; -+ } -+ *app = NULL; -+ /* -+ * This is the best so far; remember it. -+ */ -+ best_flag = got_flag; -+ if (addr_list) -+ free_wordlist(addr_list); -+ addr_list = alist; -+ -+ if (!newline) -+ break; -+ } -+ -+ /* scan for a -- word indicating the start of options */ -+ for (app = &addr_list; (ap = *app) != NULL; app = &ap->next) -+ if (strcmp(ap->word, "--") == 0) -+ break; -+ /* ap = start of options */ -+ if (ap != NULL) { -+ ap = ap->next; /* first option */ -+ free(*app); /* free the "--" word */ -+ *app = NULL; /* terminate addr list */ -+ } -+ if (opts != NULL) -+ *opts = ap; -+ else if (ap != NULL) -+ free_wordlist(ap); -+ if (addrs != NULL) -+ *addrs = addr_list; -+ else if (addr_list != NULL) -+ free_wordlist(addr_list); -+ -+ return best_flag; -+} -+ -+ -+int -+get_eaptls_secret(unit, client, server, clicertfile, servcertfile, -+ cacertfile, pkfile, am_server) -+ int unit; -+ char *client; -+ char *server; -+ char *clicertfile; -+ char *servcertfile; -+ char *cacertfile; -+ char *pkfile; -+ int am_server; -+{ -+ FILE *fp; -+ int ret; -+ char *filename = NULL; -+ struct wordlist *addrs = NULL; -+ struct wordlist *opts = NULL; -+ -+ /* in client mode the ca+cert+privkey can also be specified as options */ -+ if (!am_server && cacert_file && cert_file && privkey_file ) -+ { -+ strlcpy( clicertfile, cert_file, MAXWORDLEN ); -+ strlcpy( cacertfile, cacert_file, MAXWORDLEN ); -+ strlcpy( pkfile, privkey_file, MAXWORDLEN ); -+ servcertfile[0] = '\0'; -+ } -+ else -+ { -+ filename = (am_server ? _PATH_EAPTLSSERVFILE : _PATH_EAPTLSCLIFILE); -+ addrs = NULL; -+ -+ fp = fopen(filename, "r"); -+ if (fp == NULL) -+ { -+ error("Can't open eap-tls secret file %s: %m", filename); -+ return 0; -+ } -+ -+ check_access(fp, filename); -+ -+ ret = scan_authfile_eaptls(fp, client, server, clicertfile, servcertfile, -+ cacertfile, pkfile, &addrs, &opts, filename, 0); -+ -+ fclose(fp); -+ -+ if (ret < 0) return 0; -+ } -+ -+ if (eaptls_passwd_hook) -+ { -+ dbglog( "Calling eaptls password hook" ); -+ if ( (*eaptls_passwd_hook)(pkfile, passwd) < 0) -+ { -+ error("Unable to obtain EAP-TLS password for %s (%s) from plugin", -+ client, pkfile); -+ return 0; -+ } -+ } -+ if (am_server) -+ set_allowed_addrs(unit, addrs, opts); -+ else if (opts != NULL) -+ free_wordlist(opts); -+ if (addrs != NULL) -+ free_wordlist(addrs); -+ -+ return 1; -+} -+#endif -+ ---- a/pppd/ccp.c -+++ b/pppd/ccp.c -@@ -540,6 +540,9 @@ - if (go->mppe) { - ccp_options *ao = &ccp_allowoptions[f->unit]; - int auth_mschap_bits = auth_done[f->unit]; -+#ifdef USE_EAPTLS -+ int auth_eap_bits = auth_done[f->unit]; -+#endif - int numbits; - - /* -@@ -567,8 +570,23 @@ - lcp_close(f->unit, "MPPE required but not available"); - return; - } -+ -+#ifdef USE_EAPTLS -+ /* -+ * MPPE is also possible in combination with EAP-TLS. -+ * It is not possible to detect if we're doing EAP or EAP-TLS -+ * at this stage, hence we accept all forms of EAP. If TLS is -+ * not used then the MPPE keys will not be derived anyway. -+ */ -+ /* Leave only the eap auth bits set */ -+ auth_eap_bits &= (EAP_WITHPEER | EAP_PEER ); -+ -+ if ((numbits == 0) && (auth_eap_bits == 0)) { -+ error("MPPE required, but MS-CHAP[v2] nor EAP-TLS auth are performed."); -+#else - if (!numbits) { -- error("MPPE required, but MS-CHAP[v2] auth not performed."); -+ error("MPPE required, but MS-CHAP[v2] auth not performed."); -+#endif - lcp_close(f->unit, "MPPE required but not available"); - return; - } ---- a/pppd/chap-md5.c -+++ b/pppd/chap-md5.c -@@ -36,7 +36,11 @@ - #include "chap-new.h" - #include "chap-md5.h" - #include "magic.h" -+#ifdef USE_EAPTLS -+#include "eap-tls.h" -+#else - #include "md5.h" -+#endif /* USE_EAPTLS */ - - #define MD5_HASH_SIZE 16 - #define MD5_MIN_CHALLENGE 16 ---- /dev/null -+++ b/pppd/eap-tls.c -@@ -0,0 +1,1383 @@ -+/* * eap-tls.c - EAP-TLS implementation for PPP -+ * -+ * Copyright (c) Beniamino Galvani 2005 All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * -+ * 3. The name(s) of the authors of this software must not be used to -+ * endorse or promote products derived from this software without -+ * prior written permission. -+ * -+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO -+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY -+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN -+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING -+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include "pppd.h" -+#include "eap.h" -+#include "eap-tls.h" -+#include "fsm.h" -+#include "lcp.h" -+#include "pathnames.h" -+ -+/* The openssl configuration file and engines can be loaded only once */ -+static CONF *ssl_config = NULL; -+static ENGINE *cert_engine = NULL; -+static ENGINE *pkey_engine = NULL; -+ -+#ifdef MPPE -+ -+#define EAPTLS_MPPE_KEY_LEN 32 -+ -+/* -+ * The following stuff is only needed if SSL_export_keying_material() is not available -+ */ -+ -+#if OPENSSL_VERSION_NUMBER < 0x10001000L -+ -+/* -+ * https://wiki.openssl.org/index.php/1.1_API_Changes -+ * tries to provide some guidance but ultimately falls short. -+ * -+ */ -+ -+static void HMAC_CTX_free(HMAC_CTX *ctx) -+{ -+ if (ctx != NULL) { -+ HMAC_CTX_cleanup(ctx); -+ OPENSSL_free(ctx); -+ } -+} -+ -+static HMAC_CTX *HMAC_CTX_new(void) -+{ -+ HMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx)); -+ if (ctx != NULL) -+ HMAC_CTX_init(ctx); -+ return ctx; -+} -+ -+static size_t SSL_get_client_random(const SSL *ssl, unsigned char *out, -+ size_t outlen) -+{ -+ if (outlen == 0) -+ return sizeof(ssl->s3->client_random); -+ if (outlen > sizeof(ssl->s3->client_random)) -+ outlen = sizeof(ssl->s3->client_random); -+ memcpy(out, ssl->s3->client_random, outlen); -+ return outlen; -+} -+ -+static size_t SSL_get_server_random(const SSL *ssl, unsigned char *out, -+ size_t outlen) -+{ -+ if (outlen == 0) -+ return sizeof(ssl->s3->server_random); -+ if (outlen > sizeof(ssl->s3->server_random)) -+ outlen = sizeof(ssl->s3->server_random); -+ memcpy(out, ssl->s3->server_random, outlen); -+ return outlen; -+} -+ -+static size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, -+ unsigned char *out, size_t outlen) -+{ -+ if (outlen == 0) -+ return session->master_key_length; -+ if (outlen > session->master_key_length) -+ outlen = session->master_key_length; -+ memcpy(out, session->master_key, outlen); -+ return outlen; -+} -+ -+ -+/* -+ * TLS PRF from RFC 2246 -+ */ -+static void P_hash(const EVP_MD *evp_md, -+ const unsigned char *secret, unsigned int secret_len, -+ const unsigned char *seed, unsigned int seed_len, -+ unsigned char *out, unsigned int out_len) -+{ -+ HMAC_CTX *ctx_a, *ctx_out; -+ unsigned char a[HMAC_MAX_MD_CBLOCK]; -+ unsigned int size; -+ -+ ctx_a = HMAC_CTX_new(); -+ ctx_out = HMAC_CTX_new(); -+ HMAC_Init_ex(ctx_a, secret, secret_len, evp_md, NULL); -+ HMAC_Init_ex(ctx_out, secret, secret_len, evp_md, NULL); -+ -+ size = HMAC_size(ctx_out); -+ -+ /* Calculate A(1) */ -+ HMAC_Update(ctx_a, seed, seed_len); -+ HMAC_Final(ctx_a, a, NULL); -+ -+ while (1) { -+ /* Calculate next part of output */ -+ HMAC_Update(ctx_out, a, size); -+ HMAC_Update(ctx_out, seed, seed_len); -+ -+ /* Check if last part */ -+ if (out_len < size) { -+ HMAC_Final(ctx_out, a, NULL); -+ memcpy(out, a, out_len); -+ break; -+ } -+ -+ /* Place digest in output buffer */ -+ HMAC_Final(ctx_out, out, NULL); -+ HMAC_Init_ex(ctx_out, NULL, 0, NULL, NULL); -+ out += size; -+ out_len -= size; -+ -+ /* Calculate next A(i) */ -+ HMAC_Init_ex(ctx_a, NULL, 0, NULL, NULL); -+ HMAC_Update(ctx_a, a, size); -+ HMAC_Final(ctx_a, a, NULL); -+ } -+ -+ HMAC_CTX_free(ctx_a); -+ HMAC_CTX_free(ctx_out); -+ memset(a, 0, sizeof(a)); -+} -+ -+static void PRF(const unsigned char *secret, unsigned int secret_len, -+ const unsigned char *seed, unsigned int seed_len, -+ unsigned char *out, unsigned char *buf, unsigned int out_len) -+{ -+ unsigned int i; -+ unsigned int len = (secret_len + 1) / 2; -+ const unsigned char *s1 = secret; -+ const unsigned char *s2 = secret + (secret_len - len); -+ -+ P_hash(EVP_md5(), s1, len, seed, seed_len, out, out_len); -+ P_hash(EVP_sha1(), s2, len, seed, seed_len, buf, out_len); -+ -+ for (i=0; i < out_len; i++) { -+ out[i] ^= buf[i]; -+ } -+} -+ -+static int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, -+ const char *label, size_t llen, -+ const unsigned char *p, size_t plen, -+ int use_context) -+{ -+ unsigned char seed[64 + 2*SSL3_RANDOM_SIZE]; -+ unsigned char buf[4*EAPTLS_MPPE_KEY_LEN]; -+ unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; -+ size_t master_key_length; -+ unsigned char *pp; -+ -+ pp = seed; -+ -+ memcpy(pp, label, llen); -+ pp += llen; -+ -+ llen += SSL_get_client_random(s, pp, SSL3_RANDOM_SIZE); -+ pp += SSL3_RANDOM_SIZE; -+ -+ llen += SSL_get_server_random(s, pp, SSL3_RANDOM_SIZE); -+ -+ master_key_length = SSL_SESSION_get_master_key(SSL_get_session(s), master_key, -+ sizeof(master_key)); -+ PRF(master_key, master_key_length, seed, llen, out, buf, olen); -+ -+ return 1; -+} -+ -+#endif /* OPENSSL_VERSION_NUMBER < 0x10001000L */ -+ -+ -+/* -+ * 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 -+ -+#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ -+ -+ -+/* -+ * Generate keys according to RFC 2716 and add to reply -+ */ -+void eaptls_gen_mppe_keys(struct eaptls_session *ets, const char *prf_label, -+ int client) -+{ -+ unsigned char out[4*EAPTLS_MPPE_KEY_LEN]; -+ size_t prf_size = strlen(prf_label); -+ unsigned char *p; -+ -+ if (SSL_export_keying_material(ets->ssl, out, sizeof(out), prf_label, prf_size, NULL, 0, 0) != 1) -+ { -+ warn( "EAP-TLS: Failed generating keying material" ); -+ return; -+ } -+ -+ /* -+ * We now have the master send and receive keys. -+ * From these, generate the session send and receive keys. -+ * (see RFC3079 / draft-ietf-pppext-mppe-keys-03.txt for details) -+ */ -+ if (client) -+ { -+ p = out; -+ BCOPY( p, mppe_send_key, sizeof(mppe_send_key) ); -+ p += EAPTLS_MPPE_KEY_LEN; -+ BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) ); -+ } -+ else -+ { -+ p = out; -+ BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) ); -+ p += EAPTLS_MPPE_KEY_LEN; -+ BCOPY( p, mppe_send_key, sizeof(mppe_send_key) ); -+ } -+ -+ mppe_keys_set = 1; -+} -+ -+#endif -+ -+void log_ssl_errors( void ) -+{ -+ unsigned long ssl_err = ERR_get_error(); -+ -+ if (ssl_err != 0) -+ dbglog("EAP-TLS SSL error stack:"); -+ while (ssl_err != 0) { -+ dbglog( ERR_error_string( ssl_err, NULL ) ); -+ ssl_err = ERR_get_error(); -+ } -+} -+ -+ -+int password_callback (char *buf, int size, int rwflag, void *u) -+{ -+ if (buf) -+ { -+ strncpy (buf, passwd, size); -+ return strlen (buf); -+ } -+ return 0; -+} -+ -+ -+CONF *eaptls_ssl_load_config( void ) -+{ -+ CONF *config; -+ int ret_code; -+ long error_line = 33; -+ -+ config = NCONF_new( NULL ); -+ dbglog( "Loading OpenSSL config file" ); -+ ret_code = NCONF_load( config, _PATH_OPENSSLCONFFILE, &error_line ); -+ if (ret_code == 0) -+ { -+ warn( "EAP-TLS: Error in OpenSSL config file %s at line %d", _PATH_OPENSSLCONFFILE, error_line ); -+ NCONF_free( config ); -+ config = NULL; -+ ERR_clear_error(); -+ } -+ -+ dbglog( "Loading OpenSSL built-ins" ); -+ ENGINE_load_builtin_engines(); -+ OPENSSL_load_builtin_modules(); -+ -+ dbglog( "Loading OpenSSL configured modules" ); -+ if (CONF_modules_load( config, NULL, 0 ) <= 0 ) -+ { -+ warn( "EAP-TLS: Error loading OpenSSL modules" ); -+ log_ssl_errors(); -+ config = NULL; -+ } -+ -+ return config; -+} -+ -+ENGINE *eaptls_ssl_load_engine( char *engine_name ) -+{ -+ ENGINE *e = NULL; -+ -+ dbglog( "Enabling OpenSSL auto engines" ); -+ ENGINE_register_all_complete(); -+ -+ dbglog( "Loading OpenSSL '%s' engine support", engine_name ); -+ e = ENGINE_by_id( engine_name ); -+ if (!e) -+ { -+ dbglog( "EAP-TLS: Cannot load '%s' engine support, trying 'dynamic'", engine_name ); -+ e = ENGINE_by_id( "dynamic" ); -+ if (e) -+ { -+ if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine_name, 0) -+ || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) -+ { -+ warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name ); -+ log_ssl_errors(); -+ ENGINE_free(e); -+ e = NULL; -+ } -+ } -+ else -+ { -+ warn( "EAP-TLS: Cannot load dynamic engine support" ); -+ } -+ } -+ -+ if (e) -+ { -+ dbglog( "Initialising engine" ); -+ if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) -+ { -+ warn( "EAP-TLS: Cannot use that engine" ); -+ log_ssl_errors(); -+ ENGINE_free(e); -+ e = NULL; -+ } -+ } -+ -+ return e; -+} -+ -+/* -+ * Initialize the SSL stacks and tests if certificates, key and crl -+ * for client or server use can be loaded. -+ */ -+SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, -+ char *certfile, char *peer_certfile, char *privkeyfile) -+{ -+ char *cert_engine_name = NULL; -+ char *cert_identifier = NULL; -+ char *pkey_engine_name = NULL; -+ char *pkey_identifier = NULL; -+ SSL_CTX *ctx; -+ SSL *ssl; -+ X509_STORE *certstore; -+ X509_LOOKUP *lookup; -+ X509 *tmp; -+ int ret; -+ -+ /* -+ * Without these can't continue -+ */ -+ if (!cacertfile[0]) -+ { -+ error("EAP-TLS: CA certificate missing"); -+ return NULL; -+ } -+ -+ if (!certfile[0]) -+ { -+ error("EAP-TLS: User certificate missing"); -+ return NULL; -+ } -+ -+ if (!privkeyfile[0]) -+ { -+ error("EAP-TLS: User private key missing"); -+ return NULL; -+ } -+ -+ SSL_library_init(); -+ SSL_load_error_strings(); -+ -+ ctx = SSL_CTX_new(TLS_method()); -+ -+ if (!ctx) { -+ error("EAP-TLS: Cannot initialize SSL CTX context"); -+ goto fail; -+ } -+ -+ /* if the certificate filename is of the form engine:id. e.g. -+ pkcs11:12345 -+ then we try to load and use this engine. -+ If the certificate filename starts with a / or . then we -+ ALWAYS assume it is a file and not an engine/pkcs11 identifier -+ */ -+ if ( index( certfile, '/' ) == NULL && index( certfile, '.') == NULL ) -+ { -+ cert_identifier = index( certfile, ':' ); -+ -+ if (cert_identifier) -+ { -+ cert_engine_name = certfile; -+ *cert_identifier = '\0'; -+ cert_identifier++; -+ -+ dbglog( "Found certificate engine '%s'", cert_engine_name ); -+ dbglog( "Found certificate identifier '%s'", cert_identifier ); -+ } -+ } -+ -+ /* if the privatekey filename is of the form engine:id. e.g. -+ pkcs11:12345 -+ then we try to load and use this engine. -+ If the privatekey filename starts with a / or . then we -+ ALWAYS assume it is a file and not an engine/pkcs11 identifier -+ */ -+ if ( index( privkeyfile, '/' ) == NULL && index( privkeyfile, '.') == NULL ) -+ { -+ pkey_identifier = index( privkeyfile, ':' ); -+ -+ if (pkey_identifier) -+ { -+ pkey_engine_name = privkeyfile; -+ *pkey_identifier = '\0'; -+ pkey_identifier++; -+ -+ dbglog( "Found privatekey engine '%s'", pkey_engine_name ); -+ dbglog( "Found privatekey identifier '%s'", pkey_identifier ); -+ } -+ } -+ -+ if (cert_identifier && pkey_identifier) -+ { -+ if (strlen( cert_identifier ) == 0) -+ { -+ if (strlen( pkey_identifier ) == 0) -+ error( "EAP-TLS: both the certificate and privatekey identifiers are missing!" ); -+ else -+ { -+ dbglog( "Substituting privatekey identifier for certificate identifier" ); -+ cert_identifier = pkey_identifier; -+ } -+ } -+ else -+ { -+ if (strlen( pkey_identifier ) == 0) -+ { -+ dbglog( "Substituting certificate identifier for privatekey identifier" ); -+ pkey_identifier = cert_identifier; -+ } -+ } -+ -+ } -+ -+ /* load the openssl config file only once */ -+ if (!ssl_config) -+ { -+ if (cert_engine_name || pkey_engine_name) -+ ssl_config = eaptls_ssl_load_config(); -+ -+ if (ssl_config && cert_engine_name) -+ cert_engine = eaptls_ssl_load_engine( cert_engine_name ); -+ -+ if (ssl_config && pkey_engine_name) -+ { -+ /* don't load the same engine twice */ -+ if ( cert_engine && strcmp( cert_engine_name, pkey_engine_name) == 0 ) -+ pkey_engine = cert_engine; -+ else -+ pkey_engine = eaptls_ssl_load_engine( pkey_engine_name ); -+ } -+ } -+ -+ SSL_CTX_set_default_passwd_cb (ctx, password_callback); -+ -+ if (!SSL_CTX_load_verify_locations(ctx, cacertfile, NULL)) -+ { -+ error("EAP-TLS: Cannot load or verify CA file %s", cacertfile); -+ goto fail; -+ } -+ -+ if (init_server) -+ SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(cacertfile)); -+ -+ if (cert_engine) -+ { -+ struct -+ { -+ const char *s_slot_cert_id; -+ X509 *cert; -+ } cert_info; -+ -+ cert_info.s_slot_cert_id = cert_identifier; -+ cert_info.cert = NULL; -+ -+ if (!ENGINE_ctrl_cmd( cert_engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0 ) ) -+ { -+ error( "EAP-TLS: Error loading certificate with id '%s' from engine", cert_identifier ); -+ goto fail; -+ } -+ -+ if (cert_info.cert) -+ { -+ dbglog( "Got the certificate, adding it to SSL context" ); -+ dbglog( "subject = %s", X509_NAME_oneline( X509_get_subject_name( cert_info.cert ), NULL, 0 ) ); -+ if (SSL_CTX_use_certificate(ctx, cert_info.cert) <= 0) -+ { -+ error("EAP-TLS: Cannot use PKCS11 certificate %s", cert_identifier); -+ goto fail; -+ } -+ } -+ else -+ { -+ warn("EAP-TLS: Cannot load PKCS11 key %s", cert_identifier); -+ log_ssl_errors(); -+ } -+ } -+ else -+ { -+ if (!SSL_CTX_use_certificate_chain_file(ctx, certfile)) -+ { -+ error( "EAP-TLS: Cannot use public certificate %s", certfile ); -+ goto fail; -+ } -+ } -+ -+ -+ /* -+ * Check the Before and After dates of the certificate -+ */ -+ ssl = SSL_new(ctx); -+ tmp = SSL_get_certificate(ssl); -+ -+ ret = X509_cmp_time(X509_get_notBefore(tmp), NULL); -+ if (ret == 0) -+ { -+ warn( "EAP-TLS: Failed to read certificate notBefore field."); -+ } -+ if (ret > 0) -+ { -+ warn( "EAP-TLS: Your certificate is not yet valid!"); -+ } -+ -+ ret = X509_cmp_time(X509_get_notAfter(tmp), NULL); -+ if (ret == 0) -+ { -+ warn( "EAP-TLS: Failed to read certificate notAfter field."); -+ } -+ if (ret < 0) -+ { -+ warn( "EAP-TLS: Your certificate has expired!"); -+ } -+ SSL_free(ssl); -+ -+ if (pkey_engine) -+ { -+ EVP_PKEY *pkey = NULL; -+ PW_CB_DATA cb_data; -+ -+ cb_data.password = passwd; -+ cb_data.prompt_info = pkey_identifier; -+ -+ dbglog( "Loading private key '%s' from engine", pkey_identifier ); -+ pkey = ENGINE_load_private_key(pkey_engine, pkey_identifier, NULL, &cb_data); -+ if (pkey) -+ { -+ dbglog( "Got the private key, adding it to SSL context" ); -+ if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0) -+ { -+ error("EAP-TLS: Cannot use PKCS11 key %s", pkey_identifier); -+ goto fail; -+ } -+ } -+ else -+ { -+ warn("EAP-TLS: Cannot load PKCS11 key %s", pkey_identifier); -+ log_ssl_errors(); -+ } -+ } -+ else -+ { -+ if (!SSL_CTX_use_PrivateKey_file(ctx, privkeyfile, SSL_FILETYPE_PEM)) -+ { -+ error("EAP-TLS: Cannot use private key %s", privkeyfile); -+ goto fail; -+ } -+ } -+ -+ if (SSL_CTX_check_private_key(ctx) != 1) { -+ error("EAP-TLS: Private key %s fails security check", privkeyfile); -+ goto fail; -+ } -+ -+ /* Explicitly set the NO_TICKETS flag to support Win7/Win8 clients */ -+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 -+#ifdef SSL_OP_NO_TICKET -+ | SSL_OP_NO_TICKET -+#endif -+ ); -+ -+ SSL_CTX_set_verify_depth(ctx, 5); -+ SSL_CTX_set_verify(ctx, -+ SSL_VERIFY_PEER | -+ SSL_VERIFY_FAIL_IF_NO_PEER_CERT, -+ &ssl_verify_callback); -+ -+ if (crl_dir) { -+ if (!(certstore = SSL_CTX_get_cert_store(ctx))) { -+ error("EAP-TLS: Failed to get certificate store"); -+ goto fail; -+ } -+ -+ if (!(lookup = -+ X509_STORE_add_lookup(certstore, X509_LOOKUP_hash_dir()))) { -+ error("EAP-TLS: Store lookup for CRL failed"); -+ -+ goto fail; -+ } -+ -+ X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM); -+ X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK); -+ } -+ -+ if (crl_file) { -+ FILE *fp = NULL; -+ X509_CRL *crl = NULL; -+ -+ fp = fopen(crl_file, "r"); -+ if (!fp) { -+ error("EAP-TLS: Cannot open CRL file '%s'", crl_file); -+ goto fail; -+ } -+ -+ crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL); -+ if (!crl) { -+ error("EAP-TLS: Cannot read CRL file '%s'", crl_file); -+ goto fail; -+ } -+ -+ if (!(certstore = SSL_CTX_get_cert_store(ctx))) { -+ error("EAP-TLS: Failed to get certificate store"); -+ goto fail; -+ } -+ if (!X509_STORE_add_crl(certstore, crl)) { -+ error("EAP-TLS: Cannot add CRL to certificate store"); -+ goto fail; -+ } -+ X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK); -+ -+ } -+ -+ /* -+ * If a peer certificate file was specified, it must be valid, else fail -+ */ -+ if (peer_certfile[0]) { -+ if (!(tmp = get_X509_from_file(peer_certfile))) { -+ error("EAP-TLS: Error loading client certificate from file %s", -+ peer_certfile); -+ goto fail; -+ } -+ X509_free(tmp); -+ } -+ -+ return ctx; -+ -+fail: -+ log_ssl_errors(); -+ SSL_CTX_free(ctx); -+ return NULL; -+} -+ -+/* -+ * Determine the maximum packet size by looking at the LCP handshake -+ */ -+ -+int eaptls_get_mtu(int unit) -+{ -+ int mtu, mru; -+ -+ lcp_options *wo = &lcp_wantoptions[unit]; -+ lcp_options *go = &lcp_gotoptions[unit]; -+ lcp_options *ho = &lcp_hisoptions[unit]; -+ lcp_options *ao = &lcp_allowoptions[unit]; -+ -+ mtu = ho->neg_mru? ho->mru: PPP_MRU; -+ mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU; -+ mtu = MIN(MIN(mtu, mru), ao->mru)- PPP_HDRLEN - 10; -+ -+ dbglog("MTU = %d", mtu); -+ return mtu; -+} -+ -+ -+/* -+ * Init the ssl handshake (server mode) -+ */ -+int eaptls_init_ssl_server(eap_state * esp) -+{ -+ struct eaptls_session *ets; -+ char servcertfile[MAXWORDLEN]; -+ char clicertfile[MAXWORDLEN]; -+ char cacertfile[MAXWORDLEN]; -+ char pkfile[MAXWORDLEN]; -+ /* -+ * Allocate new eaptls session -+ */ -+ esp->es_server.ea_session = malloc(sizeof(struct eaptls_session)); -+ if (!esp->es_server.ea_session) -+ fatal("Allocation error"); -+ ets = esp->es_server.ea_session; -+ -+ if (!esp->es_server.ea_peer) { -+ error("EAP-TLS: Error: client name not set (BUG)"); -+ return 0; -+ } -+ -+ strncpy(ets->peer, esp->es_server.ea_peer, MAXWORDLEN); -+ -+ dbglog( "getting eaptls secret" ); -+ if (!get_eaptls_secret(esp->es_unit, esp->es_server.ea_peer, -+ esp->es_server.ea_name, clicertfile, -+ servcertfile, cacertfile, pkfile, 1)) { -+ error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"", -+ esp->es_server.ea_peer, esp->es_server.ea_name ); -+ return 0; -+ } -+ -+ ets->mtu = eaptls_get_mtu(esp->es_unit); -+ -+ ets->ctx = eaptls_init_ssl(1, cacertfile, servcertfile, clicertfile, pkfile); -+ if (!ets->ctx) -+ goto fail; -+ -+ if (!(ets->ssl = SSL_new(ets->ctx))) -+ goto fail; -+ -+ /* -+ * Set auto-retry to avoid timeouts on BIO_read -+ */ -+ SSL_set_mode(ets->ssl, SSL_MODE_AUTO_RETRY); -+ -+ /* -+ * Initialize the BIOs we use to read/write to ssl engine -+ */ -+ ets->into_ssl = BIO_new(BIO_s_mem()); -+ ets->from_ssl = BIO_new(BIO_s_mem()); -+ SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl); -+ -+ SSL_set_msg_callback(ets->ssl, ssl_msg_callback); -+ SSL_set_msg_callback_arg(ets->ssl, ets); -+ -+ /* -+ * Attach the session struct to the connection, so we can later -+ * retrieve it when doing certificate verification -+ */ -+ SSL_set_ex_data(ets->ssl, 0, ets); -+ -+ SSL_set_accept_state(ets->ssl); -+ -+ ets->data = NULL; -+ ets->datalen = 0; -+ ets->alert_sent = 0; -+ ets->alert_recv = 0; -+ -+ /* -+ * If we specified the client certificate file, store it in ets->peercertfile, -+ * so we can check it later in ssl_verify_callback() -+ */ -+ if (clicertfile[0]) -+ strncpy(&ets->peercertfile[0], clicertfile, MAXWORDLEN); -+ else -+ ets->peercertfile[0] = 0; -+ -+ return 1; -+ -+fail: -+ SSL_CTX_free(ets->ctx); -+ return 0; -+} -+ -+/* -+ * Init the ssl handshake (client mode) -+ */ -+int eaptls_init_ssl_client(eap_state * esp) -+{ -+ struct eaptls_session *ets; -+ char servcertfile[MAXWORDLEN]; -+ char clicertfile[MAXWORDLEN]; -+ char cacertfile[MAXWORDLEN]; -+ char pkfile[MAXWORDLEN]; -+ -+ /* -+ * Allocate new eaptls session -+ */ -+ esp->es_client.ea_session = malloc(sizeof(struct eaptls_session)); -+ if (!esp->es_client.ea_session) -+ fatal("Allocation error"); -+ ets = esp->es_client.ea_session; -+ -+ /* -+ * If available, copy server name in ets; it will be used in cert -+ * verify -+ */ -+ if (esp->es_client.ea_peer) -+ strncpy(ets->peer, esp->es_client.ea_peer, MAXWORDLEN); -+ else -+ ets->peer[0] = 0; -+ -+ ets->mtu = eaptls_get_mtu(esp->es_unit); -+ -+ dbglog( "calling get_eaptls_secret" ); -+ if (!get_eaptls_secret(esp->es_unit, esp->es_client.ea_name, -+ ets->peer, clicertfile, -+ servcertfile, cacertfile, pkfile, 0)) { -+ error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"", -+ esp->es_client.ea_name, ets->peer ); -+ return 0; -+ } -+ -+ dbglog( "calling eaptls_init_ssl" ); -+ ets->ctx = eaptls_init_ssl(0, cacertfile, clicertfile, servcertfile, pkfile); -+ if (!ets->ctx) -+ goto fail; -+ -+ ets->ssl = SSL_new(ets->ctx); -+ -+ if (!ets->ssl) -+ goto fail; -+ -+ /* -+ * Initialize the BIOs we use to read/write to ssl engine -+ */ -+ dbglog( "Initializing SSL BIOs" ); -+ ets->into_ssl = BIO_new(BIO_s_mem()); -+ ets->from_ssl = BIO_new(BIO_s_mem()); -+ SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl); -+ -+ SSL_set_msg_callback(ets->ssl, ssl_msg_callback); -+ SSL_set_msg_callback_arg(ets->ssl, ets); -+ -+ /* -+ * Attach the session struct to the connection, so we can later -+ * retrieve it when doing certificate verification -+ */ -+ SSL_set_ex_data(ets->ssl, 0, ets); -+ -+ SSL_set_connect_state(ets->ssl); -+ -+ ets->data = NULL; -+ ets->datalen = 0; -+ ets->alert_sent = 0; -+ ets->alert_recv = 0; -+ -+ /* -+ * If we specified the server certificate file, store it in -+ * ets->peercertfile, so we can check it later in -+ * ssl_verify_callback() -+ */ -+ if (servcertfile[0]) -+ strncpy(ets->peercertfile, servcertfile, MAXWORDLEN); -+ else -+ ets->peercertfile[0] = 0; -+ -+ return 1; -+ -+fail: -+ dbglog( "eaptls_init_ssl_client: fail" ); -+ SSL_CTX_free(ets->ctx); -+ return 0; -+ -+} -+ -+void eaptls_free_session(struct eaptls_session *ets) -+{ -+ if (ets->ssl) -+ SSL_free(ets->ssl); -+ -+ if (ets->ctx) -+ SSL_CTX_free(ets->ctx); -+ -+ free(ets); -+} -+ -+/* -+ * Handle a received packet, reassembling fragmented messages and -+ * passing them to the ssl engine -+ */ -+int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len) -+{ -+ u_char flags; -+ u_int tlslen = 0; -+ u_char dummy[65536]; -+ -+ if (len < 1) { -+ warn("EAP-TLS: received no or invalid data"); -+ return 1; -+ } -+ -+ GETCHAR(flags, inp); -+ len--; -+ -+ if (flags & EAP_TLS_FLAGS_LI && len > 4) { -+ /* -+ * LenghtIncluded flag set -> this is the first packet of a message -+ */ -+ -+ /* -+ * the first 4 octets are the length of the EAP-TLS message -+ */ -+ GETLONG(tlslen, inp); -+ len -= 4; -+ -+ if (!ets->data) { -+ -+ if (tlslen > EAP_TLS_MAX_LEN) { -+ error("EAP-TLS: TLS message length > %d, truncated", EAP_TLS_MAX_LEN); -+ tlslen = EAP_TLS_MAX_LEN; -+ } -+ -+ /* -+ * Allocate memory for the whole message -+ */ -+ ets->data = malloc(tlslen); -+ if (!ets->data) -+ fatal("EAP-TLS: allocation error\n"); -+ -+ ets->datalen = 0; -+ ets->tlslen = tlslen; -+ } -+ else -+ warn("EAP-TLS: non-first LI packet? that's odd..."); -+ } -+ else if (!ets->data) { -+ /* -+ * A non fragmented message without LI flag -+ */ -+ -+ ets->data = malloc(len); -+ if (!ets->data) -+ fatal("EAP-TLS: allocation error\n"); -+ -+ ets->datalen = 0; -+ ets->tlslen = len; -+ } -+ -+ if (flags & EAP_TLS_FLAGS_MF) -+ ets->frag = 1; -+ else -+ ets->frag = 0; -+ -+ if (len < 0) { -+ warn("EAP-TLS: received malformed data"); -+ return 1; -+ } -+ -+ if (len + ets->datalen > ets->tlslen) { -+ warn("EAP-TLS: received data > TLS message length"); -+ return 1; -+ } -+ -+ BCOPY(inp, ets->data + ets->datalen, len); -+ ets->datalen += len; -+ -+ if (!ets->frag) { -+ -+ /* -+ * If we have the whole message, pass it to ssl -+ */ -+ -+ if (ets->datalen != ets->tlslen) { -+ warn("EAP-TLS: received data != TLS message length"); -+ return 1; -+ } -+ -+ if (BIO_write(ets->into_ssl, ets->data, ets->datalen) == -1) -+ log_ssl_errors(); -+ -+ SSL_read(ets->ssl, dummy, 65536); -+ -+ free(ets->data); -+ ets->data = NULL; -+ ets->datalen = 0; -+ } -+ -+ return 0; -+} -+ -+/* -+ * Return an eap-tls packet in outp. -+ * A TLS message read from the ssl engine is buffered in ets->data. -+ * At each call we control if there is buffered data and send a -+ * packet of mtu bytes. -+ */ -+int eaptls_send(struct eaptls_session *ets, u_char ** outp) -+{ -+ bool first = 0; -+ int size; -+ u_char fromtls[65536]; -+ int res; -+ u_char *start; -+ -+ start = *outp; -+ -+ if (!ets->data) { -+ -+ if(!ets->alert_sent) -+ SSL_read(ets->ssl, fromtls, 65536); -+ -+ /* -+ * Read from ssl -+ */ -+ if ((res = BIO_read(ets->from_ssl, fromtls, 65536)) == -1) -+ { -+ warn("EAP-TLS send: No data from BIO_read"); -+ return 1; -+ } -+ -+ ets->datalen = res; -+ -+ ets->data = malloc(ets->datalen); -+ BCOPY(fromtls, ets->data, ets->datalen); -+ -+ ets->offset = 0; -+ first = 1; -+ -+ } -+ -+ size = ets->datalen - ets->offset; -+ -+ if (size > ets->mtu) { -+ size = ets->mtu; -+ ets->frag = 1; -+ } else -+ ets->frag = 0; -+ -+ PUTCHAR(EAPT_TLS, *outp); -+ -+ /* -+ * Set right flags and length if necessary -+ */ -+ if (ets->frag && first) { -+ PUTCHAR(EAP_TLS_FLAGS_LI | EAP_TLS_FLAGS_MF, *outp); -+ PUTLONG(ets->datalen, *outp); -+ } else if (ets->frag) { -+ PUTCHAR(EAP_TLS_FLAGS_MF, *outp); -+ } else -+ PUTCHAR(0, *outp); -+ -+ /* -+ * Copy the data in outp -+ */ -+ BCOPY(ets->data + ets->offset, *outp, size); -+ INCPTR(size, *outp); -+ -+ /* -+ * Copy the packet in retransmission buffer -+ */ -+ BCOPY(start, &ets->rtx[0], *outp - start); -+ ets->rtx_len = *outp - start; -+ -+ ets->offset += size; -+ -+ if (ets->offset >= ets->datalen) { -+ -+ /* -+ * The whole message has been sent -+ */ -+ -+ free(ets->data); -+ ets->data = NULL; -+ ets->datalen = 0; -+ ets->offset = 0; -+ } -+ -+ return 0; -+} -+ -+/* -+ * Get the sent packet from the retransmission buffer -+ */ -+void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp) -+{ -+ BCOPY(ets->rtx, *outp, ets->rtx_len); -+ INCPTR(ets->rtx_len, *outp); -+} -+ -+/* -+ * Verify a certificate. -+ * Most of the work (signatures and issuer attributes checking) -+ * is done by ssl; we check the CN in the peer certificate -+ * against the peer name. -+ */ -+int ssl_verify_callback(int 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 -+ * we can print debug information about TLS handshake. -+ */ -+void -+ssl_msg_callback(int write_p, int version, int content_type, -+ const void *buf, size_t len, SSL * ssl, void *arg) -+{ -+ char string[256]; -+ struct eaptls_session *ets = (struct eaptls_session *)arg; -+ unsigned char code; -+ const unsigned char*msg = buf; -+ int hvers = msg[1] << 8 | msg[2]; -+ -+ if(write_p) -+ strcpy(string, " -> "); -+ else -+ strcpy(string, " <- "); -+ -+ switch(content_type) { -+ -+ case SSL3_RT_HEADER: -+ strcat(string, "SSL/TLS Header: "); -+ switch(hvers) { -+ case SSL3_VERSION: -+ strcat(string, "SSL 3.0"); -+ break; -+ case TLS1_VERSION: -+ strcat(string, "TLS 1.0"); -+ break; -+ case TLS1_1_VERSION: -+ strcat(string, "TLS 1.1"); -+ break; -+ case TLS1_2_VERSION: -+ strcat(string, "TLS 1.2"); -+ break; -+ default: -+ strcat(string, "Unknown version"); -+ } -+ break; -+ -+ case SSL3_RT_ALERT: -+ strcat(string, "Alert: "); -+ code = msg[1]; -+ -+ if (write_p) { -+ ets->alert_sent = 1; -+ ets->alert_sent_desc = code; -+ } else { -+ ets->alert_recv = 1; -+ ets->alert_recv_desc = code; -+ } -+ -+ strcat(string, SSL_alert_desc_string_long(code)); -+ break; -+ -+ case SSL3_RT_CHANGE_CIPHER_SPEC: -+ strcat(string, "ChangeCipherSpec"); -+ break; -+ -+ case SSL3_RT_HANDSHAKE: -+ -+ strcat(string, "Handshake: "); -+ code = msg[0]; -+ -+ switch(code) { -+ case SSL3_MT_HELLO_REQUEST: -+ strcat(string,"Hello Request"); -+ break; -+ case SSL3_MT_CLIENT_HELLO: -+ strcat(string,"Client Hello"); -+ break; -+ case SSL3_MT_SERVER_HELLO: -+ strcat(string,"Server Hello"); -+ break; -+#ifdef SSL3_MT_NEWSESSION_TICKET -+ case SSL3_MT_NEWSESSION_TICKET: -+ strcat(string,"New Session Ticket"); -+ break; -+#endif -+ case SSL3_MT_CERTIFICATE: -+ strcat(string,"Certificate"); -+ break; -+ case SSL3_MT_SERVER_KEY_EXCHANGE: -+ strcat(string,"Server Key Exchange"); -+ break; -+ case SSL3_MT_CERTIFICATE_REQUEST: -+ strcat(string,"Certificate Request"); -+ break; -+ case SSL3_MT_SERVER_DONE: -+ strcat(string,"Server Hello Done"); -+ break; -+ case SSL3_MT_CERTIFICATE_VERIFY: -+ strcat(string,"Certificate Verify"); -+ break; -+ case SSL3_MT_CLIENT_KEY_EXCHANGE: -+ strcat(string,"Client Key Exchange"); -+ break; -+ case SSL3_MT_FINISHED: -+ strcat(string,"Finished: "); -+ hvers = SSL_version(ssl); -+ switch(hvers) { -+ case SSL3_VERSION: -+ strcat(string, "SSL 3.0"); -+ break; -+ case TLS1_VERSION: -+ strcat(string, "TLS 1.0"); -+ break; -+ case TLS1_1_VERSION: -+ strcat(string, "TLS 1.1"); -+ break; -+ case TLS1_2_VERSION: -+ strcat(string, "TLS 1.2"); -+ break; -+ default: -+ strcat(string, "Unknown version"); -+ } -+ break; -+ default: -+ sprintf( string, "Handshake: Unknown SSL3 code received: %d", code ); -+ } -+ break; -+ -+ default: -+ sprintf( string, "SSL message contains unknown content type: %d", content_type ); -+ -+ } -+ -+ /* Alert messages must always be displayed */ -+ if(content_type == SSL3_RT_ALERT) -+ error("%s", string); -+ else -+ dbglog("%s", string); -+} -+ ---- /dev/null -+++ b/pppd/eap-tls.h -@@ -0,0 +1,107 @@ -+/* -+ * eap-tls.h -+ * -+ * Copyright (c) Beniamino Galvani 2005 All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in -+ * the documentation and/or other materials provided with the -+ * distribution. -+ * -+ * 3. The name(s) of the authors of this software must not be used to -+ * endorse or promote products derived from this software without -+ * prior written permission. -+ * -+ * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO -+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY -+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN -+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING -+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ * -+ */ -+ -+#ifndef __EAP_TLS_H__ -+#define __EAP_TLS_H__ -+ -+#include "eap.h" -+ -+#include -+#include -+#include -+ -+#define EAP_TLS_FLAGS_LI 128 /* length included flag */ -+#define EAP_TLS_FLAGS_MF 64 /* more fragments flag */ -+#define EAP_TLS_FLAGS_START 32 /* start flag */ -+ -+#define EAP_TLS_MAX_LEN 65536 /* max eap tls packet size */ -+ -+struct eaptls_session -+{ -+ u_char *data; /* buffered data */ -+ int datalen; /* buffered data len */ -+ int offset; /* from where to send */ -+ int tlslen; /* total length of tls data */ -+ bool frag; /* packet is fragmented */ -+ SSL_CTX *ctx; -+ SSL *ssl; /* ssl connection */ -+ BIO *from_ssl; -+ BIO *into_ssl; -+ char peer[MAXWORDLEN]; /* peer name */ -+ char peercertfile[MAXWORDLEN]; -+ bool alert_sent; -+ u_char alert_sent_desc; -+ bool alert_recv; -+ u_char alert_recv_desc; -+ char rtx[65536]; /* retransmission buffer */ -+ int rtx_len; -+ int mtu; /* unit mtu */ -+}; -+ -+typedef struct pw_cb_data -+{ -+ const void *password; -+ const char *prompt_info; -+} PW_CB_DATA; -+ -+ -+int ssl_verify_callback(int, X509_STORE_CTX *); -+void ssl_msg_callback(int write_p, int version, int ct, const void *buf, -+ size_t len, SSL * ssl, void *arg); -+ -+X509 *get_X509_from_file(char *filename); -+int ssl_cmp_certs(char *filename, X509 * a); -+ -+SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, -+ char *certfile, char *peer_certfile, char *privkeyfile); -+int eaptls_init_ssl_server(eap_state * esp); -+int eaptls_init_ssl_client(eap_state * esp); -+void eaptls_free_session(struct eaptls_session *ets); -+ -+int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len); -+int eaptls_send(struct eaptls_session *ets, u_char ** outp); -+void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp); -+ -+int get_eaptls_secret(int unit, char *client, char *server, -+ char *clicertfile, char *servcertfile, char *cacertfile, -+ char *pkfile, int am_server); -+ -+#ifdef MPPE -+#include "mppe.h" /* MPPE_MAX_KEY_LEN */ -+extern u_char mppe_send_key[MPPE_MAX_KEY_LEN]; -+extern u_char mppe_recv_key[MPPE_MAX_KEY_LEN]; -+extern int mppe_keys_set; -+ -+void eaptls_gen_mppe_keys(struct eaptls_session *ets, const char *prf_label, int client); -+ -+#endif -+ -+#endif ---- a/pppd/eap.c -+++ b/pppd/eap.c -@@ -43,6 +43,11 @@ - * Based on draft-ietf-pppext-eap-srp-03.txt. - */ - -+/* -+ * Modification by Beniamino Galvani, Mar 2005 -+ * Implemented EAP-TLS authentication -+ */ -+ - #define RCSID "$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $" - - /* -@@ -62,8 +67,12 @@ - - #include "pppd.h" - #include "pathnames.h" --#include "md5.h" - #include "eap.h" -+#ifdef USE_EAPTLS -+#include "eap-tls.h" -+#else -+#include "md5.h" -+#endif /* USE_EAPTLS */ - - #ifdef USE_SRP - #include -@@ -209,6 +218,9 @@ - esp->es_server.ea_id = (u_char)(drand48() * 0x100); - esp->es_client.ea_timeout = EAP_DEFREQTIME; - esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ; -+#ifdef USE_EAPTLS -+ esp->es_client.ea_using_eaptls = 0; -+#endif /* USE_EAPTLS */ - } - - /* -@@ -436,8 +448,16 @@ - u_char vals[2]; - struct b64state bs; - #endif /* USE_SRP */ -+#ifdef USE_EAPTLS -+ struct eaptls_session *ets; -+ int secret_len; -+ char secret[MAXWORDLEN]; -+#endif /* USE_EAPTLS */ - - esp->es_server.ea_timeout = esp->es_savedtime; -+#ifdef USE_EAPTLS -+ esp->es_server.ea_prev_state = esp->es_server.ea_state; -+#endif /* USE_EAPTLS */ - switch (esp->es_server.ea_state) { - case eapBadAuth: - return; -@@ -562,9 +582,79 @@ - break; - } - #endif /* USE_SRP */ -+#ifdef USE_EAPTLS -+ if (!get_secret(esp->es_unit, esp->es_server.ea_peer, -+ esp->es_server.ea_name, secret, &secret_len, 1)) { -+ -+ esp->es_server.ea_state = eapTlsStart; -+ break; -+ } -+#endif /* USE_EAPTLS */ -+ - esp->es_server.ea_state = eapMD5Chall; - break; - -+#ifdef USE_EAPTLS -+ case eapTlsStart: -+ /* Initialize ssl session */ -+ if(!eaptls_init_ssl_server(esp)) { -+ esp->es_server.ea_state = eapBadAuth; -+ break; -+ } -+ -+ esp->es_server.ea_state = eapTlsRecv; -+ break; -+ -+ case eapTlsRecv: -+ ets = (struct eaptls_session *) esp->es_server.ea_session; -+ -+ if(ets->alert_sent) { -+ esp->es_server.ea_state = eapTlsSendAlert; -+ break; -+ } -+ -+ if (status) { -+ esp->es_server.ea_state = eapBadAuth; -+ break; -+ } -+ ets = (struct eaptls_session *) esp->es_server.ea_session; -+ -+ if(ets->frag) -+ esp->es_server.ea_state = eapTlsSendAck; -+ else -+ esp->es_server.ea_state = eapTlsSend; -+ break; -+ -+ case eapTlsSend: -+ ets = (struct eaptls_session *) esp->es_server.ea_session; -+ -+ if(ets->frag) -+ esp->es_server.ea_state = eapTlsRecvAck; -+ else -+ if(SSL_is_init_finished(ets->ssl)) -+ esp->es_server.ea_state = eapTlsRecvClient; -+ else -+ esp->es_server.ea_state = eapTlsRecv; -+ break; -+ -+ case eapTlsSendAck: -+ esp->es_server.ea_state = eapTlsRecv; -+ break; -+ -+ case eapTlsRecvAck: -+ if (status) { -+ esp->es_server.ea_state = eapBadAuth; -+ break; -+ } -+ -+ esp->es_server.ea_state = eapTlsSend; -+ break; -+ -+ case eapTlsSendAlert: -+ esp->es_server.ea_state = eapTlsRecvAlertAck; -+ break; -+#endif /* USE_EAPTLS */ -+ - case eapSRP1: - #ifdef USE_SRP - ts = (struct t_server *)esp->es_server.ea_session; -@@ -718,6 +808,30 @@ - INCPTR(esp->es_server.ea_namelen, outp); - break; - -+#ifdef USE_EAPTLS -+ case eapTlsStart: -+ PUTCHAR(EAPT_TLS, outp); -+ PUTCHAR(EAP_TLS_FLAGS_START, outp); -+ eap_figure_next_state(esp, 0); -+ break; -+ -+ case eapTlsSend: -+ eaptls_send(esp->es_server.ea_session, &outp); -+ eap_figure_next_state(esp, 0); -+ break; -+ -+ case eapTlsSendAck: -+ PUTCHAR(EAPT_TLS, outp); -+ PUTCHAR(0, outp); -+ eap_figure_next_state(esp, 0); -+ break; -+ -+ case eapTlsSendAlert: -+ eaptls_send(esp->es_server.ea_session, &outp); -+ eap_figure_next_state(esp, 0); -+ break; -+#endif /* USE_EAPTLS */ -+ - #ifdef USE_SRP - case eapSRP1: - PUTCHAR(EAPT_SRP, outp); -@@ -904,11 +1018,57 @@ - eap_server_timeout(arg) - void *arg; - { -+#ifdef USE_EAPTLS -+ u_char *outp; -+ u_char *lenloc; -+ int outlen; -+#endif /* USE_EAPTLS */ -+ - eap_state *esp = (eap_state *) arg; - - if (!eap_server_active(esp)) - return; - -+#ifdef USE_EAPTLS -+ switch(esp->es_server.ea_prev_state) { -+ -+ /* -+ * In eap-tls the state changes after a request, so we return to -+ * previous state ... -+ */ -+ case(eapTlsStart): -+ case(eapTlsSendAck): -+ esp->es_server.ea_state = esp->es_server.ea_prev_state; -+ break; -+ -+ /* -+ * ... or resend the stored data -+ */ -+ case(eapTlsSend): -+ case(eapTlsSendAlert): -+ outp = outpacket_buf; -+ MAKEHEADER(outp, PPP_EAP); -+ PUTCHAR(EAP_REQUEST, outp); -+ PUTCHAR(esp->es_server.ea_id, outp); -+ lenloc = outp; -+ INCPTR(2, outp); -+ -+ eaptls_retransmit(esp->es_server.ea_session, &outp); -+ -+ outlen = (outp - outpacket_buf) - PPP_HDRLEN; -+ PUTSHORT(outlen, lenloc); -+ output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN); -+ esp->es_server.ea_requests++; -+ -+ if (esp->es_server.ea_timeout > 0) -+ TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout); -+ -+ return; -+ default: -+ break; -+ } -+#endif /* USE_EAPTLS */ -+ - /* EAP ID number must not change on timeout. */ - eap_send_request(esp); - } -@@ -1166,6 +1326,81 @@ - } - #endif /* USE_SRP */ - -+#ifdef USE_EAPTLS -+/* -+ * Send an EAP-TLS response message with tls data -+ */ -+static void -+eap_tls_response(esp, id) -+eap_state *esp; -+u_char id; -+{ -+ u_char *outp; -+ int outlen; -+ u_char *lenloc; -+ -+ outp = outpacket_buf; -+ -+ MAKEHEADER(outp, PPP_EAP); -+ -+ PUTCHAR(EAP_RESPONSE, outp); -+ PUTCHAR(id, outp); -+ -+ lenloc = outp; -+ INCPTR(2, outp); -+ -+ /* -+ If the id in the request is unchanged, we must retransmit -+ the old data -+ */ -+ if(id == esp->es_client.ea_id) -+ eaptls_retransmit(esp->es_client.ea_session, &outp); -+ else -+ eaptls_send(esp->es_client.ea_session, &outp); -+ -+ outlen = (outp - outpacket_buf) - PPP_HDRLEN; -+ PUTSHORT(outlen, lenloc); -+ -+ output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen); -+ -+ esp->es_client.ea_id = id; -+ -+} -+ -+/* -+ * Send an EAP-TLS ack -+ */ -+static void -+eap_tls_sendack(esp, id) -+eap_state *esp; -+u_char id; -+{ -+ u_char *outp; -+ int outlen; -+ u_char *lenloc; -+ -+ outp = outpacket_buf; -+ -+ MAKEHEADER(outp, PPP_EAP); -+ -+ PUTCHAR(EAP_RESPONSE, outp); -+ PUTCHAR(id, outp); -+ esp->es_client.ea_id = id; -+ -+ lenloc = outp; -+ INCPTR(2, outp); -+ -+ PUTCHAR(EAPT_TLS, outp); -+ PUTCHAR(0, outp); -+ -+ outlen = (outp - outpacket_buf) - PPP_HDRLEN; -+ PUTSHORT(outlen, lenloc); -+ -+ output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen); -+ -+} -+#endif /* USE_EAPTLS */ -+ - static void - eap_send_nak(esp, id, type) - eap_state *esp; -@@ -1320,6 +1555,11 @@ - char rhostname[256]; - MD5_CTX mdContext; - u_char hash[MD5_SIGNATURE_SIZE]; -+#ifdef USE_EAPTLS -+ u_char flags; -+ struct eaptls_session *ets = esp->es_client.ea_session; -+#endif /* USE_EAPTLS */ -+ - #ifdef USE_SRP - struct t_client *tc; - struct t_num sval, gval, Nval, *Ap, Bval; -@@ -1456,6 +1696,100 @@ - esp->es_client.ea_namelen); - break; - -+#ifdef USE_EAPTLS -+ case EAPT_TLS: -+ -+ switch(esp->es_client.ea_state) { -+ -+ case eapListen: -+ -+ if (len < 1) { -+ error("EAP: received EAP-TLS Listen packet with no data"); -+ /* Bogus request; wait for something real. */ -+ return; -+ } -+ GETCHAR(flags, inp); -+ if(flags & EAP_TLS_FLAGS_START){ -+ -+ esp->es_client.ea_using_eaptls = 1; -+ -+ if (explicit_remote){ -+ esp->es_client.ea_peer = strdup(remote_name); -+ esp->es_client.ea_peerlen = strlen(remote_name); -+ } else -+ esp->es_client.ea_peer = NULL; -+ -+ /* Init ssl session */ -+ if(!eaptls_init_ssl_client(esp)) { -+ dbglog("cannot init ssl"); -+ eap_send_nak(esp, id, EAPT_TLS); -+ esp->es_client.ea_using_eaptls = 0; -+ break; -+ } -+ -+ ets = esp->es_client.ea_session; -+ eap_tls_response(esp, id); -+ esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : -+ eapTlsRecv); -+ break; -+ } -+ -+ /* The server has sent a bad start packet. */ -+ eap_send_nak(esp, id, EAPT_TLS); -+ break; -+ -+ case eapTlsRecvAck: -+ eap_tls_response(esp, id); -+ esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : -+ eapTlsRecv); -+ break; -+ -+ case eapTlsRecv: -+ if (len < 1) { -+ error("EAP: discarding EAP-TLS Receive packet with no data"); -+ /* Bogus request; wait for something real. */ -+ return; -+ } -+ eaptls_receive(ets, inp, len); -+ -+ if(ets->frag) { -+ eap_tls_sendack(esp, id); -+ esp->es_client.ea_state = eapTlsRecv; -+ break; -+ } -+ -+ if(ets->alert_recv) { -+ eap_tls_sendack(esp, id); -+ esp->es_client.ea_state = eapTlsRecvFailure; -+ break; -+ } -+ -+ /* Check if TLS handshake is finished */ -+ if(SSL_is_init_finished(ets->ssl)){ -+#ifdef MPPE -+ eaptls_gen_mppe_keys( ets, "client EAP encryption", 1 ); -+#endif -+ eaptls_free_session(ets); -+ eap_tls_sendack(esp, id); -+ esp->es_client.ea_state = eapTlsRecvSuccess; -+ break; -+ } -+ -+ eap_tls_response(esp,id); -+ esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : -+ eapTlsRecv); -+ -+ break; -+ -+ default: -+ eap_send_nak(esp, id, EAPT_TLS); -+ esp->es_client.ea_using_eaptls = 0; -+ break; -+ } -+ -+ break; -+#endif /* USE_EAPTLS */ -+ - #ifdef USE_SRP - case EAPT_SRP: - if (len < 1) { -@@ -1737,6 +2071,11 @@ - u_char dig[SHA_DIGESTSIZE]; - #endif /* USE_SRP */ - -+#ifdef USE_EAPTLS -+ struct eaptls_session *ets; -+ u_char flags; -+#endif /* USE_EAPTLS */ -+ - if (esp->es_server.ea_id != id) { - dbglog("EAP: discarding Response %d; expected ID %d", id, - esp->es_server.ea_id); -@@ -1776,6 +2115,64 @@ - eap_figure_next_state(esp, 0); - break; - -+#ifdef USE_EAPTLS -+ case EAPT_TLS: -+ switch(esp->es_server.ea_state) { -+ -+ case eapTlsRecv: -+ -+ ets = (struct eaptls_session *) esp->es_server.ea_session; -+ eap_figure_next_state(esp, -+ eaptls_receive(esp->es_server.ea_session, inp, len)); -+ -+ if(ets->alert_recv) { -+ eap_send_failure(esp); -+ break; -+ } -+ break; -+ -+ case eapTlsRecvAck: -+ if(len > 1) { -+ dbglog("EAP-TLS ACK with extra data"); -+ } -+ eap_figure_next_state(esp, 0); -+ break; -+ -+ case eapTlsRecvClient: -+ /* Receive authentication response from client */ -+ -+ if (len > 0) { -+ GETCHAR(flags, inp); -+ -+ if(len == 1 && !flags) { /* Ack = ok */ -+#ifdef MPPE -+ eaptls_gen_mppe_keys( esp->es_server.ea_session, "client EAP encryption", 0 ); -+#endif -+ eap_send_success(esp); -+ } -+ else { /* failure */ -+ warn("Server authentication failed"); -+ eap_send_failure(esp); -+ } -+ } -+ else -+ warn("Bogus EAP-TLS packet received from client"); -+ -+ eaptls_free_session(esp->es_server.ea_session); -+ -+ break; -+ -+ case eapTlsRecvAlertAck: -+ eap_send_failure(esp); -+ break; -+ -+ default: -+ eap_figure_next_state(esp, 1); -+ break; -+ } -+ break; -+#endif /* USE_EAPTLS */ -+ - case EAPT_NOTIFICATION: - dbglog("EAP unexpected Notification; response discarded"); - break; -@@ -1807,6 +2204,13 @@ - esp->es_server.ea_state = eapMD5Chall; - break; - -+#ifdef USE_EAPTLS -+ /* Send EAP-TLS start packet */ -+ case EAPT_TLS: -+ esp->es_server.ea_state = eapTlsStart; -+ break; -+#endif /* USE_EAPTLS */ -+ - default: - dbglog("EAP: peer requesting unknown Type %d", vallen); - switch (esp->es_server.ea_state) { -@@ -2018,13 +2422,27 @@ - int id; - int len; - { -- if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)) { -+ if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp) -+#ifdef USE_EAPTLS -+ && esp->es_client.ea_state != eapTlsRecvSuccess -+#endif /* USE_EAPTLS */ -+ ) { - dbglog("EAP unexpected success message in state %s (%d)", - eap_state_name(esp->es_client.ea_state), - esp->es_client.ea_state); - return; - } - -+#ifdef USE_EAPTLS -+ if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state != -+ eapTlsRecvSuccess) { -+ dbglog("EAP-TLS unexpected success message in state %s (%d)", -+ eap_state_name(esp->es_client.ea_state), -+ esp->es_client.ea_state); -+ return; -+ } -+#endif /* USE_EAPTLS */ -+ - if (esp->es_client.ea_timeout > 0) { - UNTIMEOUT(eap_client_timeout, (void *)esp); - } -@@ -2150,6 +2568,9 @@ - int code, id, len, rtype, vallen; - u_char *pstart; - u_int32_t uval; -+#ifdef USE_EAPTLS -+ u_char flags; -+#endif /* USE_EAPTLS */ - - if (inlen < EAP_HEADERLEN) - return (0); -@@ -2214,6 +2635,24 @@ - } - break; - -+#ifdef USE_EAPTLS -+ case EAPT_TLS: -+ if (len < 1) -+ break; -+ GETCHAR(flags, inp); -+ len--; -+ -+ if(flags == 0 && len == 0){ -+ printer(arg, " Ack"); -+ break; -+ } -+ -+ printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -"); -+ printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-"); -+ printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- "); -+ break; -+#endif /* USE_EAPTLS */ -+ - case EAPT_SRP: - if (len < 3) - goto truncated; -@@ -2325,6 +2764,25 @@ - } - break; - -+#ifdef USE_EAPTLS -+ case EAPT_TLS: -+ if (len < 1) -+ break; -+ GETCHAR(flags, inp); -+ len--; -+ -+ if(flags == 0 && len == 0){ -+ printer(arg, " Ack"); -+ break; -+ } -+ -+ printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -"); -+ printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-"); -+ printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- "); -+ -+ break; -+#endif /* USE_EAPTLS */ -+ - case EAPT_NAK: - if (len <= 0) { - printer(arg, " "); -@@ -2426,3 +2884,4 @@ - - return (inp - pstart); - } -+ ---- a/pppd/eap.h -+++ b/pppd/eap.h -@@ -84,6 +84,16 @@ - eapClosed, /* Authentication not in use */ - eapListen, /* Client ready (and timer running) */ - eapIdentify, /* EAP Identify sent */ -+ eapTlsStart, /* Send EAP-TLS start packet */ -+ eapTlsRecv, /* Receive EAP-TLS tls data */ -+ eapTlsSendAck, /* Send EAP-TLS ack */ -+ eapTlsSend, /* Send EAP-TLS tls data */ -+ eapTlsRecvAck, /* Receive EAP-TLS ack */ -+ eapTlsRecvClient, /* Receive EAP-TLS auth response from client*/ -+ eapTlsSendAlert, /* Send EAP-TLS tls alert (server)*/ -+ eapTlsRecvAlertAck, /* Receive EAP-TLS ack after sending alert */ -+ eapTlsRecvSuccess, /* Receive EAP success */ -+ eapTlsRecvFailure, /* Receive EAP failure */ - eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */ - eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */ - eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */ -@@ -95,9 +105,18 @@ - - #define EAP_STATES \ - "Initial", "Pending", "Closed", "Listen", "Identify", \ -+ "TlsStart", "TlsRecv", "TlsSendAck", "TlsSend", "TlsRecvAck", "TlsRecvClient",\ -+ "TlsSendAlert", "TlsRecvAlertAck" , "TlsRecvSuccess", "TlsRecvFailure", \ - "SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth" - --#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen) -+#ifdef USE_EAPTLS -+#define eap_client_active(esp) ((esp)->es_client.ea_state != eapInitial &&\ -+ (esp)->es_client.ea_state != eapPending &&\ -+ (esp)->es_client.ea_state != eapClosed) -+#else -+#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen) -+#endif /* USE_EAPTLS */ -+ - #define eap_server_active(esp) \ - ((esp)->es_server.ea_state >= eapIdentify && \ - (esp)->es_server.ea_state <= eapMD5Chall) -@@ -112,11 +131,17 @@ - u_short ea_namelen; /* Length of our name */ - u_short ea_peerlen; /* Length of peer's name */ - enum eap_state_code ea_state; -+#ifdef USE_EAPTLS -+ enum eap_state_code ea_prev_state; -+#endif - u_char ea_id; /* Current id */ - u_char ea_requests; /* Number of Requests sent/received */ - u_char ea_responses; /* Number of Responses */ - u_char ea_type; /* One of EAPT_* */ - u_int32_t ea_keyflags; /* SRP shared key usage flags */ -+#ifdef USE_EAPTLS -+ bool ea_using_eaptls; -+#endif - }; - - /* -@@ -139,7 +164,12 @@ - * Timeouts. - */ - #define EAP_DEFTIMEOUT 3 /* Timeout (seconds) for rexmit */ -+#ifdef USE_EAPTLS -+#define EAP_DEFTRANSMITS 30 /* max # times to transmit */ -+ /* certificates can be long ... */ -+#else - #define EAP_DEFTRANSMITS 10 /* max # times to transmit */ -+#endif /* USE_EAPTLS */ - #define EAP_DEFREQTIME 20 /* Time to wait for peer request */ - #define EAP_DEFALLOWREQ 20 /* max # times to accept requests */ - ---- a/pppd/md5.c -+++ b/pppd/md5.c -@@ -33,6 +33,8 @@ - *********************************************************************** - */ - -+#ifndef USE_EAPTLS -+ - #include - #include "md5.h" - -@@ -305,3 +307,5 @@ - ** End of md5.c ** - ******************************** (cut) ******************************** - */ -+#endif /* USE_EAPTLS */ -+ ---- a/pppd/md5.h -+++ b/pppd/md5.h -@@ -36,6 +36,7 @@ - ** documentation and/or software. ** - *********************************************************************** - */ -+#ifndef USE_EAPTLS - - #ifndef __MD5_INCLUDE__ - -@@ -63,3 +64,5 @@ - - #define __MD5_INCLUDE__ - #endif /* __MD5_INCLUDE__ */ -+ -+#endif /* USE_EAPTLS */ ---- a/pppd/pathnames.h -+++ b/pppd/pathnames.h -@@ -21,6 +21,13 @@ - #define _PATH_UPAPFILE _ROOT_PATH "/etc/ppp/pap-secrets" - #define _PATH_CHAPFILE _ROOT_PATH "/etc/ppp/chap-secrets" - #define _PATH_SRPFILE _ROOT_PATH "/etc/ppp/srp-secrets" -+ -+#ifdef USE_EAPTLS -+#define _PATH_EAPTLSCLIFILE _ROOT_PATH "/etc/ppp/eaptls-client" -+#define _PATH_EAPTLSSERVFILE _ROOT_PATH "/etc/ppp/eaptls-server" -+#define _PATH_OPENSSLCONFFILE _ROOT_PATH "/etc/ppp/openssl.cnf" -+#endif /* USE_EAPTLS */ -+ - #define _PATH_SYSOPTIONS _ROOT_PATH "/etc/ppp/options" - #define _PATH_IPUP _ROOT_PATH "/etc/ppp/ip-up" - #define _PATH_IPDOWN _ROOT_PATH "/etc/ppp/ip-down" ---- a/pppd/plugins/Makefile.linux -+++ b/pppd/plugins/Makefile.linux -@@ -4,6 +4,9 @@ - LDFLAGS = $(LDOPTS) - INSTALL = install - -+# EAP-TLS -+CFLAGS += -DUSE_EAPTLS=1 -+ - DESTDIR = $(INSTROOT)@DESTDIR@ - BINDIR = $(DESTDIR)/sbin - MANDIR = $(DESTDIR)/share/man/man8 ---- a/pppd/plugins/passprompt.c -+++ b/pppd/plugins/passprompt.c -@@ -107,4 +107,7 @@ - { - add_options(options); - pap_passwd_hook = promptpass; -+#ifdef USE_EAPTLS -+ eaptls_passwd_hook = promptpass; -+#endif - } ---- a/pppd/plugins/passwordfd.c -+++ b/pppd/plugins/passwordfd.c -@@ -79,4 +79,8 @@ - - chap_check_hook = pwfd_check; - chap_passwd_hook = pwfd_passwd; -+ -+#ifdef USE_EAPTLS -+ eaptls_passwd_hook = pwfd_passwd; -+#endif - } ---- a/pppd/pppd.8 -+++ b/pppd/pppd.8 -@@ -253,6 +253,12 @@ - compression in the corresponding direction. Use \fInobsdcomp\fR or - \fIbsdcomp 0\fR to disable BSD-Compress compression entirely. - .TP -+.B ca \fIca-file -+(EAP-TLS) Use the file \fIca-file\fR as the X.509 Certificate Authority -+(CA) file (in PEM format), needed for setting up an EAP-TLS connection. -+This option is used on the client-side in conjunction with the \fBcert\fR -+and \fBkey\fR options. -+.TP - .B cdtrcts - Use a non-standard hardware flow control (i.e. DTR/CTS) to control - the flow of data on the serial port. If neither the \fIcrtscts\fR, -@@ -264,6 +270,12 @@ - bi-directional flow control. The sacrifice is that this flow - control mode does not permit using DTR as a modem control line. - .TP -+.B cert \fIcertfile -+(EAP-TLS) Use the file \fIcertfile\fR as the X.509 certificate (in PEM -+format), needed for setting up an EAP-TLS connection. This option is -+used on the client-side in conjunction with the \fBca\fR and -+\fBkey\fR options. -+.TP - .B chap\-interval \fIn - If this option is given, pppd will rechallenge the peer every \fIn\fR - seconds. -@@ -292,6 +304,18 @@ - 1000 (1 second). This wait period only applies if the \fBconnect\fR - or \fBpty\fR option is used. - .TP -+.B crl \fIfilename -+(EAP-TLS) Use the file \fIfilename\fR as the Certificate Revocation List -+to check for the validity of the peer's certificate. This option is not -+mandatory for setting up an EAP-TLS connection. Also see the \fBcrl-dir\fR -+option. -+.TP -+.B crl-dir \fIdirectory -+(EAP-TLS) Use the directory \fIdirectory\fR to scan for CRL files in -+has format ($hash.r0) to check for the validity of the peer's certificate. -+This option is not mandatory for setting up an EAP-TLS connection. -+Also see the \fBcrl\fR option. -+.TP - .B debug - Enables connection debugging facilities. - If this option is given, pppd will log the contents of all -@@ -561,6 +585,12 @@ - the kernel are logged by syslog(1) to a file as directed in the - /etc/syslog.conf configuration file. - .TP -+.B key \fIkeyfile -+(EAP-TLS) Use the file \fIkeyfile\fR as the private key file (in PEM -+format), needed for setting up an EAP-TLS connection. This option is -+used on the client-side in conjunction with the \fBca\fR and -+\fBcert\fR options. -+.TP - .B ktune - Enables pppd to alter kernel settings as appropriate. Under Linux, - pppd will enable IP forwarding (i.e. set /proc/sys/net/ipv4/ip_forward -@@ -724,6 +754,9 @@ - Disable Address/Control compression in both directions (send and - receive). - .TP -+.B need-peer-eap -+(EAP-TLS) Require the peer to verify our authentication credentials. -+.TP - .B noauth - Do not require the peer to authenticate itself. This option is - privileged. ---- a/pppd/pppd.h -+++ b/pppd/pppd.h -@@ -338,6 +338,11 @@ - extern bool dryrun; /* check everything, print options, exit */ - extern int child_wait; /* # seconds to wait for children at end */ - -+#ifdef USE_EAPTLS -+extern char *crl_dir; -+extern char *crl_file; -+#endif /* USE_EAPTLS */ -+ - #ifdef MAXOCTETS - extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ - extern int maxoctets_dir; /* Direction : -@@ -758,6 +763,10 @@ - extern int (*chap_passwd_hook) __P((char *user, char *passwd)); - extern void (*multilink_join_hook) __P((void)); - -+#ifdef USE_EAPTLS -+extern int (*eaptls_passwd_hook) __P((char *user, char *passwd)); -+#endif -+ - /* Let a plugin snoop sent and received packets. Useful for L2TP */ - extern void (*snoop_recv_hook) __P((unsigned char *p, int len)); - extern void (*snoop_send_hook) __P((unsigned char *p, int len)); diff -Nru ppp-2.4.7/debian/patches/fix_linkpidfile ppp-2.4.9/debian/patches/fix_linkpidfile --- ppp-2.4.7/debian/patches/fix_linkpidfile 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/fix_linkpidfile 1970-01-01 01:00:00.000000000 +0100 @@ -1,39 +0,0 @@ -make sure that the linkpidfile is always created - -Subject: Bug#284382: ppp: linkpidfile is not created upon detachment -From: - -Package: ppp -Version: 2.4.2+20040428-2 -Severity: wishlist - -When pppd detaches from the parent normally, that is, without nodetach -or updetach set, the linkpidfile is not created even when linkname is -set. - -This is because the create_linkpidfile call in detach() is only made -if the linkpidfile is filled in. However, linkpidfile is never filled -in until create_linkpidfile has been called. - -IMHO the call should be made uncondtionally in detach() since -create_linkpidfile does its own check on linkname anyway. - -Please note that the version of pppd in woody always wrote the -linkpidfile after detaching. It did so in main() however. That -call has now been removed which is why I'm seeing this problem. - -[...] - --- ---- a/pppd/main.c -+++ b/pppd/main.c -@@ -770,8 +770,7 @@ detach() - /* update pid files if they have been written already */ - if (pidfilename[0]) - create_pidfile(pid); -- if (linkpidfile[0]) -- create_linkpidfile(pid); -+ create_linkpidfile(pid); - exit(0); /* parent dies */ - } - setsid(); diff -Nru ppp-2.4.7/debian/patches/glibc-2.28.patch ppp-2.4.9/debian/patches/glibc-2.28.patch --- ppp-2.4.7/debian/patches/glibc-2.28.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/glibc-2.28.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,107 +0,0 @@ -From 3c7b86229f7bd2600d74db14b1fe5b3896be3875 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= -Date: Fri, 6 Apr 2018 14:27:18 +0200 -Subject: [PATCH] pppd: Use openssl for the DES instead of the libcrypt / glibc -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -[https://github.com/paulusmack/ppp/commit/3c7b86229f7bd2600d74db14b1fe5b3896be3875] - -It seems the latest glibc (in Fedora glibc-2.27.9000-12.fc29) dropped -libcrypt. The libxcrypt standalone package can be used instead, but -it dropped the old setkey/encrypt API which ppp uses for DES. There -is support for using openssl in pppcrypt.c, but it contains typos -preventing it from compiling and seems to be written for an ancient -openssl version. - -This updates the code to use current openssl. - -[paulus@ozlabs.org - wrote the commit description, fixed comment in - Makefile.linux.] - -Signed-off-by: Jaroslav Škarvada -Signed-off-by: Paul Mackerras ---- - pppd/Makefile.linux | 7 ++++--- - pppd/pppcrypt.c | 18 +++++++++--------- - 2 files changed, 13 insertions(+), 12 deletions(-) ---- ppp-2.4.7.orig/pppd/Makefile.linux -+++ ppp-2.4.7/pppd/Makefile.linux -@@ -35,10 +35,10 @@ endif - COPTS = -O2 -pipe -Wall -g - LIBS = -lcrypto - --# Uncomment the next 2 lines to include support for Microsoft's -+# 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 -+#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 -@@ -142,7 +142,8 @@ endif - - ifdef NEEDDES - ifndef USE_CRYPT --LIBS += -ldes $(LIBS) -+CFLAGS += -I/usr/include/openssl -+LIBS += -lcrypto - else - CFLAGS += -DUSE_CRYPT=1 - endif ---- ppp-2.4.7.orig/pppd/pppcrypt.c -+++ ppp-2.4.7/pppd/pppcrypt.c -@@ -64,7 +64,7 @@ u_char *des_key; /* OUT 64 bit DES key w - des_key[7] = Get7Bits(key, 49); - - #ifndef USE_CRYPT -- des_set_odd_parity((des_cblock *)des_key); -+ DES_set_odd_parity((DES_cblock *)des_key); - #endif - } - -@@ -158,25 +158,25 @@ u_char *clear; /* OUT 8 octets */ - } - - #else /* USE_CRYPT */ --static des_key_schedule key_schedule; -+static DES_key_schedule key_schedule; - - bool - DesSetkey(key) - u_char *key; - { -- des_cblock des_key; -+ DES_cblock des_key; - MakeKey(key, des_key); -- des_set_key(&des_key, key_schedule); -+ DES_set_key(&des_key, &key_schedule); - return (1); - } - - bool --DesEncrypt(clear, key, cipher) -+DesEncrypt(clear, cipher) - u_char *clear; /* IN 8 octets */ - u_char *cipher; /* OUT 8 octets */ - { -- des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, -- key_schedule, 1); -+ DES_ecb_encrypt((DES_cblock *)clear, (DES_cblock *)cipher, -+ &key_schedule, 1); - return (1); - } - -@@ -185,8 +185,8 @@ DesDecrypt(cipher, clear) - u_char *cipher; /* IN 8 octets */ - u_char *clear; /* OUT 8 octets */ - { -- des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear, -- key_schedule, 0); -+ DES_ecb_encrypt((DES_cblock *)cipher, (DES_cblock *)clear, -+ &key_schedule, 0); - return (1); - } - diff -Nru ppp-2.4.7/debian/patches/ipv6-accept-remote ppp-2.4.9/debian/patches/ipv6-accept-remote --- ppp-2.4.7/debian/patches/ipv6-accept-remote 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/ipv6-accept-remote 1970-01-01 01:00:00.000000000 +0100 @@ -1,54 +0,0 @@ ---- a/pppd/ipv6cp.c -+++ b/pppd/ipv6cp.c -@@ -234,6 +234,8 @@ static option_t ipv6cp_option_list[] = { - - { "ipv6cp-accept-local", o_bool, &ipv6cp_allowoptions[0].accept_local, - "Accept peer's interface identifier for us", 1 }, -+ { "ipv6cp-accept-remote", o_bool, &ipv6cp_allowoptions[0].accept_remote, -+ "Accept peer's interface identifier for itself", 1 }, - - { "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip, - "Use (default) IPv4 address as interface identifier", 1 }, -@@ -426,6 +428,7 @@ ipv6cp_init(unit) - memset(ao, 0, sizeof(*ao)); - - wo->accept_local = 1; -+ wo->accept_remote = 1; - wo->neg_ifaceid = 1; - ao->neg_ifaceid = 1; - -@@ -951,7 +954,7 @@ ipv6cp_reqci(f, inp, len, reject_if_disa - orc = CONFREJ; /* Reject CI */ - break; - } -- if (!eui64_iszero(wo->hisid) && -+ if (!eui64_iszero(wo->hisid) && !wo->accept_remote && - !eui64_equals(ifaceid, wo->hisid) && - eui64_iszero(go->hisid)) { - ---- a/pppd/ipv6cp.h -+++ b/pppd/ipv6cp.h -@@ -150,7 +150,8 @@ - typedef struct ipv6cp_options { - int neg_ifaceid; /* Negotiate interface identifier? */ - int req_ifaceid; /* Ask peer to send interface identifier? */ -- int accept_local; /* accept peer's value for iface id? */ -+ int accept_local; /* accept peer's value for our iface id? */ -+ int accept_remote; /* accept peer's value for his iface id? */ - int opt_local; /* ourtoken set by option */ - int opt_remote; /* histoken set by option */ - int use_ip; /* use IP as interface identifier */ ---- a/pppd/pppd.8 -+++ b/pppd/pppd.8 -@@ -462,6 +462,11 @@ With this option, pppd will accept the p - interface identifier, even if the local IPv6 interface identifier - was specified in an option. - .TP -+.B ipv6cp\-accept\-remote -+With this option, pppd will accept the peer's idea of its (remote) -+IPv6 interface identifier, even if the remote IPv6 interface -+identifier was specified in an option. -+.TP - .B ipv6cp\-max\-configure \fIn - Set the maximum number of IPv6CP configure-request transmissions to - \fIn\fR (default 10). diff -Nru ppp-2.4.7/debian/patches/makefiles_cleanup ppp-2.4.9/debian/patches/makefiles_cleanup --- ppp-2.4.7/debian/patches/makefiles_cleanup 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/makefiles_cleanup 1970-01-01 01:00:00.000000000 +0100 @@ -1,260 +0,0 @@ -Makefiles cleanup - -Factor-out $COPTS and $LDOPTS to allow distributions to easily override -them. Properly use $LDFLAGS when linking and $CFLAGS when compiling. -Do not strip the installed binaries: this should be done by the -packaging system if required. - ---- a/chat/Makefile.linux -+++ b/chat/Makefile.linux -@@ -12,20 +12,21 @@ - - COPTS= -O2 -g -pipe - CFLAGS= $(COPTS) $(CDEFS) -+LDFLAGS=$(LDOPTS) - - INSTALL= install - - all: chat - - chat: chat.o -- $(CC) -o 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) -s -c chat $(BINDIR) -+ $(INSTALL) -c chat $(BINDIR) - $(INSTALL) -c -m 644 chat.8 $(MANDIR) - - clean: ---- a/pppd/plugins/Makefile.linux -+++ b/pppd/plugins/Makefile.linux -@@ -1,7 +1,7 @@ - #CC = gcc - COPTS = -O2 -g - CFLAGS = $(COPTS) -I.. -I../../include -fPIC --LDFLAGS = -shared -+LDFLAGS = $(LDOPTS) - INSTALL = install - - DESTDIR = $(INSTROOT)@DESTDIR@ -@@ -30,7 +30,7 @@ - for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d all || exit $$?; done - - %.so: %.c -- $(CC) -o $@ $(LDFLAGS) $(CFLAGS) $^ -+ $(CC) -o $@ $(LDFLAGS) -shared $(CFLAGS) $^ - - VERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../patchlevel.h) - ---- a/pppd/plugins/pppoatm/Makefile.linux -+++ b/pppd/plugins/pppoatm/Makefile.linux -@@ -1,7 +1,7 @@ - #CC = gcc - COPTS = -O2 -g - CFLAGS = $(COPTS) -I../.. -I../../../include -fPIC --LDFLAGS = -shared -+LDFLAGS = $(LDOPTS) - INSTALL = install - - #*********************************************************************** -@@ -33,7 +33,7 @@ - all: $(PLUGIN) - - $(PLUGIN): $(PLUGIN_OBJS) -- $(CC) $(CFLAGS) -o $@ -shared $^ $(LIBS) -+ $(CC) $(LDFLAGS) -o $@ -shared $^ $(LIBS) - - install: all - $(INSTALL) -d -m 755 $(LIBDIR) ---- a/pppd/plugins/pppol2tp/Makefile.linux -+++ b/pppd/plugins/pppol2tp/Makefile.linux -@@ -1,7 +1,7 @@ - #CC = gcc - COPTS = -O2 -g - CFLAGS = $(COPTS) -I. -I../.. -I../../../include -fPIC --LDFLAGS = -shared -+LDFLAGS = $(LDOPTS) - INSTALL = install - - #*********************************************************************** -@@ -16,7 +16,7 @@ - all: $(PLUGINS) - - %.so: %.o -- $(CC) $(CFLAGS) -o $@ -shared $^ $(LIBS) -+ $(CC) $(LDFLAGS) -o $@ -shared $^ $(LIBS) - - install: all - $(INSTALL) -d -m 755 $(LIBDIR) ---- a/pppd/plugins/radius/Makefile.linux -+++ b/pppd/plugins/radius/Makefile.linux -@@ -12,7 +12,9 @@ - INSTALL = install - - PLUGIN=radius.so radattr.so radrealms.so --CFLAGS=-I. -I../.. -I../../../include -O2 -fPIC -DRC_LOG_FACILITY=LOG_DAEMON -+COPTS=-g -O2 -+CFLAGS = $(COPTS) -I. -I../.. -I../../../include -fPIC -DRC_LOG_FACILITY=LOG_DAEMON -+LDFLAGS= $(LDOPTS) - - # Uncomment the next line to include support for Microsoft's - # MS-CHAP authentication protocol. -@@ -36,20 +38,20 @@ - - install: all - $(INSTALL) -d -m 755 $(LIBDIR) -- $(INSTALL) -s -c -m 755 radius.so $(LIBDIR) -- $(INSTALL) -s -c -m 755 radattr.so $(LIBDIR) -- $(INSTALL) -s -c -m 755 radrealms.so $(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) -o radius.so -shared radius.o libradiusclient.a -+ $(CC) $(LDFLAGS) -o radius.so -shared radius.o libradiusclient.a - - radattr.so: radattr.o -- $(CC) -o radattr.so -shared radattr.o -+ $(CC) $(LDFLAGS) -o radattr.so -shared radattr.o - - radrealms.so: radrealms.o -- $(CC) -o radrealms.so -shared 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 ---- a/pppd/plugins/rp-pppoe/Makefile.linux -+++ b/pppd/plugins/rp-pppoe/Makefile.linux -@@ -27,10 +27,12 @@ - - COPTS=-O2 -g - CFLAGS=$(COPTS) -I../../../include '-DRP_VERSION="$(RP_VERSION)"' -+LDFLAGS=$(LDOPTS) -+ - all: rp-pppoe.so pppoe-discovery - - pppoe-discovery: pppoe-discovery.o debug.o -- $(CC) -o 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) -c -o pppoe-discovery.o pppoe-discovery.c -@@ -39,13 +41,13 @@ - $(CC) $(CFLAGS) -c -o debug.o debug.c - - rp-pppoe.so: plugin.o discovery.o if.o common.o -- $(CC) -o rp-pppoe.so -shared plugin.o discovery.o if.o common.o -+ $(CC) $(LDFLAGS) -o rp-pppoe.so -shared $^ - - install: all - $(INSTALL) -d -m 755 $(LIBDIR) -- $(INSTALL) -s -c -m 4550 rp-pppoe.so $(LIBDIR) -+ $(INSTALL) -c -m 4550 rp-pppoe.so $(LIBDIR) - $(INSTALL) -d -m 755 $(BINDIR) -- $(INSTALL) -s -c -m 555 pppoe-discovery $(BINDIR) -+ $(INSTALL) -c -m 555 pppoe-discovery $(BINDIR) - - clean: - rm -f *.o *.so pppoe-discovery ---- a/pppstats/Makefile.linux -+++ b/pppstats/Makefile.linux -@@ -10,23 +10,24 @@ - PPPSTATOBJS = pppstats.o - - #CC = gcc --COPTS = -O -+COPTS = -O2 -g - COMPILE_FLAGS = -I../include - LIBS = - - INSTALL= install - - CFLAGS = $(COPTS) $(COMPILE_FLAGS) -+LDFLAGS= $(LDOPTS) - - all: pppstats - - install: pppstats - -mkdir -p $(MANDIR) -- $(INSTALL) -s -c pppstats $(BINDIR) -+ $(INSTALL) -c pppstats $(BINDIR) - $(INSTALL) -c -m 444 pppstats.8 $(MANDIR) - - pppstats: $(PPPSTATSRCS) -- $(CC) $(CFLAGS) -o pppstats pppstats.c $(LIBS) -+ $(CC) $(LDFLAGS) $(CFLAGS) -o pppstats pppstats.c $(LIBS) - - clean: - rm -f pppstats *~ #* core ---- a/pppdump/Makefile.linux -+++ b/pppdump/Makefile.linux -@@ -2,7 +2,10 @@ - BINDIR = $(DESTDIR)/sbin - MANDIR = $(DESTDIR)/share/man/man8 - --CFLAGS= -O -I../include/net -+COPTS=-O2 -g -+CFLAGS= $(COPTS) -I../include/net -+LDFLAGS=$(LDOPTS) -+ - OBJS = pppdump.o bsd-comp.o deflate.o zlib.o - - INSTALL= install -@@ -10,12 +13,12 @@ - all: pppdump - - pppdump: $(OBJS) -- $(CC) -o pppdump $(OBJS) -+ $(CC) $(LDFLAGS) -o pppdump $(OBJS) - - clean: - rm -f pppdump $(OBJS) *~ - - install: - mkdir -p $(BINDIR) $(MANDIR) -- $(INSTALL) -s -c pppdump $(BINDIR) -+ $(INSTALL) -c pppdump $(BINDIR) - $(INSTALL) -c -m 444 pppdump.8 $(MANDIR) ---- a/pppd/Makefile.linux -+++ b/pppd/Makefile.linux -@@ -83,6 +83,7 @@ - COMPILE_FLAGS= -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MMAP - - CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) '-DDESTDIR="@DESTDIR@"' -+LDFLAGS=$(LDOPTS) - - ifdef CHAPMS - CFLAGS += -DCHAPMS=1 -@@ -102,7 +103,7 @@ - CFLAGS += -DUSE_SRP -DOPENSSL -I/usr/local/ssl/include - LIBS += -lsrp -L/usr/local/ssl/lib -lcrypto - TARGETS += srp-entry --EXTRAINSTALL = $(INSTALL) -s -c -m 555 srp-entry $(BINDIR)/srp-entry -+EXTRAINSTALL = $(INSTALL) -c -m 555 srp-entry $(BINDIR)/srp-entry - MANPAGES += srp-entry.8 - EXTRACLEAN += srp-entry.o - NEEDDES=y -@@ -208,13 +209,13 @@ - install: pppd - mkdir -p $(BINDIR) $(MANDIR) - $(EXTRAINSTALL) -- $(INSTALL) -s -c -m 555 pppd $(BINDIR)/pppd -+ $(INSTALL) -c -m 555 pppd $(BINDIR)/pppd - if chgrp pppusers $(BINDIR)/pppd 2>/dev/null; then \ - chmod o-rx,u+s $(BINDIR)/pppd; fi - $(INSTALL) -c -m 444 pppd.8 $(MANDIR) - - pppd: $(PPPDOBJS) -- $(CC) $(CFLAGS) $(LDFLAGS) -o pppd $(PPPDOBJS) $(LIBS) -+ $(CC) $(LDFLAGS) -o pppd $(PPPDOBJS) $(LIBS) - - srp-entry: srp-entry.c - $(CC) $(CFLAGS) $(LDFLAGS) -o $@ srp-entry.c $(LIBS) diff -Nru ppp-2.4.7/debian/patches/no_crypt_hack ppp-2.4.9/debian/patches/no_crypt_hack --- ppp-2.4.7/debian/patches/no_crypt_hack 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/no_crypt_hack 2021-02-25 19:12:31.000000000 +0100 @@ -4,7 +4,7 @@ --- a/pppd/auth.c +++ b/pppd/auth.c -@@ -1442,8 +1442,10 @@ check_passwd(unit, auser, userlen, apass +@@ -1509,8 +1509,10 @@ if (secret[0] != 0 && !login_secret) { /* password given in pap-secrets - must match */ if (cryptpap || strcmp(passwd, secret) != 0) { @@ -17,14 +17,14 @@ } --- a/pppd/Makefile.linux +++ b/pppd/Makefile.linux -@@ -121,10 +121,14 @@ CFLAGS += -DHAS_SHADOW +@@ -143,10 +143,14 @@ #LIBS += -lshadow $(LIBS) endif +ifdef NO_CRYPT_HACK +CFLAGS += -DNO_CRYPT_HACK +else - ifneq ($(wildcard /usr/include/crypt.h),) + ifeq ($(shell echo '\#include ' | $(CC) -E - >/dev/null 2>&1 && echo yes),yes) CFLAGS += -DHAVE_CRYPT_H=1 LIBS += -lcrypt endif @@ -34,7 +34,7 @@ CFLAGS += -DHAVE_LOGWTMP=1 --- a/pppd/session.c +++ b/pppd/session.c -@@ -351,8 +351,10 @@ session_start(flags, user, passwd, ttyNa +@@ -343,8 +343,10 @@ */ if (pw->pw_passwd == NULL || strlen(pw->pw_passwd) < 2) return SESSION_FAILED; diff -Nru ppp-2.4.7/debian/patches/ppp-2.3.11-oedod.dif ppp-2.4.9/debian/patches/ppp-2.3.11-oedod.dif --- ppp-2.4.7/debian/patches/ppp-2.3.11-oedod.dif 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/ppp-2.3.11-oedod.dif 2021-02-25 19:12:31.000000000 +0100 @@ -1,3 +1,16 @@ +Forwarded: https://github.com/paulusmack/ppp/issues/187 + +Upstream said: + +" +Hmmm, dial-on-demand was never tested with the sync option, and in fact I don't +know what devices would use that option. + +To be accepted, the patch would need a sign-off and a description that +explained the changes in the patch - in particular, what the large lump of code +added to demand_rexmit() is doing. +" + --- a/pppd/demand.c +++ b/pppd/demand.c @@ -36,6 +36,8 @@ @@ -18,7 +31,7 @@ #ifdef PPP_FILTER #include #endif -@@ -221,6 +225,14 @@ loop_chars(p, n) +@@ -218,6 +222,14 @@ int c, rv; rv = 0; @@ -33,14 +46,12 @@ for (; n > 0; --n) { c = *p++; if (c == PPP_FLAG) { -@@ -299,17 +311,102 @@ loop_frame(frame, len) +@@ -294,16 +306,101 @@ * loopback, now that the real serial link is up. */ void --demand_rexmit(proto) -+demand_rexmit(proto, newip) - int proto; -+ u_int32_t newip; +-demand_rexmit(int proto) ++demand_rexmit(int proto, u_int32_t newip) { struct packet *pkt, *prev, *nextpkt; + unsigned short checksum; @@ -53,9 +64,11 @@ prev = NULL; pkt = pend_q; pend_q = NULL; ++ + tv.tv_sec = 1; + tv.tv_usec = 0; -+ select(0,NULL,NULL,NULL,&tv); /* Sleep for 1 Seconds */ ++ select(0,NULL,NULL,NULL,&tv); /* Sleep for 1 Second */ ++ for (; pkt != NULL; pkt = nextpkt) { nextpkt = pkt->next; if (PPP_PROTOCOL(pkt->data) == proto) { @@ -67,7 +80,6 @@ + if (checksum == 0xFFFF) { + checksum = 0; + } -+ + + if (pkt->data[13] == 17) { + pkt_checksum = *((unsigned short *) (pkt->data+10+iphdr)); @@ -139,7 +151,7 @@ } else { --- a/pppd/ipcp.c +++ b/pppd/ipcp.c -@@ -1875,7 +1875,7 @@ ipcp_up(f) +@@ -1850,7 +1850,7 @@ proxy_arp_set[f->unit] = 1; } @@ -150,9 +162,9 @@ } else { --- a/pppd/ipv6cp.c +++ b/pppd/ipv6cp.c -@@ -1232,7 +1232,7 @@ ipv6cp_up(f) - } - +@@ -1253,7 +1253,7 @@ + if (sif6defaultroute(f->unit, go->ourid, ho->hisid)) + default_route_set[f->unit] = 1; } - demand_rexmit(PPP_IPV6); + demand_rexmit(PPP_IPV6,0); @@ -161,12 +173,12 @@ } else { --- a/pppd/pppd.h +++ b/pppd/pppd.h -@@ -564,7 +564,7 @@ void demand_conf __P((void)); /* config - void demand_block __P((void)); /* set all NPs to queue up packets */ - void demand_unblock __P((void)); /* set all NPs to pass packets */ - void demand_discard __P((void)); /* set all NPs to discard packets */ --void demand_rexmit __P((int)); /* retransmit saved frames for an NP */ -+void demand_rexmit __P((int, u_int32_t)); /* retransmit saved frames for an NP*/ - int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ - int loop_frame __P((unsigned char *, int)); /* should we bring link up? */ +@@ -598,7 +598,7 @@ + void demand_block(void); /* set all NPs to queue up packets */ + void demand_unblock(void); /* set all NPs to pass packets */ + void demand_discard(void); /* set all NPs to discard packets */ +-void demand_rexmit(int); /* retransmit saved frames for an NP */ ++void demand_rexmit(int, u_int32_t); /* retransmit saved frames for an NP */ + int loop_chars(unsigned char *, int); /* process chars from loopback */ + int loop_frame(unsigned char *, int); /* should we bring link up? */ diff -Nru ppp-2.4.7/debian/patches/ppp-2.4.2-stripMSdomain ppp-2.4.9/debian/patches/ppp-2.4.2-stripMSdomain --- ppp-2.4.7/debian/patches/ppp-2.4.2-stripMSdomain 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/ppp-2.4.2-stripMSdomain 1970-01-01 01:00:00.000000000 +0100 @@ -1,35 +0,0 @@ -diff -ruN ppp.orig/pppd/chap-new.c ppp/pppd/chap-new.c ---- ppp.orig/pppd/chap-new.c 2003-11-27 23:25:17.000000000 +0100 -+++ ppp/pppd/chap-new.c 2003-12-02 12:26:21.000000000 +0100 -@@ -57,6 +57,7 @@ - int chap_timeout_time = 3; - int chap_max_transmits = 10; - int chap_rechallenge_time = 0; -+int chapms_strip_domain = 0; - - /* - * Command-line options. -@@ -68,6 +69,8 @@ - "Set max #xmits for challenge", OPT_PRIO }, - { "chap-interval", o_int, &chap_rechallenge_time, - "Set interval for rechallenge", OPT_PRIO }, -+ { "chapms-strip-domain", o_bool, &chapms_strip_domain, -+ "Strip the domain prefix before the Username", 1 }, - { NULL } - }; - -@@ -338,6 +341,14 @@ - /* Null terminate and clean remote name. */ - slprintf(rname, sizeof(rname), "%.*v", len, name); - name = rname; -+ -+ /* strip the MS domain name */ -+ if (chapms_strip_domain && strrchr(rname, '\\')) { -+ char tmp[MAXNAMELEN+1]; -+ -+ strcpy(tmp, strrchr(rname, '\\') + 1); -+ strcpy(rname, tmp); -+ } - } - - if (chap_verify_hook) diff -Nru ppp-2.4.7/debian/patches/ppp-2.4.4-strncatfix.patch ppp-2.4.9/debian/patches/ppp-2.4.4-strncatfix.patch --- ppp-2.4.7/debian/patches/ppp-2.4.4-strncatfix.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/ppp-2.4.4-strncatfix.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,31 +0,0 @@ -Description: fix a potential buffer overflow in clientid.c:rc_map2id() - -This fixes the following compile-time warning when building with --D_FORTIFY_SOURCE=2: - -In file included from /usr/include/string.h:638:0, - from ./includes.h:26, - from clientid.c:12: -In function 'strncat', - inlined from 'rc_map2id' at clientid.c:113:9: -/usr/include/i386-linux-gnu/bits/string3.h:150:3: warning: call to -__builtin___strncat_chk might overflow destination buffer [enabled by default] - return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest)); - ^ - -Origin: vendor, https://build.opensuse.org/source/network/ppp/ppp-2.4.4-strncatfix.patch?rev=7a0fdeff0b29437dd7f4581c95c7255a -Forwarded: no -Reviewed-by: Chris Boot -Last-Update: 2014-01-12 - ---- ppp-2.4.4/pppd/plugins/radius/clientid.c.xx 2006-12-19 10:25:19.000000000 +0100 -+++ ppp-2.4.4/pppd/plugins/radius/clientid.c 2006-12-19 10:25:45.000000000 +0100 -@@ -110,7 +110,7 @@ - if (*name != '/') - strcpy(ttyname, "/dev/"); - -- strncat(ttyname, name, sizeof(ttyname)); -+ strncat(ttyname, name, sizeof(ttyname)-strlen(ttyname)-1); - - for(p = map2id_list; p; p = p->next) - if (!strcmp(ttyname, p->name)) return p->id; diff -Nru ppp-2.4.7/debian/patches/pppd-soname-hack.patch ppp-2.4.9/debian/patches/pppd-soname-hack.patch --- ppp-2.4.7/debian/patches/pppd-soname-hack.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/pppd-soname-hack.patch 2021-02-25 19:12:31.000000000 +0100 @@ -7,9 +7,9 @@ Forwarded: not-needed Last-Update: 2015-12-05 ---- ppp-2.4.7.orig/pppd/Makefile.linux -+++ ppp-2.4.7/pppd/Makefile.linux -@@ -206,6 +206,8 @@ endif +--- a/pppd/Makefile.linux ++++ b/pppd/Makefile.linux +@@ -216,6 +216,8 @@ INSTALL= install @@ -18,12 +18,12 @@ all: $(TARGETS) install: pppd -@@ -217,7 +219,8 @@ install: pppd +@@ -227,7 +229,8 @@ $(INSTALL) -c -m 444 pppd.8 $(MANDIR) pppd: $(PPPDOBJS) -- $(CC) $(LDFLAGS) -o pppd $(PPPDOBJS) $(LIBS) -+ $(CC) $(LDFLAGS) -o pppd $(PPPDOBJS) $(LIBS) \ +- $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_PLUGIN) -o pppd $(PPPDOBJS) $(LIBS) ++ $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_PLUGIN) -o pppd $(PPPDOBJS) $(LIBS) \ + -Wl,-soname,pppd.so.$(VERSION) srp-entry: srp-entry.c diff -Nru ppp-2.4.7/debian/patches/pppdump_use_zlib ppp-2.4.9/debian/patches/pppdump_use_zlib --- ppp-2.4.7/debian/patches/pppdump_use_zlib 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/pppdump_use_zlib 2021-02-25 19:12:31.000000000 +0100 @@ -1,8 +1,13 @@ support building pppdump with the system zlib +Forwarded: https://github.com/paulusmack/ppp/pull/189 +but nacked: "it caused compile failures (on Fedora at least), which +reminded me that the zlib.c here is not the same as upstream; it has +extra functions that I added a long time ago." + --- a/pppdump/Makefile.linux +++ b/pppdump/Makefile.linux -@@ -2,18 +2,42 @@ DESTDIR = $(INSTROOT)@DESTDIR@ +@@ -6,15 +6,39 @@ BINDIR = $(DESTDIR)/sbin MANDIR = $(DESTDIR)/share/man/man8 @@ -10,10 +15,7 @@ +DO_BSD_COMPRESS=y +HAVE_ZLIB=n + - COPTS=-O2 -g - CFLAGS= $(COPTS) -I../include/net - LDFLAGS=$(LDOPTS) - + CFLAGS = $(COPTS) -I../include/net -OBJS = pppdump.o bsd-comp.o deflate.o zlib.o +OBJS = pppdump.o +LIBS = @@ -29,14 +31,14 @@ +else +CFLAGS += -DDO_DEFLATE=0 +endif -+ + +ifdef DO_BSD_COMPRESS +CFLAGS += -DDO_BSD_COMPRESS=1 +OBJS += bsd-comp.o +else +CFLAGS += -DDO_BSD_COMPRESS=0 +endif - ++ INSTALL= install all: pppdump diff -Nru ppp-2.4.7/debian/patches/pppoatm_cleanup ppp-2.4.9/debian/patches/pppoatm_cleanup --- ppp-2.4.7/debian/patches/pppoatm_cleanup 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/pppoatm_cleanup 1970-01-01 01:00:00.000000000 +0100 @@ -1,78 +0,0 @@ -cosmetic cleanup of the pppoatm plugin - -Removed some debugging messages and generally cleaned up the source. - ---- a/pppd/plugins/pppoatm/pppoatm.c -+++ b/pppd/plugins/pppoatm/pppoatm.c -@@ -70,18 +70,20 @@ static int setdevname_pppoatm(const char - { - struct sockaddr_atmpvc addr; - extern struct stat devstat; -+ - if (device_got_set) - return 0; -- //info("PPPoATM setdevname_pppoatm: '%s'", cp); -+ - memset(&addr, 0, sizeof addr); - if (text2atm(cp, (struct sockaddr *) &addr, sizeof(addr), -- T2A_PVC | T2A_NAME) < 0) { -- if(doit) -- info("atm does not recognize: %s", cp); -+ T2A_PVC | T2A_NAME | T2A_WILDCARD) < 0) { -+ if (doit) -+ info("cannot parse the ATM address: %s", cp); - return 0; -- } -- if (!doit) return 1; -- //if (!dev_set_ok()) return -1; -+ } -+ if (!doit) -+ return 1; -+ - memcpy(&pvcaddr, &addr, sizeof pvcaddr); - strlcpy(devnam, cp, sizeof devnam); - devstat.st_mode = S_IFSOCK; -@@ -93,7 +95,6 @@ static int setdevname_pppoatm(const char - lcp_allowoptions[0].neg_asyncmap = 0; - lcp_wantoptions[0].neg_pcompression = 0; - } -- info("PPPoATM setdevname_pppoatm - SUCCESS:%s", cp); - device_got_set = 1; - return 1; - } -@@ -108,6 +109,7 @@ static void no_device_given_pppoatm(void - static void set_line_discipline_pppoatm(int fd) - { - struct atm_backend_ppp be; -+ - be.backend_num = ATM_BACKEND_PPP; - if (!llc_encaps) - be.encaps = PPPOATM_ENCAPS_VC; -@@ -115,6 +117,7 @@ static void set_line_discipline_pppoatm( - be.encaps = PPPOATM_ENCAPS_LLC; - else - be.encaps = PPPOATM_ENCAPS_AUTODETECT; -+ - if (ioctl(fd, ATM_SETBACKEND, &be) < 0) - fatal("ioctl(ATM_SETBACKEND): %m"); - } -@@ -174,7 +177,7 @@ static void disconnect_pppoatm(void) - - void plugin_init(void) - { --#if defined(__linux__) -+#ifdef linux - extern int new_style_driver; /* From sys-linux.c */ - if (!ppp_available() && !new_style_driver) - fatal("Kernel doesn't support ppp_generic - " -@@ -182,9 +185,9 @@ void plugin_init(void) - #else - fatal("No PPPoATM support on this OS"); - #endif -- info("PPPoATM plugin_init"); - add_options(pppoa_options); - } -+ - struct channel pppoa_channel = { - options: pppoa_options, - process_extra_options: NULL, diff -Nru ppp-2.4.7/debian/patches/pppoe_noads ppp-2.4.9/debian/patches/pppoe_noads --- ppp-2.4.7/debian/patches/pppoe_noads 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/pppoe_noads 2021-02-25 19:12:31.000000000 +0100 @@ -1,12 +1,11 @@ ---- a/pppd/plugins/rp-pppoe/plugin.c -+++ b/pppd/plugins/rp-pppoe/plugin.c -@@ -345,9 +345,6 @@ plugin_init(void) +--- a/pppd/plugins/pppoe/plugin.c ++++ b/pppd/plugins/pppoe/plugin.c +@@ -412,8 +412,6 @@ } add_options(Options); - -- info("RP-PPPoE plugin version %s compiled against pppd %s", -- RP_VERSION, VERSION); +- info("PPPoE plugin from pppd %s", VERSION); } void pppoe_check_options(void) diff -Nru ppp-2.4.7/debian/patches/pr-28-pppoe-custom-host-uniq-tag.patch ppp-2.4.9/debian/patches/pr-28-pppoe-custom-host-uniq-tag.patch --- ppp-2.4.7/debian/patches/pr-28-pppoe-custom-host-uniq-tag.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/pr-28-pppoe-custom-host-uniq-tag.patch 1970-01-01 01:00:00.000000000 +0100 @@ -1,303 +0,0 @@ -From: Matteo Croce -Date: Sat, 21 Nov 2015 18:45:43 +0100 -Subject: [PATCH] pppoe: custom host-uniq tag -Forwarded: https://github.com/paulusmack/ppp/pull/28 -Reviewed-by: Chris Boot - -Add pppoe 'host-uniq' option to set an arbitrary -host-uniq tag instead of the pppd pid. -Some ISPs use such tag to authenticate the CPE, -so it must be set to a proper value to connect. - -Signed-off-by: Matteo Croce -Signed-off-by: Jo-Philipp Wich ---- - pppd/plugins/rp-pppoe/common.c | 14 ++++----- - pppd/plugins/rp-pppoe/discovery.c | 51 +++++++++++++-------------------- - pppd/plugins/rp-pppoe/plugin.c | 7 ++++- - pppd/plugins/rp-pppoe/pppoe-discovery.c | 38 +++++++++++++++--------- - pppd/plugins/rp-pppoe/pppoe.h | 31 +++++++++++++++++++- - 5 files changed, 86 insertions(+), 55 deletions(-) - -diff --git a/pppd/plugins/rp-pppoe/common.c b/pppd/plugins/rp-pppoe/common.c -index 89c633c773f9..8f175ece345b 100644 ---- a/pppd/plugins/rp-pppoe/common.c -+++ b/pppd/plugins/rp-pppoe/common.c -@@ -119,15 +119,11 @@ sendPADT(PPPoEConnection *conn, char const *msg) - conn->session = 0; - - /* If we're using Host-Uniq, copy it over */ -- if (conn->useHostUniq) { -- PPPoETag hostUniq; -- pid_t pid = getpid(); -- hostUniq.type = htons(TAG_HOST_UNIQ); -- hostUniq.length = htons(sizeof(pid)); -- memcpy(hostUniq.payload, &pid, sizeof(pid)); -- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE); -- cursor += sizeof(pid) + TAG_HDR_SIZE; -- plen += sizeof(pid) + TAG_HDR_SIZE; -+ if (conn->hostUniq.length) { -+ int len = ntohs(conn->hostUniq.length); -+ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE); -+ cursor += len + TAG_HDR_SIZE; -+ plen += len + TAG_HDR_SIZE; - } - - /* Copy error message */ -diff --git a/pppd/plugins/rp-pppoe/discovery.c b/pppd/plugins/rp-pppoe/discovery.c -index 04877cb8295f..5db8d0defc37 100644 ---- a/pppd/plugins/rp-pppoe/discovery.c -+++ b/pppd/plugins/rp-pppoe/discovery.c -@@ -80,13 +80,10 @@ static void - parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data, - void *extra) - { -- int *val = (int *) extra; -- if (type == TAG_HOST_UNIQ && len == sizeof(pid_t)) { -- pid_t tmp; -- memcpy(&tmp, data, len); -- if (tmp == getpid()) { -- *val = 1; -- } -+ PPPoETag *tag = extra; -+ -+ if (type == TAG_HOST_UNIQ && len == ntohs(tag->length)) { -+ tag->length = memcmp(data, tag->payload, len); - } - } - -@@ -104,16 +101,16 @@ parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data, - static int - packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet) - { -- int forMe = 0; -+ PPPoETag hostUniq = conn->hostUniq; - - /* If packet is not directed to our MAC address, forget it */ - if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0; - - /* If we're not using the Host-Unique tag, then accept the packet */ -- if (!conn->useHostUniq) return 1; -+ if (!conn->hostUniq.length) return 1; - -- parsePacket(packet, parseForHostUniq, &forMe); -- return forMe; -+ parsePacket(packet, parseForHostUniq, &hostUniq); -+ return !hostUniq.length; - } - - /********************************************************************** -@@ -301,16 +298,12 @@ sendPADI(PPPoEConnection *conn) - } - - /* If we're using Host-Uniq, copy it over */ -- if (conn->useHostUniq) { -- PPPoETag hostUniq; -- pid_t pid = getpid(); -- hostUniq.type = htons(TAG_HOST_UNIQ); -- hostUniq.length = htons(sizeof(pid)); -- memcpy(hostUniq.payload, &pid, sizeof(pid)); -- CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE); -- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE); -- cursor += sizeof(pid) + TAG_HDR_SIZE; -- plen += sizeof(pid) + TAG_HDR_SIZE; -+ if (conn->hostUniq.length) { -+ int len = ntohs(conn->hostUniq.length); -+ CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE); -+ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE); -+ cursor += len + TAG_HDR_SIZE; -+ plen += len + TAG_HDR_SIZE; - } - - /* Add our maximum MTU/MRU */ -@@ -478,16 +471,12 @@ sendPADR(PPPoEConnection *conn) - cursor += namelen + TAG_HDR_SIZE; - - /* If we're using Host-Uniq, copy it over */ -- if (conn->useHostUniq) { -- PPPoETag hostUniq; -- pid_t pid = getpid(); -- hostUniq.type = htons(TAG_HOST_UNIQ); -- hostUniq.length = htons(sizeof(pid)); -- memcpy(hostUniq.payload, &pid, sizeof(pid)); -- CHECK_ROOM(cursor, packet.payload, sizeof(pid)+TAG_HDR_SIZE); -- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE); -- cursor += sizeof(pid) + TAG_HDR_SIZE; -- plen += sizeof(pid) + TAG_HDR_SIZE; -+ if (conn->hostUniq.length) { -+ int len = ntohs(conn->hostUniq.length); -+ CHECK_ROOM(cursor, packet.payload, len+TAG_HDR_SIZE); -+ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE); -+ cursor += len + TAG_HDR_SIZE; -+ plen += len + TAG_HDR_SIZE; - } - - /* Add our maximum MTU/MRU */ -diff --git a/pppd/plugins/rp-pppoe/plugin.c b/pppd/plugins/rp-pppoe/plugin.c -index c89be94250bc..eb395182f77c 100644 ---- a/pppd/plugins/rp-pppoe/plugin.c -+++ b/pppd/plugins/rp-pppoe/plugin.c -@@ -68,6 +68,7 @@ static char *existingSession = NULL; - static int printACNames = 0; - static char *pppoe_reqd_mac = NULL; - unsigned char pppoe_reqd_mac_addr[6]; -+static char *host_uniq = NULL; - - static int PPPoEDevnameHook(char *cmd, char **argv, int doit); - static option_t Options[] = { -@@ -85,6 +86,8 @@ static option_t Options[] = { - "Be verbose about discovered access concentrators"}, - { "pppoe-mac", o_string, &pppoe_reqd_mac, - "Only connect to specified MAC address" }, -+ { "host-uniq", o_string, &host_uniq, -+ "Specify custom Host-Uniq" }, - { NULL } - }; - int (*OldDevnameHook)(char *cmd, char **argv, int doit) = NULL; -@@ -110,7 +113,6 @@ PPPOEInitDevice(void) - conn->ifName = devnam; - conn->discoverySocket = -1; - conn->sessionSocket = -1; -- conn->useHostUniq = 1; - conn->printACNames = printACNames; - conn->discoveryTimeout = PADI_TIMEOUT; - return 1; -@@ -166,6 +168,9 @@ PPPOEConnectDevice(void) - if (lcp_wantoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD) - lcp_wantoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD; - -+ if (host_uniq && !parseHostUniq(host_uniq, &conn->hostUniq)) -+ fatal("Illegal value for host-uniq option"); -+ - conn->acName = acName; - conn->serviceName = pppd_pppoe_service; - strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam)); -diff --git a/pppd/plugins/rp-pppoe/pppoe-discovery.c b/pppd/plugins/rp-pppoe/pppoe-discovery.c -index 3d3bf4eecc81..f4f527128c2f 100644 ---- a/pppd/plugins/rp-pppoe/pppoe-discovery.c -+++ b/pppd/plugins/rp-pppoe/pppoe-discovery.c -@@ -347,7 +347,7 @@ packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet) - if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0; - - /* If we're not using the Host-Unique tag, then accept the packet */ -- if (!conn->useHostUniq) return 1; -+ if (!conn->hostUniq.length) return 1; - - parsePacket(packet, parseForHostUniq, &forMe); - return forMe; -@@ -473,16 +473,12 @@ sendPADI(PPPoEConnection *conn) - cursor += namelen + TAG_HDR_SIZE; - - /* If we're using Host-Uniq, copy it over */ -- if (conn->useHostUniq) { -- PPPoETag hostUniq; -- pid_t pid = getpid(); -- hostUniq.type = htons(TAG_HOST_UNIQ); -- hostUniq.length = htons(sizeof(pid)); -- memcpy(hostUniq.payload, &pid, sizeof(pid)); -- CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE); -- memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE); -- cursor += sizeof(pid) + TAG_HDR_SIZE; -- plen += sizeof(pid) + TAG_HDR_SIZE; -+ if (conn->hostUniq.length) { -+ int len = ntohs(conn->hostUniq.length); -+ CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE); -+ memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE); -+ cursor += len + TAG_HDR_SIZE; -+ plen += len + TAG_HDR_SIZE; - } - - packet.length = htons(plen); -@@ -644,7 +640,7 @@ int main(int argc, char *argv[]) - - memset(conn, 0, sizeof(PPPoEConnection)); - -- while ((opt = getopt(argc, argv, "I:D:VUAS:C:h")) > 0) { -+ while ((opt = getopt(argc, argv, "I:D:VUW:AS:C:h")) > 0) { - switch(opt) { - case 'S': - conn->serviceName = xstrdup(optarg); -@@ -653,7 +649,23 @@ int main(int argc, char *argv[]) - conn->acName = xstrdup(optarg); - break; - case 'U': -- conn->useHostUniq = 1; -+ if(conn->hostUniq.length) { -+ fprintf(stderr, "-U and -W are mutually exclusive\n"); -+ exit(EXIT_FAILURE); -+ } -+ char pidbuf[5]; -+ snprintf(pidbuf, sizeof(pidbuf), "%04x", getpid()); -+ parseHostUniq(pidbuf, &conn->hostUniq); -+ break; -+ case 'W': -+ if(conn->hostUniq.length) { -+ fprintf(stderr, "-U and -W are mutually exclusive\n"); -+ exit(EXIT_FAILURE); -+ } -+ if (!parseHostUniq(optarg, &conn->hostUniq)) { -+ fprintf(stderr, "Invalid host-uniq argument: %s\n", optarg); -+ exit(EXIT_FAILURE); -+ } - break; - case 'D': - conn->debugFile = fopen(optarg, "w"); -diff --git a/pppd/plugins/rp-pppoe/pppoe.h b/pppd/plugins/rp-pppoe/pppoe.h -index 9ab2eee3914c..86d2b1e47a25 100644 ---- a/pppd/plugins/rp-pppoe/pppoe.h -+++ b/pppd/plugins/rp-pppoe/pppoe.h -@@ -21,6 +21,8 @@ - - #include /* For FILE */ - #include /* For pid_t */ -+#include -+#include - - /* How do we access raw Ethernet devices? */ - #undef USE_LINUX_PACKET -@@ -235,7 +237,7 @@ typedef struct PPPoEConnectionStruct { - char *serviceName; /* Desired service name, if any */ - char *acName; /* Desired AC name, if any */ - int synchronous; /* Use synchronous PPP */ -- int useHostUniq; /* Use Host-Uniq tag */ -+ PPPoETag hostUniq; /* Use Host-Uniq tag */ - int printACNames; /* Just print AC names */ - FILE *debugFile; /* Debug file for dumping packets */ - int numPADOs; /* Number of PADO packets received */ -@@ -291,6 +293,33 @@ void pppoe_printpkt(PPPoEPacket *packet, - void (*printer)(void *, char *, ...), void *arg); - void pppoe_log_packet(const char *prefix, PPPoEPacket *packet); - -+static inline int parseHostUniq(const char *uniq, PPPoETag *tag) -+{ -+ int i, len = strlen(uniq); -+ -+#define hex(x) \ -+ (((x) <= '9') ? ((x) - '0') : \ -+ (((x) <= 'F') ? ((x) - 'A' + 10) : \ -+ ((x) - 'a' + 10))) -+ -+ if (len % 2) -+ return 0; -+ -+ for (i = 0; i < len; i += 2) -+ { -+ if (!isxdigit(uniq[i]) || !isxdigit(uniq[i+1])) -+ return 0; -+ -+ tag->payload[i / 2] = (char)(16 * hex(uniq[i]) + hex(uniq[i+1])); -+ } -+ -+#undef hex -+ -+ tag->type = htons(TAG_HOST_UNIQ); -+ tag->length = htons(len / 2); -+ return 1; -+} -+ - #define SET_STRING(var, val) do { if (var) free(var); var = strDup(val); } while(0); - - #define CHECK_ROOM(cursor, start, len) \ --- -2.8.1 - diff -Nru ppp-2.4.7/debian/patches/radius-config.c-unkown-typo ppp-2.4.9/debian/patches/radius-config.c-unkown-typo --- ppp-2.4.7/debian/patches/radius-config.c-unkown-typo 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/radius-config.c-unkown-typo 1970-01-01 01:00:00.000000000 +0100 @@ -1,33 +0,0 @@ -Description: Correct unkown => unknown typo -Author: Chris Boot -Last-Update: 2013-09-09 - ---- ppp-2.4.5+git20130610.orig/pppd/plugins/radius/config.c -+++ ppp-2.4.5+git20130610/pppd/plugins/radius/config.c -@@ -271,7 +271,7 @@ char *rc_conf_str(char *optname) - option = find_option(optname, OT_STR); - - if (option == NULL) -- fatal("rc_conf_str: unkown config option requested: %s", optname); -+ fatal("rc_conf_str: unknown config option requested: %s", optname); - return (char *)option->val; - } - -@@ -282,7 +282,7 @@ int rc_conf_int(char *optname) - option = find_option(optname, OT_INT|OT_AUO); - - if (option == NULL) -- fatal("rc_conf_int: unkown config option requested: %s", optname); -+ fatal("rc_conf_int: unknown config option requested: %s", optname); - return *((int *)option->val); - } - -@@ -293,7 +293,7 @@ SERVER *rc_conf_srv(char *optname) - option = find_option(optname, OT_SRV); - - if (option == NULL) -- fatal("rc_conf_srv: unkown config option requested: %s", optname); -+ fatal("rc_conf_srv: unknown config option requested: %s", optname); - return (SERVER *)option->val; - } - diff -Nru ppp-2.4.7/debian/patches/radius_mtu ppp-2.4.9/debian/patches/radius_mtu --- ppp-2.4.7/debian/patches/radius_mtu 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/radius_mtu 1970-01-01 01:00:00.000000000 +0100 @@ -1,30 +0,0 @@ -add support for the Framed-MTU Radius attribute - -http://ppp.samba.org/cgi-bin/ppp-bugs/incoming?id=1532 - -From: klepikov_a@up.ua -To: ppp-bugs@ppp.samba.org -Subject: Radius plugin does not set MTU on ppp interface -Date: Mon, 22 Jan 2007 12:36:59 +0000 (GMT) - -Full_Name: Alexander Klepikov -Version: 2.4.3 -OS: rhl 7.3 (2.4.20-28.7bigmem) -Submission from: (NULL) (213.130.21.73) - - -This patch allows radius plugin to deal with Framed-MTU Radius attribute and to -set MTU on interface. - ---- a/pppd/plugins/radius/radius.c -+++ b/pppd/plugins/radius/radius.c -@@ -657,6 +657,9 @@ radius_setparams(VALUE_PAIR *vp, char *m - memcpy(rstate.class, vp->strvalue, rstate.class_len); - } /* else too big for our buffer - ignore it */ - break; -+ case PW_FRAMED_MTU: -+ netif_set_mtu(rstate.client_port,MIN(netif_get_mtu(rstate.client_port),vp->lvalue)); -+ break; - } - - diff -Nru ppp-2.4.7/debian/patches/rc_mksid-no-buffer-overflow ppp-2.4.9/debian/patches/rc_mksid-no-buffer-overflow --- ppp-2.4.7/debian/patches/rc_mksid-no-buffer-overflow 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/rc_mksid-no-buffer-overflow 1970-01-01 01:00:00.000000000 +0100 @@ -1,23 +0,0 @@ -Description: Fix buffer overflow in rc_mksid() - rc_mksid converts the PID of pppd to hex to generate a pseudo-unique string. - . - If the process id is bigger than 65535 (FFFF), its hex representation will be - longer than 4 characters, resulting in a buffer overflow. - . - The bug can be exploited to cause a remote DoS. - . -Author: Emanuele Rocca -Bug-Debian: https://bugs.debian.org/782450 -Last-Update: <2015-04-14> - ---- ppp-2.4.6.orig/pppd/plugins/radius/util.c -+++ ppp-2.4.6/pppd/plugins/radius/util.c -@@ -77,7 +77,7 @@ rc_mksid (void) - static unsigned short int cnt = 0; - sprintf (buf, "%08lX%04X%02hX", - (unsigned long int) time (NULL), -- (unsigned int) getpid (), -+ (unsigned int) getpid () % 65535, - cnt & 0xFF); - cnt++; - return buf; diff -Nru ppp-2.4.7/debian/patches/readable_connerrs ppp-2.4.9/debian/patches/readable_connerrs --- ppp-2.4.7/debian/patches/readable_connerrs 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/readable_connerrs 1970-01-01 01:00:00.000000000 +0100 @@ -1,15 +0,0 @@ -make _PATH_CONNERRS world readable - -There is nothing security-sensitive there. - ---- a/pppd/main.c -+++ b/pppd/main.c -@@ -1637,7 +1637,7 @@ device_script(program, in, out, dont_wai - if (log_to_fd >= 0) - errfd = log_to_fd; - else -- errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); -+ errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0644); - - ++conn_running; - pid = safe_fork(in, out, errfd); diff -Nru ppp-2.4.7/debian/patches/replace-vendored-hash-functions.patch ppp-2.4.9/debian/patches/replace-vendored-hash-functions.patch --- ppp-2.4.7/debian/patches/replace-vendored-hash-functions.patch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/replace-vendored-hash-functions.patch 2021-02-25 19:12:31.000000000 +0100 @@ -12,7 +12,7 @@ --- a/pppd/Makefile.linux +++ b/pppd/Makefile.linux -@@ -11,16 +11,16 @@ +@@ -15,16 +15,16 @@ TARGETS = pppd @@ -33,16 +33,16 @@ ecp.o auth.o options.o demand.o utils.o sys-linux.o ipxcp.o tty.o \ eap.o chap-md5.o session.o -@@ -33,7 +33,7 @@ - # CC = gcc - # - COPTS = -O2 -pipe -Wall -g --LIBS = -+LIBS = -lcrypto +@@ -34,7 +34,7 @@ + include .depend + endif + +-LIBS = -lrt ++LIBS = -lrt -lcrypto - # Uncomment the next 2 lines to include support for Microsoft's + # Uncomment the next line to include support for Microsoft's # MS-CHAP authentication protocol. Also, edit plugins/radius/Makefile.linux. -@@ -91,8 +91,8 @@ +@@ -98,8 +98,8 @@ ifdef CHAPMS CFLAGS += -DCHAPMS=1 NEEDDES=y @@ -53,12 +53,11 @@ ifdef MSLANMAN CFLAGS += -DMSLANMAN=1 endif -@@ -104,25 +104,18 @@ - # EAP SRP-SHA1 +@@ -113,26 +113,17 @@ ifdef USE_SRP CFLAGS += -DUSE_SRP -DOPENSSL -I/usr/local/ssl/include --LIBS += -lsrp -L/usr/local/ssl/lib -lcrypto -+LIBS += -lsrp -L/usr/local/ssl/lib + 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 @@ -75,23 +74,46 @@ # EAP-TLS ifdef USE_EAPTLS - CFLAGS += -DUSE_EAPTLS=1 -I/usr/kerberos/include --LIBS += -lssl -lcrypto -+LIBS += -lssl + CFLAGS += -DUSE_EAPTLS=1 + LIBS += -lssl +-NEEDCRYPTOLIB = y PPPDSRC += eap-tls.c HEADERS += eap-tls.h PPPDOBJS += eap-tls.o +@@ -160,7 +151,6 @@ + ifdef NEEDDES + ifndef USE_CRYPT + CFLAGS += -I$(shell $(CC) --print-sysroot)/usr/include/openssl +-NEEDCRYPTOLIB = y + else + CFLAGS += -DUSE_CRYPT=1 + endif +@@ -168,10 +158,6 @@ + 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 --- a/pppd/chap-md5.c +++ b/pppd/chap-md5.c -@@ -39,7 +39,7 @@ - #ifdef USE_EAPTLS - #include "eap-tls.h" - #else --#include "md5.h" +@@ -32,11 +32,11 @@ + + #include + #include +#include - #endif /* USE_EAPTLS */ + #include "pppd.h" + #include "chap-new.h" + #include "chap-md5.h" + #include "magic.h" +-#include "md5.h" #define MD5_HASH_SIZE 16 + #define MD5_MIN_CHALLENGE 16 --- a/pppd/chap_ms.c +++ b/pppd/chap_ms.c @@ -89,8 +89,8 @@ @@ -105,7 +127,7 @@ #include "pppcrypt.h" #include "magic.h" -@@ -535,8 +535,8 @@ +@@ -536,8 +536,8 @@ char *username, u_char Challenge[8]) { @@ -116,7 +138,7 @@ char *user; /* remove domain from "domain\username" */ -@@ -574,23 +574,11 @@ +@@ -575,23 +575,11 @@ static void NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) { @@ -143,7 +165,7 @@ } -@@ -671,8 +659,8 @@ +@@ -672,8 +660,8 @@ 0x6E }; int i; @@ -154,7 +176,7 @@ u_char Challenge[8]; SHA1_Init(&sha1Context); -@@ -725,8 +713,8 @@ +@@ -726,8 +714,8 @@ void mppe_set_keys(u_char *rchallenge, u_char PasswordHashHash[MD4_SIGNATURE_SIZE]) { @@ -165,7 +187,7 @@ SHA1_Init(&sha1Context); SHA1_Update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); -@@ -769,9 +757,9 @@ +@@ -770,9 +758,9 @@ mppe_set_keys2(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], u_char NTResponse[24], int IsServer) { @@ -180,18 +202,21 @@ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, --- a/pppd/eap.c +++ b/pppd/eap.c -@@ -71,7 +71,7 @@ - #ifdef USE_EAPTLS - #include "eap-tls.h" - #else --#include "md5.h" +@@ -59,9 +59,10 @@ + #include + #include + +#include - #endif /* USE_EAPTLS */ ++ + #include "pppd.h" + #include "pathnames.h" +-#include "md5.h" + #include "eap.h" - #ifdef USE_SRP + #ifdef CHAPMS --- a/pppd/md4.c +++ /dev/null -@@ -1,299 +0,0 @@ +@@ -1,290 +0,0 @@ -/* -** ******************************************************************** -** md4.c -- Implementation of MD4 Message Digest Algorithm ** @@ -281,8 +306,7 @@ -** This is a user-callable routine. -*/ -void --MD4Print(MDp) --MD4_CTX *MDp; +-MD4Print(MD4_CTX *MDp) -{ - int i,j; - for (i=0;i<4;i++) @@ -295,8 +319,7 @@ -** This is a user-callable routine. -*/ -void --MD4Init(MDp) --MD4_CTX *MDp; +-MD4Init(MD4_CTX *MDp) -{ - int i; - MDp->buffer[0] = I0; @@ -314,9 +337,7 @@ -** This routine is not user-callable. -*/ -static void --MDblock(MDp,Xb) --MD4_CTX *MDp; --unsigned char *Xb; +-MDblock(MD4_CTX *MDp, unsigned char *Xb) -{ - register unsigned int tmp, A, B, C, D; - unsigned int X[16]; @@ -400,10 +421,7 @@ -** if desired. -*/ -void --MD4Update(MDp,X,count) --MD4_CTX *MDp; --unsigned char *X; --unsigned int count; +-MD4Update(MD4_CTX *MDp, unsigned char *X, unsigned int count) -{ - unsigned int i, tmp, bit, byte, mask; - unsigned char XX[64]; @@ -471,9 +489,7 @@ -** Finish up MD4 computation and return message digest. -*/ -void --MD4Final(buf, MD) --unsigned char *buf; --MD4_CTX *MD; +-MD4Final(unsigned char *buf, MD4_CTX *MD) -{ - int i, j; - unsigned int w; @@ -493,7 +509,7 @@ -****************************(cut)***********************************/ --- a/pppd/md4.h +++ /dev/null -@@ -1,64 +0,0 @@ +@@ -1,55 +0,0 @@ - -/* -** ******************************************************************** @@ -504,15 +520,6 @@ -** ******************************************************************** -*/ - --#ifndef __P --# if defined(__STDC__) || defined(__GNUC__) --# define __P(x) x --# else --# define __P(x) () --# endif --#endif -- -- -/* MDstruct is the data structure for a message digest computation. -*/ -typedef struct { @@ -525,7 +532,7 @@ -** Initialize the MD4_CTX prepatory to doing a message digest -** computation. -*/ --extern void MD4Init __P((MD4_CTX *MD)); +-extern void MD4Init(MD4_CTX *MD); - -/* MD4Update(MD,X,count) -** Input: X -- a pointer to an array of unsigned characters. @@ -539,7 +546,7 @@ -** every MD computation should end with one call to MD4Update with a -** count less than 512. Zero is OK for a count. -*/ --extern void MD4Update __P((MD4_CTX *MD, unsigned char *X, unsigned int count)); +-extern void MD4Update(MD4_CTX *MD, unsigned char *X, unsigned int count); - -/* MD4Print(MD) -** Prints message digest buffer MD as 32 hexadecimal digits. @@ -547,20 +554,20 @@ -** of buffer[3]. -** Each byte is printed with high-order hexadecimal digit first. -*/ --extern void MD4Print __P((MD4_CTX *)); +-extern void MD4Print(MD4_CTX *); - -/* MD4Final(buf, MD) -** Returns message digest from MD and terminates the message -** digest computation. -*/ --extern void MD4Final __P((unsigned char *, MD4_CTX *)); +-extern void MD4Final(unsigned char *, MD4_CTX *); - -/* -** End of md4.h -****************************(cut)***********************************/ --- a/pppd/md5.c +++ /dev/null -@@ -1,311 +0,0 @@ +@@ -1,299 +0,0 @@ - - -/* @@ -596,8 +603,6 @@ - *********************************************************************** - */ - --#ifndef USE_EAPTLS -- -#include -#include "md5.h" - @@ -667,8 +672,7 @@ -/* The routine MD5_Init initializes the message-digest context - mdContext. All fields are set to zero. - */ --void MD5_Init (mdContext) --MD5_CTX *mdContext; +-void MD5_Init (MD5_CTX *mdContext) -{ - mdContext->i[0] = mdContext->i[1] = (UINT4)0; - @@ -684,10 +688,7 @@ - account for the presence of each of the characters inBuf[0..inLen-1] - in the message whose digest is being computed. - */ --void MD5_Update (mdContext, inBuf, inLen) --MD5_CTX *mdContext; --unsigned char *inBuf; --unsigned int inLen; +-void MD5_Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen) -{ - UINT4 in[16]; - int mdi; @@ -722,9 +723,7 @@ -/* The routine MD5Final terminates the message-digest computation and - ends with the desired message digest in mdContext->digest[0...15]. - */ --void MD5_Final (hash, mdContext) --unsigned char hash[]; --MD5_CTX *mdContext; +-void MD5_Final (unsigned char hash[], MD5_CTX *mdContext) -{ - UINT4 in[16]; - int mdi; @@ -765,9 +764,7 @@ - -/* Basic MD5 step. Transforms buf based on in. - */ --static void Transform (buf, in) --UINT4 *buf; --UINT4 *in; +-static void Transform (UINT4 *buf, UINT4 *in) -{ - UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; - @@ -870,11 +867,9 @@ - ** End of md5.c ** - ******************************** (cut) ******************************** - */ --#endif /* USE_EAPTLS */ -- --- a/pppd/md5.h +++ /dev/null -@@ -1,68 +0,0 @@ +@@ -1,65 +0,0 @@ -/* - *********************************************************************** - ** md5.h -- header file for implementation of MD5 ** @@ -913,7 +908,6 @@ - ** documentation and/or software. ** - *********************************************************************** - */ --#ifndef USE_EAPTLS - -#ifndef __MD5_INCLUDE__ - @@ -941,8 +935,6 @@ - -#define __MD5_INCLUDE__ -#endif /* __MD5_INCLUDE__ */ -- --#endif /* USE_EAPTLS */ --- a/pppd/plugins/radius/md5.c +++ b/pppd/plugins/radius/md5.c @@ -1,7 +1,7 @@ @@ -978,7 +970,7 @@ #include "ipcp.h" --- a/pppd/sha1.c +++ /dev/null -@@ -1,170 +0,0 @@ +@@ -1,171 +0,0 @@ -/* - * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c - * @@ -998,6 +990,7 @@ -/* #define SHA1HANDSOFF * Copies data before messing with it. */ - -#include +-#include -#include /* htonl() */ -#include -#include "sha1.h" diff -Nru ppp-2.4.7/debian/patches/secure-card-interpreter-fix ppp-2.4.9/debian/patches/secure-card-interpreter-fix --- ppp-2.4.7/debian/patches/secure-card-interpreter-fix 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/secure-card-interpreter-fix 1970-01-01 01:00:00.000000000 +0100 @@ -1,19 +0,0 @@ -Description: Change path to expect in secure-card example script - -This fixes the lintian warning: -I: ppp: example-wrong-path-for-interpreter - usr/share/doc/ppp/examples/scripts/secure-card - (#!/usr/local/bin/expect != /usr/bin/expect) - -Author: Chris Boot -Forwarded: not-needed -Last-Update: 2013-09-09 - ---- ppp-2.4.5+git20130610.orig/scripts/secure-card -+++ ppp-2.4.5+git20130610/scripts/secure-card -@@ -1,4 +1,4 @@ --#!/usr/local/bin/expect -f -+#!/usr/bin/expect -f - # - # This script was written by Jim Isaacson . It is - # designed to work as a script to use the SecureCARD(tm) device. This diff -Nru ppp-2.4.7/debian/patches/series ppp-2.4.9/debian/patches/series --- ppp-2.4.7/debian/patches/series 2020-07-23 14:38:54.000000000 +0200 +++ ppp-2.4.9/debian/patches/series 2021-08-16 18:59:45.000000000 +0200 @@ -1,63 +1,17 @@ -# merged in upstream Git, but not yet released -0001-abort-on-errors-in-subdir-builds.patch -#0002-pppd-add-support-for-defaultroute-metric-option.patch -0003-scripts-Avoid-killing-wrong-pppd.patch -0004-pppd-Fix-sign-extension-when-displaying-bytes-in-oct.patch -0005-Suppress-false-error-message-on-PPPoE-disconnect.patch -0006-Send-PADT-on-PPPoE-disconnect.patch -0007-pppd-ipxcp-Prevent-buffer-overrun-on-remote-router-n.patch -0008-pppd-Fix-ccp_options.mppe-type.patch -0009-pppd-Fix-ccp_cilen-calculated-size-if-both-deflate_c.patch -0010-Fix-a-typo-in-comment.-Diff-from-Yuuichi-Someya.patch -0011-plog-count-only-relevant-lines-from-syslog.patch -0012-Change-include-from-sys-errno.h-to-errno.h.patch -0013-pppd-allow-use-of-arbitrary-interface-names.patch -0014-pppd-Remove-unused-declaration-of-ttyname.patch -0015-pppd-Provide-error-implementation-in-pppoe-discovery.patch -0016-pppoe-include-netinet-in.h-before-linux-in.h.patch - # to be merged upstream -adaptive_echos -makefiles_cleanup -close_dev_ppp chat_man -fix_linkpidfile pppdump_use_zlib pppoatm_resolver_light -pppoatm_cleanup pppoe_noads -readable_connerrs -radius-config.c-unkown-typo - -# github pull requests -pr-28-pppoe-custom-host-uniq-tag.patch # not ready to be merged 011_scripts_redialer.diff -cifdefroute.dif ppp-2.3.11-oedod.dif -radius_mtu - -# rejected by the upstream maintainer -018_ip-up_option.diff -ppp-2.4.2-stripMSdomain -setenv_call_file - -ipv6-accept-remote -ppp-2.4.4-strncatfix.patch # debian-specific 010_scripts_README.diff no_crypt_hack resolv.conf_no_log zzz_config -secure-card-interpreter-fix -rc_mksid-no-buffer-overflow pppd-soname-hack.patch -eaptls-mppe.patch replace-vendored-hash-functions.patch - -# nmu -glibc-2.28.patch - -CVE-2020-8597.patch diff -Nru ppp-2.4.7/debian/patches/setenv_call_file ppp-2.4.9/debian/patches/setenv_call_file --- ppp-2.4.7/debian/patches/setenv_call_file 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/setenv_call_file 1970-01-01 01:00:00.000000000 +0100 @@ -1,24 +0,0 @@ -export $CALL_FILE to the link scripts - ---- a/pppd/options.c -+++ b/pppd/options.c -@@ -1472,6 +1472,7 @@ callfile(argv) - if ((fname = (char *) malloc(l)) == NULL) - novm("call file name"); - slprintf(fname, l, "%s%s", _PATH_PEERFILES, arg); -+ script_setenv("CALL_FILE", arg, 0); - - ok = options_from_file(fname, 1, 1, 1); - ---- a/pppd/pppd.8 -+++ b/pppd/pppd.8 -@@ -1656,6 +1656,9 @@ the connection. - .B LINKNAME - The logical name of the link, set with the \fIlinkname\fR option. - .TP -+.B CALL_FILE -+The value of the \fIcall\fR option. -+.TP - .B DNS1 - If the peer supplies DNS server addresses, this variable is set to the - first DNS server address supplied (whether or not the usepeerdns diff -Nru ppp-2.4.7/debian/patches/zzz_config ppp-2.4.9/debian/patches/zzz_config --- ppp-2.4.7/debian/patches/zzz_config 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/patches/zzz_config 2021-02-25 19:12:31.000000000 +0100 @@ -2,8 +2,12 @@ --- a/pppd/Makefile.linux +++ b/pppd/Makefile.linux -@@ -61,14 +61,14 @@ HAVE_MULTILINK=y - USE_TDB=y +@@ -64,17 +64,17 @@ + # 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 ++SYSTEMD=y HAS_SHADOW=y -#USE_PAM=y @@ -19,35 +23,9 @@ # Enable EAP SRP-SHA1 authentication (requires libsrp) #USE_SRP=y -@@ -182,11 +182,9 @@ LIBS += -ldl - endif - - ifdef FILTER --ifneq ($(wildcard /usr/include/pcap-bpf.h),) - LIBS += -lpcap - CFLAGS += -DPPP_FILTER - endif --endif - - ifdef HAVE_INET6 - PPPDSRCS += ipv6cp.c eui64.c ---- a/pppdump/Makefile.linux -+++ b/pppdump/Makefile.linux -@@ -2,9 +2,9 @@ DESTDIR = $(INSTROOT)@DESTDIR@ - BINDIR = $(DESTDIR)/sbin - MANDIR = $(DESTDIR)/share/man/man8 - --DO_DEFLATE=y -+#DO_DEFLATE=y - DO_BSD_COMPRESS=y --HAVE_ZLIB=n -+HAVE_ZLIB=y - - COPTS=-O2 -g - CFLAGS= $(COPTS) -I../include/net --- a/pppd/pathnames.h +++ b/pppd/pathnames.h -@@ -28,7 +28,7 @@ +@@ -33,7 +33,7 @@ #define _PATH_AUTHUP _ROOT_PATH "/etc/ppp/auth-up" #define _PATH_AUTHDOWN _ROOT_PATH "/etc/ppp/auth-down" #define _PATH_TTYOPT _ROOT_PATH "/etc/ppp/options." @@ -58,7 +36,7 @@ --- a/pppd/pppd.h +++ b/pppd/pppd.h -@@ -852,7 +852,7 @@ extern void (*snoop_send_hook) __P((unsi +@@ -879,7 +879,7 @@ || defined(DEBUGCHAP) || defined(DEBUG) || defined(DEBUGIPV6CP) #define LOG_PPP LOG_LOCAL2 #else @@ -67,3 +45,17 @@ #endif #endif /* LOG_PPP */ +--- a/pppdump/Makefile.linux ++++ b/pppdump/Makefile.linux +@@ -6,9 +6,9 @@ + BINDIR = $(DESTDIR)/sbin + MANDIR = $(DESTDIR)/share/man/man8 + +-DO_DEFLATE=y ++#DO_DEFLATE=y + DO_BSD_COMPRESS=y +-HAVE_ZLIB=n ++HAVE_ZLIB=y + + CFLAGS = $(COPTS) -I../include/net + OBJS = pppdump.o diff -Nru ppp-2.4.7/debian/ppp.dirs ppp-2.4.9/debian/ppp.dirs --- ppp-2.4.7/debian/ppp.dirs 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/ppp.dirs 2021-02-25 19:12:30.000000000 +0100 @@ -1,5 +1,6 @@ etc/chatscripts/ etc/ppp/ip-down.d/ +etc/ppp/ip-pre-up.d/ etc/ppp/ip-up.d/ etc/ppp/ipv6-down.d/ etc/ppp/ipv6-up.d/ diff -Nru ppp-2.4.7/debian/ppp.install ppp-2.4.9/debian/ppp.install --- ppp-2.4.7/debian/ppp.install 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/ppp.install 2021-02-25 19:12:30.000000000 +0100 @@ -6,6 +6,7 @@ debian/extra/ip-down.d/ etc/ppp/ debian/extra/ip-up etc/ppp/ debian/extra/ip-up.d/ etc/ppp/ +debian/extra/ip-pre-up etc/ppp/ debian/extra/ipv6-down etc/ppp/ debian/extra/ipv6-up etc/ppp/ debian/extra/options etc/ppp/ diff -Nru ppp-2.4.7/debian/ppp.lintian-overrides ppp-2.4.9/debian/ppp.lintian-overrides --- ppp-2.4.7/debian/ppp.lintian-overrides 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/ppp.lintian-overrides 2021-02-25 19:12:30.000000000 +0100 @@ -1,9 +1,5 @@ - # false positive; radrealms.c verified to build with -D_FORTIFY_SOURCE=2 -ppp binary: hardening-no-fortify-functions usr/lib/pppd/2.4.7/radrealms.so - -# pppd-dns is a one-shot init script; status doesn't make sense -ppp binary: init.d-script-does-not-implement-optional-option etc/init.d/pppd-dns status +ppp binary: hardening-no-fortify-functions usr/lib/pppd/2.4.9/radrealms.so # makes new files owned by group dip so that world read can be safely removed ppp binary: non-standard-dir-perm etc/chatscripts/ 2750 != 0755 @@ -15,3 +11,5 @@ # setuid root required to allow non-root (members of dip) to run ppp ppp binary: setuid-binary usr/sbin/pppd 4754 root/dip +# minconn.so has no dependencies outside pppd itself +ppp binary: shared-library-lacks-prerequisites usr/lib/pppd/2.4.9/minconn.so diff -Nru ppp-2.4.7/debian/ppp.maintscript ppp-2.4.9/debian/ppp.maintscript --- ppp-2.4.7/debian/ppp.maintscript 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/ppp.maintscript 2021-02-25 19:12:30.000000000 +0100 @@ -1,2 +1,5 @@ # Has been moved to /usr/share/bash-completion/completions/pon rm_conffile /etc/bash_completion.d/pon 2.4.7-1+2~ + +# Removed due to being non-functional +rm_conffile /etc/init.d/pppd-dns 2.4.8-1+1~exp1~ diff -Nru ppp-2.4.7/debian/ppp.postinst ppp-2.4.9/debian/ppp.postinst --- ppp-2.4.7/debian/ppp.postinst 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/ppp.postinst 2021-02-25 19:12:30.000000000 +0100 @@ -37,11 +37,19 @@ chmod 640 $file done +# Clean up after ppp-dns service removal +if dpkg --compare-versions "$2" le-nl "2.4.8-1+2~"; then + rm -f /lib/systemd/system/pppd-dns.service.dpkg-bak + deb-systemd-helper purge pppd-dns.service >/dev/null + deb-systemd-helper unmask pppd-dns.service >/dev/null + update-rc.d -f pppd-dns remove +fi + } case "$1" in configure) - everything + everything "$@" ;; abort-upgrade|abort-remove|abort-deconfigure) diff -Nru ppp-2.4.7/debian/ppp.pppd-dns.init ppp-2.4.9/debian/ppp.pppd-dns.init --- ppp-2.4.7/debian/ppp.pppd-dns.init 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/ppp.pppd-dns.init 1970-01-01 01:00:00.000000000 +0100 @@ -1,23 +0,0 @@ -#!/bin/sh -e -### BEGIN INIT INFO -# Provides: pppd-dns -# Required-Start: $local_fs -# Required-Stop: -# Default-Start: S -# Default-Stop: -# Short-Description: Restore resolv.conf if the system crashed. -# Description: Restore /etc/resolv.conf if the system crashed before the -# ppp link was shut down. -### END INIT INFO - -. /lib/lsb/init-functions - -case "$1" in - start) ;; - stop|restart|force-reload) exit 0 ;; - *) echo "Usage: $0 {start|stop|restart|force-reload}" >&2; exit 1 ;; -esac - -[ -x /etc/ppp/ip-down.d/0000usepeerdns ] \ - && exec /etc/ppp/ip-down.d/0000usepeerdns - diff -Nru ppp-2.4.7/debian/ppp.pppd-dns.service ppp-2.4.9/debian/ppp.pppd-dns.service --- ppp-2.4.7/debian/ppp.pppd-dns.service 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/ppp.pppd-dns.service 1970-01-01 01:00:00.000000000 +0100 @@ -1,10 +0,0 @@ -[Unit] -Description=Restore /etc/resolv.conf if the system crashed before the ppp link was shut down - -[Service] -Type=oneshot -ExecStart=/etc/ppp/ip-down.d/0000usepeerdns - -[Install] -WantedBy=multi-user.target - diff -Nru ppp-2.4.7/debian/ppp.symbols ppp-2.4.9/debian/ppp.symbols --- ppp-2.4.7/debian/ppp.symbols 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/ppp.symbols 2021-02-25 19:12:30.000000000 +0100 @@ -1,4 +1,5 @@ -pppd.so.2.4.7 ppp #MINVER# +pppd.so.2.4.9 ppp #MINVER# +* Build-Depends-Package: ppp-dev # Ignore all symbols that start with an underscore in the Base module (regex|optional)"^_.*@Base$" 2.4.7-1+2~ # Ignore $global$ which seems to appear on hppa only @@ -41,6 +42,7 @@ bundle_id@Base 2.4.7-1+2~ bundle_name@Base 2.4.7-1+2~ bundle_terminating@Base 2.4.7-1+2~ + ca_path@Base 2.4.9-1+1~ cacert_file@Base 2.4.7-2+1~ callback_script@Base 2.4.7-1+2~ cbcp@Base 2.4.7-1+2~ @@ -61,6 +63,8 @@ chap_auth_peer@Base 2.4.7-1+2~ chap_auth_with_peer@Base 2.4.7-1+2~ chap_check_hook@Base 2.4.7-1+2~ + chap_client_timeout_time@Base 2.4.9-1+1~ + chap_find_digest@Base 2.4.9-1+1~ chap_max_transmits@Base 2.4.7-1+2~ chap_md5_init@Base 2.4.7-1+2~ chap_mdtype_all@Base 2.4.7-1+2~ @@ -68,7 +72,7 @@ chap_protent@Base 2.4.7-1+2~ chap_rechallenge_time@Base 2.4.7-1+2~ chap_register_digest@Base 2.4.7-1+2~ - chap_timeout_time@Base 2.4.7-1+2~ + chap_server_timeout_time@Base 2.4.9-1+1~ chap_verify_hook@Base 2.4.7-1+2~ chapms_init@Base 2.4.7-1+2~ chapms_strip_domain@Base 2.4.7-1+2~ @@ -78,6 +82,7 @@ child_wait@Base 2.4.7-1+2~ childwait_done@Base 2.4.7-1+2~ cif6addr@Base 2.4.7-1+2~ + cif6defaultroute@Base 2.4.8-1+1~ cifaddr@Base 2.4.7-1+2~ cifdefaultroute@Base 2.4.7-1+2~ cifproxyarp@Base 2.4.7-1+2~ @@ -113,6 +118,7 @@ devnam@Base 2.4.7-1+2~ devnam_fixed@Base 2.4.7-1+2~ devstat@Base 2.4.7-1+2~ + dfl_route_metric@Base 2.4.8-1+1~ die@Base 2.4.7-1+2~ disable_defaultip@Base 2.4.7-1+2~ disconnect_script@Base 2.4.7-1+2~ @@ -134,6 +140,7 @@ eaptls_init_ssl@Base 2.4.7-2+1~ eaptls_init_ssl_client@Base 2.4.7-2+1~ eaptls_init_ssl_server@Base 2.4.7-2+1~ + eaptls_is_init_finished@Base 2.4.9-1+1~ eaptls_passwd_hook@Base 2.4.7-2+1~ eaptls_receive@Base 2.4.7-2+1~ eaptls_retransmit@Base 2.4.7-2+1~ @@ -152,7 +159,6 @@ error@Base 2.4.7-1+2~ error_count@Base 2.4.7-1+2~ escape_flag@Base 2.4.7-1+2~ - ether_to_eui64@Base 2.4.7-1+2~ eui64_ntoa@Base 2.4.7-1+2~ exitnotify@Base 2.4.7-1+2~ explicit_passwd@Base 2.4.7-1+2~ @@ -180,7 +186,7 @@ generic_establish_ppp@Base 2.4.7-1+2~ get_X509_from_file@Base 2.4.7-2+1~ get_eaptls_secret@Base 2.4.7-2+1~ - get_first_ethernet@Base 2.4.7-1+2~ + get_first_ether_hwaddr@Base 2.4.9-1+1~ get_host_seed@Base 2.4.7-1+2~ get_idle_time@Base 2.4.7-1+2~ get_if_hwaddr@Base 2.4.7-1+2~ @@ -189,6 +195,7 @@ get_pty@Base 2.4.7-1+2~ get_secret@Base 2.4.7-1+2~ get_srp_secret@Base 2.4.7-1+2~ + get_time@Base 2.4.9-1+1~ getword@Base 2.4.7-1+2~ got_sighup@Base 2.4.7-1+2~ got_sigterm@Base 2.4.7-1+2~ @@ -275,6 +282,7 @@ log_default@Base 2.4.7-1+2~ log_ssl_errors@Base 2.4.7-2+1~ log_to_fd@Base 2.4.7-1+2~ + logwtmp@Base 2.4.9-1+1~ loop_chars@Base 2.4.7-1+2~ loop_frame@Base 2.4.7-1+2~ magic@Base 2.4.7-1+2~ @@ -283,6 +291,7 @@ make_new_bundle@Base 2.4.7-1+2~ master_detach@Base 2.4.7-1+2~ max_data_rate@Base 2.4.7-1+2~ + max_tls_version@Base 2.4.9-1+1~ maxconnect@Base 2.4.7-1+2~ maxfail@Base 2.4.7-1+2~ maxoctets@Base 2.4.7-1+2~ @@ -415,6 +424,7 @@ setdtr@Base 2.4.7-1+2~ setipaddr@Base 2.4.7-1+2~ sif6addr@Base 2.4.7-1+2~ + sif6defaultroute@Base 2.4.8-1+1~ sif6down@Base 2.4.7-1+2~ sif6up@Base 2.4.7-1+2~ sifaddr@Base 2.4.7-1+2~ @@ -432,6 +442,7 @@ speeds@Base 2.4.7-1+2~ ssl_cmp_certs@Base 2.4.7-2+1~ ssl_msg_callback@Base 2.4.7-2+1~ + ssl_new_session_cb@Base 2.4.9-1+1~ ssl_verify_callback@Base 2.4.7-2+1~ start_link@Base 2.4.7-1+2~ start_networks@Base 2.4.7-1+2~ @@ -496,6 +507,7 @@ unlock_db@Base 2.4.7-1+2~ unsuccess@Base 2.4.7-1+2~ untimeout@Base 2.4.7-1+2~ + up_sdnotify@Base 2.4.8-1+1~ upap@Base 2.4.7-1+2~ upap_authpeer@Base 2.4.7-1+2~ upap_authwithpeer@Base 2.4.7-1+2~ diff -Nru ppp-2.4.7/debian/ppp-udeb.lintian-overrides ppp-2.4.9/debian/ppp-udeb.lintian-overrides --- ppp-2.4.7/debian/ppp-udeb.lintian-overrides 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/debian/ppp-udeb.lintian-overrides 2021-01-07 01:10:29.000000000 +0100 @@ -0,0 +1,6 @@ +# HOSTNAME is set in the script +ppp-udeb udeb: possible-bashism-in-maintainer-script postinst:184 '$HOSTNAME' +ppp-udeb udeb: possible-bashism-in-maintainer-script postinst:221 '$HOSTNAME' +ppp-udeb udeb: possible-bashism-in-maintainer-script postinst:222 '$HOSTNAME' +ppp-udeb udeb: possible-bashism-in-maintainer-script postinst:225 '$HOSTNAME' +ppp-udeb udeb: possible-bashism-in-maintainer-script postinst:227 '$HOSTNAME' diff -Nru ppp-2.4.7/debian/ppp-udeb.postinst ppp-2.4.9/debian/ppp-udeb.postinst --- ppp-2.4.7/debian/ppp-udeb.postinst 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/ppp-udeb.postinst 2021-02-25 19:12:30.000000000 +0100 @@ -31,7 +31,7 @@ db_progress START 0 $TOTWAIT ppp/detect_progress for P in "" "-U" ; do rm -f /tmp/probe-finished /tmp/ppp-errors - ( R=$(/usr/sbin/pppoe-discovery -A $P -I $1 2>/tmp/ppp-errors | \ + ( R=$(pppoe-discovery -A $P -I $1 2>/tmp/ppp-errors | \ grep AC | wc -l) echo $R > /tmp/probe-finished ) & WAIT=0 @@ -197,10 +197,17 @@ # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). +source /etc/network/interfaces.d/* + # The loopback network interface auto lo iface lo inet loopback +# This configuration stanza prevents ifupdown-aware network daemons +# like NetworkManager from managing the interface which is used for +# the PPPoE connection +iface $IFACE inet manual + # PPPoE connection auto provider iface provider inet ppp @@ -209,7 +216,7 @@ EOF # Set hostname and create a basic /etc/hosts file -echo -e "127.0.0.1\tlocalhost" > /etc/hosts +echo "127.0.0.1 localhost" > /etc/hosts if [ "$HOSTNAME" ]; then echo "$HOSTNAME" >/etc/hostname @@ -341,6 +348,4 @@ fi fi -#DEBHELPER# - exit 0 diff -Nru ppp-2.4.7/debian/rules ppp-2.4.9/debian/rules --- ppp-2.4.7/debian/rules 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/rules 2021-02-25 19:12:30.000000000 +0100 @@ -28,7 +28,7 @@ CHAPMS= USE_CRYPT= NO_CRYPT_HACK=1 MPPE= FILTER= HAVE_MULTILINK= \ USE_TDB= HAS_SHADOW= USE_PAM= HAVE_INET6= CBCP= USE_SRP= MAXOCTETS= \ USE_BUILTIN_CRYPTO=1 USE_EAPTLS= -UDEB_PLUGIN_DIRS := pppoatm rp-pppoe +UDEB_PLUGIN_DIRS := pppoatm pppoe ############################################################################## %: @@ -55,7 +55,7 @@ fi override_dh_auto_clean: - rm -rf pppd-udeb changelog-from-README $(TMP_PPP) $(TMP_UDEB) \ + rm -rf pppd-udeb debian/changelog-from-README $(TMP_PPP) $(TMP_UDEB) \ debian/extra/dh_ppp.1p [ ! -f Makefile ] || $(MAKE) dist-clean @@ -69,27 +69,25 @@ cd pppd-udeb/plugins/ && make clean perl -i -pe 's/ -DIPX_CHANGE\b//' pppd-udeb/Makefile -changelog-from-README: +debian/changelog-from-README: { \ sed -e "/^What's new in ppp-/,/^. New hooks have been added./!d" README ; \ echo ; \ echo ; \ cat Changes-2.3 ; \ - } > changelog-from-README + } > debian/changelog-from-README -override_dh_auto_build-arch: changelog-from-README +override_dh_auto_build-arch: debian/changelog-from-README dh_auto_build -- \ - COPTS="$(CFLAGS) $(CPPFLAGS)" LDOPTS="$(LDFLAGS)" + COPTS="$(CFLAGS) $(CPPFLAGS)" dh_auto_build -Dpppd-udeb/ -- \ COPTS="$(CFLAGS) $(CPPFLAGS) -Os -fomit-frame-pointer" \ - LDOPTS="$(LDFLAGS)" \ $(UDEB_MAKEOPTS) dh_auto_build -Dpppd-udeb/plugins -- \ COPTS="$(CFLAGS) $(CPPFLAGS) -Os -fomit-frame-pointer" \ - LDOPTS="$(LDFLAGS)" \ SUBDIRS="$(UDEB_PLUGIN_DIRS)" PLUGINS= -override_dh_auto_build-indep: changelog-from-README +override_dh_auto_build-indep: debian/changelog-from-README pod2man --section=1p --utf8 debian/extra/dh_ppp \ debian/extra/dh_ppp.1p @@ -110,7 +108,7 @@ > $(DIR_PPP_DEV)/usr/share/ppp-dev/substvars override_dh_installchangelogs: - dh_installchangelogs changelog-from-README + dh_installchangelogs debian/changelog-from-README override_dh_installexamples-arch: dh_installexamples @@ -119,11 +117,10 @@ mv $(DIR_PPP)/usr/share/doc/ppp/examples/autopppd \ $(DIR_PPP)/usr/share/doc/ppp/examples/scripts/ -override_dh_installinit: - dh_installinit --name=pppd-dns --no-stop-on-upgrade --no-start - -override_dh_installsystemd: - dh_installsystemd --name=pppd-dns --no-stop-on-upgrade --no-start +override_dh_lintian: + dh_lintian + install -D -p -m644 debian/ppp-udeb.lintian-overrides \ + debian/ppp-udeb/usr/share/lintian/overrides/ppp-udeb override_dh_perl: dh_perl -d --package=ppp-dev @@ -145,10 +142,5 @@ # the build fails if there are any discrepancies in the symbols file in order # to catch ABI changes. override_dh_makeshlibs: - dh_makeshlibs --package=ppp -- -c2 -edebian/ppp/usr/sbin/pppd -V + dh_makeshlibs --no-scripts --package=ppp -- -c2 -edebian/ppp/usr/sbin/pppd -V dh_makeshlibs --no-package=ppp - -## http://wiki.debian.org/onlyjob/get-orig-source -get-orig-source: $(info I: $(DEB_SOURCE)_$(DEB_VERSION_UPSTREAM)) - @echo "# Downloading..." - uscan --noconf --verbose --rename --destdir=$(CURDIR) --check-dirname-level=0 --force-download --download-version $(DEB_VERSION_UPSTREAM) $(PKD) diff -Nru ppp-2.4.7/debian/salsa-ci.yml ppp-2.4.9/debian/salsa-ci.yml --- ppp-2.4.7/debian/salsa-ci.yml 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/debian/salsa-ci.yml 2021-01-07 01:10:29.000000000 +0100 @@ -0,0 +1,10 @@ +--- +include: + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/salsa-ci.yml + - https://salsa.debian.org/salsa-ci-team/pipeline/raw/master/pipeline-jobs.yml + +variables: + # Disable reprotest until salsa-ci-team/pipeline#26 is resolved. + SALSA_CI_DISABLE_REPROTEST: 1 + +# vim: ts=2 sw=2 et sts=2 ft=yaml diff -Nru ppp-2.4.7/debian/upstream/metadata ppp-2.4.9/debian/upstream/metadata --- ppp-2.4.7/debian/upstream/metadata 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/debian/upstream/metadata 2021-01-07 01:10:29.000000000 +0100 @@ -0,0 +1,4 @@ +Bug-Database: https://github.com/paulusmack/ppp/issues +Bug-Submit: https://github.com/paulusmack/ppp/issues/new +Repository: https://github.com/paulusmack/ppp.git +Repository-Browse: https://github.com/paulusmack/ppp diff -Nru ppp-2.4.7/debian/upstream/signing-key.asc ppp-2.4.9/debian/upstream/signing-key.asc --- ppp-2.4.7/debian/upstream/signing-key.asc 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/upstream/signing-key.asc 2021-02-25 19:12:30.000000000 +0100 @@ -1,102 +1,86 @@ -pub 4096R/9E4295D605F66CE9 2011-10-12 - Key fingerprint = 631E 179E 370C D727 A7F2 A33A 9E42 95D6 05F6 6CE9 -uid [ unknown] Paul Mackerras (Signing key) - -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1 -mQINBE6U85gBEACYU+BDUOcO7uG3S2JilDFgHjr0i9bpoHjvEiFp63i6SDXPtWl4 -QtOVXM+f3uahAHyzfrJ0xe9Jx0hDDVNZqsk3jnEj5siAMAm80atoST5h4bk5TE9w -5fIOqUuKWh4i7bJOnUzmGoIF9N0xVCfcSaU4+kzRtnBnTPon+q+brDc79Tyk7PVj -P/2YTa5Vjzx1zqrHTOFBwXRk1RyVSATDAvqkA8vVw1odhmCP7EhKKT7nLBh8swz4 -DVk8ylVCkB+6UFlAXlq8c0cbFMB8Zjr9gYJaQ4nxJVQcSFizS67EalathxeHOjjg -QUK9kCWExOfkcf3zAfKxFUM6oq/iH+A1O0ieVYKxbGHYDZLmMAgkJweDhbyWzSoZ -WeWneuIIxaPvxH3wHDf5NLlsHaiTxoR08zq2PN5IHEmYgR6nvYxAd3ZXLEojWXZB -AbOIZxPUvbB+DHF+7WYMKPdBLWvY6W8w0t4EYOt5N0W+/+AL2ZTCYJjZCHvhZxhC -ki8grkIcShPf6BQLe3UJc/maJGu0Co1mhiCYx2a3AAkq8E1NZ0nzEP9+eoGohjvF -ht5P/omDpU/VrZOBrgCFBDHUymvBsKw9ofaLUIplH4gJRHB47pLLFob3LDzbXyb4 -GB3LrOuioqLaVgrjz6lymzxXVTzHlQkAYayN4jvve6jauFQF/QAZg1gotwARAQAB -tC9QYXVsIE1hY2tlcnJhcyAoU2lnbmluZyBrZXkpIDxwYXVsdXNAc2FtYmEub3Jn -PokCHAQQAQIABgUCTpT4/gAKCRDNW4dL6sGz9T6fD/4/lZuDrmBEX4pNkeLy3k8e -4yhURNxbAus1E7d56PJITEJx1LwpDysMJQaXf30XSlLr4X8XIkAGJNqdb1UAxpuq -QnH0oAwf0VtKFIwV/90g+622pVrrxTg81dXsR9j0Noc0djLpoKPcZiKiColIPtye -TAp+M6ugPEcDmjuFNLbDFWQ+g69U4wnRgICjcBTNA/CHqKgdkCPFjCkoay9K/szJ -vMYJ6D9PxJuikMfUTFBNZCJ1PQLXDyZZbx0FpCDBiqgH0oXrSQB7QlqddXMvVXNh -UVG3IY6JuFZQaUbfIGXO+XFtn1t1UkE2tsjhAO/fn01Aw7a4VvSDxOsn6lUnFgxA -o1WtVEPEP0ctyTWVgQlxkzlB4klfuCREsLBNynuS4dOgy3u+DqlqcNwSnABJFDDS -C9Cez3zxC1zAdcVfW7NNXrlallRFTX0iTd7iJhlNjbvYAoUWMXWedc9KhDQtXy6A -1KkvhdU0jSWJrCxzQAPsVUHIW7EFf3U3dNrZNNHEveVz8mGBthyYEBz115cDn5g0 -YJRXiWxQ1/dGFJMtnC1/ykIFiAR8ZL6zVVeQjuQTT1WKhyfxgitiCJR+qjxG3b/n -f1xSt26lswyqTGVCLj39L3TU4epuFXYRyZnMc8FZvX1zlA/83hBpxD2wkXdhJNt+ -jUyxS9SLRIgCtU8kdxb9JIkCHAQQAQIABgUCTpztgQAKCRDZIA5s0a248WecD/9h -89Tsu5CfKmhAL/mS33bWrreWg9w2ZvUQJ8yquPjVAgdrno7D/oOUhoC8wEoM7wwT -J4gv2HDNsNGeyB58ajiHyrAKEWFVpkr27DlTTw52F4MPZAn6IG0GXzETaZa00MOc -7YivWA7PbQGwhs7wiTvxzjEQxN6zZzA/eB8XWC452Qsn5pc7xPFlFaPq3yeIScgc -DQmO3YQiS/lfwCEoPoL9zgVhVfFu9coVVQylnGaJV4ibArNkU1nJ+RgMn/UmQtFW -yjAUBi9Ogq3l1KQ22RybDkQtQVxCXfh7xWGdhiJw5mqePSr3QlwYVpIO/7tovMGO -ELihPW00Pm5XC2Jav+FljoMZkNU4qdVZa8du85eSiV33yyF5RxWqbpdtKqMpvwlA -IUfYuW+p2VaeoNw34U9yhagWRSSy5jGiW0vo+nGc6PEjeg1u9GZUDt7BrcfALgVP -ZyQLWAe2qKJgtKL01GVBfhanHjYiUnCeA4qOeEG8vCQc+gmNhM89JCUV+f5D/5Fz -DxCGxCZKQRvhgSWeBGw0uzfBBGDmKDtlwJlzpuS+6Pec1/nuWBhaKb0RXO0BFnGy -pzPfGSq5sjekjbh/oUL5oZ163vvTfDsvC2l2CDHgidvio4fyfQIDOFwBayCZhrcf -cjf29qaRKAe8i6k2CUiFhbFz6c/BzCPg1YOaOS062YkCIAQQAQIACgUCTpT5PAMF -AXgACgkQkNE7g/JkgWUq5RAAr2P/Ff5IBrNkwP6Uc84JeOOZAhS/0gPg9HqENTpb -oHXODy8xH5yxG4lwyNidyuWVDd1b6fUZ5gE2x7qIPU7vmeVix9vma+2B0ndx2Al+ -qHJcO6xu0/iyF9RfgrcJh+pyGCeuyEcVGB0tPs7Y7GFeuV9b8/5yVyOqfmFARA1u -kH7M4ni+SX5k9f9mOV65x6lmJd8pp2x5oe1xnH92Ra/Xr4B2qkvhMyaI5I1lIvk1 -4xZQ9R1dSzJjhopFQbOEXBmb4yDYgdzyy1hIc/dtBwojJkfvB8+4mjr/fBEHAVFa -7hM4eDa21Ze0kMZ+0BPUa2P14bH/pLIYRYwd4dcMaPoevsTAHpWqoWT2SyxrFtr+ -TH/OpZKp21bRN6VDBojJUmx/KeJjCfo2Xvo97KEkWrUmcv9WxwXZVevI1HXIAPFn -c22kmATbQNEwzBXo+hHnnSUB97pJW+hDh44xjZTjLX5xz+sd4xbLkhAfcHRhhEcv -G4HOfSDYbZKnYAEN7eDijoO25OtIxSCczDC17r7fSJWolxLW1nWnlckPtxrYHnWW -0hCTX1wnOYzNcIRbdbcGL+e66ZT9eQDEGYoJku8xKqxJWvekfnVcUeB4Y2SwVdq4 -U/kHTjAggOYuM/aHxAM2LfNfWfrgDuZQcItRYFV0cMFMlI3rXBYnvPPUtU9c5qP+ -/JWJAiAEEAECAAoFAk6U+f4DBQE8AAoJEFcNXmq0LVJTgo8P/11kdGCmmnA87iCx -0k7CjdhwIH3ITwe4rVt8K9HvdrlzCQwWWpIFB+0dtGknUwHoXW9tHfZ3dZirzfEJ -1XImWE2tH/P/9Xcn2O3avjBj/+t7fMfEMENoRZap60Jp7D5WayYqhAwuPOi+otGP -7n/Acp5xN9OS17qvdfnbiO1fdZj10nQCPFdE7MP+0U9/qjXylgiEO9ri7ijh4cuF -01zCMRLc6fBv9cS+pU64C7AWoayg9fE7/C39JtN8aMntsNwVEvVvWqegOMV0gFJl -sqsdqGxUoYUyy3/rWIB+7ZR5l2L1Kblt+ItP+zOqt/uC6CJF8IlxW2Q+BlxlfSu3 -HPVZyBWJQPVGnDALqoUMognHfsV4lkJFPExTfWvC2Kfto/KbP6Og8WupcFSSI/G6 -CwRvwgTbcV18k+RGQ2Iny4tVX7pdg1+L6djuHVlcpH8qCibPGnYpTm93FkidB3Ub -87ZYO2jcSLcJnZCr5iNTT6tW+SchTupvd9gv9WXGvuNBZSn6zkKdRi9wzSZe6RkC -G1AjY3qmInthbvdLOP5G/FrFxkLcnNDwv3IxQFtUCT0/rM4xKYgTvr91LcnxK2Hc -tNxAdISN/OPSgTiubc44e8cHN3K+rl+zqSAqcFLwJdr9vEMSf+div0kDjPVsEWlU -LV3U6PrOVL1D/a48sLGKXfscq/P0iQIgBBMBCAAKBQJOlPrxAwUBPAAKCRBeRCCI -7WMuhylqD/oD+LLi5ix4Yp9sJT36falK3gxfeqOb4klZKrmZ6D5e7b+E/DUAPwyu -xEJBmJ3ZzwYd1Qe78PdLANQQd3+1Vz0P6SZ3rFrOAeDhNpmbtl89B6eo+787TQ8H -LplFndj83ziZbsr043tabMdUwrwzqYx7xqT+GNWS1xY95U+fSk++iGyeoK1thCn0 -Opv4s8FYQZw5p5jj6lz67pUv7IUpv3P6x31O0/jb+F0m/FONC+mtwzemepJctxxs -B/SL5ypQa+hq4YEq7w0XtJOWEv3DdOIu/rKn00i0kpF+drEHeCvEtAxw9EVdxpkm -flKwX9g8QowWdk3bdqZRa4jxlmF4CJIzAQmUsCfo++l3tzL8qYyaZe9/eaQcCAbS -tkTt7uB2qki9pM6AdP2W0/Yr7I7EFKsIANABwnEXxPxW+wYycXvCfhUdmeqcuuu3 -y/6LXBd2WMFcfqB/Yg8IloyJO1rZWc1+l08xw3eLfkSxZaF0XPDqHQRV9s0fY7mK -6U/4+dRVpnpt8Rqoo+Loi4DDAyaZjhSZO8fHC6rwPc96P33ZqLWixTOHMdua8APT -rFQar+cepBcaK8Qr+S9Q9BXdxeG/eUnRjqG69jG+Zdlx2ZA4zOaPIdkE9CgkIHxV -z+s0WMv1bLua06aUXe2Fc+a7XeD6TmSmdcMbxr7XCkHdORAzUecJGokCIAQTAQgA -CgUCTpUG3wMFATwACgkQWtJCEcBg0cikhRAAluVdH0GzGyEiYX7cRmqPb5wOfiht -bndw/I5PeYUAYzTsHaCdsZi5mrygN0zNS8WdDE4sl+4EGe9WiwgH/ZMIrItsq+fX -FakFzA5tFiLYu58dg7p2lqCZyX69PRt2u462tueHqdFb9boRW3GysiCpB2z+0yKM -Li+yRNr75u+zltDv0so+/zzUkcN1sM5gguThNs4L1LAsQS6Cf+lXz9pyGUeqnRUH -QrEQPsIlon3neidJ1rL2haKi9pi9pLzk35LFcmh7vFyaRhgBqs5lbPUY4kT3psm5 -eBzr5bytJ4Iwbflo78If2MbOT6NqRhztlTV0MUce5AoYpqygwhX5OO0AQ1xhh1mF -hfzFxMh/CdFsSU9lUnl/jE9CTGnOD/e2PggoBZ69HfG1XjlYQh42mvs51LAi+jIe -BD5llX5JliHtM1mnlcB1ZNcuTxflIHpD763eL7t8w3xhVlE1H+pSQQXL2Hm7CuY7 -l2RhkQjcHo9gdNTTj2J1DZ3MBzZEoeMiqCJUB0ks/FjYxbiO/dsD04u9c8w7IOLm -j7pjIevm3aiqc7PezI/c2XBCIAFgL6dl8/2FWrKVXbGJdmN9rJ0S2dCYWMz994fC -q0D2iUIOfoYZ1Db7TIMhOzMq2rTqC63wq82JjBW4ooaprJ7LO8TKpsV5Qud3A5zH -U2C9KtE6jWrxlkuJAjgEEwECACIFAk6U85gCGwMGCwkIBwMCBhUIAgkKCwQWAgMB -Ah4BAheAAAoJEJ5CldYF9mzpjzgP/RKJuRGzzD2I4+3owd6R5t0m8/xfdzWH7ynA -mv8Bo678F3oCxuxzjc7QMg9n7a/NS34kkxPvYj3GxJo3Lya1mjviHdy7k1U7zXuz -cs7v0qTNg1FQyLLqig6Va1zuRVIwFNyUcU8j7HGguwSSRaJLG8FxLjcgrWfIwsW/ -me58Z1Sa8YeKemeQ7nIrIkG4FbjHDNiwbWc/Ak3gDiMFIJjVbip0Sc78jxIgu8TD -fIpZGvwOVxw23CfDBLlkm9nCtxEwODlNof8WEuoStnh4o9ijkpVm8AW7aQAMu9/s -JLtb9ihLpbAtWGkWAiRNZcmfVpL4NBK1sWJpexw5bgO7MFg8bvieD8sX1qKHfvHh -ALOJG/FgmNSk1xIaKCKF+16OggruBcVB9UGtI3bahP8HvS9DTV7pfgH4T1Ew8pFg -F2BpTYBZw8yeJVrBpUSttSrumuERayvTtW75dwd8AB+e5FinGFYA3tYvwv6Byw2l -ikPnv4NoNO6KE/YMySMhW0/Ax3xWAD+WuaAiyp0drQH5ralsbkqBl9NiHAWNm5o2 -dahHoljr8/lkGzAMf9ZdHuNjTg71DhytkiJ8/hDy8q6EP7mkkk55Ud8jYMoZq9Ap -ZZZeYKhSMFbHLE08wy6EdzWG+SD0W8nvWi/AQzuqP/kxWlkO2GBgHUFAASKooqxF -lOsLutsZ -=ALo8 +mQINBE6U9CMBEADlOHAMjZEsRW0/0kNcckRWRbW5J29rhPM7N0cgSC2NcJEcPYDT +/yoNsv8gbzhGCACSvYDMscTdifon7o9JZyOxoUcn+AaFMyNCuZRcvmZNsHcKfB82 +dkmSniM+nCwC6Oqv4av5XyeRz9k5o06Gno6k8nio0zX5ZIdHjtHTxB8mvur7tNkk +UiDvl++VXk8txsJNKLNti3EqRTaHHG9Uu+bx4j1HuDyqh5+RAWoVClAc9OaiaPxQ +w44p1meWPLcR/E4ClEUvzN/L03AKFj2Kd85HuYc5zoqP4GsfnDwvqMKZZvNP7Ohq +9hw3rtweoFrU476umQ+XYyBhEtY7ktP6jVbipZpS4UoF49/ZZHx/pA+8VzMUWf5O +wgGUxHYHWdeR7ffgsWKBM2+EZlfmAEzLWMC5FEvpvQkdAgy+QsZWE+Hvom4IueBx +EiimcL2DjIfIx0HcVsMObM82/w35p3ymYHM+WuKuqq8eXNgx6uAMnGYPvVXrp/1D +xCMog+aaZslPhgKelF31Oh4S7IIeG/YRRsQaxiFl2M01+uhpNOGoLhW08H6Y3irw +Jz5x8WACDaA9adZN6qJB1LI1QnxUxan4ZUqPoCuUuwn8uqBet7OU8Z8u3VEMs9EM +W477wjkRqZedIopUJRgQnnlUYTPPY235gn/UNSy6X27o33vWngt3A5JLLQARAQAB +tCFQYXVsIE1hY2tlcnJhcyA8cGF1bHVzQHNhbWJhLm9yZz6JAjgEEwECACICGwMG +CwkIBwMCBhUIAgkKCwQWAgMBAh4BAheABQJaAotiAAoJEAQPHUnsnbuMBPEP/3c+ +knvINXGkFgf7NOdTh98V0M9Jks0ljglqgVrPa0GIq+nnjxB/e1kd32/f3H6BjXmJ +GmHv7Y/mzHnD6i/hqTO2QPbT1p2TNyaW/19E+M5wl/BFfwksXu8asiJbGq993sLs +3SC8Y+LOlv2jYugXkviDZcQlZcPD3+3XD+jQh8Jci6qDh4ckwL91kqHfsulWlrvR +OqZ4Hq5J4bekcne01Wj7+mf9l+oFRovZy+F/SF9Yz7VJcuaRdoXXlMRItz4cPT8o +a9qiFyV1jfPPr/Ao+wXPaWPp9DvaLm+He75g/oubnS7dbgyl/I06HAjlNRAz3oxZ +RIuE5bk9SEQELfBxelrpmHNfjb4hVFui4/L1ktuYqKtCiqOBD4DHtiZqMDM0D47X +BE083z2/KtFT90uzXV56Rz8LqKkwy+k5YUD9XgUNKcoD1npAiaR5YJFLDmNCNkOg +qidMRXgTRpzJrs9KsT6inP6+o7AAkCeull91F/WY6iHlAGmE2oMEa6PG1ezAZ/L0 +X0R9JFxocHDzSqk/qUQw4XQe2Aj2LQ4Tq6hi10JE8uSGrqUkNo4vx2E4R6+yvyxH +Mfv1PkDR81t+byntMTNH75rM+BqWp4ucP622TeAPlfPG9+SrPDXj73TNs8qQpgSi +JS8Y2tcinjf2ORDro7GtZ6hUioaNVL3csTtfOaJNtCJQYXVsIE1hY2tlcnJhcyA8 +cGF1bHVzQG96bGFicy5vcmc+iQI4BBMBAgAiBQJaAo3IAhsDBgsJCAcDAgYVCAIJ +CgsEFgIDAQIeAQIXgAAKCRAEDx1J7J27jEfeD/4mJeHQet0Zar/XcVKRMk0PHj9i +fnK2E62I0tloTyJFFuUeVGuAlIlGKlAH+TN9IbL7levwaB8QE0LbcxbcZu0H1sYo +8CfOFUqSDb5rTi5oEmI++wG/rSR10Ey6Ie9t+UnvLGYN+e6Akws/7UD1adoyBktT +kw9Wp7WN/z4QGJx7xiuXFdEfE49Rchnh2r192ewHJZn3wkn+Rq54v+mDCQOvpHhg +KWUkkK4ibaXlLVZIGLhaE2x5MCD2Uhr/PI63z2M1U6q2LZlwFlQhUqvILkrd8fmh +PTTn/bvHPjwekuTLLaUybCZQmu8fslAhXGeKSXpKYQsX+yWMLFbQG6o5DylVX7y1 +jcLAUUnObj/8/OLseIguOFTBKMK2Usm28jilqcXN6Hwn03PJ5xAuu8n2QhQjb07i +QiGl2uC+/jL5AmdVsKAEXj4EKa7b5N3CuJHDEKV60UFtN/hdU5IEmuLSf4Z/rLeO +mlBgKFlBhT3BEu9SEgMtk4XMeVHGZHpuOzgABPgVVXKYpY2R/tHZ7YHgh5/RQSNe +61BNsoOnZgsieQBEO0Wgni5nQbvl0xSxce2vkWJtwe+7gFNjfAHhk9GPzVJcwgX8 +cvm1G/yOi3ZK1yth+Qg/5nr2PrT2oF5GHnco4TNlRaXn9P0GY5E1ky8FWs/7t/OR +0PCoPHr1DRpwmZXxV7kBDQRaAo0zAQgA6KEVJORU3OZy+ynOIPqsyU5ZKIFOzIO+ +MZP78AJD4Yzh7izQFK3E8DT08CzQ/Z835llnLSPvXXmG3bnv9eh4zDePvNQ8H8jm +wScaxc03xKUbwNEJhdkqf5vCwpn/pSKwJ/KfGmwHvYOoDz908y/CHOpBM6/kdGll +Gk8iCXGjaAEY3Wl0wj7MAx/3SbpqeusQ0/REA+J9GsoGZh456iG22s6SCyw1jxGG +NcIeMJsKTgnxuHAGORemXjOMjA87rsPokgQ1xgE0mxPmqXT9QeE3FE4pTUsyDf8S +c33NIXW7MT5HWnmqw22R7PWySMtqmILIxCZAEXKILk1LtsNQQs16ewARAQABiQM+ +BBgBAgAJBQJaAo0zAhsCASkJEAQPHUnsnbuMwF0gBBkBAgAGBQJaAo0zAAoJEJ2a +6ncsY3GfdyEH/3CBs9J8W+ysJRJkWxZFEcX2ZPMJQCFhQtpfWkndn+5JAJCkMbao +28BlZTjACQh9SUyvgzK1V8b5cm6Wfg6sHDbnEoPQ6W72v+TKf+gD33ofPnFd4gov +/xpr1bGmJAYkO5xTfeG1xZbAdsf5dtTM0sIM+oPnr5n51f+tqM9Hh/jKi7JWX5bM +zfhjZ1LzU1spCWuEqizJQ9/nrxL6NDpU4BwZ3le7VaDUSwlTpeOO5Fe72WhDt2nP +1jZDEgegE2KO53C4EI5T7VMaG5ttjgKxLoHmXBejw/laTI5nonDrHVmA0RmHUzCu +WzL5QUiMi2EJ4UlizMXYi/xJy/M4RSY0Qes6/Q//dmoEIzjiNvfVD/E2MjsFbpgS +Vk0vttbyxgiLAc6FpdPhemiMSZBSnbBK4dbsYcNXP/uq6YhXpEEMPx/bKtmO/dVa +LtJfSK1oxoPQfOL6nL0b3+x/nWCGWdDDR793sX2PQdljUmrZlwGBOjZs5dndcE1E +S5tM2gWcKwdDNFdswCERuVV+CopCiQ8lMYZb8crnLem+LihPCyuTDEO6kBZmiDp7 +TiHd8Ct61AX77bl+ZO+fF610/bVP5Ipu2zuhCe9td8WwZ8aLhMzAbCTHMWJ8g8Cj +XBF+nv/9Xunq4gdv6v+1fGJOcfH9SOJKjQxY+3u7JwaXw/q4yRmE1l6X5frBKI3q +TT7HgFLINupStaiN+Of5jUfpg4xNNWFiBn5PfegtXNozHcE45EC8VDKXbfM+omDV ++rhvzyzkkgIijrl9rfdlQTqVln29eZib7+LObRO3d9gKbBNJGL9nD1qdT97neJsk +Xy+yC0VStoHgTOd7ibg/CktfL5JgoeSiiJxOXHsfmszhL+c/rOprJBt1/+9i6jKt +XvWfafSNrM2j/rKaLGGTsoWW8MNiE9Qtjf16luHxZasrDGNy4VPCCroJPfHML6ZA +3fiQF0ewp1wDbG71OPMk+rpagm+TL0pwegvihZOJ4mvBoUYGZOIUnQNMHhvNwPJT +VJdfDfKwfGxTSsWDsJe5Ag0ETpT0IwEQANUxk+BdFar5lO7SscYUpmiED4a/HRf0 +pjN+nbhVFBxYrKQobroy1W/yXAg757iz4v7w3B/UtaGemTbOaVj+mgEyZckL9S7j +Zc8O0Q5+JK1gq7gvZX961GX0h5iPfJp8Cs9pVOB7laoeHGnKvg5dm02xzr28hK85 +HSEj7FoV2XB86x8Tmn5GoiYQDIft0ZxYuacyqu2D+kl7neM/ohffKQBnO326cjKT +NFNKtibOQboGH6NgWl6OcdxDpXd34DZGX8cUkPqq+lEka9F9jHqyPk0/kG25mBKi +PX2PcceaHwDOD7yCsYSFDYBBQ1y98tShcPSGl9hYgzH8o2H+yTem8bU2HgCytcBo +qwoBJdlbJcf/BARLOWb1prM4N/v0qxNO+j4/5Bh82vzU8tuf865AuIs6q/pP4ni/ +9t5o/839p7rJP3Awb0cZo7XqJ/iA2UTU/+2Q3VCPyRMfL30jj61cZUBovoRlTCXA +MgzDDpXuwWR4w5KKGdLmYvPF9AYa9Hzl4YSwjKfyNnuRVeXhFnmzuDsq6JtjsT03 +ZvmSs9olnbWajPF7VQM/24s7jHT5wBoxCvJOV5G14Cep9yu74OzLkzeWzMvHKtW6 +EWdvf7/I79S3aDJHiKzqwce2hkzmlqt9XZjILhlfjZ9KUPOlGcSYBHKbeGfLnCdc +iFNbW3yu7tvNABEBAAGJAh8EGAECAAkCGwwFAloCi6kACgkQBA8dSeydu4wjfhAA +jtcqWUPiSGow8lwCgEOGmsCTVedMsCRkqzWugnT/Ig5wOC4VBhHYPECwXYbuV2gf +/4S7cwFWqxG7Ykhh35VLt+dpADbVI49/QFittPPCuoEZsEaZ95QAQ+qAa8dPY0Wf +4xviqrMEVjo4bZtjvnSMwVtooQwWo7xyFy9Tb+6hsOXZYPbz/pfeTxO3GGVD/HOd +HJy2WNmN9ZzpDKHY/3YlipTHNaYHvd0yRLErHzXLZ4KkD9S/SDNbJagc2WYLUUhW +l5EVOOZQT8xBPQDfErdj1dQ6e2u2b1V7uyYAm0ir1d49hn+8S0o+ZvrKQhtwdoJa +8m0SBz/e6bDDMx0uEJm5S8pzWtB7M8fHk0rQzyXeiIUhrxXm8Fhwhxd44/5wl49n +j6nADDyXsc99tfh/4dHykiRnaWtW1ESEfsJL4w5ZVu3oQ8Z3cY+zLsgwG8EnW+G8 +amcNobv1eh8YQXiFBis+C76zcgkqXZ9qhdouKWESbgQln2txDC4Zs8bL8D+G5bLU +I2yTBakamSKMMN82MW2yJU+VajbsMkSpbnLHc2A6IvouvtVKKIenKdQ+vDoMrvXW +doXG/pi1JXGy7lgfK7WUbGHAdHwM8mvdJfxT0mhK79KrJ0Hnck0cE+t59g4zybwh +EfwWHNmulXYL1Dby9/zhTsNYawbZxeMnGu2dceuPqlc= +=NyOk -----END PGP PUBLIC KEY BLOCK----- diff -Nru ppp-2.4.7/debian/watch ppp-2.4.9/debian/watch --- ppp-2.4.7/debian/watch 2019-02-08 17:37:29.000000000 +0100 +++ ppp-2.4.9/debian/watch 2021-02-25 19:12:30.000000000 +0100 @@ -1,3 +1,3 @@ -version=3 +version=4 opts=pgpsigurlmangle=s/$/.asc/ \ -https://download.samba.org/pub/ppp/ppp-([0-9\.]+)\.tar\.gz +https://ftp.samba.org/pub/ppp/ .*/ppp-?(\d\S+)\.tar\.gz diff -Nru ppp-2.4.7/etc.ppp/eaptls-client ppp-2.4.9/etc.ppp/eaptls-client --- ppp-2.4.7/etc.ppp/eaptls-client 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/etc.ppp/eaptls-client 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,10 @@ +# Parameters for authentication using EAP-TLS (client) + +# client name (can be *) +# server name (can be *) +# client certificate file (required) +# server certificate file (optional, if unused put '-') +# CA certificate file (required) +# client private key file (required) + +#client server /root/cert/client.crt - /root/cert/ca.crt /root/cert/client.key diff -Nru ppp-2.4.7/etc.ppp/eaptls-server ppp-2.4.9/etc.ppp/eaptls-server --- ppp-2.4.7/etc.ppp/eaptls-server 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/etc.ppp/eaptls-server 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,11 @@ +# Parameters for authentication using EAP-TLS (server) + +# client name (can be *) +# server name (can be *) +# client certificate file (optional, if unused put '-') +# server certificate file (required) +# CA certificate file (required) +# server private key file (required) +# allowed addresses (required, can be *) + +#client server - /root/cert/server.crt /root/cert/ca.crt /root/cert/server.key 192.168.1.0/24 diff -Nru ppp-2.4.7/etc.ppp/openssl.cnf ppp-2.4.9/etc.ppp/openssl.cnf --- ppp-2.4.7/etc.ppp/openssl.cnf 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/etc.ppp/openssl.cnf 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,14 @@ +openssl_conf = openssl_def + +[ openssl_def ] +engines = engine_section + +[ engine_section ] +pkcs11 = pkcs11_section + +[ pkcs11_section ] +engine_id = pkcs11 +dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so +MODULE_PATH = /usr/lib64/libeTPkcs11.so +init = 0 + diff -Nru ppp-2.4.7/.github/workflows/buildroot.yaml ppp-2.4.9/.github/workflows/buildroot.yaml --- ppp-2.4.7/.github/workflows/buildroot.yaml 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/.github/workflows/buildroot.yaml 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,56 @@ +name: Buildroot +on: [push, pull_request] + +jobs: + buildroot: + runs-on: ubuntu-latest + strategy: + matrix: + defconfig_name: [qemu_x86_defconfig, qemu_x86_64_defconfig, raspberrypi4_defconfig, raspberrypi4_64_defconfig, qemu_ppc64le_pseries_defconfig, qemu_mips32r2_malta_defconfig, qemu_mips64_malta_defconfig] + libc_name: [glibc, uclibc, musl] + steps: + - name: Checkout Buildroot sources + run: git clone --depth=1 --branch=2020.11.1 https://git.busybox.net/buildroot + - name: Select latest PPP version + working-directory: buildroot/package/pppd + run: | + # Allow package to build when musl libc is selected + sed -i '/depends on !BR2_TOOLCHAIN_USES_MUSL/d' Config.in + # Upstream version always needs OpenSSL + sed -i '/select BR2_PACKAGE_OPENSSL/c\\select BR2_PACKAGE_OPENSSL' Config.in + # Do not check for package hash, so there is no need to compute it + rm pppd.hash + # Buildroot patch is already applied upstream + 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 '9iPPPD_SITE_METHOD = git' pppd.mk + # Plugin rp-pppoe has been renamed in "pppoe" + sed -i 's/rp-pppoe/pppoe/g' pppd.mk + - name: Enable PPP build + working-directory: buildroot + run: | + # Enable all Buildroot PPP options as everything is built by upstream build system + echo "BR2_PACKAGE_PPPD=y" >> configs/${{ matrix.defconfig_name }} + echo "BR2_PACKAGE_PPPD_FILTER=y" >> configs/${{ matrix.defconfig_name }} + echo "BR2_PACKAGE_PPPD_RADIUS=y" >> configs/${{ matrix.defconfig_name }} + echo "BR2_PACKAGE_PPPD_OVERWRITE_RESOLV_CONF=y" >> configs/${{ matrix.defconfig_name }} + - name: Select glibc + if: ${{ matrix.libc_name == 'glibc' }} + working-directory: buildroot + run: echo "BR2_TOOLCHAIN_BUILDROOT_GLIBC=y" >> configs/${{ matrix.defconfig_name }} + - name: Select uClibc + if: ${{ matrix.libc_name == 'uclibc' }} + working-directory: buildroot + run: echo "BR2_TOOLCHAIN_BUILDROOT_UCLIBC=y" >> configs/${{ matrix.defconfig_name }} + - name: Select musl + if: ${{ matrix.libc_name == 'musl' }} + working-directory: buildroot + run: echo "BR2_TOOLCHAIN_BUILDROOT_MUSL=y" >> configs/${{ matrix.defconfig_name }} + - name: Configure Buildroot + working-directory: buildroot + run: make ${{ matrix.defconfig_name }} + - name: Build + working-directory: buildroot + run: make diff -Nru ppp-2.4.7/.github/workflows/solaris.yaml ppp-2.4.9/.github/workflows/solaris.yaml --- ppp-2.4.7/.github/workflows/solaris.yaml 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/.github/workflows/solaris.yaml 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,17 @@ +name: Solaris +on: [push, pull_request] + +jobs: + solaris: + runs-on: macos-latest + steps: + - name: Checkout PPP sources + uses: actions/checkout@v2 + - name: Build + uses: vmactions/solaris-vm@v0.0.1 + with: + run: | + pkg update + pkg install gcc + ./configure + make diff -Nru ppp-2.4.7/include/linux/ppp_defs.h ppp-2.4.9/include/linux/ppp_defs.h --- ppp-2.4.7/include/linux/ppp_defs.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/include/linux/ppp_defs.h 2021-01-05 00:06:37.000000000 +0100 @@ -184,12 +184,4 @@ time_t recv_idle; /* time since last NP packet received */ }; -#ifndef __P -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif -#endif - #endif /* _PPP_DEFS_H_ */ diff -Nru ppp-2.4.7/include/net/if_ppp.h ppp-2.4.9/include/net/if_ppp.h --- ppp-2.4.7/include/net/if_ppp.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/include/net/if_ppp.h 2021-01-05 00:06:37.000000000 +0100 @@ -150,7 +150,7 @@ #endif #if (defined(_KERNEL) || defined(KERNEL)) && !defined(NeXT) -void pppattach __P((void)); -void pppintr __P((void)); +void pppattach(void); +void pppintr(void); #endif #endif /* _IF_PPP_H_ */ diff -Nru ppp-2.4.7/include/net/ppp-comp.h ppp-2.4.9/include/net/ppp-comp.h --- ppp-2.4.7/include/net/ppp-comp.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/include/net/ppp-comp.h 2021-01-05 00:06:37.000000000 +0100 @@ -59,36 +59,36 @@ int compress_proto; /* CCP compression protocol number */ /* Allocate space for a compressor (transmit side) */ - void *(*comp_alloc) __P((u_char *options, int opt_len)); + void *(*comp_alloc)(u_char *options, int opt_len); /* Free space used by a compressor */ - void (*comp_free) __P((void *state)); + void (*comp_free)(void *state); /* Initialize a compressor */ - int (*comp_init) __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int debug)); + int (*comp_init)(void *state, u_char *options, int opt_len, + int unit, int hdrlen, int debug); /* Reset a compressor */ - void (*comp_reset) __P((void *state)); + void (*comp_reset)(void *state); /* Compress a packet */ - int (*compress) __P((void *state, PACKETPTR *mret, - PACKETPTR mp, int orig_len, int max_len)); + int (*compress)(void *state, PACKETPTR *mret, + PACKETPTR mp, int orig_len, int max_len); /* Return compression statistics */ - void (*comp_stat) __P((void *state, struct compstat *stats)); + void (*comp_stat)(void *state, struct compstat *stats); /* Allocate space for a decompressor (receive side) */ - void *(*decomp_alloc) __P((u_char *options, int opt_len)); + void *(*decomp_alloc)(u_char *options, int opt_len); /* Free space used by a decompressor */ - void (*decomp_free) __P((void *state)); + void (*decomp_free)(void *state); /* Initialize a decompressor */ - int (*decomp_init) __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int mru, int debug)); + int (*decomp_init)(void *state, u_char *options, int opt_len, + int unit, int hdrlen, int mru, int debug); /* Reset a decompressor */ - void (*decomp_reset) __P((void *state)); + void (*decomp_reset)(void *state); /* Decompress a packet. */ - int (*decompress) __P((void *state, PACKETPTR mp, - PACKETPTR *dmpp)); + int (*decompress)(void *state, PACKETPTR mp, + PACKETPTR *dmpp); /* Update state for an incompressible packet received */ - void (*incomp) __P((void *state, PACKETPTR mp)); + void (*incomp)(void *state, PACKETPTR mp); /* Return decompression statistics */ - void (*decomp_stat) __P((void *state, struct compstat *stats)); + void (*decomp_stat)(void *state, struct compstat *stats); }; #endif /* PACKETPTR */ diff -Nru ppp-2.4.7/include/net/ppp_defs.h ppp-2.4.9/include/net/ppp_defs.h --- ppp-2.4.7/include/net/ppp_defs.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/include/net/ppp_defs.h 2021-01-05 00:06:37.000000000 +0100 @@ -183,12 +183,4 @@ time_t recv_idle; /* time since last NP packet received */ }; -#ifndef __P -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif -#endif - #endif /* _PPP_DEFS_H_ */ diff -Nru ppp-2.4.7/include/net/slcompress.h ppp-2.4.9/include/net/slcompress.h --- ppp-2.4.7/include/net/slcompress.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/include/net/slcompress.h 2021-01-05 00:06:37.000000000 +0100 @@ -137,12 +137,12 @@ /* flag values */ #define SLF_TOSS 1 /* tossing rcvd frames because of input err */ -void sl_compress_init __P((struct slcompress *)); -void sl_compress_setup __P((struct slcompress *, int)); -u_int sl_compress_tcp __P((struct mbuf *, - struct ip *, struct slcompress *, int)); -int sl_uncompress_tcp __P((u_char **, int, u_int, struct slcompress *)); -int sl_uncompress_tcp_core __P((u_char *, int, int, u_int, - struct slcompress *, u_char **, u_int *)); +void sl_compress_init(struct slcompress *); +void sl_compress_setup(struct slcompress *, int); +u_int sl_compress_tcp(struct mbuf *, + struct ip *, struct slcompress *, int); +int sl_uncompress_tcp(u_char **, int, u_int, struct slcompress *); +int sl_uncompress_tcp_core(u_char *, int, int, u_int, + struct slcompress *, u_char **, u_int *); #endif /* _SLCOMPRESS_H_ */ diff -Nru ppp-2.4.7/include/net/vjcompress.h ppp-2.4.9/include/net/vjcompress.h --- ppp-2.4.7/include/net/vjcompress.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/include/net/vjcompress.h 2021-01-05 00:06:37.000000000 +0100 @@ -130,15 +130,15 @@ /* flag values */ #define VJF_TOSS 1 /* tossing rcvd frames because of input err */ -extern void vj_compress_init __P((struct vjcompress *comp, int max_state)); -extern u_int vj_compress_tcp __P((struct ip *ip, u_int mlen, +extern void vj_compress_init(struct vjcompress *comp, int max_state); +extern u_int vj_compress_tcp(struct ip *ip, u_int mlen, struct vjcompress *comp, int compress_cid_flag, - u_char **vjhdrp)); -extern void vj_uncompress_err __P((struct vjcompress *comp)); -extern int vj_uncompress_uncomp __P((u_char *buf, int buflen, - struct vjcompress *comp)); -extern int vj_uncompress_tcp __P((u_char *buf, int buflen, int total_len, + u_char **vjhdrp); +extern void vj_uncompress_err(struct vjcompress *comp); +extern int vj_uncompress_uncomp(u_char *buf, int buflen, + struct vjcompress *comp); +extern int vj_uncompress_tcp(u_char *buf, int buflen, int total_len, struct vjcompress *comp, u_char **hdrp, - u_int *hlenp)); + u_int *hlenp); #endif /* _VJCOMPRESS_H_ */ diff -Nru ppp-2.4.7/linux/Makefile.top ppp-2.4.9/linux/Makefile.top --- ppp-2.4.7/linux/Makefile.top 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/linux/Makefile.top 2021-01-05 00:06:37.000000000 +0100 @@ -26,7 +26,7 @@ cd pppdump; $(MAKE) $(MFLAGS) install install-etcppp: $(ETCDIR) $(ETCDIR)/options $(ETCDIR)/pap-secrets \ - $(ETCDIR)/chap-secrets + $(ETCDIR)/chap-secrets $(ETCDIR)/eaptls-server $(ETCDIR)/eaptls-client install-devel: cd pppd; $(MAKE) $(MFLAGS) install-devel @@ -37,6 +37,10 @@ $(INSTALL) -c -m 600 etc.ppp/pap-secrets $@ $(ETCDIR)/chap-secrets: $(INSTALL) -c -m 600 etc.ppp/chap-secrets $@ +$(ETCDIR)/eaptls-server: + $(INSTALL) -c -m 600 etc.ppp/eaptls-server $@ +$(ETCDIR)/eaptls-client: + $(INSTALL) -c -m 600 etc.ppp/eaptls-client $@ $(BINDIR): $(INSTALL) -d -m 755 $@ diff -Nru ppp-2.4.7/modules/bsd-comp.c ppp-2.4.9/modules/bsd-comp.c --- ppp-2.4.7/modules/bsd-comp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/modules/bsd-comp.c 2021-01-05 00:06:37.000000000 +0100 @@ -148,19 +148,19 @@ #define BSD_OVHD 2 /* BSD compress overhead/packet */ #define BSD_INIT_BITS BSD_MIN_BITS -static void *bsd_comp_alloc __P((u_char *options, int opt_len)); -static void *bsd_decomp_alloc __P((u_char *options, int opt_len)); -static void bsd_free __P((void *state)); -static int bsd_comp_init __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int debug)); -static int bsd_decomp_init __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int mru, int debug)); -static int bsd_compress __P((void *state, mblk_t **mret, - mblk_t *mp, int slen, int maxolen)); -static void bsd_incomp __P((void *state, mblk_t *dmsg)); -static int bsd_decompress __P((void *state, mblk_t *cmp, mblk_t **dmpp)); -static void bsd_reset __P((void *state)); -static void bsd_comp_stats __P((void *state, struct compstat *stats)); +static void *bsd_comp_alloc(u_char *options, int opt_len); +static void *bsd_decomp_alloc(u_char *options, int opt_len); +static void bsd_free(void *state); +static int bsd_comp_init(void *state, u_char *options, int opt_len, + int unit, int hdrlen, int debug); +static int bsd_decomp_init(void *state, u_char *options, int opt_len, + int unit, int hdrlen, int mru, int debug); +static int bsd_compress(void *state, mblk_t **mret, + mblk_t *mp, int slen, int maxolen); +static void bsd_incomp(void *state, mblk_t *dmsg); +static int bsd_decompress(void *state, mblk_t *cmp, mblk_t **dmpp); +static void bsd_reset(void *state); +static void bsd_comp_stats(void *state, struct compstat *stats); /* * Procedures exported to ppp_comp.c. diff -Nru ppp-2.4.7/modules/deflate.c ppp-2.4.9/modules/deflate.c --- ppp-2.4.7/modules/deflate.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/modules/deflate.c 2021-01-05 00:06:37.000000000 +0100 @@ -80,25 +80,25 @@ #define DEFLATE_OVHD 2 /* Deflate overhead/packet */ -static void *z_alloc __P((void *, u_int items, u_int size)); -static void *z_alloc_init __P((void *, u_int items, u_int size)); -static void z_free __P((void *, void *ptr)); -static void *z_comp_alloc __P((u_char *options, int opt_len)); -static void *z_decomp_alloc __P((u_char *options, int opt_len)); -static void z_comp_free __P((void *state)); -static void z_decomp_free __P((void *state)); -static int z_comp_init __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int debug)); -static int z_decomp_init __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int mru, int debug)); -static int z_compress __P((void *state, mblk_t **mret, - mblk_t *mp, int slen, int maxolen)); -static void z_incomp __P((void *state, mblk_t *dmsg)); -static int z_decompress __P((void *state, mblk_t *cmp, - mblk_t **dmpp)); -static void z_comp_reset __P((void *state)); -static void z_decomp_reset __P((void *state)); -static void z_comp_stats __P((void *state, struct compstat *stats)); +static void *z_alloc(void *, u_int items, u_int size); +static void *z_alloc_init(void *, u_int items, u_int size); +static void z_free(void *, void *ptr); +static void *z_comp_alloc(u_char *options, int opt_len); +static void *z_decomp_alloc(u_char *options, int opt_len); +static void z_comp_free(void *state); +static void z_decomp_free(void *state); +static int z_comp_init(void *state, u_char *options, int opt_len, + int unit, int hdrlen, int debug); +static int z_decomp_init(void *state, u_char *options, int opt_len, + int unit, int hdrlen, int mru, int debug); +static int z_compress(void *state, mblk_t **mret, + mblk_t *mp, int slen, int maxolen); +static void z_incomp(void *state, mblk_t *dmsg); +static int z_decompress(void *state, mblk_t *cmp, + mblk_t **dmpp); +static void z_comp_reset(void *state); +static void z_decomp_reset(void *state); +static void z_comp_stats(void *state, struct compstat *stats); /* * Procedures exported to ppp_comp.c. diff -Nru ppp-2.4.7/modules/if_ppp.c ppp-2.4.9/modules/if_ppp.c --- ppp-2.4.7/modules/if_ppp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/modules/if_ppp.c 2021-01-05 00:06:37.000000000 +0100 @@ -80,10 +80,10 @@ #define ifr_mtu ifr_metric -static int if_ppp_open __P((queue_t *, int, int, int)); -static int if_ppp_close __P((queue_t *, int)); -static int if_ppp_wput __P((queue_t *, mblk_t *)); -static int if_ppp_rput __P((queue_t *, mblk_t *)); +static int if_ppp_open(queue_t *, int, int, int); +static int if_ppp_close(queue_t *, int); +static int if_ppp_wput(queue_t *, mblk_t *); +static int if_ppp_rput(queue_t *, mblk_t *); #define PPP_IF_ID 0x8021 static struct module_info minfo = { @@ -117,11 +117,11 @@ static struct ifnet **ifs; /* Array of pointers to interface structs */ static if_ppp_t **states; /* Array of pointers to state structs */ -static int if_ppp_output __P((struct ifnet *, struct mbuf *, - struct sockaddr *)); -static int if_ppp_ioctl __P((struct ifnet *, u_int, caddr_t)); -static struct mbuf *make_mbufs __P((mblk_t *, int)); -static mblk_t *make_message __P((struct mbuf *, int)); +static int if_ppp_output(struct ifnet *, struct mbuf *, + struct sockaddr *); +static int if_ppp_ioctl(struct ifnet *, u_int, caddr_t); +static struct mbuf *make_mbufs(mblk_t *, int); +static mblk_t *make_message(struct mbuf *, int); #ifdef SNIT_SUPPORT /* Fake ether header for SNIT */ @@ -129,7 +129,7 @@ #endif #ifndef __osf__ -static void ppp_if_detach __P((struct ifnet *)); +static void ppp_if_detach(struct ifnet *); /* * Detach all the interfaces before unloading. diff -Nru ppp-2.4.7/modules/ppp_ahdlc.c ppp-2.4.9/modules/ppp_ahdlc.c --- ppp-2.4.7/modules/ppp_ahdlc.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/modules/ppp_ahdlc.c 2021-01-05 00:06:37.000000000 +0100 @@ -55,8 +55,6 @@ * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, * OR MODIFICATIONS. - * - * $Id: ppp_ahdlc.c,v 1.18 2002/12/06 09:49:15 paulus Exp $ */ /* @@ -107,11 +105,11 @@ MOD_OPEN_DECL(ahdlc_open); MOD_CLOSE_DECL(ahdlc_close); -static int ahdlc_wput __P((queue_t *, mblk_t *)); -static int ahdlc_rput __P((queue_t *, mblk_t *)); -static void ahdlc_encode __P((queue_t *, mblk_t *)); -static void ahdlc_decode __P((queue_t *, mblk_t *)); -static int msg_byte __P((mblk_t *, unsigned int)); +static int ahdlc_wput(queue_t *, mblk_t *); +static int ahdlc_rput(queue_t *, mblk_t *); +static void ahdlc_encode(queue_t *, mblk_t *); +static void ahdlc_decode(queue_t *, mblk_t *); +static int msg_byte(mblk_t *, unsigned int); #if defined(SOL2) /* diff -Nru ppp-2.4.7/modules/ppp.c ppp-2.4.9/modules/ppp.c --- ppp-2.4.7/modules/ppp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/modules/ppp.c 2021-01-05 00:06:37.000000000 +0100 @@ -31,8 +31,6 @@ * 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. - * - * $Id: ppp.c,v 1.26 2002/12/06 09:49:15 paulus Exp $ */ /* @@ -85,12 +83,6 @@ #include /* leave this outside of PRIOQ for htons */ -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif - /* * The IP module may use this SAP value for IP packets. */ @@ -254,43 +246,43 @@ static upperstr_t *ppas = NULL; #ifdef SVR4 -static int pppopen __P((queue_t *, dev_t *, int, int, cred_t *)); -static int pppclose __P((queue_t *, int, cred_t *)); +static int pppopen(queue_t *, dev_t *, int, int, cred_t *); +static int pppclose(queue_t *, int, cred_t *); #else -static int pppopen __P((queue_t *, int, int, int)); -static int pppclose __P((queue_t *, int)); +static int pppopen(queue_t *, int, int, int); +static int pppclose(queue_t *, int); #endif /* SVR4 */ -static int pppurput __P((queue_t *, mblk_t *)); -static int pppuwput __P((queue_t *, mblk_t *)); -static int pppursrv __P((queue_t *)); -static int pppuwsrv __P((queue_t *)); -static int ppplrput __P((queue_t *, mblk_t *)); -static int ppplwput __P((queue_t *, mblk_t *)); -static int ppplrsrv __P((queue_t *)); -static int ppplwsrv __P((queue_t *)); +static int pppurput(queue_t *, mblk_t *); +static int pppuwput(queue_t *, mblk_t *); +static int pppursrv(queue_t *); +static int pppuwsrv(queue_t *); +static int ppplrput(queue_t *, mblk_t *); +static int ppplwput(queue_t *, mblk_t *); +static int ppplrsrv(queue_t *); +static int ppplwsrv(queue_t *); #ifndef NO_DLPI -static void dlpi_request __P((queue_t *, mblk_t *, upperstr_t *)); -static void dlpi_error __P((queue_t *, upperstr_t *, int, int, int)); -static void dlpi_ok __P((queue_t *, int)); +static void dlpi_request(queue_t *, mblk_t *, upperstr_t *); +static void dlpi_error(queue_t *, upperstr_t *, int, int, int); +static void dlpi_ok(queue_t *, int); #endif -static int send_data __P((mblk_t *, upperstr_t *)); -static void new_ppa __P((queue_t *, mblk_t *)); -static void attach_ppa __P((queue_t *, mblk_t *)); -static void detach_ppa __P((queue_t *, mblk_t *)); -static void detach_lower __P((queue_t *, mblk_t *)); -static void debug_dump __P((queue_t *, mblk_t *)); -static upperstr_t *find_dest __P((upperstr_t *, int)); +static int send_data(mblk_t *, upperstr_t *); +static void new_ppa(queue_t *, mblk_t *); +static void attach_ppa(queue_t *, mblk_t *); +static void detach_ppa(queue_t *, mblk_t *); +static void detach_lower(queue_t *, mblk_t *); +static void debug_dump(queue_t *, mblk_t *); +static upperstr_t *find_dest(upperstr_t *, int); #if defined(SOL2) -static upperstr_t *find_promisc __P((upperstr_t *, int)); -static mblk_t *prepend_ether __P((upperstr_t *, mblk_t *, int)); -static mblk_t *prepend_udind __P((upperstr_t *, mblk_t *, int)); -static void promisc_sendup __P((upperstr_t *, mblk_t *, int, int)); +static upperstr_t *find_promisc(upperstr_t *, int); +static mblk_t *prepend_ether(upperstr_t *, mblk_t *, int); +static mblk_t *prepend_udind(upperstr_t *, mblk_t *, int); +static void promisc_sendup(upperstr_t *, mblk_t *, int, int); #endif /* defined(SOL2) */ -static int putctl2 __P((queue_t *, int, int, int)); -static int putctl4 __P((queue_t *, int, int, int)); -static int pass_packet __P((upperstr_t *ppa, mblk_t *mp, int outbound)); +static int putctl2(queue_t *, int, int, int); +static int putctl4(queue_t *, int, int, int); +static int pass_packet(upperstr_t *ppa, mblk_t *mp, int outbound); #ifdef FILTER_PACKETS -static int ip_hard_filter __P((upperstr_t *ppa, mblk_t *mp, int outbound)); +static int ip_hard_filter(upperstr_t *ppa, mblk_t *mp, int outbound); #endif /* FILTER_PACKETS */ #define PPP_ID 0xb1a6 diff -Nru ppp-2.4.7/modules/ppp_comp.c ppp-2.4.9/modules/ppp_comp.c --- ppp-2.4.7/modules/ppp_comp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/modules/ppp_comp.c 2021-01-05 00:06:37.000000000 +0100 @@ -31,8 +31,6 @@ * 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. - * - * $Id: ppp_comp.c,v 1.14 2002/12/06 09:49:15 paulus Exp $ */ /* @@ -74,12 +72,12 @@ MOD_OPEN_DECL(ppp_comp_open); MOD_CLOSE_DECL(ppp_comp_close); -static int ppp_comp_rput __P((queue_t *, mblk_t *)); -static int ppp_comp_rsrv __P((queue_t *)); -static int ppp_comp_wput __P((queue_t *, mblk_t *)); -static int ppp_comp_wsrv __P((queue_t *)); -static void ppp_comp_ccp __P((queue_t *, mblk_t *, int)); -static int msg_byte __P((mblk_t *, unsigned int)); +static int ppp_comp_rput(queue_t *, mblk_t *); +static int ppp_comp_rsrv(queue_t *); +static int ppp_comp_wput(queue_t *, mblk_t *); +static int ppp_comp_wsrv(queue_t *); +static void ppp_comp_ccp(queue_t *, mblk_t *, int); +static int msg_byte(mblk_t *, unsigned int); /* Extract byte i of message mp. */ #define MSG_BYTE(mp, i) ((i) < (mp)->b_wptr - (mp)->b_rptr? (mp)->b_rptr[i]: \ @@ -118,7 +116,7 @@ #ifdef __osf__ -static void ppp_comp_alloc __P((comp_state_t *)); +static void ppp_comp_alloc(comp_state_t *); typedef struct memreq { unsigned char comp_opts[20]; int cmd; diff -Nru ppp-2.4.7/modules/ppp_mod.h ppp-2.4.9/modules/ppp_mod.h --- ppp-2.4.7/modules/ppp_mod.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/modules/ppp_mod.h 2021-01-05 00:06:37.000000000 +0100 @@ -143,10 +143,10 @@ */ #ifdef SVR4 #define MOD_OPEN_DECL(name) \ -static int name __P((queue_t *, dev_t *, int, int, cred_t *)) +static int name(queue_t *, dev_t *, int, int, cred_t *) #define MOD_CLOSE_DECL(name) \ -static int name __P((queue_t *, int, cred_t *)) +static int name(queue_t *, int, cred_t *) #define MOD_OPEN(name) \ static int name(q, devp, flag, sflag, credp) \ @@ -168,10 +168,10 @@ #else /* not SVR4 */ #define MOD_OPEN_DECL(name) \ -static int name __P((queue_t *, int, int, int)) +static int name(queue_t *, int, int, int) #define MOD_CLOSE_DECL(name) \ -static int name __P((queue_t *, int)) +static int name(queue_t *, int) #define MOD_OPEN(name) \ static int name(q, dev, flag, sflag) \ diff -Nru ppp-2.4.7/pppd/auth.c ppp-2.4.9/pppd/auth.c --- ppp-2.4.7/pppd/auth.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/auth.c 2021-01-05 00:06:37.000000000 +0100 @@ -78,6 +78,7 @@ #include #include #include +#include #include #include #include @@ -100,6 +101,10 @@ #endif #include +#ifdef SYSTEMD +#include +#endif + #include "pppd.h" #include "fsm.h" #include "lcp.h" @@ -109,13 +114,15 @@ #include "upap.h" #include "chap-new.h" #include "eap.h" +#ifdef USE_EAPTLS +#include "eap-tls.h" +#endif #ifdef CBCP_SUPPORT #include "cbcp.h" #endif #include "pathnames.h" #include "session.h" -static const char rcsid[] = RCSID; /* Bits in scan_authfile return value */ #define NONWILD_SERVER 1 @@ -161,38 +168,43 @@ static bool default_auth; /* Hook to enable a plugin to control the idle time limit */ -int (*idle_time_hook) __P((struct ppp_idle *)) = NULL; +int (*idle_time_hook)(struct ppp_idle *) = NULL; /* Hook for a plugin to say whether we can possibly authenticate any peer */ -int (*pap_check_hook) __P((void)) = NULL; +int (*pap_check_hook)(void) = NULL; /* Hook for a plugin to check the PAP user and password */ -int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp, - struct wordlist **paddrs, - struct wordlist **popts)) = NULL; +int (*pap_auth_hook)(char *user, char *passwd, char **msgp, + struct wordlist **paddrs, + struct wordlist **popts) = NULL; /* Hook for a plugin to know about the PAP user logout */ -void (*pap_logout_hook) __P((void)) = NULL; +void (*pap_logout_hook)(void) = NULL; /* Hook for a plugin to get the PAP password for authenticating us */ -int (*pap_passwd_hook) __P((char *user, char *passwd)) = NULL; +int (*pap_passwd_hook)(char *user, char *passwd) = NULL; /* Hook for a plugin to say if we can possibly authenticate a peer using CHAP */ -int (*chap_check_hook) __P((void)) = NULL; +int (*chap_check_hook)(void) = NULL; /* Hook for a plugin to get the CHAP password for authenticating us */ -int (*chap_passwd_hook) __P((char *user, char *passwd)) = NULL; +int (*chap_passwd_hook)(char *user, char *passwd) = NULL; + +#ifdef USE_EAPTLS +/* Hook for a plugin to get the EAP-TLS password for authenticating us */ +int (*eaptls_passwd_hook)(char *user, char *passwd) = NULL; +#endif /* Hook for a plugin to say whether it is OK if the peer refuses to authenticate. */ -int (*null_auth_hook) __P((struct wordlist **paddrs, - struct wordlist **popts)) = NULL; +int (*null_auth_hook)(struct wordlist **paddrs, + struct wordlist **popts) = NULL; -int (*allowed_address_hook) __P((u_int32_t addr)) = NULL; +int (*allowed_address_hook)(u_int32_t addr) = NULL; #ifdef HAVE_MULTILINK /* Hook for plugin to hear when an interface joins a multilink bundle */ -void (*multilink_join_hook) __P((void)) = NULL; +void (*multilink_join_hook)(void) = NULL; #endif /* A notifier for when the peer has authenticated itself, @@ -238,40 +250,63 @@ 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 */ +#endif static char *uafname; /* name of most recent +ua file */ -extern char *crypt __P((const char *, const char *)); +extern char *crypt (const char *, const char *); /* Prototypes for procedures local to this file. */ -static void network_phase __P((int)); -static void check_idle __P((void *)); -static void connect_time_expired __P((void *)); -static int null_login __P((int)); -static int get_pap_passwd __P((char *)); -static int have_pap_secret __P((int *)); -static int have_chap_secret __P((char *, char *, int, int *)); -static int have_srp_secret __P((char *client, char *server, int need_ip, - int *lacks_ipp)); -static int ip_addr_check __P((u_int32_t, struct permitted_ip *)); -static int scan_authfile __P((FILE *, char *, char *, char *, - struct wordlist **, struct wordlist **, - char *, int)); -static void free_wordlist __P((struct wordlist *)); -static void auth_script __P((char *)); -static void auth_script_done __P((void *)); -static void set_allowed_addrs __P((int, struct wordlist *, struct wordlist *)); -static int some_ip_ok __P((struct wordlist *)); -static int setupapfile __P((char **)); -static int privgroup __P((char **)); -static int set_noauth_addr __P((char **)); -static int set_permitted_number __P((char **)); -static void check_access __P((FILE *, char *)); -static int wordlist_count __P((struct wordlist *)); +static void network_phase (int); +static void check_idle (void *); +static void connect_time_expired (void *); +static int null_login (int); +static int get_pap_passwd (char *); +static int have_pap_secret (int *); +static int have_chap_secret (char *, char *, int, int *); +static int have_srp_secret(char *client, char *server, int need_ip, + int *lacks_ipp); + +#ifdef USE_EAPTLS +static int have_eaptls_secret_server +(char *client, char *server, int need_ip, int *lacks_ipp); +static int have_eaptls_secret_client (char *client, char *server); +static int scan_authfile_eaptls(FILE * f, char *client, char *server, + char *cli_cert, char *serv_cert, + char *ca_cert, char *pk, + struct wordlist ** addrs, + struct wordlist ** opts, + char *filename, int flags); +#endif + +static int ip_addr_check (u_int32_t, struct permitted_ip *); +static int scan_authfile(FILE *, char *, char *, char *, + struct wordlist **, struct wordlist **, + char *, int); +static void free_wordlist (struct wordlist *); +static void auth_script (char *); +static void auth_script_done (void *); +static void set_allowed_addrs (int, struct wordlist *, struct wordlist *); +static int some_ip_ok (struct wordlist *); +static int setupapfile (char **); +static int privgroup (char **); +static int set_noauth_addr (char **); +static int set_permitted_number (char **); +static void check_access (FILE *, char *); +static int wordlist_count (struct wordlist *); #ifdef MAXOCTETS -static void check_maxoctets __P((void *)); +static void check_maxoctets (void *); #endif /* @@ -401,6 +436,18 @@ "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" }, + { "max-tls-version", o_string, &max_tls_version, + "Maximum TLS version (1.0/1.1/1.2 (default)/1.3)" }, + { "need-peer-eap", o_bool, &need_peer_eap, + "Require the peer to authenticate us", 1 }, +#endif /* USE_EAPTLS */ { NULL } }; @@ -408,8 +455,7 @@ * setupapfile - specifies UPAP info for authenticating with peer. */ static int -setupapfile(argv) - char **argv; +setupapfile(char **argv) { FILE *ufile; int l; @@ -426,6 +472,7 @@ euid = geteuid(); if (seteuid(getuid()) == -1) { option_error("unable to reset uid before opening %s: %m", fname); + free(fname); return 0; } ufile = fopen(fname, "r"); @@ -433,6 +480,7 @@ fatal("unable to regain privileges: %m"); if (ufile == NULL) { option_error("unable to open user login data file %s", fname); + free(fname); return 0; } check_access(ufile, fname); @@ -443,6 +491,7 @@ || fgets(p, MAXSECRETLEN - 1, ufile) == NULL) { fclose(ufile); option_error("unable to read user login data file %s", fname); + free(fname); return 0; } fclose(ufile); @@ -464,6 +513,7 @@ explicit_passwd = 1; } + free(fname); return (1); } @@ -472,8 +522,7 @@ * privgroup - allow members of the group to have privileged access. */ static int -privgroup(argv) - char **argv; +privgroup(char **argv) { struct group *g; int i; @@ -498,8 +547,7 @@ * Equivalent to specifying an entry like `"" * "" addr' in pap-secrets. */ static int -set_noauth_addr(argv) - char **argv; +set_noauth_addr(char **argv) { char *addr = *argv; int l = strlen(addr) + 1; @@ -520,8 +568,7 @@ * set_permitted_number - set remote telephone number(s) that may connect. */ static int -set_permitted_number(argv) - char **argv; +set_permitted_number(char **argv) { char *number = *argv; int l = strlen(number) + 1; @@ -542,16 +589,14 @@ * An Open on LCP has requested a change from Dead to Establish phase. */ void -link_required(unit) - int unit; +link_required(int unit) { } /* * Bring the link up to the point of being able to do ppp. */ -void start_link(unit) - int unit; +void start_link(int unit) { status = EXIT_CONNECT_FAILED; new_phase(PHASE_SERIALCONN); @@ -610,8 +655,7 @@ * physical layer down. */ void -link_terminated(unit) - int unit; +link_terminated(int unit) { if (phase == PHASE_DEAD || phase == PHASE_MASTER) return; @@ -680,8 +724,7 @@ * LCP has gone down; it will either die or try to re-establish. */ void -link_down(unit) - int unit; +link_down(int unit) { if (auth_state != s_down) { notify(link_down_notifier, 0); @@ -723,13 +766,15 @@ * Proceed to the Dead, Authenticate or Network phase as appropriate. */ void -link_established(unit) - int unit; +link_established(int unit) { int auth; lcp_options *wo = &lcp_wantoptions[unit]; lcp_options *go = &lcp_gotoptions[unit]; lcp_options *ho = &lcp_hisoptions[unit]; +#ifdef USE_EAPTLS + lcp_options *ao = &lcp_allowoptions[unit]; +#endif int i; struct protent *protp; @@ -764,6 +809,22 @@ } } +#ifdef USE_EAPTLS + if (need_peer_eap && !ao->neg_eap) { + warn("eap required to authenticate us but no suitable secrets"); + lcp_close(unit, "couldn't negotiate eap"); + status = EXIT_AUTH_TOPEER_FAILED; + return; + } + + if (need_peer_eap && !ho->neg_eap) { + warn("peer doesn't want to authenticate us with eap"); + lcp_close(unit, "couldn't negotiate eap"); + status = EXIT_PEER_AUTH_FAILED; + return; + } +#endif + new_phase(PHASE_AUTHENTICATE); auth = 0; if (go->neg_eap) { @@ -804,8 +865,7 @@ * Proceed to the network phase. */ static void -network_phase(unit) - int unit; +network_phase(int unit) { lcp_options *go = &lcp_gotoptions[unit]; @@ -816,8 +876,8 @@ /* * If the peer had to authenticate, run the auth-up script now. */ + notify(auth_up_notifier, 0); if (go->neg_chap || go->neg_upap || go->neg_eap) { - notify(auth_up_notifier, 0); auth_state = s_up; if (auth_script_state == s_down && auth_script_pid == 0) { auth_script_state = s_up; @@ -848,8 +908,7 @@ } void -start_networks(unit) - int unit; +start_networks(int unit) { int i; struct protent *protp; @@ -889,8 +948,7 @@ } void -continue_networks(unit) - int unit; +continue_networks(int unit) { int i; struct protent *protp; @@ -915,8 +973,7 @@ * The peer has failed to authenticate himself using `protocol'. */ void -auth_peer_fail(unit, protocol) - int unit, protocol; +auth_peer_fail(int unit, int protocol) { /* * Authentication failure: take the link down @@ -929,10 +986,8 @@ * The peer has been successfully authenticated using `protocol'. */ void -auth_peer_success(unit, protocol, prot_flavor, name, namelen) - int unit, protocol, prot_flavor; - char *name; - int namelen; +auth_peer_success(int unit, int protocol, int prot_flavor, + char *name, int namelen) { int bit; @@ -988,8 +1043,7 @@ * We have failed to authenticate ourselves to the peer using `protocol'. */ void -auth_withpeer_fail(unit, protocol) - int unit, protocol; +auth_withpeer_fail(int unit, int protocol) { if (passwd_from_file) BZERO(passwd, MAXSECRETLEN); @@ -1007,8 +1061,7 @@ * We have successfully authenticated ourselves with the peer using `protocol'. */ void -auth_withpeer_success(unit, protocol, prot_flavor) - int unit, protocol, prot_flavor; +auth_withpeer_success(int unit, int protocol, int prot_flavor) { int bit; const char *prot = ""; @@ -1064,8 +1117,7 @@ * np_up - a network protocol has come up. */ void -np_up(unit, proto) - int unit, proto; +np_up(int unit, int proto) { int tlim; @@ -1099,8 +1151,15 @@ /* * Detach now, if the updetach option was given. */ - if (updetach && !nodetach) + if (updetach && !nodetach) { + dbglog("updetach is set. Now detaching."); detach(); +#ifdef SYSTEMD + } else if (nodetach && up_sdnotify) { + dbglog("up_sdnotify is set. Now notifying systemd: READY=1"); + sd_notify(0, "READY=1"); +#endif + } } ++num_np_up; } @@ -1109,8 +1168,7 @@ * np_down - a network protocol has gone down. */ void -np_down(unit, proto) - int unit, proto; +np_down(int unit, int proto) { if (--num_np_up == 0) { UNTIMEOUT(check_idle, NULL); @@ -1126,8 +1184,7 @@ * np_finished - a network protocol has finished using the link. */ void -np_finished(unit, proto) - int unit, proto; +np_finished(int unit, int proto) { if (--num_np_open <= 0) { /* no further use for the link: shut up shop. */ @@ -1137,8 +1194,7 @@ #ifdef MAXOCTETS static void -check_maxoctets(arg) - void *arg; +check_maxoctets(void *arg) { unsigned int used; @@ -1176,8 +1232,7 @@ * enough that we can shut it down. */ static void -check_idle(arg) - void *arg; +check_idle(void *arg) { struct ppp_idle idle; time_t itime; @@ -1206,8 +1261,7 @@ * connect_time_expired - log a message and close the connection. */ static void -connect_time_expired(arg) - void *arg; +connect_time_expired(void *arg) { info("Connect time expired"); status = EXIT_CONNECT_TIME; @@ -1218,7 +1272,7 @@ * auth_check_options - called to check authentication options. */ void -auth_check_options() +auth_check_options(void) { lcp_options *wo = &lcp_wantoptions[0]; int can_auth; @@ -1277,6 +1331,15 @@ our_name, 1, &lacks_ip); } +#ifdef USE_EAPTLS + if (!can_auth && wo->neg_eap) { + can_auth = + have_eaptls_secret_server((explicit_remote ? remote_name : + NULL), our_name, 1, &lacks_ip); + + } +#endif + if (auth_required && !can_auth && noauth_addrs == NULL) { if (default_auth) { option_error( @@ -1314,8 +1377,7 @@ * to use for authenticating ourselves and/or the peer. */ void -auth_reset(unit) - int unit; +auth_reset(int unit) { lcp_options *go = &lcp_gotoptions[unit]; lcp_options *ao = &lcp_allowoptions[unit]; @@ -1324,14 +1386,18 @@ hadchap = -1; ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); ao->neg_chap = (!refuse_chap || !refuse_mschap || !refuse_mschap_v2) - && (passwd[0] != 0 || + && ((passwd[0] != 0 || explicit_passwd) || (hadchap = have_chap_secret(user, (explicit_remote? remote_name: NULL), 0, NULL))); ao->neg_eap = !refuse_eap && ( passwd[0] != 0 || (hadchap == 1 || (hadchap == -1 && have_chap_secret(user, (explicit_remote? remote_name: NULL), 0, NULL))) || - have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)); + have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL) +#ifdef USE_EAPTLS + || have_eaptls_secret_client(user, (explicit_remote? remote_name: NULL)) +#endif + ); hadchap = -1; if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) @@ -1346,7 +1412,12 @@ !have_chap_secret((explicit_remote? remote_name: NULL), our_name, 1, NULL))) && !have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1, - NULL)) + NULL) +#ifdef USE_EAPTLS + && !have_eaptls_secret_server((explicit_remote? remote_name: NULL), + our_name, 1, NULL) +#endif + ) go->neg_eap = 0; } @@ -1362,13 +1433,9 @@ * In either case, msg points to an appropriate message. */ int -check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) - int unit; - char *auser; - int userlen; - char *apasswd; - int passwdlen; - char **msg; +check_passwd(int unit, + char *auser, int userlen, + char *apasswd, int passwdlen, char **msg) { int ret; char *filename; @@ -1490,8 +1557,7 @@ * and return 1. */ static int -null_login(unit) - int unit; +null_login(int unit) { char *filename; FILE *f; @@ -1541,8 +1607,7 @@ * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null). */ static int -get_pap_passwd(passwd) - char *passwd; +get_pap_passwd(char *passwd) { char *filename; FILE *f; @@ -1581,8 +1646,7 @@ * secrets that we could possibly use for authenticating the peer. */ static int -have_pap_secret(lacks_ipp) - int *lacks_ipp; +have_pap_secret(int *lacks_ipp) { FILE *f; int ret; @@ -1623,11 +1687,8 @@ * know the identity yet. */ static int -have_chap_secret(client, server, need_ip, lacks_ipp) - char *client; - char *server; - int need_ip; - int *lacks_ipp; +have_chap_secret(char *client, char *server, + int need_ip, int *lacks_ipp) { FILE *f; int ret; @@ -1672,11 +1733,7 @@ * know the identity yet. */ static int -have_srp_secret(client, server, need_ip, lacks_ipp) - char *client; - char *server; - int need_ip; - int *lacks_ipp; +have_srp_secret(char *client, char *server, int need_ip, int *lacks_ipp) { FILE *f; int ret; @@ -1713,13 +1770,8 @@ * (We could be either client or server). */ int -get_secret(unit, client, server, secret, secret_len, am_server) - int unit; - char *client; - char *server; - char *secret; - int *secret_len; - int am_server; +get_secret(int unit, char *client, char *server, + char *secret, int *secret_len, int am_server) { FILE *f; int ret, len; @@ -1779,12 +1831,8 @@ * (We could be either client or server). */ int -get_srp_secret(unit, client, server, secret, am_server) - int unit; - char *client; - char *server; - char *secret; - int am_server; +get_srp_secret(int unit, char *client, char *server, + char *secret, int am_server) { FILE *fp; int ret; @@ -1828,10 +1876,8 @@ * and leaves the following words in extra_options. */ static void -set_allowed_addrs(unit, addrs, opts) - int unit; - struct wordlist *addrs; - struct wordlist *opts; +set_allowed_addrs(int unit, struct wordlist *addrs, + struct wordlist *opts) { int n; struct wordlist *ap, **plink; @@ -1984,9 +2030,7 @@ * a given IP address. Returns 1 if authorized, 0 otherwise. */ int -auth_ip_addr(unit, addr) - int unit; - u_int32_t addr; +auth_ip_addr(int unit, u_int32_t addr) { int ok; @@ -2011,9 +2055,7 @@ } static int -ip_addr_check(addr, addrs) - u_int32_t addr; - struct permitted_ip *addrs; +ip_addr_check(u_int32_t addr, struct permitted_ip *addrs) { for (; ; ++addrs) if ((addr & addrs->mask) == addrs->base) @@ -2026,8 +2068,7 @@ * addr is in network byte order. */ int -bad_ip_adrs(addr) - u_int32_t addr; +bad_ip_adrs(u_int32_t addr) { addr = ntohl(addr); return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET @@ -2039,8 +2080,7 @@ * IP address(es). */ static int -some_ip_ok(addrs) - struct wordlist *addrs; +some_ip_ok(struct wordlist *addrs) { for (; addrs != 0; addrs = addrs->next) { if (addrs->word[0] == '-') @@ -2056,7 +2096,7 @@ * Returns 1 if authorized, 0 otherwise. */ int -auth_number() +auth_number(void) { struct wordlist *wp = permitted_numbers; int l; @@ -2083,9 +2123,7 @@ * check_access - complain if a secret file has too-liberal permissions. */ static void -check_access(f, filename) - FILE *f; - char *filename; +check_access(FILE *f, char *filename) { struct stat sbuf; @@ -2113,15 +2151,10 @@ * match. */ static int -scan_authfile(f, client, server, secret, addrs, opts, filename, flags) - FILE *f; - char *client; - char *server; - char *secret; - struct wordlist **addrs; - struct wordlist **opts; - char *filename; - int flags; +scan_authfile(FILE *f, char *client, char *server, + char *secret, struct wordlist **addrs, + struct wordlist **opts, char *filename, + int flags) { int newline, xxx; int got_flag, best_flag; @@ -2276,8 +2309,7 @@ * wordlist_count - return the number of items in a wordlist */ static int -wordlist_count(wp) - struct wordlist *wp; +wordlist_count(struct wordlist *wp) { int n; @@ -2290,8 +2322,7 @@ * free_wordlist - release memory allocated for a wordlist. */ static void -free_wordlist(wp) - struct wordlist *wp; +free_wordlist(struct wordlist *wp) { struct wordlist *next; @@ -2307,8 +2338,7 @@ * has finished. */ static void -auth_script_done(arg) - void *arg; +auth_script_done(void *arg) { auth_script_pid = 0; switch (auth_script_state) { @@ -2332,8 +2362,7 @@ * interface-name peer-name real-user tty speed */ static void -auth_script(script) - char *script; +auth_script(char *script) { char strspeed[32]; struct passwd *pw; @@ -2359,3 +2388,323 @@ auth_script_pid = run_program(script, argv, 0, auth_script_done, NULL, 0); } + + +#ifdef USE_EAPTLS +static int +have_eaptls_secret_server(char *client, char *server, + int need_ip, int *lacks_ipp) +{ + FILE *f; + int ret; + char *filename; + struct wordlist *addrs; + char servcertfile[MAXWORDLEN]; + char clicertfile[MAXWORDLEN]; + char cacertfile[MAXWORDLEN]; + char pkfile[MAXWORDLEN]; + + filename = _PATH_EAPTLSSERVFILE; + f = fopen(filename, "r"); + if (f == NULL) + return 0; + + if (client != NULL && client[0] == 0) + client = NULL; + else if (server != NULL && server[0] == 0) + server = NULL; + + ret = + scan_authfile_eaptls(f, client, server, clicertfile, servcertfile, + cacertfile, pkfile, &addrs, NULL, filename, + 0); + + fclose(f); + +/* + if (ret >= 0 && !eaptls_init_ssl(1, cacertfile, servcertfile, + clicertfile, pkfile)) + ret = -1; +*/ + + if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { + if (lacks_ipp != 0) + *lacks_ipp = 1; + ret = -1; + } + if (addrs != 0) + free_wordlist(addrs); + + return ret >= 0; +} + + +static int +have_eaptls_secret_client(char *client, char *server) +{ + FILE *f; + int ret; + char *filename; + struct wordlist *addrs = NULL; + char servcertfile[MAXWORDLEN]; + char clicertfile[MAXWORDLEN]; + char cacertfile[MAXWORDLEN]; + char pkfile[MAXWORDLEN]; + + if (client != NULL && client[0] == 0) + client = NULL; + else if (server != NULL && server[0] == 0) + server = NULL; + + if ((cacert_file || ca_path) && cert_file && privkey_file) + return 1; + + filename = _PATH_EAPTLSCLIFILE; + f = fopen(filename, "r"); + if (f == NULL) + return 0; + + ret = + scan_authfile_eaptls(f, client, server, clicertfile, servcertfile, + cacertfile, pkfile, &addrs, NULL, filename, + 0); + fclose(f); + +/* + if (ret >= 0 && !eaptls_init_ssl(0, cacertfile, clicertfile, + servcertfile, pkfile)) + ret = -1; +*/ + + if (addrs != 0) + free_wordlist(addrs); + + return ret >= 0; +} + + +static int +scan_authfile_eaptls(FILE *f, char *client, char *server, + char *cli_cert, char *serv_cert, char *ca_cert, + char *pk, struct wordlist **addrs, + struct wordlist **opts, + char *filename, int flags) +{ + int newline; + int got_flag, best_flag; + struct wordlist *ap, *addr_list, *alist, **app; + char word[MAXWORDLEN]; + + if (addrs != NULL) + *addrs = NULL; + if (opts != NULL) + *opts = NULL; + addr_list = NULL; + if (!getword(f, word, &newline, filename)) + return -1; /* file is empty??? */ + newline = 1; + best_flag = -1; + for (;;) { + /* + * Skip until we find a word at the start of a line. + */ + while (!newline && getword(f, word, &newline, filename)); + if (!newline) + break; /* got to end of file */ + + /* + * Got a client - check if it's a match or a wildcard. + */ + got_flag = 0; + if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) { + newline = 0; + continue; + } + if (!ISWILD(word)) + got_flag = NONWILD_CLIENT; + + /* + * Now get a server and check if it matches. + */ + if (!getword(f, word, &newline, filename)) + break; + if (newline) + continue; + if (!ISWILD(word)) { + if (server != NULL && strcmp(word, server) != 0) + continue; + got_flag |= NONWILD_SERVER; + } + + /* + * Got some sort of a match - see if it's better than what + * we have already. + */ + if (got_flag <= best_flag) + continue; + + /* + * Get the cli_cert + */ + if (!getword(f, word, &newline, filename)) + break; + if (newline) + continue; + if (strcmp(word, "-") != 0) { + strlcpy(cli_cert, word, MAXWORDLEN); + } else + cli_cert[0] = 0; + + /* + * Get serv_cert + */ + if (!getword(f, word, &newline, filename)) + break; + if (newline) + continue; + if (strcmp(word, "-") != 0) { + strlcpy(serv_cert, word, MAXWORDLEN); + } else + serv_cert[0] = 0; + + /* + * Get ca_cert + */ + if (!getword(f, word, &newline, filename)) + break; + if (newline) + continue; + strlcpy(ca_cert, word, MAXWORDLEN); + + /* + * Get pk + */ + if (!getword(f, word, &newline, filename)) + break; + if (newline) + continue; + strlcpy(pk, word, MAXWORDLEN); + + + /* + * Now read address authorization info and make a wordlist. + */ + app = &alist; + for (;;) { + if (!getword(f, word, &newline, filename) || newline) + break; + ap = (struct wordlist *) + malloc(sizeof(struct wordlist) + strlen(word) + 1); + if (ap == NULL) + novm("authorized addresses"); + ap->word = (char *) (ap + 1); + strcpy(ap->word, word); + *app = ap; + app = &ap->next; + } + *app = NULL; + /* + * This is the best so far; remember it. + */ + best_flag = got_flag; + if (addr_list) + free_wordlist(addr_list); + addr_list = alist; + + if (!newline) + break; + } + + /* scan for a -- word indicating the start of options */ + for (app = &addr_list; (ap = *app) != NULL; app = &ap->next) + if (strcmp(ap->word, "--") == 0) + break; + /* ap = start of options */ + if (ap != NULL) { + ap = ap->next; /* first option */ + free(*app); /* free the "--" word */ + *app = NULL; /* terminate addr list */ + } + if (opts != NULL) + *opts = ap; + else if (ap != NULL) + free_wordlist(ap); + if (addrs != NULL) + *addrs = addr_list; + else if (addr_list != NULL) + free_wordlist(addr_list); + + return best_flag; +} + + +int +get_eaptls_secret(int unit, char *client, char *server, + char *clicertfile, char *servcertfile, char *cacertfile, + char *capath, char *pkfile, int am_server) +{ + FILE *fp; + int ret; + char *filename = NULL; + struct wordlist *addrs = NULL; + struct wordlist *opts = NULL; + + /* maybe overkill, but it eases debugging */ + bzero(clicertfile, MAXWORDLEN); + bzero(servcertfile, MAXWORDLEN); + bzero(cacertfile, MAXWORDLEN); + bzero(capath, MAXWORDLEN); + bzero(pkfile, MAXWORDLEN); + + /* the ca+cert+privkey can also be specified as options */ + if (!am_server && (cacert_file || ca_path) && cert_file && privkey_file ) + { + strlcpy( clicertfile, cert_file, MAXWORDLEN ); + if (cacert_file) + strlcpy( cacertfile, cacert_file, MAXWORDLEN ); + if (ca_path) + strlcpy( capath, ca_path, MAXWORDLEN ); + strlcpy( pkfile, privkey_file, MAXWORDLEN ); + } + else + { + filename = (am_server ? _PATH_EAPTLSSERVFILE : _PATH_EAPTLSCLIFILE); + addrs = NULL; + + fp = fopen(filename, "r"); + if (fp == NULL) + { + error("Can't open eap-tls secret file %s: %m", filename); + return 0; + } + + check_access(fp, filename); + + ret = scan_authfile_eaptls(fp, client, server, clicertfile, servcertfile, + cacertfile, pkfile, &addrs, &opts, filename, 0); + + fclose(fp); + + if (ret < 0) return 0; + } + + if (eaptls_passwd_hook) + { + dbglog( "Calling eaptls password hook" ); + if ( (*eaptls_passwd_hook)(pkfile, passwd) < 0) + { + error("Unable to obtain EAP-TLS password for %s (%s) from plugin", + client, pkfile); + return 0; + } + } + if (am_server) + set_allowed_addrs(unit, addrs, opts); + else if (opts != NULL) + free_wordlist(opts); + if (addrs != NULL) + free_wordlist(addrs); + + return 1; +} +#endif diff -Nru ppp-2.4.7/pppd/cbcp.c ppp-2.4.9/pppd/cbcp.c --- ppp-2.4.7/pppd/cbcp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/cbcp.c 2021-01-05 00:06:37.000000000 +0100 @@ -33,8 +33,6 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: cbcp.c,v 1.17 2006/05/22 00:04:07 paulus Exp $" - #include #include #include @@ -45,12 +43,11 @@ #include "fsm.h" #include "lcp.h" -static const char rcsid[] = RCSID; /* * Options. */ -static int setcbcp __P((char **)); +static int setcbcp (char **); static option_t cbcp_option_list[] = { { "callback", o_special, (void *)setcbcp, @@ -61,14 +58,14 @@ /* * Protocol entry points. */ -static void cbcp_init __P((int unit)); -static void cbcp_open __P((int unit)); -static void cbcp_lowerup __P((int unit)); -static void cbcp_input __P((int unit, u_char *pkt, int len)); -static void cbcp_protrej __P((int unit)); -static int cbcp_printpkt __P((u_char *pkt, int len, - void (*printer) __P((void *, char *, ...)), - void *arg)); +static void cbcp_init (int unit); +static void cbcp_open (int unit); +static void cbcp_lowerup (int unit); +static void cbcp_input (int unit, u_char *pkt, int len); +static void cbcp_protrej (int unit); +static int cbcp_printpkt (u_char *pkt, int len, + void (*printer)(void *, char *, ...), + void *arg); struct protent cbcp_protent = { PPP_CBCP, @@ -94,16 +91,15 @@ /* internal prototypes */ -static void cbcp_recvreq __P((cbcp_state *us, u_char *pckt, int len)); -static void cbcp_resp __P((cbcp_state *us)); -static void cbcp_up __P((cbcp_state *us)); -static void cbcp_recvack __P((cbcp_state *us, u_char *pckt, int len)); -static void cbcp_send __P((cbcp_state *us, int code, u_char *buf, int len)); +static void cbcp_recvreq (cbcp_state *us, u_char *pckt, int len); +static void cbcp_resp (cbcp_state *us); +static void cbcp_up (cbcp_state *us); +static void cbcp_recvack (cbcp_state *us, u_char *pckt, int len); +static void cbcp_send (cbcp_state *us, int code, u_char *buf, int len); /* option processing */ static int -setcbcp(argv) - char **argv; +setcbcp(char **argv) { lcp_wantoptions[0].neg_cbcp = 1; cbcp_protent.enabled_flag = 1; @@ -117,8 +113,7 @@ /* init state */ static void -cbcp_init(iface) - int iface; +cbcp_init(int iface) { cbcp_state *us; @@ -130,8 +125,7 @@ /* lower layer is up */ static void -cbcp_lowerup(iface) - int iface; +cbcp_lowerup(int iface) { cbcp_state *us = &cbcp[iface]; @@ -143,18 +137,14 @@ } static void -cbcp_open(unit) - int unit; +cbcp_open(int unit) { dbglog("cbcp_open"); } /* process an incomming packet */ static void -cbcp_input(unit, inpacket, pktlen) - int unit; - u_char *inpacket; - int pktlen; +cbcp_input(int unit, u_char *inpacket, int pktlen) { u_char *inp; u_char code, id; @@ -224,11 +214,8 @@ /* pretty print a packet */ static int -cbcp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; +cbcp_printpkt(u_char *p, int plen, + void (*printer) (void *, char *, ...), void *arg) { int code, opt, id, len, olen, delay; u_char *pstart; @@ -302,10 +289,7 @@ /* received CBCP request */ static void -cbcp_recvreq(us, pckt, pcktlen) - cbcp_state *us; - u_char *pckt; - int pcktlen; +cbcp_recvreq(cbcp_state *us, u_char *pckt, int pcktlen) { u_char type, opt_len, delay, addr_type; char address[256]; @@ -361,8 +345,7 @@ } static void -cbcp_resp(us) - cbcp_state *us; +cbcp_resp(cbcp_state *us) { u_char cb_type; u_char buf[256]; @@ -417,11 +400,7 @@ } static void -cbcp_send(us, code, buf, len) - cbcp_state *us; - int code; - u_char *buf; - int len; +cbcp_send(cbcp_state *us, int code, u_char *buf, int len) { u_char *outp; int outlen; @@ -443,10 +422,7 @@ } static void -cbcp_recvack(us, pckt, len) - cbcp_state *us; - u_char *pckt; - int len; +cbcp_recvack(cbcp_state *us, u_char *pckt, int len) { u_char type, delay, addr_type; int opt_len; @@ -479,8 +455,7 @@ /* ok peer will do callback */ static void -cbcp_up(us) - cbcp_state *us; +cbcp_up(cbcp_state *us) { persist = 0; status = EXIT_CALLBACK; diff -Nru ppp-2.4.7/pppd/ccp.c ppp-2.4.9/pppd/ccp.c --- ppp-2.4.7/pppd/ccp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/ccp.c 2021-01-05 00:06:37.000000000 +0100 @@ -43,7 +43,6 @@ #include "lcp.h" /* lcp_close(), lcp_fsm */ #endif -static const char rcsid[] = RCSID; /* * Unfortunately there is a bug in zlib which means that using a @@ -57,8 +56,8 @@ /* * Command-line options. */ -static int setbsdcomp __P((char **)); -static int setdeflate __P((char **)); +static int setbsdcomp (char **); +static int setdeflate (char **); static char bsd_value[8]; static char deflate_value[8]; @@ -164,17 +163,17 @@ /* * Protocol entry points from main code. */ -static void ccp_init __P((int unit)); -static void ccp_open __P((int unit)); -static void ccp_close __P((int unit, char *)); -static void ccp_lowerup __P((int unit)); -static void ccp_lowerdown __P((int)); -static void ccp_input __P((int unit, u_char *pkt, int len)); -static void ccp_protrej __P((int unit)); -static int ccp_printpkt __P((u_char *pkt, int len, - void (*printer) __P((void *, char *, ...)), - void *arg)); -static void ccp_datainput __P((int unit, u_char *pkt, int len)); +static void ccp_init (int unit); +static void ccp_open (int unit); +static void ccp_close (int unit, char *); +static void ccp_lowerup (int unit); +static void ccp_lowerdown (int); +static void ccp_input (int unit, u_char *pkt, int len); +static void ccp_protrej (int unit); +static int ccp_printpkt (u_char *pkt, int len, + void (*printer)(void *, char *, ...), + void *arg); +static void ccp_datainput (int unit, u_char *pkt, int len); struct protent ccp_protent = { PPP_CCP, @@ -205,18 +204,18 @@ /* * Callbacks for fsm code. */ -static void ccp_resetci __P((fsm *)); -static int ccp_cilen __P((fsm *)); -static void ccp_addci __P((fsm *, u_char *, int *)); -static int ccp_ackci __P((fsm *, u_char *, int)); -static int ccp_nakci __P((fsm *, u_char *, int, int)); -static int ccp_rejci __P((fsm *, u_char *, int)); -static int ccp_reqci __P((fsm *, u_char *, int *, int)); -static void ccp_up __P((fsm *)); -static void ccp_down __P((fsm *)); -static int ccp_extcode __P((fsm *, int, int, u_char *, int)); -static void ccp_rack_timeout __P((void *)); -static char *method_name __P((ccp_options *, ccp_options *)); +static void ccp_resetci (fsm *); +static int ccp_cilen (fsm *); +static void ccp_addci (fsm *, u_char *, int *); +static int ccp_ackci (fsm *, u_char *, int); +static int ccp_nakci (fsm *, u_char *, int, int); +static int ccp_rejci (fsm *, u_char *, int); +static int ccp_reqci (fsm *, u_char *, int *, int); +static void ccp_up (fsm *); +static void ccp_down (fsm *); +static int ccp_extcode (fsm *, int, int, u_char *, int); +static void ccp_rack_timeout (void *); +static char *method_name (ccp_options *, ccp_options *); static fsm_callbacks ccp_callbacks = { ccp_resetci, @@ -258,8 +257,7 @@ * Option parsing. */ static int -setbsdcomp(argv) - char **argv; +setbsdcomp(char **argv) { int rbits, abits; char *str, *endp; @@ -297,8 +295,7 @@ } static int -setdeflate(argv) - char **argv; +setdeflate(char **argv) { int rbits, abits; char *str, *endp; @@ -348,8 +345,7 @@ * ccp_init - initialize CCP. */ static void -ccp_init(unit) - int unit; +ccp_init(int unit) { fsm *f = &ccp_fsm[unit]; @@ -384,8 +380,7 @@ * ccp_open - CCP is allowed to come up. */ static void -ccp_open(unit) - int unit; +ccp_open(int unit) { fsm *f = &ccp_fsm[unit]; @@ -407,9 +402,7 @@ * ccp_close - Terminate CCP. */ static void -ccp_close(unit, reason) - int unit; - char *reason; +ccp_close(int unit, char *reason) { ccp_flags_set(unit, 0, 0); fsm_close(&ccp_fsm[unit], reason); @@ -419,8 +412,7 @@ * ccp_lowerup - we may now transmit CCP packets. */ static void -ccp_lowerup(unit) - int unit; +ccp_lowerup(int unit) { fsm_lowerup(&ccp_fsm[unit]); } @@ -429,8 +421,7 @@ * ccp_lowerdown - we may not transmit CCP packets. */ static void -ccp_lowerdown(unit) - int unit; +ccp_lowerdown(int unit) { fsm_lowerdown(&ccp_fsm[unit]); } @@ -439,10 +430,7 @@ * ccp_input - process a received CCP packet. */ static void -ccp_input(unit, p, len) - int unit; - u_char *p; - int len; +ccp_input(int unit, u_char *p, int len) { fsm *f = &ccp_fsm[unit]; int oldstate; @@ -475,11 +463,7 @@ * Handle a CCP-specific code. */ static int -ccp_extcode(f, code, id, p, len) - fsm *f; - int code, id; - u_char *p; - int len; +ccp_extcode(fsm *f, int code, int id, u_char *p, int len) { switch (code) { case CCP_RESETREQ: @@ -508,8 +492,7 @@ * ccp_protrej - peer doesn't talk CCP. */ static void -ccp_protrej(unit) - int unit; +ccp_protrej(int unit) { ccp_flags_set(unit, 0, 0); fsm_lowerdown(&ccp_fsm[unit]); @@ -527,8 +510,7 @@ * ccp_resetci - initialize at start of negotiation. */ static void -ccp_resetci(f) - fsm *f; +ccp_resetci(fsm *f) { ccp_options *go = &ccp_gotoptions[f->unit]; u_char opt_buf[CCP_MAX_OPTION_LENGTH]; @@ -540,6 +522,9 @@ if (go->mppe) { ccp_options *ao = &ccp_allowoptions[f->unit]; int auth_mschap_bits = auth_done[f->unit]; +#ifdef USE_EAPTLS + int auth_eap_bits = auth_done[f->unit]; +#endif int numbits; /* @@ -567,8 +552,23 @@ lcp_close(f->unit, "MPPE required but not available"); return; } + +#ifdef USE_EAPTLS + /* + * MPPE is also possible in combination with EAP-TLS. + * It is not possible to detect if we're doing EAP or EAP-TLS + * at this stage, hence we accept all forms of EAP. If TLS is + * not used then the MPPE keys will not be derived anyway. + */ + /* Leave only the eap auth bits set */ + auth_eap_bits &= (EAP_WITHPEER | EAP_PEER ); + + if ((numbits == 0) && (auth_eap_bits == 0)) { + error("MPPE required, but MS-CHAP[v2] nor EAP-TLS auth are performed."); +#else if (!numbits) { error("MPPE required, but MS-CHAP[v2] auth not performed."); +#endif lcp_close(f->unit, "MPPE required but not available"); return; } @@ -670,13 +670,13 @@ * ccp_cilen - Return total length of our configuration info. */ static int -ccp_cilen(f) - fsm *f; + ccp_cilen(fsm *f) { ccp_options *go = &ccp_gotoptions[f->unit]; return (go->bsd_compress? CILEN_BSD_COMPRESS: 0) - + (go->deflate? CILEN_DEFLATE: 0) + + (go->deflate && go->deflate_correct? CILEN_DEFLATE: 0) + + (go->deflate && go->deflate_draft? CILEN_DEFLATE: 0) + (go->predictor_1? CILEN_PREDICTOR_1: 0) + (go->predictor_2? CILEN_PREDICTOR_2: 0) + (go->mppe? CILEN_MPPE: 0); @@ -686,10 +686,7 @@ * ccp_addci - put our requests in a packet. */ static void -ccp_addci(f, p, lenp) - fsm *f; - u_char *p; - int *lenp; + ccp_addci(fsm *f, u_char *p, int *lenp) { int res; ccp_options *go = &ccp_gotoptions[f->unit]; @@ -805,10 +802,7 @@ * 1 iff the packet was OK. */ static int -ccp_ackci(f, p, len) - fsm *f; - u_char *p; - int len; + ccp_ackci(fsm *f, u_char *p, int len) { ccp_options *go = &ccp_gotoptions[f->unit]; u_char *p0 = p; @@ -894,11 +888,7 @@ * Returns 1 iff the nak was OK. */ static int -ccp_nakci(f, p, len, treat_as_reject) - fsm *f; - u_char *p; - int len; - int treat_as_reject; + ccp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { ccp_options *go = &ccp_gotoptions[f->unit]; ccp_options no; /* options we've seen already */ @@ -984,10 +974,7 @@ * ccp_rejci - reject some of our suggested compression methods. */ static int -ccp_rejci(f, p, len) - fsm *f; - u_char *p; - int len; +ccp_rejci(fsm *f, u_char *p, int len) { ccp_options *go = &ccp_gotoptions[f->unit]; ccp_options try; /* options to request next time */ @@ -1066,11 +1053,7 @@ * appropriately. */ static int -ccp_reqci(f, p, lenp, dont_nak) - fsm *f; - u_char *p; - int *lenp; - int dont_nak; +ccp_reqci(fsm *f, u_char *p, int *lenp, int dont_nak) { int ret, newret, res; u_char *p0, *retp; @@ -1357,8 +1340,7 @@ * Make a string name for a compression method (or 2). */ static char * -method_name(opt, opt2) - ccp_options *opt, *opt2; +method_name(ccp_options *opt, ccp_options *opt2) { static char result[64]; @@ -1422,8 +1404,7 @@ * CCP has come up - inform the kernel driver and log a message. */ static void -ccp_up(f) - fsm *f; +ccp_up(fsm *f) { ccp_options *go = &ccp_gotoptions[f->unit]; ccp_options *ho = &ccp_hisoptions[f->unit]; @@ -1456,8 +1437,7 @@ * CCP has gone down - inform the kernel driver. */ static void -ccp_down(f) - fsm *f; +ccp_down(fsm *f) { if (ccp_localstate[f->unit] & RACK_PENDING) UNTIMEOUT(ccp_rack_timeout, f); @@ -1486,11 +1466,8 @@ }; static int -ccp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; +ccp_printpkt(u_char *p, int plen, + void (*printer) (void *, char *, ...), void *arg) { u_char *p0, *optend; int code, id, len; @@ -1619,10 +1596,7 @@ * compression :-(, otherwise we issue the reset-request. */ static void -ccp_datainput(unit, pkt, len) - int unit; - u_char *pkt; - int len; +ccp_datainput(int unit, u_char *pkt, int len) { fsm *f; @@ -1663,8 +1637,7 @@ * Timeout waiting for reset-ack. */ static void -ccp_rack_timeout(arg) - void *arg; +ccp_rack_timeout(void *arg) { fsm *f = arg; diff -Nru ppp-2.4.7/pppd/ccp.h ppp-2.4.9/pppd/ccp.h --- ppp-2.4.7/pppd/ccp.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/ccp.h 2021-01-05 00:06:37.000000000 +0100 @@ -37,7 +37,7 @@ bool predictor_2; /* do Predictor-2? */ bool deflate_correct; /* use correct code for deflate? */ bool deflate_draft; /* use draft RFC code for deflate? */ - bool mppe; /* do MPPE? */ + u_char mppe; /* MPPE bitfield */ u_short bsd_bits; /* # bits/code for BSD Compress */ u_short deflate_size; /* lg(window size) for Deflate */ short method; /* code for chosen compression method */ diff -Nru ppp-2.4.7/pppd/chap_ms.c ppp-2.4.9/pppd/chap_ms.c --- ppp-2.4.7/pppd/chap_ms.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/chap_ms.c 2021-01-05 00:06:37.000000000 +0100 @@ -94,25 +94,24 @@ #include "pppcrypt.h" #include "magic.h" -static const char rcsid[] = RCSID; -static void ascii2unicode __P((char[], int, u_char[])); -static void NTPasswordHash __P((u_char *, int, u_char[MD4_SIGNATURE_SIZE])); -static void ChallengeResponse __P((u_char *, u_char *, u_char[24])); -static void ChapMS_NT __P((u_char *, char *, int, u_char[24])); -static void ChapMS2_NT __P((u_char *, u_char[16], char *, char *, int, - u_char[24])); +static void ascii2unicode (char[], int, u_char[]); +static void NTPasswordHash (u_char *, int, u_char[MD4_SIGNATURE_SIZE]); +static void ChallengeResponse (u_char *, u_char *, u_char[24]); +static void ChapMS_NT (u_char *, char *, int, u_char[24]); +static void ChapMS2_NT (u_char *, u_char[16], char *, char *, int, + u_char[24]); static void GenerateAuthenticatorResponsePlain - __P((char*, int, u_char[24], u_char[16], u_char *, - char *, u_char[41])); + (char*, int, u_char[24], u_char[16], u_char *, + char *, u_char[41]); #ifdef MSLANMAN -static void ChapMS_LANMan __P((u_char *, char *, int, u_char *)); +static void ChapMS_LANMan (u_char *, char *, int, u_char *); #endif #ifdef MPPE -static void Set_Start_Key __P((u_char *, char *, int)); -static void SetMasterKeys __P((char *, int, u_char[24], int)); +static void Set_Start_Key (u_char *, char *, int); +static void SetMasterKeys (char *, int, u_char[24], int); #endif #ifdef MSLANMAN @@ -424,6 +423,8 @@ len -= MS_AUTH_RESPONSE_LENGTH; if ((len >= 3) && !strncmp((char *)msg, " M=", 3)) { msg += 3; /* Eat the delimiter */ + } else if ((len >= 2) && !strncmp((char *)msg, "M=", 2)) { + msg += 2; /* Eat the delimiter */ } else if (len) { /* Packet has extra text which does not begin " M=" */ error("MS-CHAPv2 Success packet is badly formed."); diff -Nru ppp-2.4.7/pppd/chap_ms.h ppp-2.4.9/pppd/chap_ms.h --- ppp-2.4.7/pppd/chap_ms.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/chap_ms.h 2021-01-05 00:06:37.000000000 +0100 @@ -87,16 +87,16 @@ #define MS_CHAP2_AUTHENTICATEE 0 #define MS_CHAP2_AUTHENTICATOR 1 -void ChapMS __P((u_char *, char *, int, u_char *)); -void ChapMS2 __P((u_char *, u_char *, char *, char *, int, - u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int)); +void ChapMS (u_char *, char *, int, u_char *); +void ChapMS2 (u_char *, u_char *, char *, char *, int, + u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int); #ifdef MPPE -void mppe_set_keys __P((u_char *, u_char[MD4_SIGNATURE_SIZE])); +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 __P((u_char[16], u_char *, char *, u_char[8])); +void ChallengeHash (u_char[16], u_char *, char *, u_char[8]); void GenerateAuthenticatorResponse(u_char PasswordHashHash[MD4_SIGNATURE_SIZE], u_char NTResponse[24], u_char PeerChallenge[16], diff -Nru ppp-2.4.7/pppd/chap-new.c ppp-2.4.9/pppd/chap-new.c --- ppp-2.4.7/pppd/chap-new.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/chap-new.c 2021-01-05 00:06:37.000000000 +0100 @@ -55,20 +55,26 @@ /* * Option variables. */ -int chap_timeout_time = 3; +int chap_server_timeout_time = 3; int chap_max_transmits = 10; int chap_rechallenge_time = 0; +int chap_client_timeout_time = 60; +int chapms_strip_domain = 0; /* * Command-line options. */ static option_t chap_option_list[] = { - { "chap-restart", o_int, &chap_timeout_time, - "Set timeout for CHAP", OPT_PRIO }, + { "chap-restart", o_int, &chap_server_timeout_time, + "Set timeout for CHAP (as server)", OPT_PRIO }, { "chap-max-challenge", o_int, &chap_max_transmits, "Set max #xmits for challenge", OPT_PRIO }, { "chap-interval", o_int, &chap_rechallenge_time, "Set interval for rechallenge", OPT_PRIO }, + { "chap-timeout", o_int, &chap_client_timeout_time, + "Set timeout for CHAP (as client)", OPT_PRIO }, + { "chapms-strip-domain", o_bool, &chapms_strip_domain, + "Strip the domain prefix before the Username", 1 }, { NULL } }; @@ -114,7 +120,8 @@ static void chap_init(int unit); static void chap_lowerup(int unit); static void chap_lowerdown(int unit); -static void chap_timeout(void *arg); +static void chap_server_timeout(void *arg); +static void chap_client_timeout(void *arg); static void chap_generate_challenge(struct chap_server_state *ss); static void chap_handle_response(struct chap_server_state *ss, int code, unsigned char *pkt, int len); @@ -129,7 +136,7 @@ static void chap_protrej(int unit); static void chap_input(int unit, unsigned char *pkt, int pktlen); static int chap_print_pkt(unsigned char *p, int plen, - void (*printer) __P((void *, char *, ...)), void *arg); + void (*printer)(void *, char *, ...), void *arg); /* List of digest types that we know about */ static struct chap_digest_type *chap_digests; @@ -160,6 +167,18 @@ } /* + * Lookup a digest type by code + */ +struct chap_digest_type * +chap_find_digest(int digest_code) { + struct chap_digest_type *dp = NULL; + for (dp = chap_digests; dp != NULL; dp = dp->next) + if (dp->code == digest_code) + break; + return dp; +} + +/* * chap_lowerup - we can start doing stuff now. */ static void @@ -171,7 +190,7 @@ cs->flags |= LOWERUP; ss->flags |= LOWERUP; if (ss->flags & AUTH_STARTED) - chap_timeout(ss); + chap_server_timeout(ss); } static void @@ -180,9 +199,11 @@ struct chap_client_state *cs = &client; struct chap_server_state *ss = &server; + if (cs->flags & TIMEOUT_PENDING) + UNTIMEOUT(chap_client_timeout, cs); cs->flags = 0; if (ss->flags & TIMEOUT_PENDING) - UNTIMEOUT(chap_timeout, ss); + UNTIMEOUT(chap_server_timeout, ss); ss->flags = 0; } @@ -214,7 +235,7 @@ ss->id = (unsigned char)(drand48() * 256); ss->flags |= AUTH_STARTED; if (ss->flags & LOWERUP) - chap_timeout(ss); + chap_server_timeout(ss); } /* @@ -240,16 +261,17 @@ cs->digest = dp; cs->name = our_name; - cs->flags |= AUTH_STARTED; + cs->flags |= AUTH_STARTED | TIMEOUT_PENDING; + TIMEOUT(chap_client_timeout, cs, chap_client_timeout_time); } /* - * chap_timeout - It's time to send another challenge to the peer. + * chap_server_timeout - It's time to send another challenge to the peer. * This could be either a retransmission of a previous challenge, * or a new challenge to start re-authentication. */ static void -chap_timeout(void *arg) +chap_server_timeout(void *arg) { struct chap_server_state *ss = arg; @@ -268,7 +290,19 @@ output(0, ss->challenge, ss->challenge_pktlen); ++ss->challenge_xmits; ss->flags |= TIMEOUT_PENDING; - TIMEOUT(chap_timeout, arg, chap_timeout_time); + TIMEOUT(chap_server_timeout, arg, chap_server_timeout_time); +} + +/* chap_client_timeout - Authentication with peer timed out. */ +static void +chap_client_timeout(void *arg) +{ + struct chap_client_state *cs = arg; + + cs->flags &= ~TIMEOUT_PENDING; + cs->flags |= AUTH_DONE | AUTH_FAILED; + error("CHAP authentication timed out"); + auth_withpeer_fail(0, PPP_CHAP); } /* @@ -327,7 +361,7 @@ if (ss->flags & TIMEOUT_PENDING) { ss->flags &= ~TIMEOUT_PENDING; - UNTIMEOUT(chap_timeout, ss); + UNTIMEOUT(chap_server_timeout, ss); } if (explicit_remote) { @@ -336,6 +370,14 @@ /* Null terminate and clean remote name. */ slprintf(rname, sizeof(rname), "%.*v", len, name); name = rname; + + /* strip the MS domain name */ + if (chapms_strip_domain && strrchr(rname, '\\')) { + char tmp[MAXNAMELEN+1]; + + strcpy(tmp, strrchr(rname, '\\') + 1); + strcpy(rname, tmp); + } } if (chap_verify_hook) @@ -392,7 +434,7 @@ name, strlen(name)); if (chap_rechallenge_time) { ss->flags |= TIMEOUT_PENDING; - TIMEOUT(chap_timeout, ss, + TIMEOUT(chap_server_timeout, ss, chap_rechallenge_time); } } @@ -495,6 +537,9 @@ return; cs->flags |= AUTH_DONE; + UNTIMEOUT(chap_client_timeout, cs); + cs->flags &= ~TIMEOUT_PENDING; + if (code == CHAP_SUCCESS) { /* used for MS-CHAP v2 mutual auth, yuck */ if (cs->digest->check_success != NULL) { @@ -562,7 +607,7 @@ if (ss->flags & TIMEOUT_PENDING) { ss->flags &= ~TIMEOUT_PENDING; - UNTIMEOUT(chap_timeout, ss); + UNTIMEOUT(chap_server_timeout, ss); } if (ss->flags & AUTH_STARTED) { ss->flags = 0; @@ -584,7 +629,7 @@ static int chap_print_pkt(unsigned char *p, int plen, - void (*printer) __P((void *, char *, ...)), void *arg) + void (*printer)(void *, char *, ...), void *arg) { int code, id, len; int clen, nlen; diff -Nru ppp-2.4.7/pppd/chap-new.h ppp-2.4.9/pppd/chap-new.h --- ppp-2.4.7/pppd/chap-new.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/chap-new.h 2021-01-05 00:06:37.000000000 +0100 @@ -120,6 +120,9 @@ /* Called by digest code to register a digest type */ extern void chap_register_digest(struct chap_digest_type *); +/* Lookup a digest handler by type */ +extern struct chap_digest_type *chap_find_digest(int digest_code); + /* Called by authentication code to start authenticating the peer. */ extern void chap_auth_peer(int unit, char *our_name, int digest_code); diff -Nru ppp-2.4.7/pppd/demand.c ppp-2.4.9/pppd/demand.c --- ppp-2.4.7/pppd/demand.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/demand.c 2021-01-05 00:06:37.000000000 +0100 @@ -52,7 +52,6 @@ #include "ipcp.h" #include "lcp.h" -static const char rcsid[] = RCSID; char *frame; int framelen; @@ -70,13 +69,13 @@ struct packet *pend_q; struct packet *pend_qtail; -static int active_packet __P((unsigned char *, int)); +static int active_packet(unsigned char *, int); /* * demand_conf - configure the interface for doing dial-on-demand. */ void -demand_conf() +demand_conf(void) { int i; struct protent *protp; @@ -117,7 +116,7 @@ * demand_block - set each network protocol to block further packets. */ void -demand_block() +demand_block(void) { int i; struct protent *protp; @@ -133,7 +132,7 @@ * with an error. */ void -demand_discard() +demand_discard(void) { struct packet *pkt, *nextpkt; int i; @@ -160,7 +159,7 @@ * demand_unblock - set each enabled network protocol to pass packets. */ void -demand_unblock() +demand_unblock(void) { int i; struct protent *protp; @@ -214,9 +213,7 @@ * Return value is 1 if we need to bring up the link, 0 otherwise. */ int -loop_chars(p, n) - unsigned char *p; - int n; +loop_chars(unsigned char *p, int n) { int c, rv; @@ -266,9 +263,7 @@ * bring up the link. */ int -loop_frame(frame, len) - unsigned char *frame; - int len; +loop_frame(unsigned char *frame, int len) { struct packet *pkt; @@ -299,8 +294,7 @@ * loopback, now that the real serial link is up. */ void -demand_rexmit(proto) - int proto; +demand_rexmit(int proto) { struct packet *pkt, *prev, *nextpkt; @@ -330,9 +324,7 @@ * that is, whether it is worth bringing up the link for. */ static int -active_packet(p, len) - unsigned char *p; - int len; +active_packet(unsigned char *p, int len) { int proto, i; struct protent *protp; diff -Nru ppp-2.4.7/pppd/eap.c ppp-2.4.9/pppd/eap.c --- ppp-2.4.7/pppd/eap.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/eap.c 2021-01-05 00:06:37.000000000 +0100 @@ -43,10 +43,9 @@ * Based on draft-ietf-pppext-eap-srp-03.txt. */ -#define RCSID "$Id: eap.c,v 1.4 2004/11/09 22:39:25 paulus Exp $" - /* - * TODO: + * Modification by Beniamino Galvani, Mar 2005 + * Implemented EAP-TLS authentication */ #include @@ -65,6 +64,10 @@ #include "md5.h" #include "eap.h" +#ifdef CHAPMS +#include "chap_ms.h" +#endif + #ifdef USE_SRP #include #include @@ -76,7 +79,14 @@ #define SHA_DIGESTSIZE 20 #endif -static const char rcsid[] = RCSID; +#ifdef USE_EAPTLS +#include "eap-tls.h" +#endif /* USE_EAPTLS */ +#ifdef CHAPMS +#include "magic.h" +#include "chap_ms.h" +#include "chap-new.h" +#endif /* CHAPMS */ eap_state eap_states[NUM_PPP]; /* EAP state; one for each unit */ #ifdef USE_SRP @@ -111,13 +121,13 @@ /* * Protocol entry points. */ -static void eap_init __P((int unit)); -static void eap_input __P((int unit, u_char *inp, int inlen)); -static void eap_protrej __P((int unit)); -static void eap_lowerup __P((int unit)); -static void eap_lowerdown __P((int unit)); -static int eap_printpkt __P((u_char *inp, int inlen, - void (*)(void *arg, char *fmt, ...), void *arg)); +static void eap_init (int unit); +static void eap_input (int unit, u_char *inp, int inlen); +static void eap_protrej (int unit); +static void eap_lowerup (int unit); +static void eap_lowerdown (int unit); +static int eap_printpkt (u_char *inp, int inlen, + void (*)(void *arg, char *fmt, ...), void *arg); struct protent eap_protent = { PPP_EAP, /* protocol number */ @@ -139,6 +149,7 @@ NULL /* say whether to bring up link for this pkt */ }; +#ifdef USE_SRP /* * A well-known 2048 bit modulus. */ @@ -176,16 +187,16 @@ 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2, 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73 }; +#endif /* USE_SRP */ /* Local forward declarations. */ -static void eap_server_timeout __P((void *arg)); +static void eap_server_timeout (void *arg); /* * Convert EAP state code to printable string for debug. */ static const char * -eap_state_name(esc) -enum eap_state_code esc; +eap_state_name(enum eap_state_code esc) { static const char *state_names[] = { EAP_STATES }; @@ -197,8 +208,7 @@ * called once by main() during start-up. */ static void -eap_init(unit) -int unit; +eap_init(int unit) { eap_state *esp = &eap_states[unit]; @@ -209,6 +219,12 @@ esp->es_server.ea_id = (u_char)(drand48() * 0x100); esp->es_client.ea_timeout = EAP_DEFREQTIME; esp->es_client.ea_maxrequests = EAP_DEFALLOWREQ; +#ifdef USE_EAPTLS + esp->es_client.ea_using_eaptls = 0; +#endif /* USE_EAPTLS */ +#ifdef CHAPMS + esp->es_client.digest = chap_find_digest(CHAP_MICROSOFT_V2); +#endif } /* @@ -216,8 +232,7 @@ * Request messages. */ static void -eap_client_timeout(arg) -void *arg; +eap_client_timeout(void *arg) { eap_state *esp = (eap_state *) arg; @@ -236,9 +251,7 @@ * after eap_lowerup. */ void -eap_authwithpeer(unit, localname) -int unit; -char *localname; +eap_authwithpeer(int unit, char *localname) { eap_state *esp = &eap_states[unit]; @@ -262,8 +275,7 @@ * (Server operation) */ static void -eap_send_failure(esp) -eap_state *esp; +eap_send_failure(eap_state *esp) { u_char *outp; @@ -287,8 +299,7 @@ * (Server operation) */ static void -eap_send_success(esp) -eap_state *esp; +eap_send_success(eap_state *esp) { u_char *outp; @@ -342,11 +353,7 @@ }; static int -b64enc(bs, inp, inlen, outp) -struct b64state *bs; -u_char *inp; -int inlen; -u_char *outp; +b64enc(struct b64state *bs, u_char *inp, int inlen, u_char *outp) { int outlen = 0; @@ -368,9 +375,7 @@ } static int -b64flush(bs, outp) -struct b64state *bs; -u_char *outp; +b64flush(struct b64state *bs, u_char *outp) { int outlen = 0; @@ -390,11 +395,7 @@ } static int -b64dec(bs, inp, inlen, outp) -struct b64state *bs; -u_char *inp; -int inlen; -u_char *outp; +b64dec(struct b64state *bs, u_char *inp, int inlen, u_char *outp) { int outlen = 0; char *cp; @@ -422,9 +423,7 @@ * 0 for success and non-zero for failure. */ static void -eap_figure_next_state(esp, status) -eap_state *esp; -int status; +eap_figure_next_state(eap_state *esp, int status) { #ifdef USE_SRP unsigned char secbuf[MAXWORDLEN], clear[8], *sp, *dp; @@ -436,8 +435,16 @@ u_char vals[2]; struct b64state bs; #endif /* USE_SRP */ +#ifdef USE_EAPTLS + struct eaptls_session *ets; + int secret_len; + char secret[MAXWORDLEN]; +#endif /* USE_EAPTLS */ esp->es_server.ea_timeout = esp->es_savedtime; +#ifdef USE_EAPTLS + esp->es_server.ea_prev_state = esp->es_server.ea_state; +#endif /* USE_EAPTLS */ switch (esp->es_server.ea_state) { case eapBadAuth: return; @@ -562,9 +569,81 @@ break; } #endif /* USE_SRP */ +#ifdef USE_EAPTLS + if (!get_secret(esp->es_unit, esp->es_server.ea_peer, + esp->es_server.ea_name, secret, &secret_len, 1)) { + + esp->es_server.ea_state = eapTlsStart; + break; + } +#endif /* USE_EAPTLS */ + esp->es_server.ea_state = eapMD5Chall; break; +#ifdef USE_EAPTLS + case eapTlsStart: + /* Initialize ssl session */ + if(!eaptls_init_ssl_server(esp)) { + esp->es_server.ea_state = eapBadAuth; + break; + } + + esp->es_server.ea_state = eapTlsRecv; + break; + + case eapTlsRecv: + ets = (struct eaptls_session *) esp->es_server.ea_session; + + if(ets->alert_sent) { + esp->es_server.ea_state = eapTlsSendAlert; + break; + } + + if (status) { + esp->es_server.ea_state = eapBadAuth; + break; + } + ets = (struct eaptls_session *) esp->es_server.ea_session; + + if(ets->frag) + esp->es_server.ea_state = eapTlsSendAck; + else + esp->es_server.ea_state = eapTlsSend; + break; + + case eapTlsSend: + ets = (struct eaptls_session *) esp->es_server.ea_session; + + if(ets->frag) + esp->es_server.ea_state = eapTlsRecvAck; + else + if(SSL_is_init_finished(ets->ssl)) + esp->es_server.ea_state = eapTlsRecvClient; + else + /* JJK Add "TLS empty record" message here ??? */ + esp->es_server.ea_state = eapTlsRecv; + break; + + case eapTlsSendAck: + esp->es_server.ea_state = eapTlsRecv; + break; + + case eapTlsRecvAck: + if (status) + { + esp->es_server.ea_state = eapBadAuth; + break; + } + + esp->es_server.ea_state = eapTlsSend; + break; + + case eapTlsSendAlert: + esp->es_server.ea_state = eapTlsRecvAlertAck; + break; +#endif /* USE_EAPTLS */ + case eapSRP1: #ifdef USE_SRP ts = (struct t_server *)esp->es_server.ea_session; @@ -616,6 +695,9 @@ } break; +#ifdef CHAPMS + case eapMSCHAPv2Chall: +#endif case eapMD5Chall: if (status != 0) { esp->es_server.ea_state = eapBadAuth; @@ -630,15 +712,174 @@ } if (esp->es_server.ea_state == eapBadAuth) eap_send_failure(esp); + +#ifdef USE_EAPTLS + dbglog("EAP id=0x%2x '%s' -> '%s'", esp->es_server.ea_id, eap_state_name(esp->es_server.ea_prev_state), eap_state_name(esp->es_server.ea_state)); +#endif /* USE_EAPTLS */ +} + +#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= M=" + * where + * is the Authenticator Response (mutual auth) + * is a text message + * + * However, some versions of Windows (win98 tested) do not know + * about the M= 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 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 + * succeeded), or 0 if it doesn't. + */ +static int +eap_chap_verify_response(char *name, char *ourname, int id, + struct chap_digest_type *digest, + unsigned char *challenge, unsigned char *response, + char *message, int message_space) +{ + int ok; + unsigned char secret[MAXSECRETLEN]; + int secret_len; + + /* Get the secret that the peer is supposed to know */ + if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) { + error("No CHAP secret found for authenticating %q", name); + return 0; + } + + ok = digest->verify_response(id, name, secret, secret_len, challenge, + response, message, message_space); + memset(secret, 0, sizeof(secret)); + + return ok; } /* + * Format and send an CHAPV2-Success/Failure EAP Request message. + */ +static void +eap_chapms2_send_request(eap_state *esp, u_char id, + u_char opcode, u_char chapid, + char *message, int message_len) +{ + u_char *outp; + int msglen; + + outp = outpacket_buf; + + MAKEHEADER(outp, PPP_EAP); + + msglen = EAP_HEADERLEN + 5 * sizeof (u_char); + msglen += message_len; + + PUTCHAR(EAP_REQUEST, outp); + PUTCHAR(id, outp); + PUTSHORT(msglen, outp); + PUTCHAR(EAPT_MSCHAPV2, outp); + PUTCHAR(opcode, outp); + PUTCHAR(chapid, outp); + /* MS len */ + PUTSHORT(msglen - 5, outp); + BCOPY(message, outp, message_len); + + output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); + + if (opcode == CHAP_SUCCESS) { + auth_peer_success(esp->es_unit, PPP_EAP, 0, + esp->es_server.ea_peer, esp->es_server.ea_peerlen); + } + else { + esp->es_server.ea_state = eapBadAuth; + auth_peer_fail(esp->es_unit, PPP_EAP); + } +} +#endif /* CHAPMS */ + +/* * Format an EAP Request message and send it to the peer. Message * type depends on current state. (Server operation) */ static void -eap_send_request(esp) -eap_state *esp; +eap_send_request(eap_state *esp) { u_char *outp; u_char *lenloc; @@ -718,6 +959,54 @@ INCPTR(esp->es_server.ea_namelen, outp); break; +#ifdef CHAPMS + case eapMSCHAPv2Chall: + challen = 0x10; + esp->es_challen = challen; + esp->es_challenge[0] = challen; + random_bytes(&esp->es_challenge[1], challen); + + PUTCHAR(EAPT_MSCHAPV2, outp); + PUTCHAR(CHAP_CHALLENGE, outp); + PUTCHAR(esp->es_server.ea_id, outp); + /* MS len */ + PUTSHORT(5 + challen + + esp->es_server.ea_namelen, + outp); + /* challen + challenge */ + BCOPY(esp->es_challenge, outp, challen+1); + INCPTR(challen+1, outp); + BCOPY(esp->es_server.ea_name, + outp, + esp->es_server.ea_namelen); + INCPTR(esp->es_server.ea_namelen, outp); + break; +#endif /* CHAPMS */ + +#ifdef USE_EAPTLS + case eapTlsStart: + PUTCHAR(EAPT_TLS, outp); + PUTCHAR(EAP_TLS_FLAGS_START, outp); + eap_figure_next_state(esp, 0); + break; + + case eapTlsSend: + eaptls_send(esp->es_server.ea_session, &outp); + eap_figure_next_state(esp, 0); + break; + + case eapTlsSendAck: + PUTCHAR(EAPT_TLS, outp); + PUTCHAR(0, outp); + eap_figure_next_state(esp, 0); + break; + + case eapTlsSendAlert: + eaptls_send(esp->es_server.ea_session, &outp); + eap_figure_next_state(esp, 0); + break; +#endif /* USE_EAPTLS */ + #ifdef USE_SRP case eapSRP1: PUTCHAR(EAPT_SRP, outp); @@ -871,9 +1160,7 @@ * after eap_lowerup. */ void -eap_authpeer(unit, localname) -int unit; -char *localname; +eap_authpeer(int unit, char *localname) { eap_state *esp = &eap_states[unit]; @@ -901,14 +1188,59 @@ * expired. */ static void -eap_server_timeout(arg) -void *arg; +eap_server_timeout(void *arg) { +#ifdef USE_EAPTLS + u_char *outp; + u_char *lenloc; + int outlen; +#endif /* USE_EAPTLS */ + eap_state *esp = (eap_state *) arg; if (!eap_server_active(esp)) return; +#ifdef USE_EAPTLS + switch(esp->es_server.ea_prev_state) { + + /* + * In eap-tls the state changes after a request, so we return to + * previous state ... + */ + case(eapTlsStart): + case(eapTlsSendAck): + esp->es_server.ea_state = esp->es_server.ea_prev_state; + break; + + /* + * ... or resend the stored data + */ + case(eapTlsSend): + case(eapTlsSendAlert): + outp = outpacket_buf; + MAKEHEADER(outp, PPP_EAP); + PUTCHAR(EAP_REQUEST, outp); + PUTCHAR(esp->es_server.ea_id, outp); + lenloc = outp; + INCPTR(2, outp); + + eaptls_retransmit(esp->es_server.ea_session, &outp); + + outlen = (outp - outpacket_buf) - PPP_HDRLEN; + PUTSHORT(outlen, lenloc); + output(esp->es_unit, outpacket_buf, outlen + PPP_HDRLEN); + esp->es_server.ea_requests++; + + if (esp->es_server.ea_timeout > 0) + TIMEOUT(eap_server_timeout, esp, esp->es_server.ea_timeout); + + return; + default: + break; + } +#endif /* USE_EAPTLS */ + /* EAP ID number must not change on timeout. */ eap_send_request(esp); } @@ -919,8 +1251,7 @@ * will restart the timer. If it fails, then the link is dropped. */ static void -eap_rechallenge(arg) -void *arg; +eap_rechallenge(void *arg) { eap_state *esp = (eap_state *)arg; @@ -936,8 +1267,7 @@ } static void -srp_lwrechallenge(arg) -void *arg; +srp_lwrechallenge(void *arg) { eap_state *esp = (eap_state *)arg; @@ -960,8 +1290,7 @@ * thing. */ static void -eap_lowerup(unit) -int unit; +eap_lowerup(int unit) { eap_state *esp = &eap_states[unit]; @@ -984,8 +1313,7 @@ * Cancel all timeouts and return to initial state. */ static void -eap_lowerdown(unit) -int unit; +eap_lowerdown(int unit) { eap_state *esp = &eap_states[unit]; @@ -1019,8 +1347,7 @@ * failure. */ static void -eap_protrej(unit) -int unit; +eap_protrej(int unit) { eap_state *esp = &eap_states[unit]; @@ -1039,12 +1366,8 @@ * Format and send a regular EAP Response message. */ static void -eap_send_response(esp, id, typenum, str, lenstr) -eap_state *esp; -u_char id; -u_char typenum; -u_char *str; -int lenstr; +eap_send_response(eap_state *esp, u_char id, u_char typenum, + u_char *str, int lenstr) { u_char *outp; int msglen; @@ -1070,12 +1393,8 @@ * Format and send an MD5-Challenge EAP Response message. */ static void -eap_chap_response(esp, id, hash, name, namelen) -eap_state *esp; -u_char id; -u_char *hash; -char *name; -int namelen; +eap_chap_response(eap_state *esp, u_char id, u_char *hash, + char *name, int namelen) { u_char *outp; int msglen; @@ -1106,12 +1425,8 @@ * Format and send a SRP EAP Response message. */ static void -eap_srp_response(esp, id, subtypenum, str, lenstr) -eap_state *esp; -u_char id; -u_char subtypenum; -u_char *str; -int lenstr; +eap_srp_response(eap_state *esp, u_char id, u_char subtypenum, + u_char *str, int lenstr) { u_char *outp; int msglen; @@ -1138,11 +1453,7 @@ * Format and send a SRP EAP Client Validator Response message. */ static void -eap_srpval_response(esp, id, flags, str) -eap_state *esp; -u_char id; -u_int32_t flags; -u_char *str; +eap_srpval_response(eap_state *esp, u_char id, u_int32_t flags, u_char *str) { u_char *outp; int msglen; @@ -1166,11 +1477,77 @@ } #endif /* USE_SRP */ +#ifdef USE_EAPTLS +/* + * Send an EAP-TLS response message with tls data + */ +static void +eap_tls_response(eap_state *esp, u_char id) +{ + u_char *outp; + int outlen; + u_char *lenloc; + + outp = outpacket_buf; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_RESPONSE, outp); + PUTCHAR(id, outp); + + lenloc = outp; + INCPTR(2, outp); + + /* + If the id in the request is unchanged, we must retransmit + the old data + */ + if(id == esp->es_client.ea_id) + eaptls_retransmit(esp->es_client.ea_session, &outp); + else + eaptls_send(esp->es_client.ea_session, &outp); + + outlen = (outp - outpacket_buf) - PPP_HDRLEN; + PUTSHORT(outlen, lenloc); + + output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen); + + esp->es_client.ea_id = id; +} + +/* + * Send an EAP-TLS ack + */ +static void +eap_tls_sendack(eap_state *esp, u_char id) +{ + u_char *outp; + int outlen; + u_char *lenloc; + + outp = outpacket_buf; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_RESPONSE, outp); + PUTCHAR(id, outp); + esp->es_client.ea_id = id; + + lenloc = outp; + INCPTR(2, outp); + + PUTCHAR(EAPT_TLS, outp); + PUTCHAR(0, outp); + + outlen = (outp - outpacket_buf) - PPP_HDRLEN; + PUTSHORT(outlen, lenloc); + + output(esp->es_unit, outpacket_buf, PPP_HDRLEN + outlen); +} +#endif /* USE_EAPTLS */ + static void -eap_send_nak(esp, id, type) -eap_state *esp; -u_char id; -u_char type; +eap_send_nak(eap_state *esp, u_char id, u_char type) { u_char *outp; int msglen; @@ -1192,7 +1569,7 @@ #ifdef USE_SRP static char * -name_of_pn_file() +name_of_pn_file(void) { char *user, *path, *file; struct passwd *pw; @@ -1218,8 +1595,7 @@ } static int -open_pn_file(modebits) -mode_t modebits; +open_pn_file(mode_t modebits) { char *path; int fd, err; @@ -1234,7 +1610,7 @@ } static void -remove_pn_file() +remove_pn_file(void) { char *path; @@ -1245,10 +1621,7 @@ } static void -write_pseudonym(esp, inp, len, id) -eap_state *esp; -u_char *inp; -int len, id; +write_pseudonym(eap_state *esp, u_char *inp, int len, int id) { u_char val; u_char *datp, *digp; @@ -1303,15 +1676,44 @@ } #endif /* USE_SRP */ +#if CHAPMS +/* + * Format and send an CHAPV2-Challenge EAP Response message. + */ +static void +eap_chapv2_response(eap_state *esp, u_char id, u_char chapid, u_char *response, char *user, int user_len) +{ + u_char *outp; + int msglen; + + outp = outpacket_buf; + + MAKEHEADER(outp, PPP_EAP); + + PUTCHAR(EAP_RESPONSE, outp); + PUTCHAR(id, outp); + esp->es_client.ea_id = id; + msglen = EAP_HEADERLEN + 6 * sizeof (u_char) + MS_CHAP2_RESPONSE_LEN + user_len; + PUTSHORT(msglen, outp); + PUTCHAR(EAPT_MSCHAPV2, outp); + PUTCHAR(CHAP_RESPONSE, outp); + PUTCHAR(chapid, outp); + PUTCHAR(0, outp); + /* len */ + 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); + + output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen); +} +#endif + /* * eap_request - Receive EAP Request message (client mode). */ static void -eap_request(esp, inp, id, len) -eap_state *esp; -u_char *inp; -int id; -int len; +eap_request(eap_state *esp, u_char *inp, int id, int len) { u_char typenum; u_char vallen; @@ -1320,6 +1722,11 @@ char rhostname[256]; MD5_CTX mdContext; u_char hash[MD5_SIGNATURE_SIZE]; +#ifdef USE_EAPTLS + u_char flags; + struct eaptls_session *ets = esp->es_client.ea_session; +#endif /* USE_EAPTLS */ + #ifdef USE_SRP struct t_client *tc; struct t_num sval, gval, Nval, *Ap, Bval; @@ -1330,6 +1737,12 @@ #endif /* USE_SRP */ /* + * Ignore requests if we're not open + */ + if (esp->es_client.ea_state <= eapClosed) + return; + + /* * Note: we update es_client.ea_id *only if* a Response * message is being generated. Otherwise, we leave it the * same for duplicate detection purposes. @@ -1385,7 +1798,7 @@ esp->es_usedpseudo = 2; } #endif /* USE_SRP */ - eap_send_response(esp, id, typenum, esp->es_client.ea_name, + eap_send_response(esp, id, typenum, (u_char *)esp->es_client.ea_name, esp->es_client.ea_namelen); break; @@ -1421,7 +1834,7 @@ } /* Not so likely to happen. */ - if (vallen >= len + sizeof (rhostname)) { + if (len - vallen >= sizeof (rhostname)) { dbglog("EAP: trimming really long peer name down"); BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1); rhostname[sizeof (rhostname) - 1] = '\0'; @@ -1456,6 +1869,96 @@ esp->es_client.ea_namelen); break; +#ifdef USE_EAPTLS + case EAPT_TLS: + + switch(esp->es_client.ea_state) { + + case eapListen: + + if (len < 1) { + error("EAP: received EAP-TLS Listen packet with no data"); + /* Bogus request; wait for something real. */ + return; + } + GETCHAR(flags, inp); + if(flags & EAP_TLS_FLAGS_START){ + + esp->es_client.ea_using_eaptls = 1; + + if (explicit_remote){ + esp->es_client.ea_peer = strdup(remote_name); + esp->es_client.ea_peerlen = strlen(remote_name); + } else + esp->es_client.ea_peer = NULL; + + /* Init ssl session */ + if(!eaptls_init_ssl_client(esp)) { + dbglog("cannot init ssl"); + eap_send_nak(esp, id, EAPT_MSCHAPV2); + esp->es_client.ea_using_eaptls = 0; + break; + } + + ets = esp->es_client.ea_session; + eap_tls_response(esp, id); + esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv); + break; + } + + /* The server has sent a bad start packet. */ + eap_send_nak(esp, id, EAPT_MSCHAPV2); + break; + + case eapTlsRecvAck: + eap_tls_response(esp, id); + esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv); + break; + + case eapTlsRecv: + if (len < 1) { + error("EAP: discarding EAP-TLS Receive packet with no data"); + /* Bogus request; wait for something real. */ + return; + } + eaptls_receive(ets, inp, len); + + if(ets->frag) { + eap_tls_sendack(esp, id); + esp->es_client.ea_state = eapTlsRecv; + break; + } + + if(ets->alert_recv) { + eap_tls_sendack(esp, id); + esp->es_client.ea_state = eapTlsRecvFailure; + break; + } + + /* Check if TLS handshake is finished */ + if(eaptls_is_init_finished(ets)) { +#ifdef MPPE + eaptls_gen_mppe_keys(ets, 1); +#endif + eaptls_free_session(ets); + eap_tls_sendack(esp, id); + esp->es_client.ea_state = eapTlsRecvSuccess; + break; + } + + eap_tls_response(esp,id); + esp->es_client.ea_state = (ets->frag ? eapTlsRecvAck : eapTlsRecv); + break; + + default: + eap_send_nak(esp, id, EAPT_MSCHAPV2); + esp->es_client.ea_using_eaptls = 0; + break; + } + + break; +#endif /* USE_EAPTLS */ + #ifdef USE_SRP case EAPT_SRP: if (len < 1) { @@ -1687,6 +2190,113 @@ } break; #endif /* USE_SRP */ + +#ifdef CHAPMS + case EAPT_MSCHAPV2: + if (len < 4) { + error("EAP: received invalid MSCHAPv2 packet, too short"); + return; + } + unsigned char opcode; + GETCHAR(opcode, inp); + unsigned char chapid; /* Chapv2-ID */ + GETCHAR(chapid, inp); + short mssize; + GETSHORT(mssize, inp); + + /* Validate the mssize field */ + if (len != mssize) { + error("EAP: received invalid MSCHAPv2 packet, invalid length"); + return; + } + len -= 4; + + /* If MSCHAPv2 digest was not found, NAK the packet */ + if (!esp->es_client.digest) { + error("EAP MSCHAPv2 not supported"); + eap_send_nak(esp, id, EAPT_SRP); + return; + } + + switch (opcode) { + case CHAP_CHALLENGE: { + + /* make_response() expects: VLEN + VALUE */ + u_char *challenge = inp; + + unsigned char vsize; + GETCHAR(vsize, inp); + len -= 1; + + /* Validate the VALUE field */ + if (vsize != MS_CHAP2_PEER_CHAL_LEN || len < MS_CHAP2_PEER_CHAL_LEN) { + error("EAP: received invalid MSCHAPv2 packet, invalid value-length: %d", vsize); + return; + } + + /* Increment past the VALUE field */ + INCPTR(MS_CHAP2_PEER_CHAL_LEN, inp); + len -= MS_CHAP2_PEER_CHAL_LEN; + + /* Extract the hostname */ + rhostname[0] = '\0'; + if (len > 0) { + if (len >= sizeof (rhostname)) { + dbglog("EAP: trimming really long peer name down"); + len = sizeof(rhostname) - 1; + } + BCOPY(inp, rhostname, len); + rhostname[len] = '\0'; + } + + /* In case the remote doesn't give us his name. */ + if (explicit_remote || (remote_name[0] != '\0' && len == 0)) + strlcpy(rhostname, remote_name, sizeof(rhostname)); + + /* Get the secret for authenticating ourselves with the specified host. */ + if (!get_secret(esp->es_unit, esp->es_client.ea_name, + rhostname, secret, &secret_len, 0)) { + dbglog("EAP: no CHAP secret for auth to %q", rhostname); + eap_send_nak(esp, id, EAPT_SRP); + break; + } + + /* Create the MSCHAPv2 response (and add to cache) */ + unsigned char response[MS_CHAP2_RESPONSE_LEN+1]; // VLEN + VALUE + esp->es_client.digest->make_response(response, chapid, esp->es_client.ea_name, + challenge, secret, secret_len, NULL); + + eap_chapv2_response(esp, id, chapid, response, esp->es_client.ea_name, esp->es_client.ea_namelen); + break; + } + case CHAP_SUCCESS: { + + /* Check response for mutual authentication */ + u_char status = CHAP_FAILURE; + if (esp->es_client.digest->check_success(chapid, inp, len) == 1) { + info("Chap authentication succeeded! %.*v", len, inp); + status = CHAP_SUCCESS; + } + eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status)); + break; + } + case CHAP_FAILURE: { + + /* Process the failure string, and log appropriate information */ + esp->es_client.digest->handle_failure(inp, len); + + u_char status = CHAP_FAILURE; + eap_send_response(esp, id, EAPT_MSCHAPV2, &status, sizeof(status)); + goto client_failure; /* force termination */ + } + default: + + error("EAP: received invalid MSCHAPv2 packet, invalid or unsupported opcode: %d", opcode); + eap_send_nak(esp, id, EAPT_SRP); + } + + break; +#endif /* CHAPMS */ default: info("EAP: unknown authentication type %d; Naking", typenum); @@ -1701,13 +2311,13 @@ } return; -#ifdef USE_SRP client_failure: esp->es_client.ea_state = eapBadAuth; if (esp->es_client.ea_timeout > 0) { UNTIMEOUT(eap_client_timeout, (void *)esp); } esp->es_client.ea_session = NULL; +#ifdef USE_SRP t_clientclose(tc); auth_withpeer_fail(esp->es_unit, PPP_EAP); #endif /* USE_SRP */ @@ -1717,11 +2327,7 @@ * eap_response - Receive EAP Response message (server mode). */ static void -eap_response(esp, inp, id, len) -eap_state *esp; -u_char *inp; -int id; -int len; +eap_response(eap_state *esp, u_char *inp, int id, int len) { u_char typenum; u_char vallen; @@ -1735,8 +2341,27 @@ 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 + struct eaptls_session *ets; + u_char flags; +#endif /* USE_EAPTLS */ +#ifdef CHAPMS + u_char opcode; + int (*chap_verifier)(char *, char *, int, struct chap_digest_type *, + unsigned char *, unsigned char *, char *, int); + char response_message[256]; +#endif /* CHAPMS */ + + /* + * Ignore responses if we're not open + */ + if (esp->es_server.ea_state <= eapClosed) + return; + if (esp->es_server.ea_id != id) { dbglog("EAP: discarding Response %d; expected ID %d", id, esp->es_server.ea_id); @@ -1776,6 +2401,64 @@ eap_figure_next_state(esp, 0); break; +#ifdef USE_EAPTLS + case EAPT_TLS: + switch(esp->es_server.ea_state) { + + case eapTlsRecv: + + ets = (struct eaptls_session *) esp->es_server.ea_session; + + eap_figure_next_state(esp, + eaptls_receive(esp->es_server.ea_session, inp, len)); + + if(ets->alert_recv) { + eap_send_failure(esp); + break; + } + break; + + case eapTlsRecvAck: + if(len > 1) { + dbglog("EAP-TLS ACK with extra data"); + } + eap_figure_next_state(esp, 0); + break; + + case eapTlsRecvClient: + /* Receive authentication response from client */ + if (len > 0) { + GETCHAR(flags, inp); + + if(len == 1 && !flags) { /* Ack = ok */ +#ifdef MPPE + eaptls_gen_mppe_keys( esp->es_server.ea_session, 0 ); +#endif + eap_send_success(esp); + } + else { /* failure */ + warn("Server authentication failed"); + eap_send_failure(esp); + } + } + else + warn("Bogus EAP-TLS packet received from client"); + + eaptls_free_session(esp->es_server.ea_session); + + break; + + case eapTlsRecvAlertAck: + eap_send_failure(esp); + break; + + default: + eap_figure_next_state(esp, 1); + break; + } + break; +#endif /* USE_EAPTLS */ + case EAPT_NOTIFICATION: dbglog("EAP unexpected Notification; response discarded"); break; @@ -1807,6 +2490,20 @@ esp->es_server.ea_state = eapMD5Chall; break; +#ifdef USE_EAPTLS + /* Send EAP-TLS start packet */ + case EAPT_TLS: + esp->es_server.ea_state = eapTlsStart; + break; +#endif /* USE_EAPTLS */ + +#ifdef CHAPMS + case EAPT_MSCHAPV2: + info("EAP: peer proposes MSCHAPv2"); + esp->es_server.ea_state = eapMSCHAPv2Chall; + break; +#endif /* CHAPMS */ + default: dbglog("EAP: peer requesting unknown Type %d", vallen); switch (esp->es_server.ea_state) { @@ -1847,7 +2544,7 @@ } /* Not so likely to happen. */ - if (vallen >= len + sizeof (rhostname)) { + if (len - vallen >= sizeof (rhostname)) { dbglog("EAP: trimming really long peer name down"); BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1); rhostname[sizeof (rhostname) - 1] = '\0'; @@ -1888,6 +2585,103 @@ TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge); break; +#ifdef CHAPMS + case EAPT_MSCHAPV2: + if (len < 1) { + error("EAP: received MSCHAPv2 with no data"); + eap_figure_next_state(esp, 1); + break; + } + GETCHAR(opcode, inp); + len--; + + switch (opcode) { + case CHAP_RESPONSE: + if (esp->es_server.ea_state != eapMSCHAPv2Chall) { + error("EAP: unexpected MSCHAPv2-Response"); + eap_figure_next_state(esp, 1); + break; + } + /* skip MS ID + len */ + INCPTR(3, inp); + GETCHAR(vallen, inp); + len -= 4; + + if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) { + error("EAP: Invalid MSCHAPv2-Response " + "length %d", vallen); + eap_figure_next_state(esp, 1); + break; + } + + /* Not so likely to happen. */ + if (len - vallen >= sizeof (rhostname)) { + dbglog("EAP: trimming really long peer name down"); + BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1); + rhostname[sizeof (rhostname) - 1] = '\0'; + } else { + BCOPY(inp + vallen, rhostname, len - vallen); + rhostname[len - vallen] = '\0'; + } + + /* In case the remote doesn't give us his name. */ + if (explicit_remote || + (remote_name[0] != '\0' && vallen == len)) + strlcpy(rhostname, remote_name, sizeof (rhostname)); + + if (chap_verify_hook) + chap_verifier = chap_verify_hook; + else + chap_verifier = eap_chap_verify_response; + + esp->es_server.ea_id += 1; + if ((*chap_verifier)(rhostname, + esp->es_server.ea_name, + id, + &eap_chapms2_digest, + esp->es_challenge, + inp - 1, + response_message, + sizeof(response_message))) + { + info("EAP: MSCHAPv2 success for peer %q", + rhostname); + esp->es_server.ea_type = EAPT_MSCHAPV2; + eap_chapms2_send_request(esp, + esp->es_server.ea_id, + CHAP_SUCCESS, + esp->es_server.ea_id, + response_message, + strlen(response_message)); + eap_figure_next_state(esp, 0); + if (esp->es_rechallenge != 0) + TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge); + } + else { + warn("EAP: MSCHAPv2 failure for peer %q", + rhostname); + eap_chapms2_send_request(esp, + esp->es_server.ea_id, + CHAP_FAILURE, + esp->es_server.ea_id, + response_message, + strlen(response_message)); + } + break; + case CHAP_SUCCESS: + info("EAP: MSCHAPv2 success confirmed"); + break; + case CHAP_FAILURE: + info("EAP: MSCHAPv2 failure confirmed"); + break; + default: + error("EAP: Unhandled MSCHAPv2 opcode %d", opcode); + eap_send_nak(esp, id, EAPT_SRP); + } + + break; +#endif /* CHAPMS */ + #ifdef USE_SRP case EAPT_SRP: if (len < 1) { @@ -2012,19 +2806,29 @@ * eap_success - Receive EAP Success message (client mode). */ static void -eap_success(esp, inp, id, len) -eap_state *esp; -u_char *inp; -int id; -int len; +eap_success(eap_state *esp, u_char *inp, int id, int len) { - if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp)) { + if (esp->es_client.ea_state != eapOpen && !eap_client_active(esp) +#ifdef USE_EAPTLS + && esp->es_client.ea_state != eapTlsRecvSuccess +#endif /* USE_EAPTLS */ + ) { dbglog("EAP unexpected success message in state %s (%d)", eap_state_name(esp->es_client.ea_state), esp->es_client.ea_state); return; } +#ifdef USE_EAPTLS + if(esp->es_client.ea_using_eaptls && esp->es_client.ea_state != + eapTlsRecvSuccess) { + dbglog("EAP-TLS unexpected success message in state %s (%d)", + eap_state_name(esp->es_client.ea_state), + esp->es_client.ea_state); + return; + } +#endif /* USE_EAPTLS */ + if (esp->es_client.ea_timeout > 0) { UNTIMEOUT(eap_client_timeout, (void *)esp); } @@ -2042,12 +2846,14 @@ * eap_failure - Receive EAP Failure message (client mode). */ static void -eap_failure(esp, inp, id, len) -eap_state *esp; -u_char *inp; -int id; -int len; +eap_failure(eap_state *esp, u_char *inp, int id, int len) { + /* + * Ignore failure messages if we're not open + */ + if (esp->es_client.ea_state <= eapClosed) + return; + if (!eap_client_active(esp)) { dbglog("EAP unexpected failure message in state %s (%d)", eap_state_name(esp->es_client.ea_state), @@ -2073,10 +2879,7 @@ * eap_input - Handle received EAP message. */ static void -eap_input(unit, inp, inlen) -int unit; -u_char *inp; -int inlen; +eap_input(int unit, u_char *inp, int inlen) { eap_state *esp = &eap_states[unit]; u_char code, id; @@ -2137,19 +2940,24 @@ "OTP", "Generic-Token", NULL, NULL, "RSA", "DSS", "KEA", "KEA-Validate", "TLS", "Defender", "Windows 2000", "Arcot", - "Cisco", "Nokia", "SRP" + "Cisco", "Nokia", "SRP", NULL, + "TTLS", "RAS", "AKA", "3COM", "PEAP", + "MSCHAPv2" }; static int -eap_printpkt(inp, inlen, printer, arg) -u_char *inp; -int inlen; -void (*printer) __P((void *, char *, ...)); -void *arg; +eap_printpkt(u_char *inp, int inlen, + void (*printer) (void *, char *, ...), void *arg) { int code, id, len, rtype, vallen; u_char *pstart; u_int32_t uval; +#ifdef USE_EAPTLS + u_char flags; +#endif /* USE_EAPTLS */ +#ifdef CHAPMS + u_char opcode; +#endif /* CHAPMS */ if (inlen < EAP_HEADERLEN) return (0); @@ -2214,6 +3022,79 @@ } break; +#ifdef CHAPMS + case EAPT_MSCHAPV2: + if (len <= 0) + break; + GETCHAR(opcode, inp); + len--; + switch (opcode) { + case CHAP_CHALLENGE: + INCPTR(3, inp); + len -= 3; + GETCHAR(vallen, inp); + len--; + if (vallen > len) + goto truncated; + len -= vallen; + printer(arg, " Challenge <"); + for (; vallen > 0; --vallen) { + u_char val; + GETCHAR(val, inp); + printer(arg, "%.2x", val); + } + printer(arg, ">"); + if (len > 0) { + printer(arg, ", "); + INCPTR(len, inp); + len = 0; + } else { + printer(arg, ", "); + } + break; + case CHAP_SUCCESS: + INCPTR(3, inp); + len -= 3; + printer(arg, " Success "); + break; + case CHAP_FAILURE: + INCPTR(3, inp); + len -= 3; + printer(arg, " Failure "); + break; + default: + INCPTR(3, inp); + len -= 3; + printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp); + break; + } + break; +#endif /* CHAPMS */ + +#ifdef USE_EAPTLS + case EAPT_TLS: + if (len < 1) + break; + GETCHAR(flags, inp); + len--; + + if(flags == 0 && len == 0){ + printer(arg, " Ack"); + break; + } + + printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -"); + printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-"); + printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- "); + break; +#endif /* USE_EAPTLS */ + case EAPT_SRP: if (len < 3) goto truncated; @@ -2325,6 +3206,25 @@ } break; +#ifdef USE_EAPTLS + case EAPT_TLS: + if (len < 1) + break; + GETCHAR(flags, inp); + len--; + + if(flags == 0 && len == 0){ + printer(arg, " Ack"); + break; + } + + printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -"); + printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-"); + printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- "); + + break; +#endif /* USE_EAPTLS */ + case EAPT_NAK: if (len <= 0) { printer(arg, " "); @@ -2334,7 +3234,7 @@ len--; printer(arg, " = 1 && - rtype < sizeof (eap_typenames) / sizeof (char *)) + rtype <= sizeof (eap_typenames) / sizeof (char *)) printer(arg, " (%s)", eap_typenames[rtype-1]); printer(arg, ">"); break; @@ -2362,6 +3262,51 @@ } break; +#ifdef CHAPMS + case EAPT_MSCHAPV2: + if (len <= 0) + break; + GETCHAR(opcode, inp); + len--; + switch (opcode) { + case CHAP_RESPONSE: + INCPTR(3, inp); + len -= 3; + GETCHAR(vallen, inp); + len--; + if (vallen > len) + goto truncated; + len -= vallen; + printer(arg, " Response <"); + for (; vallen > 0; --vallen) { + u_char val; + GETCHAR(val, inp); + printer(arg, "%.2x", val); + } + printer(arg, ">"); + if (len > 0) { + printer(arg, ", "); + INCPTR(len, inp); + len = 0; + } else { + printer(arg, ", "); + } + break; + case CHAP_SUCCESS: + printer(arg, " Success"); + break; + case CHAP_FAILURE: + printer(arg, " Failure"); + break; + default: + printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp); + break; + } + break; +#endif /* CHAPMS */ + case EAPT_SRP: if (len < 1) goto truncated; diff -Nru ppp-2.4.7/pppd/eap.h ppp-2.4.9/pppd/eap.h --- ppp-2.4.7/pppd/eap.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/eap.h 2021-01-05 00:06:37.000000000 +0100 @@ -59,6 +59,18 @@ #define EAPT_NOKIACARD 18 /* Nokia IP smart card */ #define EAPT_SRP 19 /* Secure Remote Password */ /* 20 is deprecated */ +#define EAPT_TTLS 21 /* EAP Tunneled TLS Authentication Protocol RFC5281 */ +#define EAPT_RAS 22 /* Remote Access Service */ +#define EAPT_AKA 23 /* EAP method for 3rd Generation Authentication and Key Agreement RFC4187 */ +#define EAPT_3COM 24 /* EAP-3Com Wireless */ +#define EAPT_PEAP 25 /* Protected EAP */ +#define EAPT_MSCHAPV2 26 /* EAP-MSCHAPv2 RFC-draft-kamath-pppext-eap-mschapv2-02 */ + +/* OpCodes for MSCHAPv2 */ +#define CHAP_CHALLENGE 1 +#define CHAP_RESPONSE 2 +#define CHAP_SUCCESS 3 +#define CHAP_FAILURE 4 /* EAP SRP-SHA1 Subtypes */ #define EAPSRP_CHALLENGE 1 /* Request 1 - Challenge */ @@ -84,10 +96,21 @@ eapClosed, /* Authentication not in use */ eapListen, /* Client ready (and timer running) */ eapIdentify, /* EAP Identify sent */ + eapTlsStart, /* Send EAP-TLS start packet */ + eapTlsRecv, /* Receive EAP-TLS tls data */ + eapTlsSendAck, /* Send EAP-TLS ack */ + eapTlsSend, /* Send EAP-TLS tls data */ + eapTlsRecvAck, /* Receive EAP-TLS ack */ + eapTlsRecvClient, /* Receive EAP-TLS auth response from client*/ + eapTlsSendAlert, /* Send EAP-TLS tls alert (server)*/ + eapTlsRecvAlertAck, /* Receive EAP-TLS ack after sending alert */ + eapTlsRecvSuccess, /* Receive EAP success */ + eapTlsRecvFailure, /* Receive EAP failure */ eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */ eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */ eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */ eapMD5Chall, /* Sent MD5-Challenge */ + eapMSCHAPv2Chall, /* Sent MSCHAPv2-Challenge */ eapOpen, /* Completed authentication */ eapSRP4, /* Sent EAP SRP-SHA1 Subtype 4 */ eapBadAuth /* Failed authentication */ @@ -95,9 +118,18 @@ #define EAP_STATES \ "Initial", "Pending", "Closed", "Listen", "Identify", \ - "SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth" + "TlsStart", "TlsRecv", "TlsSendAck", "TlsSend", "TlsRecvAck", "TlsRecvClient",\ + "TlsSendAlert", "TlsRecvAlertAck" , "TlsRecvSuccess", "TlsRecvFailure", \ + "SRP1", "SRP2", "SRP3", "MD5Chall", "MSCHAPv2Chall", "Open", "SRP4", "BadAuth" + +#ifdef USE_EAPTLS +#define eap_client_active(esp) ((esp)->es_client.ea_state != eapInitial &&\ + (esp)->es_client.ea_state != eapPending &&\ + (esp)->es_client.ea_state != eapClosed) +#else +#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen) +#endif /* USE_EAPTLS */ -#define eap_client_active(esp) ((esp)->es_client.ea_state == eapListen) #define eap_server_active(esp) \ ((esp)->es_server.ea_state >= eapIdentify && \ (esp)->es_server.ea_state <= eapMD5Chall) @@ -112,11 +144,20 @@ u_short ea_namelen; /* Length of our name */ u_short ea_peerlen; /* Length of peer's name */ enum eap_state_code ea_state; +#ifdef USE_EAPTLS + enum eap_state_code ea_prev_state; +#endif +#ifdef CHAPMS + struct chap_digest_type *digest; +#endif u_char ea_id; /* Current id */ u_char ea_requests; /* Number of Requests sent/received */ u_char ea_responses; /* Number of Responses */ u_char ea_type; /* One of EAPT_* */ u_int32_t ea_keyflags; /* SRP shared key usage flags */ +#ifdef USE_EAPTLS + bool ea_using_eaptls; +#endif }; /* @@ -139,14 +180,19 @@ * Timeouts. */ #define EAP_DEFTIMEOUT 3 /* Timeout (seconds) for rexmit */ +#ifdef USE_EAPTLS +#define EAP_DEFTRANSMITS 30 /* max # times to transmit */ + /* certificates can be long ... */ +#else #define EAP_DEFTRANSMITS 10 /* max # times to transmit */ +#endif /* USE_EAPTLS */ #define EAP_DEFREQTIME 20 /* Time to wait for peer request */ #define EAP_DEFALLOWREQ 20 /* max # times to accept requests */ extern eap_state eap_states[]; -void eap_authwithpeer __P((int unit, char *localname)); -void eap_authpeer __P((int unit, char *localname)); +void eap_authwithpeer (int unit, char *localname); +void eap_authpeer (int unit, char *localname); extern struct protent eap_protent; diff -Nru ppp-2.4.7/pppd/eap-tls.c ppp-2.4.9/pppd/eap-tls.c --- ppp-2.4.7/pppd/eap-tls.c 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/pppd/eap-tls.c 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,1428 @@ +/* * eap-tls.c - EAP-TLS implementation for PPP + * + * Copyright (c) Beniamino Galvani 2005 All rights reserved. + * Jan Just Keijser 2006-2019 All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "pppd.h" +#include "eap.h" +#include "eap-tls.h" +#include "fsm.h" +#include "lcp.h" +#include "pathnames.h" + +typedef struct pw_cb_data +{ + const void *password; + const char *prompt_info; +} PW_CB_DATA; + +/* 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; + +/* 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 + */ +void eaptls_gen_mppe_keys(struct eaptls_session *ets, int client) +{ + unsigned char out[4*EAPTLS_MPPE_KEY_LEN]; + const char *prf_label; + size_t prf_size; + unsigned char eap_tls13_context[] = { EAPT_TLS }; + unsigned char *context = NULL; + size_t context_len = 0; + unsigned char *p; + + dbglog("EAP-TLS generating MPPE keys"); + if (ets->tls_v13) + { + prf_label = "EXPORTER_EAP_TLS_Key_Material"; + context = eap_tls13_context; + context_len = 1; + } + else + { + prf_label = "client EAP encryption"; + } + + dbglog("EAP-TLS PRF label = %s", prf_label); + prf_size = strlen(prf_label); + if (SSL_export_keying_material(ets->ssl, out, sizeof(out), prf_label, prf_size, + context, context_len, 0) != 1) + { + warn( "EAP-TLS: Failed generating keying material" ); + return; + } + + /* + * We now have the master send and receive keys. + * From these, generate the session send and receive keys. + * (see RFC3079 / draft-ietf-pppext-mppe-keys-03.txt for details) + */ + if (client) + { + p = out; + BCOPY( p, mppe_send_key, sizeof(mppe_send_key) ); + p += EAPTLS_MPPE_KEY_LEN; + BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) ); + } + else + { + p = out; + BCOPY( p, mppe_recv_key, sizeof(mppe_recv_key) ); + p += EAPTLS_MPPE_KEY_LEN; + BCOPY( p, mppe_send_key, sizeof(mppe_send_key) ); + } + + mppe_keys_set = 1; +} + +#endif /* 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) + { + strlcpy (buf, passwd, size); + return strlen (buf); + } + return 0; +} + + +CONF *eaptls_ssl_load_config( void ) +{ + CONF *config; + int ret_code; + long error_line = 33; + + config = NCONF_new( NULL ); + dbglog( "Loading OpenSSL config file" ); + ret_code = NCONF_load( config, _PATH_OPENSSLCONFFILE, &error_line ); + if (ret_code == 0) + { + warn( "EAP-TLS: Error in OpenSSL config file %s at line %d", _PATH_OPENSSLCONFFILE, error_line ); + NCONF_free( config ); + config = NULL; + ERR_clear_error(); + } + + dbglog( "Loading OpenSSL built-ins" ); + ENGINE_load_builtin_engines(); + OPENSSL_load_builtin_modules(); + + dbglog( "Loading OpenSSL configured modules" ); + if (CONF_modules_load( config, NULL, 0 ) <= 0 ) + { + warn( "EAP-TLS: Error loading OpenSSL modules" ); + log_ssl_errors(); + config = NULL; + } + + return config; +} + +ENGINE *eaptls_ssl_load_engine( char *engine_name ) +{ + ENGINE *e = NULL; + + dbglog( "Enabling OpenSSL auto engines" ); + ENGINE_register_all_complete(); + + dbglog( "Loading OpenSSL '%s' engine support", engine_name ); + e = ENGINE_by_id( engine_name ); + if (!e) + { + dbglog( "EAP-TLS: Cannot load '%s' engine support, trying 'dynamic'", engine_name ); + e = ENGINE_by_id( "dynamic" ); + if (e) + { + if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", engine_name, 0) + || !ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) + { + warn( "EAP-TLS: Error loading dynamic engine '%s'", engine_name ); + log_ssl_errors(); + ENGINE_free(e); + e = NULL; + } + } + else + { + warn( "EAP-TLS: Cannot load dynamic engine support" ); + } + } + + if (e) + { + dbglog( "Initialising engine" ); + if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) + { + warn( "EAP-TLS: Cannot use that engine" ); + log_ssl_errors(); + ENGINE_free(e); + e = NULL; + } + } + + return e; +} + + + +/* + * Initialize the SSL stacks and tests if certificates, key and crl + * for client or server use can be loaded. + */ +SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath, + char *certfile, char *peer_certfile, char *privkeyfile) +{ + char *cert_engine_name = NULL; + char *cert_identifier = NULL; + char *pkey_engine_name = NULL; + char *pkey_identifier = NULL; + SSL_CTX *ctx; + SSL *ssl; + X509_STORE *certstore; + X509_LOOKUP *lookup; + X509 *tmp; + 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 + + /* + * Without these can't continue + */ + 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 (!privkeyfile[0]) + { + error("EAP-TLS: Private key missing"); + return NULL; + } + + SSL_library_init(); + SSL_load_error_strings(); + + /* 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(); + + ctx = SSL_CTX_new(TLS_method()); + + if (!ctx) { + error("EAP-TLS: Cannot initialize SSL CTX context"); + goto fail; + } + + /* if the certificate filename is of the form engine:id. e.g. + pkcs11:12345 + then we try to load and use this engine. + If the certificate filename starts with a / or . then we + ALWAYS assume it is a file and not an engine/pkcs11 identifier + */ + if ( index( certfile, '/' ) == NULL && index( certfile, '.') == NULL ) + { + cert_identifier = index( certfile, ':' ); + + if (cert_identifier) + { + cert_engine_name = certfile; + *cert_identifier = '\0'; + cert_identifier++; + + dbglog( "Found certificate engine '%s'", cert_engine_name ); + dbglog( "Found certificate identifier '%s'", cert_identifier ); + } + } + + /* if the privatekey filename is of the form engine:id. e.g. + pkcs11:12345 + then we try to load and use this engine. + If the privatekey filename starts with a / or . then we + ALWAYS assume it is a file and not an engine/pkcs11 identifier + */ + if ( index( privkeyfile, '/' ) == NULL && index( privkeyfile, '.') == NULL ) + { + pkey_identifier = index( privkeyfile, ':' ); + + if (pkey_identifier) + { + pkey_engine_name = privkeyfile; + *pkey_identifier = '\0'; + pkey_identifier++; + + dbglog( "Found privatekey engine '%s'", pkey_engine_name ); + dbglog( "Found privatekey identifier '%s'", pkey_identifier ); + } + } + + if (cert_identifier && pkey_identifier) + { + if (strlen( cert_identifier ) == 0) + { + if (strlen( pkey_identifier ) == 0) + error( "EAP-TLS: both the certificate and privatekey identifiers are missing!" ); + else + { + dbglog( "Substituting privatekey identifier for certificate identifier" ); + cert_identifier = pkey_identifier; + } + } + else + { + if (strlen( pkey_identifier ) == 0) + { + dbglog( "Substituting certificate identifier for privatekey identifier" ); + pkey_identifier = cert_identifier; + } + } + } + + if (ssl_config && cert_engine_name) + cert_engine = eaptls_ssl_load_engine( cert_engine_name ); + + if (ssl_config && pkey_engine_name) + { + /* don't load the same engine twice */ + if ( cert_engine && strcmp( cert_engine_name, pkey_engine_name) == 0 ) + pkey_engine = cert_engine; + else + pkey_engine = eaptls_ssl_load_engine( pkey_engine_name ); + } + + SSL_CTX_set_default_passwd_cb (ctx, password_callback); + + if (strlen(cacertfile) == 0) cacertfile = NULL; + if (strlen(capath) == 0) capath = NULL; + + 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); + goto fail; + } + + if (init_server) + SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(cacertfile)); + + if (cert_engine) + { + struct + { + const char *s_slot_cert_id; + X509 *cert; + } cert_info; + + cert_info.s_slot_cert_id = cert_identifier; + cert_info.cert = NULL; + + if (!ENGINE_ctrl_cmd( cert_engine, "LOAD_CERT_CTRL", 0, &cert_info, NULL, 0 ) ) + { + error( "EAP-TLS: Error loading certificate with id '%s' from engine", cert_identifier ); + goto fail; + } + + if (cert_info.cert) + { + dbglog( "Got the certificate, adding it to SSL context" ); + dbglog( "subject = %s", X509_NAME_oneline( X509_get_subject_name( cert_info.cert ), NULL, 0 ) ); + if (SSL_CTX_use_certificate(ctx, cert_info.cert) <= 0) + { + error("EAP-TLS: Cannot use PKCS11 certificate %s", cert_identifier); + goto fail; + } + } + else + { + warn("EAP-TLS: Cannot load PKCS11 key %s", cert_identifier); + log_ssl_errors(); + } + } + else + { + if (!SSL_CTX_use_certificate_chain_file(ctx, certfile)) + { + error( "EAP-TLS: Cannot use public certificate %s", certfile ); + goto fail; + } + } + + + /* + * Check the Before and After dates of the certificate + */ + ssl = SSL_new(ctx); + tmp = SSL_get_certificate(ssl); + + ret = X509_cmp_time(X509_get_notBefore(tmp), NULL); + if (ret == 0) + { + warn( "EAP-TLS: Failed to read certificate notBefore field."); + } + if (ret > 0) + { + warn( "EAP-TLS: Your certificate is not yet valid!"); + } + + ret = X509_cmp_time(X509_get_notAfter(tmp), NULL); + if (ret == 0) + { + warn( "EAP-TLS: Failed to read certificate notAfter field."); + } + if (ret < 0) + { + warn( "EAP-TLS: Your certificate has expired!"); + } + SSL_free(ssl); + + if (pkey_engine) + { + EVP_PKEY *pkey = NULL; + PW_CB_DATA cb_data; + + cb_data.password = passwd; + cb_data.prompt_info = pkey_identifier; + + 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); + + 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); + } + if (pkey) + { + dbglog( "Got the private key, adding it to SSL context" ); + if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0) + { + error("EAP-TLS: Cannot use PKCS11 key %s", pkey_identifier); + goto fail; + } + } + else + { + warn("EAP-TLS: Cannot load PKCS11 key %s", pkey_identifier); + log_ssl_errors(); + } + } + else + { + if (!SSL_CTX_use_PrivateKey_file(ctx, privkeyfile, SSL_FILETYPE_PEM)) + { + error("EAP-TLS: Cannot use private key %s", privkeyfile); + goto fail; + } + } + + if (SSL_CTX_check_private_key(ctx) != 1) { + error("EAP-TLS: Private key %s fails security check", privkeyfile); + goto fail; + } + + /* Explicitly set the NO_TICKETS flag to support Win7/Win8 clients */ + SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 +#ifdef SSL_OP_NO_TICKET + | SSL_OP_NO_TICKET +#endif + ); + + /* 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"); + */ + + + /* 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 + * that the handshake is finished, even before the client has sent its + * credentials to the server. The actual connection (and moment that the + * client sends its credentials) only starts after the arrival of the first + * session ticket. The 'ssl_new_session_cb' catches this ticket. + */ + 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"); + + goto fail; + } + + X509_LOOKUP_add_dir(lookup, crl_dir, X509_FILETYPE_PEM); + X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK); + } + + if (crl_file) { + FILE *fp = NULL; + X509_CRL *crl = NULL; + + fp = fopen(crl_file, "r"); + if (!fp) { + error("EAP-TLS: Cannot open CRL file '%s'", crl_file); + goto fail; + } + + crl = PEM_read_X509_CRL(fp, NULL, NULL, NULL); + if (!crl) { + error("EAP-TLS: Cannot read CRL file '%s'", crl_file); + goto fail; + } + + if (!(certstore = SSL_CTX_get_cert_store(ctx))) { + error("EAP-TLS: Failed to get certificate store"); + goto fail; + } + if (!X509_STORE_add_crl(certstore, crl)) { + error("EAP-TLS: Cannot add CRL to certificate store"); + goto fail; + } + X509_STORE_set_flags(certstore, X509_V_FLAG_CRL_CHECK); + + } + + /* + * If a peer certificate file was specified, it must be valid, else fail + */ + if (peer_certfile[0]) { + if (!(tmp = get_X509_from_file(peer_certfile))) { + error("EAP-TLS: Error loading client certificate from file %s", + peer_certfile); + goto fail; + } + X509_free(tmp); + } + + return ctx; + +fail: + log_ssl_errors(); + SSL_CTX_free(ctx); + return NULL; +} + +/* + * Determine the maximum packet size by looking at the LCP handshake + */ + +int eaptls_get_mtu(int unit) +{ + int mtu, mru; + + lcp_options *wo = &lcp_wantoptions[unit]; + lcp_options *go = &lcp_gotoptions[unit]; + lcp_options *ho = &lcp_hisoptions[unit]; + lcp_options *ao = &lcp_allowoptions[unit]; + + mtu = ho->neg_mru? ho->mru: PPP_MRU; + mru = go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU; + mtu = MIN(MIN(mtu, mru), ao->mru)- PPP_HDRLEN - 10; + + dbglog("MTU = %d", mtu); + return mtu; +} + + +/* + * Init the ssl handshake (server mode) + */ +int eaptls_init_ssl_server(eap_state * esp) +{ + struct eaptls_session *ets; + char servcertfile[MAXWORDLEN]; + char clicertfile[MAXWORDLEN]; + char cacertfile[MAXWORDLEN]; + char capath[MAXWORDLEN]; + char pkfile[MAXWORDLEN]; + /* + * Allocate new eaptls session + */ + esp->es_server.ea_session = malloc(sizeof(struct eaptls_session)); + if (!esp->es_server.ea_session) + fatal("Allocation error"); + ets = esp->es_server.ea_session; + + if (!esp->es_server.ea_peer) { + error("EAP-TLS: Error: client name not set (BUG)"); + return 0; + } + + 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)) { + 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); + if (!ets->ctx) + goto fail; + + if (!(ets->ssl = SSL_new(ets->ctx))) + goto fail; + + /* + * Set auto-retry to avoid timeouts on BIO_read + */ + SSL_set_mode(ets->ssl, SSL_MODE_AUTO_RETRY); + + /* + * Initialize the BIOs we use to read/write to ssl engine + */ + ets->into_ssl = BIO_new(BIO_s_mem()); + ets->from_ssl = BIO_new(BIO_s_mem()); + SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl); + + SSL_set_msg_callback(ets->ssl, ssl_msg_callback); + SSL_set_msg_callback_arg(ets->ssl, ets); + + /* + * Attach the session struct to the connection, so we can later + * retrieve it when doing certificate verification + */ + SSL_set_ex_data(ets->ssl, 0, ets); + + SSL_set_accept_state(ets->ssl); + + ets->tls_v13 = 0; + + ets->data = NULL; + ets->datalen = 0; + ets->alert_sent = 0; + ets->alert_recv = 0; + + /* + * If we specified the client certificate file, store it in ets->peercertfile, + * so we can check it later in ssl_verify_callback() + */ + if (clicertfile[0]) + strlcpy(&ets->peercertfile[0], clicertfile, MAXWORDLEN); + else + ets->peercertfile[0] = 0; + + return 1; + +fail: + SSL_CTX_free(ets->ctx); + return 0; +} + +/* + * Init the ssl handshake (client mode) + */ +int eaptls_init_ssl_client(eap_state * esp) +{ + struct eaptls_session *ets; + char servcertfile[MAXWORDLEN]; + char clicertfile[MAXWORDLEN]; + char cacertfile[MAXWORDLEN]; + char capath[MAXWORDLEN]; + char pkfile[MAXWORDLEN]; + + /* + * Allocate new eaptls session + */ + esp->es_client.ea_session = malloc(sizeof(struct eaptls_session)); + if (!esp->es_client.ea_session) + fatal("Allocation error"); + ets = esp->es_client.ea_session; + + /* + * If available, copy server name in ets; it will be used in cert + * verify + */ + if (esp->es_client.ea_peer) + 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)) { + error( "EAP-TLS: Cannot get secret/password for client \"%s\", server \"%s\"", + esp->es_client.ea_name, ets->peer ); + return 0; + } + + dbglog( "calling eaptls_init_ssl" ); + ets->ctx = eaptls_init_ssl(0, cacertfile, capath, clicertfile, servcertfile, pkfile); + if (!ets->ctx) + goto fail; + + ets->ssl = SSL_new(ets->ctx); + + if (!ets->ssl) + goto fail; + + /* + * Initialize the BIOs we use to read/write to ssl engine + */ + dbglog( "Initializing SSL BIOs" ); + ets->into_ssl = BIO_new(BIO_s_mem()); + ets->from_ssl = BIO_new(BIO_s_mem()); + SSL_set_bio(ets->ssl, ets->into_ssl, ets->from_ssl); + + SSL_set_msg_callback(ets->ssl, ssl_msg_callback); + SSL_set_msg_callback_arg(ets->ssl, ets); + + /* + * Attach the session struct to the connection, so we can later + * retrieve it when doing certificate verification + */ + SSL_set_ex_data(ets->ssl, 0, ets); + + SSL_set_connect_state(ets->ssl); + + ets->tls_v13 = 0; + + ets->data = NULL; + ets->datalen = 0; + ets->alert_sent = 0; + ets->alert_recv = 0; + + /* + * If we specified the server certificate file, store it in + * ets->peercertfile, so we can check it later in + * ssl_verify_callback() + */ + if (servcertfile[0]) + strlcpy(ets->peercertfile, servcertfile, MAXWORDLEN); + else + ets->peercertfile[0] = 0; + + return 1; + +fail: + dbglog( "eaptls_init_ssl_client: fail" ); + SSL_CTX_free(ets->ctx); + return 0; + +} + +void eaptls_free_session(struct eaptls_session *ets) +{ + if (ets->ssl) + SSL_free(ets->ssl); + + if (ets->ctx) + SSL_CTX_free(ets->ctx); + + free(ets); +} + + +int eaptls_is_init_finished(struct eaptls_session *ets) +{ + if (ets->ssl && SSL_is_init_finished(ets->ssl)) + { + if (ets->tls_v13) + return have_session_ticket; + else + return 1; + } + + return 0; +} + +/* + * Handle a received packet, reassembling fragmented messages and + * passing them to the ssl engine + */ +int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len) +{ + u_char flags; + u_int tlslen = 0; + u_char dummy[65536]; + + if (len < 1) { + warn("EAP-TLS: received no or invalid data"); + return 1; + } + + GETCHAR(flags, inp); + len--; + + if (flags & EAP_TLS_FLAGS_LI && len > 4) { + /* + * LenghtIncluded flag set -> this is the first packet of a message + */ + + /* + * the first 4 octets are the length of the EAP-TLS message + */ + GETLONG(tlslen, inp); + len -= 4; + + if (!ets->data) { + + if (tlslen > EAP_TLS_MAX_LEN) { + error("EAP-TLS: TLS message length > %d, truncated", EAP_TLS_MAX_LEN); + tlslen = EAP_TLS_MAX_LEN; + } + + /* + * Allocate memory for the whole message + */ + ets->data = malloc(tlslen); + if (!ets->data) + fatal("EAP-TLS: allocation error\n"); + + ets->datalen = 0; + ets->tlslen = tlslen; + } + else + warn("EAP-TLS: non-first LI packet? that's odd..."); + } + else if (!ets->data) { + /* + * A non fragmented message without LI flag + */ + + ets->data = malloc(len); + if (!ets->data) + fatal("EAP-TLS: memory allocation error in eaptls_receive\n"); + + ets->datalen = 0; + ets->tlslen = len; + } + + if (flags & EAP_TLS_FLAGS_MF) + ets->frag = 1; + else + ets->frag = 0; + + if (len < 0) { + warn("EAP-TLS: received malformed data"); + return 1; + } + + if (len + ets->datalen > ets->tlslen) { + warn("EAP-TLS: received data > TLS message length"); + return 1; + } + + BCOPY(inp, ets->data + ets->datalen, len); + ets->datalen += len; + + if (!ets->frag) { + + /* + * If we have the whole message, pass it to ssl + */ + + if (ets->datalen != ets->tlslen) { + warn("EAP-TLS: received data != TLS message length"); + return 1; + } + + if (BIO_write(ets->into_ssl, ets->data, ets->datalen) == -1) + log_ssl_errors(); + + SSL_read(ets->ssl, dummy, 65536); + + free(ets->data); + ets->data = NULL; + ets->datalen = 0; + } + + return 0; +} + +/* + * Return an eap-tls packet in outp. + * A TLS message read from the ssl engine is buffered in ets->data. + * At each call we control if there is buffered data and send a + * packet of mtu bytes. + */ +int eaptls_send(struct eaptls_session *ets, u_char ** outp) +{ + bool first = 0; + int size; + u_char fromtls[65536]; + int res; + u_char *start; + + start = *outp; + + if (!ets->data) + { + if(!ets->alert_sent) + { + res = SSL_read(ets->ssl, fromtls, 65536); + } + + /* + * Read from ssl + */ + if ((res = BIO_read(ets->from_ssl, fromtls, 65536)) == -1) + { + warn("EAP-TLS send: No data from BIO_read"); + return 1; + } + + ets->datalen = res; + + ets->data = malloc(ets->datalen); + if (!ets->data) + fatal("EAP-TLS: memory allocation error in eaptls_send\n"); + + BCOPY(fromtls, ets->data, ets->datalen); + + ets->offset = 0; + first = 1; + } + + size = ets->datalen - ets->offset; + + if (size > ets->mtu) { + size = ets->mtu; + ets->frag = 1; + } else + ets->frag = 0; + + PUTCHAR(EAPT_TLS, *outp); + + /* + * Set right flags and length if necessary + */ + if (ets->frag && first) { + PUTCHAR(EAP_TLS_FLAGS_LI | EAP_TLS_FLAGS_MF, *outp); + PUTLONG(ets->datalen, *outp); + } else if (ets->frag) { + PUTCHAR(EAP_TLS_FLAGS_MF, *outp); + } else + PUTCHAR(0, *outp); + + /* + * Copy the data in outp + */ + BCOPY(ets->data + ets->offset, *outp, size); + INCPTR(size, *outp); + + /* + * Copy the packet in retransmission buffer + */ + BCOPY(start, &ets->rtx[0], *outp - start); + ets->rtx_len = *outp - start; + + ets->offset += size; + + if (ets->offset >= ets->datalen) { + + /* + * The whole message has been sent + */ + + free(ets->data); + ets->data = NULL; + ets->datalen = 0; + ets->offset = 0; + } + + return 0; +} + +/* + * Get the sent packet from the retransmission buffer + */ +void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp) +{ + BCOPY(ets->rtx, *outp, ets->rtx_len); + INCPTR(ets->rtx_len, *outp); +} + +/* + * Verify a certificate. + * Most of the work (signatures and issuer attributes checking) + * is done by ssl; we check the CN in the peer certificate + * against the peer name. + */ +int ssl_verify_callback(int 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 + * we can print debug information about TLS handshake. + */ +void +ssl_msg_callback(int write_p, int version, int content_type, + const void *buf, size_t len, SSL * ssl, void *arg) +{ + char string[256]; + struct eaptls_session *ets = (struct eaptls_session *)arg; + unsigned char code; + const unsigned char*msg = buf; + int hvers = msg[1] << 8 | msg[2]; + + if(write_p) + strcpy(string, " -> "); + else + strcpy(string, " <- "); + + switch(content_type) { + + case SSL3_RT_HEADER: + strcat(string, "SSL/TLS Header: "); + switch(hvers) { + case SSL3_VERSION: + strcat(string, "SSL 3.0"); + break; + case TLS1_VERSION: + strcat(string, "TLS 1.0"); + break; + case TLS1_1_VERSION: + strcat(string, "TLS 1.1"); + break; + case TLS1_2_VERSION: + strcat(string, "TLS 1.2"); + break; + default: + sprintf(string, "SSL/TLS Header: Unknown version (%d)", hvers); + } + break; + + case SSL3_RT_ALERT: + strcat(string, "Alert: "); + code = msg[1]; + + if (write_p) { + ets->alert_sent = 1; + ets->alert_sent_desc = code; + } else { + ets->alert_recv = 1; + ets->alert_recv_desc = code; + } + + strcat(string, SSL_alert_desc_string_long(code)); + break; + + case SSL3_RT_CHANGE_CIPHER_SPEC: + strcat(string, "ChangeCipherSpec"); + break; + +#ifdef SSL3_RT_INNER_CONTENT_TYPE + case SSL3_RT_INNER_CONTENT_TYPE: + strcat(string, "InnerContentType (TLS1.3)"); + break; +#endif + + case SSL3_RT_HANDSHAKE: + + strcat(string, "Handshake: "); + code = msg[0]; + + switch(code) { + case SSL3_MT_HELLO_REQUEST: + strcat(string,"Hello Request"); + break; + case SSL3_MT_CLIENT_HELLO: + strcat(string,"Client Hello"); + break; + case SSL3_MT_SERVER_HELLO: + strcat(string,"Server Hello"); + break; +#ifdef SSL3_MT_NEWSESSION_TICKET + case SSL3_MT_NEWSESSION_TICKET: + strcat(string,"New Session Ticket"); + break; +#endif +#ifdef SSL3_MT_END_OF_EARLY_DATA + case SSL3_MT_END_OF_EARLY_DATA: + strcat(string,"End of Early Data"); + break; +#endif +#ifdef SSL3_MT_ENCRYPTED_EXTENSIONS + case SSL3_MT_ENCRYPTED_EXTENSIONS: + strcat(string,"Encryped Extensions"); + break; +#endif + case SSL3_MT_CERTIFICATE: + strcat(string,"Certificate"); + break; + case SSL3_MT_SERVER_KEY_EXCHANGE: + strcat(string,"Server Key Exchange"); + break; + case SSL3_MT_CERTIFICATE_REQUEST: + strcat(string,"Certificate Request"); + break; + case SSL3_MT_SERVER_DONE: + strcat(string,"Server Hello Done"); + break; + case SSL3_MT_CERTIFICATE_VERIFY: + strcat(string,"Certificate Verify"); + break; + case SSL3_MT_CLIENT_KEY_EXCHANGE: + strcat(string,"Client Key Exchange"); + break; + case SSL3_MT_FINISHED: + strcat(string,"Finished: "); + hvers = SSL_version(ssl); + switch(hvers){ + case SSL3_VERSION: + strcat(string, "SSL 3.0"); + break; + case TLS1_VERSION: + strcat(string, "TLS 1.0"); + break; + case TLS1_1_VERSION: + strcat(string, "TLS 1.1"); + break; + case TLS1_2_VERSION: + strcat(string, "TLS 1.2"); + break; +#ifdef TLS1_3_VERSION + case TLS1_3_VERSION: + strcat(string, "TLS 1.3 (experimental)"); + ets->tls_v13 = 1; + break; +#endif + default: + strcat(string, "Unknown version"); + } + break; + default: + sprintf( string, "Handshake: Unknown SSL3 code received: %d", code ); + } + break; + + default: + sprintf( string, "SSL message contains unknown content type: %d", content_type ); + } + + /* Alert messages must always be displayed */ + if(content_type == SSL3_RT_ALERT) + error("%s", string); + else + dbglog("%s", string); +} + +int +ssl_new_session_cb(SSL *s, SSL_SESSION *sess) +{ + dbglog("EAP-TLS: Post-Handshake New Session Ticket arrived:"); + have_session_ticket = 1; + + /* always return success */ + return 1; +} + diff -Nru ppp-2.4.7/pppd/eap-tls.h ppp-2.4.9/pppd/eap-tls.h --- ppp-2.4.7/pppd/eap-tls.h 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/pppd/eap-tls.h 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,96 @@ +/* + * eap-tls.h + * + * Copyright (c) Beniamino Galvani 2005 All rights reserved. + * Jan Just Keijser 2006-2019 All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name(s) of the authors of this software must not be used to + * endorse or promote products derived from this software without + * prior written permission. + * + * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +#ifndef __EAP_TLS_H__ +#define __EAP_TLS_H__ + +#include "eap.h" + +#include +#include + +#define EAP_TLS_FLAGS_LI 128 /* length included flag */ +#define EAP_TLS_FLAGS_MF 64 /* more fragments flag */ +#define EAP_TLS_FLAGS_START 32 /* start flag */ + +#define EAP_TLS_MAX_LEN 65536 /* max eap tls packet size */ + +struct eaptls_session +{ + u_char *data; /* buffered data */ + int datalen; /* buffered data len */ + int offset; /* from where to send */ + int tlslen; /* total length of tls data */ + bool frag; /* packet is fragmented */ + bool tls_v13; /* whether we've negotiated TLSv1.3 */ + SSL_CTX *ctx; + SSL *ssl; /* ssl connection */ + BIO *from_ssl; + BIO *into_ssl; + char peer[MAXWORDLEN]; /* peer name */ + char peercertfile[MAXWORDLEN]; + bool alert_sent; + u_char alert_sent_desc; + bool alert_recv; + u_char alert_recv_desc; + char rtx[EAP_TLS_MAX_LEN]; /* retransmission buffer */ + int rtx_len; + int mtu; /* unit mtu */ +}; + + +SSL_CTX *eaptls_init_ssl(int init_server, char *cacertfile, char *capath, + char *certfile, char *peer_certfile, char *privkeyfile); +int eaptls_init_ssl_server(eap_state * esp); +int eaptls_init_ssl_client(eap_state * esp); +void eaptls_free_session(struct eaptls_session *ets); + +int eaptls_is_init_finished(struct eaptls_session *ets); + +int eaptls_receive(struct eaptls_session *ets, u_char * inp, int len); +int eaptls_send(struct eaptls_session *ets, u_char ** outp); +void eaptls_retransmit(struct eaptls_session *ets, u_char ** outp); + +int get_eaptls_secret(int unit, char *client, char *server, + char *clicertfile, char *servcertfile, char *cacertfile, + char *capath, char *pkfile, int am_server); + +#ifdef MPPE +#include "mppe.h" /* MPPE_MAX_KEY_LEN */ +extern u_char mppe_send_key[MPPE_MAX_KEY_LEN]; +extern u_char mppe_recv_key[MPPE_MAX_KEY_LEN]; +extern int mppe_keys_set; + +void eaptls_gen_mppe_keys(struct eaptls_session *ets, int client); +#endif + +#endif diff -Nru ppp-2.4.7/pppd/ecp.c ppp-2.4.9/pppd/ecp.c --- ppp-2.4.7/pppd/ecp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/ecp.c 2021-01-05 00:06:37.000000000 +0100 @@ -57,10 +57,6 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: ecp.c,v 1.4 2004/11/04 10:02:26 paulus Exp $" - -static const char rcsid[] = RCSID; - #include #include "pppd.h" @@ -79,20 +75,20 @@ /* * Protocol entry points from main code. */ -static void ecp_init __P((int unit)); +static void ecp_init (int unit); /* -static void ecp_open __P((int unit)); -static void ecp_close __P((int unit, char *)); -static void ecp_lowerup __P((int unit)); -static void ecp_lowerdown __P((int)); -static void ecp_input __P((int unit, u_char *pkt, int len)); -static void ecp_protrej __P((int unit)); +static void ecp_open (int unit); +static void ecp_close (int unit, char *); +static void ecp_lowerup (int unit); +static void ecp_lowerdown (int); +static void ecp_input (int unit, u_char *pkt, int len); +static void ecp_protrej (int unit); */ -static int ecp_printpkt __P((u_char *pkt, int len, - void (*printer) __P((void *, char *, ...)), - void *arg)); +static int ecp_printpkt (u_char *pkt, int len, + void (*printer)(void *, char *, ...), + void *arg); /* -static void ecp_datainput __P((int unit, u_char *pkt, int len)); +static void ecp_datainput (int unit, u_char *pkt, int len); */ struct protent ecp_protent = { @@ -143,8 +139,7 @@ * ecp_init - initialize ECP. */ static void -ecp_init(unit) - int unit; +ecp_init(int unit) { fsm *f = &ecp_fsm[unit]; @@ -162,11 +157,8 @@ static int -ecp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; +ecp_printpkt(u_char *p, int plen, + void (*printer)(void *, char *, ...), void *arg) { return 0; } diff -Nru ppp-2.4.7/pppd/eui64.c ppp-2.4.9/pppd/eui64.c --- ppp-2.4.7/pppd/eui64.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/eui64.c 2021-01-05 00:06:37.000000000 +0100 @@ -32,21 +32,16 @@ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: eui64.c,v 1.6 2002/12/04 23:03:32 paulus Exp $ */ -#define RCSID "$Id: eui64.c,v 1.6 2002/12/04 23:03:32 paulus Exp $" - #include "pppd.h" -static const char rcsid[] = RCSID; /* * eui64_ntoa - Make an ascii representation of an interface identifier */ char * -eui64_ntoa(e) - eui64_t e; +eui64_ntoa(eui64_t e) { static char buf[32]; diff -Nru ppp-2.4.7/pppd/eui64.h ppp-2.4.9/pppd/eui64.h --- ppp-2.4.7/pppd/eui64.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/eui64.h 2021-01-05 00:06:37.000000000 +0100 @@ -32,8 +32,7 @@ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: eui64.h,v 1.6 2002/12/04 23:03:32 paulus Exp $ -*/ + */ #ifndef __EUI64_H__ #define __EUI64_H__ @@ -108,7 +107,7 @@ } while (0) #define eui64_setlo32(e, l) eui64_set32(e, l) -char *eui64_ntoa __P((eui64_t)); /* Returns ascii representation of id */ +char *eui64_ntoa(eui64_t); /* Returns ascii representation of id */ #endif /* __EUI64_H__ */ diff -Nru ppp-2.4.7/pppd/fsm.c ppp-2.4.9/pppd/fsm.c --- ppp-2.4.7/pppd/fsm.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/fsm.c 2021-01-05 00:06:37.000000000 +0100 @@ -40,8 +40,6 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: fsm.c,v 1.23 2004/11/13 02:28:15 paulus Exp $" - /* * TODO: * Randomize fsm id on link/init. @@ -55,16 +53,15 @@ #include "pppd.h" #include "fsm.h" -static const char rcsid[] = RCSID; -static void fsm_timeout __P((void *)); -static void fsm_rconfreq __P((fsm *, int, u_char *, int)); -static void fsm_rconfack __P((fsm *, int, u_char *, int)); -static void fsm_rconfnakrej __P((fsm *, int, int, u_char *, int)); -static void fsm_rtermreq __P((fsm *, int, u_char *, int)); -static void fsm_rtermack __P((fsm *)); -static void fsm_rcoderej __P((fsm *, u_char *, int)); -static void fsm_sconfreq __P((fsm *, int)); +static void fsm_timeout (void *); +static void fsm_rconfreq (fsm *, int, u_char *, int); +static void fsm_rconfack (fsm *, int, u_char *, int); +static void fsm_rconfnakrej (fsm *, int, int, u_char *, int); +static void fsm_rtermreq (fsm *, int, u_char *, int); +static void fsm_rtermack (fsm *); +static void fsm_rcoderej (fsm *, u_char *, int); +static void fsm_sconfreq (fsm *, int); #define PROTO_NAME(f) ((f)->callbacks->proto_name) @@ -77,8 +74,7 @@ * Initialize fsm state. */ void -fsm_init(f) - fsm *f; +fsm_init(fsm *f) { f->state = INITIAL; f->flags = 0; @@ -95,8 +91,7 @@ * fsm_lowerup - The lower layer is up. */ void -fsm_lowerup(f) - fsm *f; +fsm_lowerup(fsm *f) { switch( f->state ){ case INITIAL: @@ -125,8 +120,7 @@ * Cancel all timeouts and inform upper layers. */ void -fsm_lowerdown(f) - fsm *f; +fsm_lowerdown(fsm *f) { switch( f->state ){ case CLOSED: @@ -168,8 +162,7 @@ * fsm_open - Link is allowed to come up. */ void -fsm_open(f) - fsm *f; +fsm_open(fsm *f) { switch( f->state ){ case INITIAL: @@ -208,9 +201,7 @@ * send a terminate-request message as configured. */ static void -terminate_layer(f, nextstate) - fsm *f; - int nextstate; +terminate_layer(fsm *f, int nextstate) { if( f->state != OPENED ) UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ @@ -247,9 +238,7 @@ * the CLOSED state. */ void -fsm_close(f, reason) - fsm *f; - char *reason; +fsm_close(fsm *f, char *reason) { f->term_reason = reason; f->term_reason_len = (reason == NULL? 0: strlen(reason)); @@ -278,8 +267,7 @@ * fsm_timeout - Timeout expired. */ static void -fsm_timeout(arg) - void *arg; +fsm_timeout(void *arg) { fsm *f = (fsm *) arg; @@ -331,10 +319,7 @@ * fsm_input - Input packet. */ void -fsm_input(f, inpacket, l) - fsm *f; - u_char *inpacket; - int l; +fsm_input(fsm *f, u_char *inpacket, int l) { u_char *inp; u_char code, id; @@ -410,11 +395,7 @@ * fsm_rconfreq - Receive Configure-Request. */ static void -fsm_rconfreq(f, id, inp, len) - fsm *f; - u_char id; - u_char *inp; - int len; +fsm_rconfreq(fsm *f, int id, u_char *inp, int len) { int code, reject_if_disagree; @@ -468,7 +449,7 @@ f->nakloops = 0; } else { - /* we sent CONFACK or CONFREJ */ + /* we sent CONFNAK or CONFREJ */ if (f->state != ACKRCVD) f->state = REQSENT; if( code == CONFNAK ) @@ -481,11 +462,7 @@ * fsm_rconfack - Receive Configure-Ack. */ static void -fsm_rconfack(f, id, inp, len) - fsm *f; - int id; - u_char *inp; - int len; +fsm_rconfack(fsm *f, int id, u_char *inp, int len) { if (id != f->reqid || f->seen_ack) /* Expected id? */ return; /* Nope, toss... */ @@ -539,11 +516,7 @@ * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. */ static void -fsm_rconfnakrej(f, code, id, inp, len) - fsm *f; - int code, id; - u_char *inp; - int len; +fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) { int ret; int treat_as_reject; @@ -608,11 +581,7 @@ * fsm_rtermreq - Receive Terminate-Req. */ static void -fsm_rtermreq(f, id, p, len) - fsm *f; - int id; - u_char *p; - int len; +fsm_rtermreq(fsm *f, int id, u_char *p, int len) { switch (f->state) { case ACKRCVD: @@ -641,8 +610,7 @@ * fsm_rtermack - Receive Terminate-Ack. */ static void -fsm_rtermack(f) - fsm *f; +fsm_rtermack(fsm *f) { switch (f->state) { case CLOSING: @@ -676,10 +644,7 @@ * fsm_rcoderej - Receive an Code-Reject. */ static void -fsm_rcoderej(f, inp, len) - fsm *f; - u_char *inp; - int len; +fsm_rcoderej(fsm *f, u_char *inp, int len) { u_char code, id; @@ -702,8 +667,7 @@ * Treat this as a catastrophic error (RXJ-). */ void -fsm_protreject(f) - fsm *f; +fsm_protreject(fsm *f) { switch( f->state ){ case CLOSING: @@ -742,9 +706,7 @@ * fsm_sconfreq - Send a Configure-Request. */ static void -fsm_sconfreq(f, retransmit) - fsm *f; - int retransmit; +fsm_sconfreq(fsm *f, int retransmit) { u_char *outp; int cilen; @@ -793,11 +755,7 @@ * Used for all packets sent to our peer by this module. */ void -fsm_sdata(f, code, id, data, datalen) - fsm *f; - u_char code, id; - u_char *data; - int datalen; +fsm_sdata(fsm *f, int code, int id, u_char *data, int datalen) { u_char *outp; int outlen; diff -Nru ppp-2.4.7/pppd/fsm.h ppp-2.4.9/pppd/fsm.h --- ppp-2.4.7/pppd/fsm.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/fsm.h 2021-01-05 00:06:37.000000000 +0100 @@ -85,34 +85,26 @@ typedef struct fsm_callbacks { - void (*resetci) /* Reset our Configuration Information */ - __P((fsm *)); - int (*cilen) /* Length of our Configuration Information */ - __P((fsm *)); + void (*resetci)(fsm *); /* Reset our Configuration Information */ + int (*cilen)(fsm *); /* Length of our Configuration Information */ void (*addci) /* Add our Configuration Information */ - __P((fsm *, u_char *, int *)); + (fsm *, u_char *, int *); int (*ackci) /* ACK our Configuration Information */ - __P((fsm *, u_char *, int)); + (fsm *, u_char *, int); int (*nakci) /* NAK our Configuration Information */ - __P((fsm *, u_char *, int, int)); + (fsm *, u_char *, int, int); int (*rejci) /* Reject our Configuration Information */ - __P((fsm *, u_char *, int)); + (fsm *, u_char *, int); int (*reqci) /* Request peer's Configuration Information */ - __P((fsm *, u_char *, int *, int)); - void (*up) /* Called when fsm reaches OPENED state */ - __P((fsm *)); - void (*down) /* Called when fsm leaves OPENED state */ - __P((fsm *)); - void (*starting) /* Called when we want the lower layer */ - __P((fsm *)); - void (*finished) /* Called when we don't want the lower layer */ - __P((fsm *)); - void (*protreject) /* Called when Protocol-Reject received */ - __P((int)); - void (*retransmit) /* Retransmission is necessary */ - __P((fsm *)); + (fsm *, u_char *, int *, int); + void (*up)(fsm *); /* Called when fsm reaches OPENED state */ + void (*down)(fsm *); /* Called when fsm leaves OPENED state */ + void (*starting)(fsm *); /* Called when we want the lower layer */ + void (*finished)(fsm *); /* Called when we don't want the lower layer */ + void (*protreject)(int); /* Called when Protocol-Reject received */ + void (*retransmit)(fsm *); /* Retransmission is necessary */ int (*extcode) /* Called when unknown code received */ - __P((fsm *, int, int, u_char *, int)); + (fsm *, int, int, u_char *, int); char *proto_name; /* String name for protocol (for messages) */ } fsm_callbacks; @@ -152,14 +144,14 @@ /* * Prototypes */ -void fsm_init __P((fsm *)); -void fsm_lowerup __P((fsm *)); -void fsm_lowerdown __P((fsm *)); -void fsm_open __P((fsm *)); -void fsm_close __P((fsm *, char *)); -void fsm_input __P((fsm *, u_char *, int)); -void fsm_protreject __P((fsm *)); -void fsm_sdata __P((fsm *, int, int, u_char *, int)); +void fsm_init (fsm *); +void fsm_lowerup (fsm *); +void fsm_lowerdown (fsm *); +void fsm_open (fsm *); +void fsm_close (fsm *, char *); +void fsm_input (fsm *, u_char *, int); +void fsm_protreject (fsm *); +void fsm_sdata (fsm *, int, int, u_char *, int); /* diff -Nru ppp-2.4.7/pppd/ipcp.c ppp-2.4.9/pppd/ipcp.c --- ppp-2.4.7/pppd/ipcp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/ipcp.c 2021-01-05 00:06:37.000000000 +0100 @@ -40,8 +40,6 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: ipcp.c,v 1.73 2008/05/26 08:33:22 paulus Exp $" - /* * TODO: */ @@ -55,13 +53,13 @@ #include #include #include +#include #include "pppd.h" #include "fsm.h" #include "ipcp.h" #include "pathnames.h" -static const char rcsid[] = RCSID; /* global vars */ ipcp_options ipcp_wantoptions[NUM_PPP]; /* Options that we want to request */ @@ -75,13 +73,13 @@ bool noremoteip = 0; /* Let him have no IP address */ /* Hook for a plugin to know when IP protocol has come up */ -void (*ip_up_hook) __P((void)) = NULL; +void (*ip_up_hook)(void) = NULL; /* Hook for a plugin to know when IP protocol has come down */ -void (*ip_down_hook) __P((void)) = NULL; +void (*ip_down_hook)(void) = NULL; /* Hook for a plugin to choose the remote IP address */ -void (*ip_choose_hook) __P((u_int32_t *)) = NULL; +void (*ip_choose_hook)(u_int32_t *) = NULL; /* Notifiers for when IPCP goes up and down */ struct notifier *ip_up_notifier = NULL; @@ -100,16 +98,16 @@ /* * Callbacks for fsm code. (CI = Configuration Information) */ -static void ipcp_resetci __P((fsm *)); /* Reset our CI */ -static int ipcp_cilen __P((fsm *)); /* Return length of our CI */ -static void ipcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ -static int ipcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ -static int ipcp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */ -static int ipcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ -static int ipcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ -static void ipcp_up __P((fsm *)); /* We're UP */ -static void ipcp_down __P((fsm *)); /* We're DOWN */ -static void ipcp_finished __P((fsm *)); /* Don't need lower layer */ +static void ipcp_resetci (fsm *); /* Reset our CI */ +static int ipcp_cilen (fsm *); /* Return length of our CI */ +static void ipcp_addci (fsm *, u_char *, int *); /* Add our CI */ +static int ipcp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */ +static int ipcp_nakci (fsm *, u_char *, int, int);/* Peer nak'd our CI */ +static int ipcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */ +static int ipcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */ +static void ipcp_up (fsm *); /* We're UP */ +static void ipcp_down (fsm *); /* We're DOWN */ +static void ipcp_finished (fsm *); /* Don't need lower layer */ fsm ipcp_fsm[NUM_PPP]; /* IPCP fsm structure */ @@ -134,12 +132,12 @@ /* * Command-line options. */ -static int setvjslots __P((char **)); -static int setdnsaddr __P((char **)); -static int setwinsaddr __P((char **)); -static int setnetmask __P((char **)); -int setipaddr __P((char *, char **, int)); -static void printipaddr __P((option_t *, void (*)(void *, char *,...),void *)); +static int setvjslots (char **); +static int setdnsaddr (char **); +static int setwinsaddr (char **); +static int setnetmask (char **); +int setipaddr (char *, char **, int); +static void printipaddr (option_t *, void (*)(void *, char *,...),void *); static option_t ipcp_option_list[] = { { "noip", o_bool, &ipcp_protent.enabled_flag, @@ -175,10 +173,10 @@ { "noipdefault", o_bool, &disable_defaultip, "Don't use name for default IP adrs", 1 }, - { "ms-dns", 1, (void *)setdnsaddr, - "DNS address for the peer's use" }, - { "ms-wins", 1, (void *)setwinsaddr, - "Nameserver for SMB over TCP/IP for peer" }, + { "ms-dns", o_special, (void *)setdnsaddr, + "DNS address for the peer's use", OPT_A2LIST }, + { "ms-wins", o_special, (void *)setwinsaddr, + "Nameserver for SMB over TCP/IP for peer", OPT_A2LIST }, { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime, "Set timeout for IPCP", OPT_PRIO }, @@ -198,6 +196,15 @@ "disable defaultroute option", OPT_ALIAS | OPT_A2CLR, &ipcp_wantoptions[0].default_route }, +#ifdef __linux__ + { "replacedefaultroute", o_bool, + &ipcp_wantoptions[0].replace_default_route, + "Replace default route", OPT_PRIV | 1 + }, + { "noreplacedefaultroute", o_bool, + &ipcp_wantoptions[0].replace_default_route, + "Do not replace default route", 0 }, +#endif { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp, "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp }, { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, @@ -237,19 +244,19 @@ /* * Protocol entry points from main code. */ -static void ipcp_init __P((int)); -static void ipcp_open __P((int)); -static void ipcp_close __P((int, char *)); -static void ipcp_lowerup __P((int)); -static void ipcp_lowerdown __P((int)); -static void ipcp_input __P((int, u_char *, int)); -static void ipcp_protrej __P((int)); -static int ipcp_printpkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); -static void ip_check_options __P((void)); -static int ip_demand_conf __P((int)); -static int ip_active_pkt __P((u_char *, int)); -static void create_resolv __P((u_int32_t, u_int32_t)); +static void ipcp_init (int); +static void ipcp_open (int); +static void ipcp_close (int, char *); +static void ipcp_lowerup (int); +static void ipcp_lowerdown (int); +static void ipcp_input (int, u_char *, int); +static void ipcp_protrej (int); +static int ipcp_printpkt (u_char *, int, + void (*) (void *, char *, ...), void *); +static void ip_check_options (void); +static int ip_demand_conf (int); +static int ip_active_pkt (u_char *, int); +static void create_resolv (u_int32_t, u_int32_t); struct protent ipcp_protent = { PPP_IPCP, @@ -271,9 +278,9 @@ ip_active_pkt }; -static void ipcp_clear_addrs __P((int, u_int32_t, u_int32_t)); -static void ipcp_script __P((char *, int)); /* Run an up/down script */ -static void ipcp_script_done __P((void *)); +static void ipcp_clear_addrs (int, u_int32_t, u_int32_t, bool); +static void ipcp_script (char *, int); /* Run an up/down script */ +static void ipcp_script_done (void *); /* * Lengths of configuration options. @@ -302,8 +309,7 @@ * Make a string representation of a network IP address. */ char * -ip_ntoa(ipaddr) -u_int32_t ipaddr; +ip_ntoa(u_int32_t ipaddr) { static char b[64]; @@ -319,8 +325,7 @@ * setvjslots - set maximum number of connection slots for VJ compression */ static int -setvjslots(argv) - char **argv; +setvjslots(char **argv) { int value; @@ -340,8 +345,7 @@ * setdnsaddr - set the dns address(es) */ static int -setdnsaddr(argv) - char **argv; +setdnsaddr(char **argv) { u_int32_t dns; struct hostent *hp; @@ -376,8 +380,7 @@ * the caller to the existing WINS server on a Windows NT platform. */ static int -setwinsaddr(argv) - char **argv; +setwinsaddr(char **argv) { u_int32_t wins; struct hostent *hp; @@ -413,10 +416,7 @@ * Not static so that plugins can call it to set the addresses */ int -setipaddr(arg, argv, doit) - char *arg; - char **argv; - int doit; +setipaddr(char *arg, char **argv, int doit) { struct hostent *hp; char *colon; @@ -480,10 +480,7 @@ } static void -printipaddr(opt, printer, arg) - option_t *opt; - void (*printer) __P((void *, char *, ...)); - void *arg; +printipaddr(option_t *opt, void (*printer) (void *, char *, ...), void *arg) { ipcp_options *wo = &ipcp_wantoptions[0]; @@ -498,8 +495,7 @@ * setnetmask - set the netmask to be used on the interface. */ static int -setnetmask(argv) - char **argv; +setnetmask(char **argv) { u_int32_t mask; int n; @@ -526,9 +522,7 @@ } int -parse_dotted_ip(p, vp) - char *p; - u_int32_t *vp; +parse_dotted_ip(char *p, u_int32_t *vp) { int n; u_int32_t v, b; @@ -563,8 +557,7 @@ * ipcp_init - Initialize IPCP. */ static void -ipcp_init(unit) - int unit; +ipcp_init(int unit) { fsm *f = &ipcp_fsm[unit]; ipcp_options *wo = &ipcp_wantoptions[unit]; @@ -615,8 +608,7 @@ * ipcp_open - IPCP is allowed to come up. */ static void -ipcp_open(unit) - int unit; +ipcp_open(int unit) { fsm_open(&ipcp_fsm[unit]); ipcp_is_open = 1; @@ -627,9 +619,7 @@ * ipcp_close - Take IPCP down. */ static void -ipcp_close(unit, reason) - int unit; - char *reason; +ipcp_close(int unit, char *reason) { fsm_close(&ipcp_fsm[unit], reason); } @@ -639,8 +629,7 @@ * ipcp_lowerup - The lower layer is up. */ static void -ipcp_lowerup(unit) - int unit; +ipcp_lowerup(int unit) { fsm_lowerup(&ipcp_fsm[unit]); } @@ -650,8 +639,7 @@ * ipcp_lowerdown - The lower layer is down. */ static void -ipcp_lowerdown(unit) - int unit; +ipcp_lowerdown(int unit) { fsm_lowerdown(&ipcp_fsm[unit]); } @@ -661,10 +649,7 @@ * ipcp_input - Input IPCP packet. */ static void -ipcp_input(unit, p, len) - int unit; - u_char *p; - int len; +ipcp_input(int unit, u_char *p, int len) { fsm_input(&ipcp_fsm[unit], p, len); } @@ -676,8 +661,7 @@ * Pretend the lower layer went down, so we shut up. */ static void -ipcp_protrej(unit) - int unit; +ipcp_protrej(int unit) { fsm_lowerdown(&ipcp_fsm[unit]); } @@ -688,8 +672,7 @@ * Called by fsm_sconfreq, Send Configure Request. */ static void -ipcp_resetci(f) - fsm *f; +ipcp_resetci(fsm *f) { ipcp_options *wo = &ipcp_wantoptions[f->unit]; ipcp_options *go = &ipcp_gotoptions[f->unit]; @@ -721,8 +704,7 @@ * Called by fsm_sconfreq, Send Configure Request. */ static int -ipcp_cilen(f) - fsm *f; +ipcp_cilen(fsm *f) { ipcp_options *go = &ipcp_gotoptions[f->unit]; ipcp_options *wo = &ipcp_wantoptions[f->unit]; @@ -765,10 +747,7 @@ * Called by fsm_sconfreq, Send Configure Request. */ static void -ipcp_addci(f, ucp, lenp) - fsm *f; - u_char *ucp; - int *lenp; +ipcp_addci(fsm *f, u_char *ucp, int *lenp) { ipcp_options *go = &ipcp_gotoptions[f->unit]; int len = *lenp; @@ -872,10 +851,7 @@ * 1 - Ack was good. */ static int -ipcp_ackci(f, p, len) - fsm *f; - u_char *p; - int len; +ipcp_ackci(fsm *f, u_char *p, int len) { ipcp_options *go = &ipcp_gotoptions[f->unit]; u_short cilen, citype, cishort; @@ -1016,11 +992,7 @@ * 1 - Nak was good. */ static int -ipcp_nakci(f, p, len, treat_as_reject) - fsm *f; - u_char *p; - int len; - int treat_as_reject; +ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { ipcp_options *go = &ipcp_gotoptions[f->unit]; u_char cimaxslotindex, cicflag; @@ -1265,10 +1237,7 @@ * Callback from fsm_rconfnakrej. */ static int -ipcp_rejci(f, p, len) - fsm *f; - u_char *p; - int len; +ipcp_rejci(fsm *f, u_char *p, int len) { ipcp_options *go = &ipcp_gotoptions[f->unit]; u_char cimaxslotindex, ciflag, cilen; @@ -1416,11 +1385,7 @@ * CONFNAK; returns CONFREJ if it can't return CONFACK. */ static int -ipcp_reqci(f, inp, len, reject_if_disagree) - fsm *f; - u_char *inp; /* Requested CIs */ - int *len; /* Length of requested CIs */ - int reject_if_disagree; +ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { ipcp_options *wo = &ipcp_wantoptions[f->unit]; ipcp_options *ho = &ipcp_hisoptions[f->unit]; @@ -1705,7 +1670,7 @@ * and assign appropriate defaults. */ static void -ip_check_options() +ip_check_options(void) { struct hostent *hp; u_int32_t local; @@ -1737,8 +1702,7 @@ * IPCP were up, for use with dial-on-demand. */ static int -ip_demand_conf(u) - int u; +ip_demand_conf(int u) { ipcp_options *wo = &ipcp_wantoptions[u]; @@ -1761,7 +1725,8 @@ if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE)) return 0; if (wo->default_route) - if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr)) + if (sifdefaultroute(u, wo->ouraddr, wo->hisaddr, + wo->replace_default_route)) default_route_set[u] = 1; if (wo->proxy_arp) if (sifproxyarp(u, wo->hisaddr)) @@ -1781,13 +1746,13 @@ * Configure the IP network interface appropriately and bring it up. */ static void -ipcp_up(f) - fsm *f; +ipcp_up(fsm *f) { u_int32_t mask; ipcp_options *ho = &ipcp_hisoptions[f->unit]; ipcp_options *go = &ipcp_gotoptions[f->unit]; ipcp_options *wo = &ipcp_wantoptions[f->unit]; + int ifindex; IPCPDEBUG(("ipcp: up")); @@ -1849,7 +1814,8 @@ */ if (demand) { if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) { - ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr); + ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr, + wo->replace_default_route); if (go->ouraddr != wo->ouraddr) { warn("Local IP address changed to %I", go->ouraddr); script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0); @@ -1874,7 +1840,8 @@ /* assign a default route through the interface if required */ if (ipcp_wantoptions[f->unit].default_route) - if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) + if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr, + wo->replace_default_route)) default_route_set[f->unit] = 1; /* Make a proxy ARP entry if requested. */ @@ -1901,9 +1868,18 @@ } #endif + ifindex = if_nametoindex(ifname); + /* run the pre-up script, if any, and wait for it to finish */ ipcp_script(_PATH_IPPREUP, 1); + /* check if preup script renamed the interface */ + if (!if_indextoname(ifindex, ifname)) { + error("Interface index %d failed to get renamed by a pre-up script", ifindex); + ipcp_close(f->unit, "Interface configuration failed"); + return; + } + /* bring the interface up for IP */ if (!sifup(f->unit)) { if (debug) @@ -1924,7 +1900,8 @@ /* assign a default route through the interface if required */ if (ipcp_wantoptions[f->unit].default_route) - if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr)) + if (sifdefaultroute(f->unit, go->ouraddr, ho->hisaddr, + wo->replace_default_route)) default_route_set[f->unit] = 1; /* Make a proxy ARP entry if requested. */ @@ -1958,7 +1935,7 @@ */ if (ipcp_script_state == s_down && ipcp_script_pid == 0) { ipcp_script_state = s_up; - ipcp_script(_PATH_IPUP, 0); + ipcp_script(path_ipup, 0); } } @@ -1970,8 +1947,7 @@ * and delete routes through it. */ static void -ipcp_down(f) - fsm *f; +ipcp_down(fsm *f) { IPCPDEBUG(("ipcp: down")); /* XXX a bit IPv4-centric here, we only need to get the stats @@ -2002,13 +1978,13 @@ sifnpmode(f->unit, PPP_IP, NPMODE_DROP); sifdown(f->unit); ipcp_clear_addrs(f->unit, ipcp_gotoptions[f->unit].ouraddr, - ipcp_hisoptions[f->unit].hisaddr); + ipcp_hisoptions[f->unit].hisaddr, 0); } /* Execute the ip-down script */ if (ipcp_script_state == s_up && ipcp_script_pid == 0) { ipcp_script_state = s_down; - ipcp_script(_PATH_IPDOWN, 0); + ipcp_script(path_ipdown, 0); } } @@ -2018,16 +1994,21 @@ * proxy arp entries, etc. */ static void -ipcp_clear_addrs(unit, ouraddr, hisaddr) - int unit; - u_int32_t ouraddr; /* local address */ - u_int32_t hisaddr; /* remote address */ +ipcp_clear_addrs(int unit, u_int32_t ouraddr, u_int32_t hisaddr, bool replacedefaultroute) { if (proxy_arp_set[unit]) { cifproxyarp(unit, hisaddr); proxy_arp_set[unit] = 0; } - if (default_route_set[unit]) { + /* If replacedefaultroute, sifdefaultroute will be called soon + * with replacedefaultroute set and that will overwrite the current + * default route. This is the case only when doing demand, otherwise + * during demand, this cifdefaultroute would restore the old default + * route which is not what we want in this case. In the non-demand + * case, we'll delete the default route and restore the old if there + * is one saved by an sifdefaultroute with replacedefaultroute. + */ + if (!replacedefaultroute && default_route_set[unit]) { cifdefaultroute(unit, ouraddr, hisaddr); default_route_set[unit] = 0; } @@ -2039,8 +2020,7 @@ * ipcp_finished - possibly shut down the lower layers. */ static void -ipcp_finished(f) - fsm *f; +ipcp_finished(fsm *f) { if (ipcp_is_open) { ipcp_is_open = 0; @@ -2054,21 +2034,20 @@ * has finished. */ static void -ipcp_script_done(arg) - void *arg; +ipcp_script_done(void *arg) { ipcp_script_pid = 0; switch (ipcp_script_state) { case s_up: if (ipcp_fsm[0].state != OPENED) { ipcp_script_state = s_down; - ipcp_script(_PATH_IPDOWN, 0); + ipcp_script(path_ipdown, 0); } break; case s_down: if (ipcp_fsm[0].state == OPENED) { ipcp_script_state = s_up; - ipcp_script(_PATH_IPUP, 0); + ipcp_script(path_ipup, 0); } break; } @@ -2080,9 +2059,7 @@ * interface-name tty-name speed local-IP remote-IP. */ static void -ipcp_script(script, wait) - char *script; - int wait; +ipcp_script(char *script, int wait) { char strspeed[32], strlocal[32], strremote[32]; char *argv[8]; @@ -2110,8 +2087,7 @@ * create_resolv - create the replacement resolv.conf file */ static void -create_resolv(peerdns1, peerdns2) - u_int32_t peerdns1, peerdns2; +create_resolv(u_int32_t peerdns1, u_int32_t peerdns2) { FILE *f; @@ -2142,11 +2118,8 @@ }; static int -ipcp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; +ipcp_printpkt(u_char *p, int plen, + void (*printer) (void *, char *, ...), void *arg) { int code, id, len, olen; u_char *pstart, *optend; @@ -2286,9 +2259,7 @@ #define get_tcpflags(x) (((unsigned char *)(x))[13]) static int -ip_active_pkt(pkt, len) - u_char *pkt; - int len; +ip_active_pkt(u_char *pkt, int len) { u_char *tcp; int hlen; diff -Nru ppp-2.4.7/pppd/ipcp.h ppp-2.4.9/pppd/ipcp.h --- ppp-2.4.7/pppd/ipcp.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/ipcp.h 2021-01-05 00:06:37.000000000 +0100 @@ -38,8 +38,6 @@ * 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. - * - * $Id: ipcp.h,v 1.14 2002/12/04 23:03:32 paulus Exp $ */ /* @@ -70,6 +68,7 @@ bool old_addrs; /* Use old (IP-Addresses) option? */ bool req_addr; /* Ask peer to send IP address? */ bool default_route; /* Assign default route through interface? */ + bool replace_default_route; /* Replace default route through interface? */ bool proxy_arp; /* Make proxy ARP entry for peer? */ bool neg_vj; /* Van Jacobson Compression? */ bool old_vj; /* use old (short) form of VJ option? */ @@ -91,6 +90,6 @@ extern ipcp_options ipcp_allowoptions[]; extern ipcp_options ipcp_hisoptions[]; -char *ip_ntoa __P((u_int32_t)); +char *ip_ntoa(u_int32_t); extern struct protent ipcp_protent; diff -Nru ppp-2.4.7/pppd/ipv6cp.c ppp-2.4.9/pppd/ipv6cp.c --- ppp-2.4.7/pppd/ipv6cp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/ipv6cp.c 2021-01-05 00:06:37.000000000 +0100 @@ -134,12 +134,8 @@ * 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. - * - * $Id: ipv6cp.c,v 1.21 2005/08/25 23:59:34 paulus Exp $ */ -#define RCSID "$Id: ipv6cp.c,v 1.21 2005/08/25 23:59:34 paulus Exp $" - /* * TODO: * @@ -168,7 +164,6 @@ #include "magic.h" #include "pathnames.h" -static const char rcsid[] = RCSID; /* global vars */ ipv6cp_options ipv6cp_wantoptions[NUM_PPP]; /* Options that we want to request */ @@ -178,13 +173,14 @@ int no_ifaceid_neg = 0; /* local vars */ +static int default_route_set[NUM_PPP]; /* Have set up a default route */ static int ipv6cp_is_up; /* Hook for a plugin to know when IPv6 protocol has come up */ -void (*ipv6_up_hook) __P((void)) = NULL; +void (*ipv6_up_hook)(void) = NULL; /* Hook for a plugin to know when IPv6 protocol has come down */ -void (*ipv6_down_hook) __P((void)) = NULL; +void (*ipv6_down_hook)(void) = NULL; /* Notifiers for when IPCPv6 goes up and down */ struct notifier *ipv6_up_notifier = NULL; @@ -193,16 +189,16 @@ /* * Callbacks for fsm code. (CI = Configuration Information) */ -static void ipv6cp_resetci __P((fsm *)); /* Reset our CI */ -static int ipv6cp_cilen __P((fsm *)); /* Return length of our CI */ -static void ipv6cp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ -static int ipv6cp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ -static int ipv6cp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */ -static int ipv6cp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ -static int ipv6cp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ -static void ipv6cp_up __P((fsm *)); /* We're UP */ -static void ipv6cp_down __P((fsm *)); /* We're DOWN */ -static void ipv6cp_finished __P((fsm *)); /* Don't need lower layer */ +static void ipv6cp_resetci (fsm *); /* Reset our CI */ +static int ipv6cp_cilen (fsm *); /* Return length of our CI */ +static void ipv6cp_addci (fsm *, u_char *, int *); /* Add our CI */ +static int ipv6cp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */ +static int ipv6cp_nakci (fsm *, u_char *, int, int);/* Peer nak'd our CI */ +static int ipv6cp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */ +static int ipv6cp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */ +static void ipv6cp_up (fsm *); /* We're UP */ +static void ipv6cp_down (fsm *); /* We're DOWN */ +static void ipv6cp_finished (fsm *); /* Don't need lower layer */ fsm ipv6cp_fsm[NUM_PPP]; /* IPV6CP fsm structure */ @@ -227,9 +223,9 @@ /* * Command-line options. */ -static int setifaceid __P((char **arg)); -static void printifaceid __P((option_t *, - void (*)(void *, char *, ...), void *)); +static int setifaceid (char **arg); +static void printifaceid (option_t *, + void (*)(void *, char *, ...), void *); static option_t ipv6cp_option_list[] = { { "ipv6", o_special, (void *)setifaceid, @@ -245,6 +241,17 @@ { "ipv6cp-accept-local", o_bool, &ipv6cp_allowoptions[0].accept_local, "Accept peer's interface identifier for us", 1 }, + { "ipv6cp-accept-remote", o_bool, &ipv6cp_allowoptions[0].accept_remote, + "Accept peer's interface identifier for itself", 1 }, + + { "defaultroute6", o_bool, &ipv6cp_wantoptions[0].default_route, + "Add default IPv6 route", OPT_ENABLE|1, &ipv6cp_allowoptions[0].default_route }, + { "nodefaultroute6", o_bool, &ipv6cp_allowoptions[0].default_route, + "disable defaultroute6 option", OPT_A2CLR, + &ipv6cp_wantoptions[0].default_route }, + { "-defaultroute6", o_bool, &ipv6cp_allowoptions[0].default_route, + "disable defaultroute6 option", OPT_ALIAS | OPT_A2CLR, + &ipv6cp_wantoptions[0].default_route }, { "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip, "Use (default) IPv4 address as interface identifier", 1 }, @@ -268,18 +275,18 @@ /* * Protocol entry points from main code. */ -static void ipv6cp_init __P((int)); -static void ipv6cp_open __P((int)); -static void ipv6cp_close __P((int, char *)); -static void ipv6cp_lowerup __P((int)); -static void ipv6cp_lowerdown __P((int)); -static void ipv6cp_input __P((int, u_char *, int)); -static void ipv6cp_protrej __P((int)); -static int ipv6cp_printpkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); -static void ipv6_check_options __P((void)); -static int ipv6_demand_conf __P((int)); -static int ipv6_active_pkt __P((u_char *, int)); +static void ipv6cp_init (int); +static void ipv6cp_open (int); +static void ipv6cp_close (int, char *); +static void ipv6cp_lowerup (int); +static void ipv6cp_lowerdown (int); +static void ipv6cp_input (int, u_char *, int); +static void ipv6cp_protrej (int); +static int ipv6cp_printpkt (u_char *, int, + void (*) (void *, char *, ...), void *); +static void ipv6_check_options (void); +static int ipv6_demand_conf (int); +static int ipv6_active_pkt (u_char *, int); struct protent ipv6cp_protent = { PPP_IPV6CP, @@ -292,7 +299,7 @@ ipv6cp_close, ipv6cp_printpkt, NULL, - 0, + 1, "IPV6CP", "IPV6", ipv6cp_option_list, @@ -301,9 +308,9 @@ ipv6_active_pkt }; -static void ipv6cp_clear_addrs __P((int, eui64_t, eui64_t)); -static void ipv6cp_script __P((char *)); -static void ipv6cp_script_done __P((void *)); +static void ipv6cp_clear_addrs (int, eui64_t, eui64_t); +static void ipv6cp_script (char *); +static void ipv6cp_script_done (void *); /* * Lengths of configuration options. @@ -329,8 +336,7 @@ * setifaceid - set the interface identifiers manually */ static int -setifaceid(argv) - char **argv; +setifaceid(char **argv) { char *comma, *arg, c; ipv6cp_options *wo = &ipv6cp_wantoptions[0]; @@ -387,10 +393,7 @@ char *llv6_ntoa(eui64_t ifaceid); static void -printifaceid(opt, printer, arg) - option_t *opt; - void (*printer) __P((void *, char *, ...)); - void *arg; +printifaceid(option_t *opt, void (*printer) (void *, char *, ...), void *arg) { ipv6cp_options *wo = &ipv6cp_wantoptions[0]; @@ -405,8 +408,7 @@ * Make a string representation of a network address. */ char * -llv6_ntoa(ifaceid) - eui64_t ifaceid; +llv6_ntoa(eui64_t ifaceid) { static char b[64]; @@ -419,8 +421,7 @@ * ipv6cp_init - Initialize IPV6CP. */ static void -ipv6cp_init(unit) - int unit; +ipv6cp_init(int unit) { fsm *f = &ipv6cp_fsm[unit]; ipv6cp_options *wo = &ipv6cp_wantoptions[unit]; @@ -434,7 +435,8 @@ memset(wo, 0, sizeof(*wo)); memset(ao, 0, sizeof(*ao)); - wo->accept_local = 1; + wo->accept_local = 0; + wo->accept_remote = 0; wo->neg_ifaceid = 1; ao->neg_ifaceid = 1; @@ -444,6 +446,10 @@ wo->vj_protocol = IPV6CP_COMP; #endif + /* + * XXX This controls whether the user may use the defaultroute option. + */ + ao->default_route = 1; } @@ -451,8 +457,7 @@ * ipv6cp_open - IPV6CP is allowed to come up. */ static void -ipv6cp_open(unit) - int unit; +ipv6cp_open(int unit) { fsm_open(&ipv6cp_fsm[unit]); } @@ -462,9 +467,7 @@ * ipv6cp_close - Take IPV6CP down. */ static void -ipv6cp_close(unit, reason) - int unit; - char *reason; +ipv6cp_close(int unit, char *reason) { fsm_close(&ipv6cp_fsm[unit], reason); } @@ -474,8 +477,7 @@ * ipv6cp_lowerup - The lower layer is up. */ static void -ipv6cp_lowerup(unit) - int unit; +ipv6cp_lowerup(int unit) { fsm_lowerup(&ipv6cp_fsm[unit]); } @@ -485,8 +487,7 @@ * ipv6cp_lowerdown - The lower layer is down. */ static void -ipv6cp_lowerdown(unit) - int unit; +ipv6cp_lowerdown(int unit) { fsm_lowerdown(&ipv6cp_fsm[unit]); } @@ -496,10 +497,7 @@ * ipv6cp_input - Input IPV6CP packet. */ static void -ipv6cp_input(unit, p, len) - int unit; - u_char *p; - int len; +ipv6cp_input(int unit, u_char *p, int len) { fsm_input(&ipv6cp_fsm[unit], p, len); } @@ -511,8 +509,7 @@ * Pretend the lower layer went down, so we shut up. */ static void -ipv6cp_protrej(unit) - int unit; +ipv6cp_protrej(int unit) { fsm_lowerdown(&ipv6cp_fsm[unit]); } @@ -522,8 +519,7 @@ * ipv6cp_resetci - Reset our CI. */ static void -ipv6cp_resetci(f) - fsm *f; +ipv6cp_resetci(fsm *f) { ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; @@ -531,8 +527,11 @@ wo->req_ifaceid = wo->neg_ifaceid && ipv6cp_allowoptions[f->unit].neg_ifaceid; if (!wo->opt_local) { + wo->accept_local = 1; eui64_magic_nz(wo->ourid); } + if (!wo->opt_remote) + wo->accept_remote = 1; *go = *wo; eui64_zero(go->hisid); /* last proposed interface identifier */ @@ -543,8 +542,7 @@ * ipv6cp_cilen - Return length of our CI. */ static int -ipv6cp_cilen(f) - fsm *f; +ipv6cp_cilen(fsm *f) { ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; @@ -560,10 +558,7 @@ * ipv6cp_addci - Add our desired CIs to a packet. */ static void -ipv6cp_addci(f, ucp, lenp) - fsm *f; - u_char *ucp; - int *lenp; +ipv6cp_addci(fsm *f, u_char *ucp, int *lenp) { ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; int len = *lenp; @@ -608,10 +603,7 @@ * 1 - Ack was good. */ static int -ipv6cp_ackci(f, p, len) - fsm *f; - u_char *p; - int len; +ipv6cp_ackci(fsm *f, u_char *p, int len) { ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; u_short cilen, citype, cishort; @@ -679,11 +671,7 @@ * 1 - Nak was good. */ static int -ipv6cp_nakci(f, p, len, treat_as_reject) - fsm *f; - u_char *p; - int len; - int treat_as_reject; +ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; u_char citype, cilen, *next; @@ -817,10 +805,7 @@ * ipv6cp_rejci - Reject some of our CIs. */ static int -ipv6cp_rejci(f, p, len) - fsm *f; - u_char *p; - int len; +ipv6cp_rejci(fsm *f, u_char *p, int len) { ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; u_char cilen; @@ -892,11 +877,7 @@ * CONFNAK; returns CONFREJ if it can't return CONFACK. */ static int -ipv6cp_reqci(f, inp, len, reject_if_disagree) - fsm *f; - u_char *inp; /* Requested CIs */ - int *len; /* Length of requested CIs */ - int reject_if_disagree; +ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { ipv6cp_options *wo = &ipv6cp_wantoptions[f->unit]; ipv6cp_options *ho = &ipv6cp_hisoptions[f->unit]; @@ -960,7 +941,7 @@ orc = CONFREJ; /* Reject CI */ break; } - if (!eui64_iszero(wo->hisid) && + if (!eui64_iszero(wo->hisid) && !wo->accept_remote && !eui64_equals(ifaceid, wo->hisid) && eui64_iszero(go->hisid)) { @@ -1075,11 +1056,46 @@ /* + * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI + * + * walks the list of valid ethernet interfaces, starting with devnam + * (for PPPoE it is ethernet interface), and convert the first + * found 48-bit MAC address into EUI 64. caller also assumes that + * the system has a properly configured Ethernet interface for this + * function to return non-zero. + */ +static int +ether_to_eui64(eui64_t *p_eui64) +{ + u_char addr[6]; + + if (get_if_hwaddr(addr, devnam) < 0 || get_first_ether_hwaddr(addr) < 0) { + error("ipv6cp: no persistent id can be found"); + return 0; + } + + /* + * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1] + */ + p_eui64->e8[0] = addr[0] | 0x02; + p_eui64->e8[1] = addr[1]; + p_eui64->e8[2] = addr[2]; + p_eui64->e8[3] = 0xFF; + p_eui64->e8[4] = 0xFE; + p_eui64->e8[5] = addr[3]; + p_eui64->e8[6] = addr[4]; + p_eui64->e8[7] = addr[5]; + + return 1; +} + + +/* * ipv6_check_options - check that any IP-related options are OK, * and assign appropriate defaults. */ static void -ipv6_check_options() +ipv6_check_options(void) { ipv6cp_options *wo = &ipv6cp_wantoptions[0]; @@ -1137,8 +1153,7 @@ * IPV6CP were up, for use with dial-on-demand. */ static int -ipv6_demand_conf(u) - int u; +ipv6_demand_conf(int u) { ipv6cp_options *wo = &ipv6cp_wantoptions[u]; @@ -1152,6 +1167,9 @@ #endif if (!sifnpmode(u, PPP_IPV6, NPMODE_QUEUE)) return 0; + if (wo->default_route) + 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)); @@ -1167,8 +1185,7 @@ * Configure the IPv6 network interface appropriately and bring it up. */ static void -ipv6cp_up(f) - fsm *f; +ipv6cp_up(fsm *f) { ipv6cp_options *ho = &ipv6cp_hisoptions[f->unit]; ipv6cp_options *go = &ipv6cp_gotoptions[f->unit]; @@ -1231,6 +1248,10 @@ return; } + /* assign a default route through the interface if required */ + if (ipv6cp_wantoptions[f->unit].default_route) + if (sif6defaultroute(f->unit, go->ourid, ho->hisid)) + default_route_set[f->unit] = 1; } demand_rexmit(PPP_IPV6); sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); @@ -1252,6 +1273,11 @@ } sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); + /* assign a default route through the interface if required */ + if (ipv6cp_wantoptions[f->unit].default_route) + if (sif6defaultroute(f->unit, go->ourid, ho->hisid)) + default_route_set[f->unit] = 1; + notice("local LL address %s", llv6_ntoa(go->ourid)); notice("remote LL address %s", llv6_ntoa(ho->hisid)); } @@ -1281,8 +1307,7 @@ * and delete routes through it. */ static void -ipv6cp_down(f) - fsm *f; +ipv6cp_down(fsm *f) { IPV6CPDEBUG(("ipv6cp: down")); update_link_stats(f->unit); @@ -1331,10 +1356,7 @@ * proxy neighbour discovery entries, etc. */ static void -ipv6cp_clear_addrs(unit, ourid, hisid) - int unit; - eui64_t ourid; - eui64_t hisid; +ipv6cp_clear_addrs(int unit, eui64_t ourid, eui64_t hisid) { cif6addr(unit, ourid, hisid); } @@ -1344,8 +1366,7 @@ * ipv6cp_finished - possibly shut down the lower layers. */ static void -ipv6cp_finished(f) - fsm *f; +ipv6cp_finished(fsm *f) { np_finished(f->unit, PPP_IPV6); } @@ -1356,8 +1377,7 @@ * has finished. */ static void -ipv6cp_script_done(arg) - void *arg; +ipv6cp_script_done(void *arg) { ipv6cp_script_pid = 0; switch (ipv6cp_script_state) { @@ -1382,8 +1402,7 @@ * interface-name tty-name speed local-LL remote-LL. */ static void -ipv6cp_script(script) - char *script; +ipv6cp_script(char *script) { char strspeed[32], strlocal[32], strremote[32]; char *argv[8]; @@ -1414,11 +1433,8 @@ }; static int -ipv6cp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; +ipv6cp_printpkt(u_char *p, int plen, + void (*printer) (void *, char *, ...), void *arg) { int code, id, len, olen; u_char *pstart, *optend; @@ -1521,9 +1537,7 @@ #define get_tcpflags(x) (((unsigned char *)(x))[13]) static int -ipv6_active_pkt(pkt, len) - u_char *pkt; - int len; +ipv6_active_pkt(u_char *pkt, int len) { u_char *tcp; diff -Nru ppp-2.4.7/pppd/ipv6cp.h ppp-2.4.9/pppd/ipv6cp.h --- ppp-2.4.7/pppd/ipv6cp.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/ipv6cp.h 2021-01-05 00:06:37.000000000 +0100 @@ -134,8 +134,6 @@ * 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. - * - * $Id: ipv6cp.h,v 1.7 2002/12/04 23:03:32 paulus Exp $ */ /* @@ -150,7 +148,9 @@ typedef struct ipv6cp_options { int neg_ifaceid; /* Negotiate interface identifier? */ int req_ifaceid; /* Ask peer to send interface identifier? */ - int accept_local; /* accept peer's value for iface id? */ + int default_route; /* Assign default route through interface? */ + int accept_local; /* accept peer's value for our iface id? */ + int accept_remote; /* accept peer's value for his iface id? */ int opt_local; /* ourtoken set by option */ int opt_remote; /* histoken set by option */ int use_ip; /* use IP as interface identifier */ diff -Nru ppp-2.4.7/pppd/ipxcp.c ppp-2.4.9/pppd/ipxcp.c --- ppp-2.4.7/pppd/ipxcp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/ipxcp.c 2021-01-05 00:06:37.000000000 +0100 @@ -42,8 +42,6 @@ #ifdef IPX_CHANGE -#define RCSID "$Id: ipxcp.c,v 1.24 2005/08/25 23:59:34 paulus Exp $" - /* * TODO: */ @@ -62,7 +60,6 @@ #include "pathnames.h" #include "magic.h" -static const char rcsid[] = RCSID; /* global vars */ ipxcp_options ipxcp_wantoptions[NUM_PPP]; /* Options that we want to request */ @@ -78,17 +75,17 @@ /* * Callbacks for fsm code. (CI = Configuration Information) */ -static void ipxcp_resetci __P((fsm *)); /* Reset our CI */ -static int ipxcp_cilen __P((fsm *)); /* Return length of our CI */ -static void ipxcp_addci __P((fsm *, u_char *, int *)); /* Add our CI */ -static int ipxcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ -static int ipxcp_nakci __P((fsm *, u_char *, int, int));/* Peer nak'd our CI */ -static int ipxcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ -static int ipxcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv CI */ -static void ipxcp_up __P((fsm *)); /* We're UP */ -static void ipxcp_down __P((fsm *)); /* We're DOWN */ -static void ipxcp_finished __P((fsm *)); /* Don't need lower layer */ -static void ipxcp_script __P((fsm *, char *)); /* Run an up/down script */ +static void ipxcp_resetci (fsm *); /* Reset our CI */ +static int ipxcp_cilen (fsm *); /* Return length of our CI */ +static void ipxcp_addci (fsm *, u_char *, int *); /* Add our CI */ +static int ipxcp_ackci (fsm *, u_char *, int); /* Peer ack'd our CI */ +static int ipxcp_nakci (fsm *, u_char *, int, int);/* Peer nak'd our CI */ +static int ipxcp_rejci (fsm *, u_char *, int); /* Peer rej'd our CI */ +static int ipxcp_reqci (fsm *, u_char *, int *, int); /* Rcv CI */ +static void ipxcp_up (fsm *); /* We're UP */ +static void ipxcp_down (fsm *); /* We're DOWN */ +static void ipxcp_finished (fsm *); /* Don't need lower layer */ +static void ipxcp_script (fsm *, char *); /* Run an up/down script */ fsm ipxcp_fsm[NUM_PPP]; /* IPXCP fsm structure */ @@ -113,10 +110,10 @@ /* * Command-line options. */ -static int setipxnode __P((char **)); -static void printipxnode __P((option_t *, - void (*)(void *, char *, ...), void *)); -static int setipxname __P((char **)); +static int setipxnode (char **); +static void printipxnode (option_t *, + void (*)(void *, char *, ...), void *); +static int setipxname (char **); static option_t ipxcp_option_list[] = { { "ipx", o_bool, &ipxcp_protent.enabled_flag, @@ -170,15 +167,15 @@ * Protocol entry points. */ -static void ipxcp_init __P((int)); -static void ipxcp_open __P((int)); -static void ipxcp_close __P((int, char *)); -static void ipxcp_lowerup __P((int)); -static void ipxcp_lowerdown __P((int)); -static void ipxcp_input __P((int, u_char *, int)); -static void ipxcp_protrej __P((int)); -static int ipxcp_printpkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); +static void ipxcp_init (int); +static void ipxcp_open (int); +static void ipxcp_close (int, char *); +static void ipxcp_lowerup (int); +static void ipxcp_lowerdown (int); +static void ipxcp_input (int, u_char *, int); +static void ipxcp_protrej (int); +static int ipxcp_printpkt (u_char *, int, + void (*) (void *, char *, ...), void *); struct protent ipxcp_protent = { PPP_IPXCP, @@ -217,7 +214,7 @@ static int ipxcp_is_up; -static char *ipx_ntoa __P((u_int32_t)); +static char *ipx_ntoa (u_int32_t); /* Used in printing the node number */ #define NODE(base) base[0], base[1], base[2], base[3], base[4], base[5] @@ -230,8 +227,7 @@ */ static short int -to_external(internal) -short int internal; +to_external(short int internal) { short int external; @@ -248,8 +244,7 @@ */ static char * -ipx_ntoa(ipxaddr) -u_int32_t ipxaddr; +ipx_ntoa(u_int32_t ipxaddr) { static char b[64]; slprintf(b, sizeof(b), "%x", ipxaddr); @@ -258,8 +253,7 @@ static u_char * -setipxnodevalue(src,dst) -u_char *src, *dst; +setipxnodevalue(u_char *src, u_char *dst) { int indx; int item; @@ -286,8 +280,7 @@ static int ipx_prio_our, ipx_prio_his; static int -setipxnode(argv) - char **argv; +setipxnode(char **argv) { u_char *end; int have_his = 0; @@ -297,7 +290,7 @@ memset (our_node, 0, 6); memset (his_node, 0, 6); - end = setipxnodevalue (*argv, our_node); + end = setipxnodevalue ((u_char *)*argv, our_node); if (*end == ':') { have_his = 1; end = setipxnodevalue (++end, his_node); @@ -321,10 +314,7 @@ } static void -printipxnode(opt, printer, arg) - option_t *opt; - void (*printer) __P((void *, char *, ...)); - void *arg; +printipxnode(option_t *opt, void (*printer) (void *, char *, ...), void *arg) { unsigned char *p; @@ -340,8 +330,7 @@ } static int -setipxname (argv) - char **argv; +setipxname (char **argv) { u_char *dest = ipxcp_wantoptions[0].name; char *src = *argv; @@ -377,8 +366,7 @@ * ipxcp_init - Initialize IPXCP. */ static void -ipxcp_init(unit) - int unit; +ipxcp_init(int unit) { fsm *f = &ipxcp_fsm[unit]; @@ -414,8 +402,7 @@ */ static void -copy_node (src, dst) -u_char *src, *dst; +copy_node (u_char *src, u_char *dst) { memcpy (dst, src, sizeof (ipxcp_wantoptions[0].our_node)); } @@ -425,8 +412,7 @@ */ static int -compare_node (src, dst) -u_char *src, *dst; +compare_node (u_char *src, u_char *dst) { return memcmp (dst, src, sizeof (ipxcp_wantoptions[0].our_node)) == 0; } @@ -436,8 +422,7 @@ */ static int -zero_node (node) -u_char *node; +zero_node (u_char *node) { int indx; for (indx = 0; indx < sizeof (ipxcp_wantoptions[0].our_node); ++indx) @@ -451,8 +436,7 @@ */ static void -inc_node (node) -u_char *node; +inc_node (u_char *node) { u_char *outp; u_int32_t magic_num; @@ -468,8 +452,7 @@ * ipxcp_open - IPXCP is allowed to come up. */ static void -ipxcp_open(unit) - int unit; +ipxcp_open(int unit) { fsm_open(&ipxcp_fsm[unit]); } @@ -478,9 +461,7 @@ * ipxcp_close - Take IPXCP down. */ static void -ipxcp_close(unit, reason) - int unit; - char *reason; +ipxcp_close(int unit, char *reason) { fsm_close(&ipxcp_fsm[unit], reason); } @@ -490,8 +471,7 @@ * ipxcp_lowerup - The lower layer is up. */ static void -ipxcp_lowerup(unit) - int unit; +ipxcp_lowerup(int unit) { fsm_lowerup(&ipxcp_fsm[unit]); } @@ -501,8 +481,7 @@ * ipxcp_lowerdown - The lower layer is down. */ static void -ipxcp_lowerdown(unit) - int unit; +ipxcp_lowerdown(int unit) { fsm_lowerdown(&ipxcp_fsm[unit]); } @@ -512,10 +491,7 @@ * ipxcp_input - Input IPXCP packet. */ static void -ipxcp_input(unit, p, len) - int unit; - u_char *p; - int len; +ipxcp_input(int unit, u_char *p, int len) { fsm_input(&ipxcp_fsm[unit], p, len); } @@ -527,8 +503,7 @@ * Pretend the lower layer went down, so we shut up. */ static void -ipxcp_protrej(unit) - int unit; +ipxcp_protrej(int unit) { fsm_lowerdown(&ipxcp_fsm[unit]); } @@ -538,8 +513,7 @@ * ipxcp_resetci - Reset our CI. */ static void -ipxcp_resetci(f) - fsm *f; +ipxcp_resetci(fsm *f) { wo->req_node = wo->neg_node && ao->neg_node; wo->req_nn = wo->neg_nn && ao->neg_nn; @@ -586,8 +560,7 @@ */ static int -ipxcp_cilen(f) - fsm *f; +ipxcp_cilen(fsm *f) { int len; @@ -607,10 +580,7 @@ * ipxcp_addci - Add our desired CIs to a packet. */ static void -ipxcp_addci(f, ucp, lenp) - fsm *f; - u_char *ucp; - int *lenp; +ipxcp_addci(fsm *f, u_char *ucp, int *lenp) { /* * Add the options to the record. @@ -656,10 +626,7 @@ * 1 - Ack was good. */ static int -ipxcp_ackci(f, p, len) - fsm *f; - u_char *p; - int len; +ipxcp_ackci(fsm *f, u_char *p, int len) { u_short cilen, citype, cishort; u_char cichar; @@ -763,11 +730,7 @@ */ static int -ipxcp_nakci(f, p, len, treat_as_reject) - fsm *f; - u_char *p; - int len; - int treat_as_reject; +ipxcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { u_char citype, cilen, *next; u_short s; @@ -876,10 +839,7 @@ * ipxcp_rejci - Reject some of our CIs. */ static int -ipxcp_rejci(f, p, len) - fsm *f; - u_char *p; - int len; +ipxcp_rejci(fsm *f, u_char *p, int len) { u_short cilen, citype, cishort; u_char cichar; @@ -987,11 +947,7 @@ * CONFNAK; returns CONFREJ if it can't return CONFACK. */ static int -ipxcp_reqci(f, inp, len, reject_if_disagree) - fsm *f; - u_char *inp; /* Requested CIs */ - int *len; /* Length of requested CIs */ - int reject_if_disagree; +ipxcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { u_char *cip, *next; /* Pointer to current and next CIs */ u_short cilen, citype; /* Parsed len, type */ @@ -1194,7 +1150,7 @@ case IPX_ROUTER_NAME: if (cilen >= CILEN_NAME) { int name_size = cilen - CILEN_NAME; - if (name_size > sizeof (ho->name)) + if (name_size >= sizeof (ho->name)) name_size = sizeof (ho->name) - 1; memset (ho->name, 0, sizeof (ho->name)); memcpy (ho->name, p, name_size); @@ -1290,8 +1246,7 @@ */ static void -ipxcp_up(f) - fsm *f; +ipxcp_up(fsm *f) { int unit = f->unit; @@ -1369,8 +1324,7 @@ */ static void -ipxcp_down(f) - fsm *f; +ipxcp_down(fsm *f) { IPXCPDEBUG(("ipxcp: down")); @@ -1389,8 +1343,7 @@ * ipxcp_finished - possibly shut down the lower layers. */ static void -ipxcp_finished(f) - fsm *f; +ipxcp_finished(fsm *f) { np_finished(f->unit, PPP_IPX); } @@ -1401,9 +1354,7 @@ * interface-name tty-name speed local-IPX remote-IPX networks. */ static void -ipxcp_script(f, script) - fsm *f; - char *script; +ipxcp_script(fsm *f, char *script) { char strspeed[32], strlocal[32], strremote[32]; char strnetwork[32], strpid[32]; @@ -1470,11 +1421,8 @@ }; static int -ipxcp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; +ipxcp_printpkt(u_char *p, int plen, + void (*printer) (void *, char *, ...), void *arg) { int code, id, len, olen; u_char *pstart, *optend; diff -Nru ppp-2.4.7/pppd/ipxcp.h ppp-2.4.9/pppd/ipxcp.h --- ppp-2.4.7/pppd/ipxcp.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/ipxcp.h 2021-01-05 00:06:37.000000000 +0100 @@ -38,8 +38,6 @@ * 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. - * - * $Id: ipxcp.h,v 1.5 2002/12/04 23:03:32 paulus Exp $ */ /* diff -Nru ppp-2.4.7/pppd/lcp.c ppp-2.4.9/pppd/lcp.c --- ppp-2.4.7/pppd/lcp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/lcp.c 2021-01-05 00:06:37.000000000 +0100 @@ -40,12 +40,6 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: lcp.c,v 1.76 2006/05/22 00:04:07 paulus Exp $" - -/* - * TODO: - */ - #include #include #include @@ -56,7 +50,6 @@ #include "chap-new.h" #include "magic.h" -static const char rcsid[] = RCSID; /* * When the link comes up we want to be able to wait for a short while, @@ -66,22 +59,22 @@ /* steal a bit in fsm flags word */ #define DELAYED_UP 0x100 -static void lcp_delayed_up __P((void *)); +static void lcp_delayed_up(void *); /* * LCP-related command-line options. */ int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ +bool lcp_echo_adaptive = 0; /* request echo only if the link was idle */ bool lax_recv = 0; /* accept control chars in asyncmap */ bool noendpoint = 0; /* don't send/accept endpoint discriminator */ -static int noopt __P((char **)); +static int noopt(char **); #ifdef HAVE_MULTILINK -static int setendpoint __P((char **)); -static void printendpoint __P((option_t *, void (*)(void *, char *, ...), - void *)); +static int setendpoint(char **); +static void printendpoint(option_t *, void (*)(void *, char *, ...), void *); #endif /* HAVE_MULTILINK */ static option_t lcp_option_list[] = { @@ -151,6 +144,8 @@ OPT_PRIO }, { "lcp-echo-interval", o_int, &lcp_echo_interval, "Set time in seconds between LCP echo requests", OPT_PRIO }, + { "lcp-echo-adaptive", o_bool, &lcp_echo_adaptive, + "Suppress LCP echo requests if traffic was received", 1 }, { "lcp-restart", o_int, &lcp_fsm[0].timeouttime, "Set time in seconds between LCP retransmissions", OPT_PRIO }, { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits, @@ -202,31 +197,31 @@ /* * Callbacks for fsm code. (CI = Configuration Information) */ -static void lcp_resetci __P((fsm *)); /* Reset our CI */ -static int lcp_cilen __P((fsm *)); /* Return length of our CI */ -static void lcp_addci __P((fsm *, u_char *, int *)); /* Add our CI to pkt */ -static int lcp_ackci __P((fsm *, u_char *, int)); /* Peer ack'd our CI */ -static int lcp_nakci __P((fsm *, u_char *, int, int)); /* Peer nak'd our CI */ -static int lcp_rejci __P((fsm *, u_char *, int)); /* Peer rej'd our CI */ -static int lcp_reqci __P((fsm *, u_char *, int *, int)); /* Rcv peer CI */ -static void lcp_up __P((fsm *)); /* We're UP */ -static void lcp_down __P((fsm *)); /* We're DOWN */ -static void lcp_starting __P((fsm *)); /* We need lower layer up */ -static void lcp_finished __P((fsm *)); /* We need lower layer down */ -static int lcp_extcode __P((fsm *, int, int, u_char *, int)); -static void lcp_rprotrej __P((fsm *, u_char *, int)); +static void lcp_resetci(fsm *); /* Reset our CI */ +static int lcp_cilen(fsm *); /* Return length of our CI */ +static void lcp_addci(fsm *, u_char *, int *); /* Add our CI to pkt */ +static int lcp_ackci(fsm *, u_char *, int); /* Peer ack'd our CI */ +static int lcp_nakci(fsm *, u_char *, int, int); /* Peer nak'd our CI */ +static int lcp_rejci(fsm *, u_char *, int); /* Peer rej'd our CI */ +static int lcp_reqci(fsm *, u_char *, int *, int); /* Rcv peer CI */ +static void lcp_up(fsm *); /* We're UP */ +static void lcp_down(fsm *); /* We're DOWN */ +static void lcp_starting(fsm *); /* We need lower layer up */ +static void lcp_finished(fsm *); /* We need lower layer down */ +static int lcp_extcode(fsm *, int, int, u_char *, int); +static void lcp_rprotrej(fsm *, u_char *, int); /* * routines to send LCP echos to peer */ -static void lcp_echo_lowerup __P((int)); -static void lcp_echo_lowerdown __P((int)); -static void LcpEchoTimeout __P((void *)); -static void lcp_received_echo_reply __P((fsm *, int, u_char *, int)); -static void LcpSendEchoRequest __P((fsm *)); -static void LcpLinkFailure __P((fsm *)); -static void LcpEchoCheck __P((fsm *)); +static void lcp_echo_lowerup(int); +static void lcp_echo_lowerdown(int); +static void LcpEchoTimeout(void *); +static void lcp_received_echo_reply(fsm *, int, u_char *, int); +static void LcpSendEchoRequest(fsm *); +static void LcpLinkFailure(fsm *); +static void LcpEchoCheck(fsm *); static fsm_callbacks lcp_callbacks = { /* LCP callback routines */ lcp_resetci, /* Reset our Configuration Information */ @@ -251,11 +246,10 @@ * Some of these are called directly. */ -static void lcp_init __P((int)); -static void lcp_input __P((int, u_char *, int)); -static void lcp_protrej __P((int)); -static int lcp_printpkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); +static void lcp_init(int); +static void lcp_input(int, u_char *, int); +static void lcp_protrej(int); +static int lcp_printpkt(u_char *, int, void (*)(void *, char *, ...), void *); struct protent lcp_protent = { PPP_LCP, @@ -297,8 +291,7 @@ * noopt - Disable all options (why?). */ static int -noopt(argv) - char **argv; +noopt(char **argv) { BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options)); BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options)); @@ -308,8 +301,7 @@ #ifdef HAVE_MULTILINK static int -setendpoint(argv) - char **argv; +setendpoint(char **argv) { if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) { lcp_wantoptions[0].neg_endpoint = 1; @@ -320,10 +312,7 @@ } static void -printendpoint(opt, printer, arg) - option_t *opt; - void (*printer) __P((void *, char *, ...)); - void *arg; +printendpoint(option_t *opt, void (*printer)(void *, char *, ...), void *arg) { printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint)); } @@ -333,8 +322,7 @@ * lcp_init - Initialize LCP. */ static void -lcp_init(unit) - int unit; +lcp_init(int unit) { fsm *f = &lcp_fsm[unit]; lcp_options *wo = &lcp_wantoptions[unit]; @@ -373,8 +361,7 @@ * lcp_open - LCP is allowed to come up. */ void -lcp_open(unit) - int unit; +lcp_open(int unit) { fsm *f = &lcp_fsm[unit]; lcp_options *wo = &lcp_wantoptions[unit]; @@ -392,9 +379,7 @@ * lcp_close - Take LCP down. */ void -lcp_close(unit, reason) - int unit; - char *reason; +lcp_close(int unit, char *reason) { fsm *f = &lcp_fsm[unit]; int oldstate; @@ -427,8 +412,7 @@ * lcp_lowerup - The lower layer is up. */ void -lcp_lowerup(unit) - int unit; +lcp_lowerup(int unit) { lcp_options *wo = &lcp_wantoptions[unit]; fsm *f = &lcp_fsm[unit]; @@ -456,8 +440,7 @@ * lcp_lowerdown - The lower layer is down. */ void -lcp_lowerdown(unit) - int unit; +lcp_lowerdown(int unit) { fsm *f = &lcp_fsm[unit]; @@ -473,8 +456,7 @@ * lcp_delayed_up - Bring the lower layer up now. */ static void -lcp_delayed_up(arg) - void *arg; +lcp_delayed_up(void *arg) { fsm *f = arg; @@ -489,10 +471,7 @@ * lcp_input - Input LCP packet. */ static void -lcp_input(unit, p, len) - int unit; - u_char *p; - int len; +lcp_input(int unit, u_char *p, int len) { fsm *f = &lcp_fsm[unit]; @@ -508,11 +487,7 @@ * lcp_extcode - Handle a LCP-specific code. */ static int -lcp_extcode(f, code, id, inp, len) - fsm *f; - int code, id; - u_char *inp; - int len; +lcp_extcode(fsm *f, int code, int id, u_char *inp, int len) { u_char *magp; @@ -551,10 +526,7 @@ * Figure out which protocol is rejected and inform it. */ static void -lcp_rprotrej(f, inp, len) - fsm *f; - u_char *inp; - int len; +lcp_rprotrej(fsm *f, u_char *inp, int len) { int i; struct protent *protp; @@ -606,8 +578,7 @@ */ /*ARGSUSED*/ static void -lcp_protrej(unit) - int unit; +lcp_protrej(int unit) { /* * Can't reject LCP! @@ -621,10 +592,7 @@ * lcp_sprotrej - Send a Protocol-Reject for some protocol. */ void -lcp_sprotrej(unit, p, len) - int unit; - u_char *p; - int len; +lcp_sprotrej(int unit, u_char *p, int len) { /* * Send back the protocol and the information field of the @@ -642,8 +610,7 @@ * lcp_resetci - Reset our CI. */ static void -lcp_resetci(f) - fsm *f; +lcp_resetci(fsm *f) { lcp_options *wo = &lcp_wantoptions[f->unit]; lcp_options *go = &lcp_gotoptions[f->unit]; @@ -668,8 +635,7 @@ * lcp_cilen - Return length of our CI. */ static int -lcp_cilen(f) - fsm *f; +lcp_cilen(fsm *f) { lcp_options *go = &lcp_gotoptions[f->unit]; @@ -704,10 +670,7 @@ * lcp_addci - Add our desired CIs to a packet. */ static void -lcp_addci(f, ucp, lenp) - fsm *f; - u_char *ucp; - int *lenp; +lcp_addci(fsm *f, u_char *ucp, int *lenp) { lcp_options *go = &lcp_gotoptions[f->unit]; u_char *start_ucp = ucp; @@ -792,10 +755,7 @@ * 1 - Ack was good. */ static int -lcp_ackci(f, p, len) - fsm *f; - u_char *p; - int len; +lcp_ackci(fsm *f, u_char *p, int len) { lcp_options *go = &lcp_gotoptions[f->unit]; u_char cilen, citype, cichar; @@ -947,11 +907,7 @@ * 1 - Nak was good. */ static int -lcp_nakci(f, p, len, treat_as_reject) - fsm *f; - u_char *p; - int len; - int treat_as_reject; +lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { lcp_options *go = &lcp_gotoptions[f->unit]; lcp_options *wo = &lcp_wantoptions[f->unit]; @@ -1341,10 +1297,7 @@ * 1 - Reject was good. */ static int -lcp_rejci(f, p, len) - fsm *f; - u_char *p; - int len; +lcp_rejci(fsm *f, u_char *p, int len) { lcp_options *go = &lcp_gotoptions[f->unit]; u_char cichar; @@ -1500,11 +1453,7 @@ * CONFNAK; returns CONFREJ if it can't return CONFACK. */ static int -lcp_reqci(f, inp, lenp, reject_if_disagree) - fsm *f; - u_char *inp; /* Requested CIs */ - int *lenp; /* Length of requested CIs */ - int reject_if_disagree; +lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { lcp_options *go = &lcp_gotoptions[f->unit]; lcp_options *ho = &lcp_hisoptions[f->unit]; @@ -1891,8 +1840,7 @@ * lcp_up - LCP has come UP. */ static void -lcp_up(f) - fsm *f; +lcp_up(fsm *f) { lcp_options *wo = &lcp_wantoptions[f->unit]; lcp_options *ho = &lcp_hisoptions[f->unit]; @@ -1942,8 +1890,7 @@ * Alert other protocols. */ static void -lcp_down(f) - fsm *f; +lcp_down(fsm *f) { lcp_options *go = &lcp_gotoptions[f->unit]; @@ -1963,8 +1910,7 @@ * lcp_starting - LCP needs the lower layer up. */ static void -lcp_starting(f) - fsm *f; +lcp_starting(fsm *f) { link_required(f->unit); } @@ -1974,8 +1920,7 @@ * lcp_finished - LCP has finished with the lower layer. */ static void -lcp_finished(f) - fsm *f; +lcp_finished(fsm *f) { link_terminated(f->unit); } @@ -1992,11 +1937,7 @@ }; static int -lcp_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; +lcp_printpkt(u_char *p, int plen, void (*printer)(void *, char *, ...), void *arg) { int code, id, len, olen, i; u_char *pstart, *optend; @@ -2235,8 +2176,7 @@ */ static -void LcpLinkFailure (f) - fsm *f; +void LcpLinkFailure (fsm *f) { if (f->state == OPENED) { info("No response to %d echo-requests", lcp_echos_pending); @@ -2251,8 +2191,7 @@ */ static void -LcpEchoCheck (f) - fsm *f; +LcpEchoCheck (fsm *f) { LcpSendEchoRequest (f); if (f->state != OPENED) @@ -2272,8 +2211,7 @@ */ static void -LcpEchoTimeout (arg) - void *arg; +LcpEchoTimeout (void *arg) { if (lcp_echo_timer_running != 0) { lcp_echo_timer_running = 0; @@ -2286,11 +2224,7 @@ */ static void -lcp_received_echo_reply (f, id, inp, len) - fsm *f; - int id; - u_char *inp; - int len; +lcp_received_echo_reply (fsm *f, int id, u_char *inp, int len) { u_int32_t magic; @@ -2315,8 +2249,7 @@ */ static void -LcpSendEchoRequest (f) - fsm *f; +LcpSendEchoRequest (fsm *f) { u_int32_t lcp_magic; u_char pkt[4], *pktp; @@ -2332,6 +2265,20 @@ } /* + * If adaptive echos have been enabled, only send the echo request if + * no traffic was received since the last one. + */ + if (lcp_echo_adaptive) { + static unsigned int last_pkts_in = 0; + struct pppd_stats cur_stats; + + if (get_ppp_stats(f->unit, &cur_stats) && cur_stats.pkts_in != last_pkts_in) { + last_pkts_in = cur_stats.pkts_in; + return; + } + } + + /* * Make and send the echo request frame. */ if (f->state == OPENED) { @@ -2348,8 +2295,7 @@ */ static void -lcp_echo_lowerup (unit) - int unit; +lcp_echo_lowerup (int unit) { fsm *f = &lcp_fsm[unit]; @@ -2368,8 +2314,7 @@ */ static void -lcp_echo_lowerdown (unit) - int unit; +lcp_echo_lowerdown (int unit) { fsm *f = &lcp_fsm[unit]; diff -Nru ppp-2.4.7/pppd/lcp.h ppp-2.4.9/pppd/lcp.h --- ppp-2.4.7/pppd/lcp.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/lcp.h 2021-01-05 00:06:37.000000000 +0100 @@ -38,8 +38,6 @@ * 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. - * - * $Id: lcp.h,v 1.20 2004/11/14 22:53:42 carlsonj Exp $ */ /* @@ -122,11 +120,11 @@ #define MINMRU 128 /* No MRUs below this */ #define MAXMRU 16384 /* Normally limit MRU to this */ -void lcp_open __P((int)); -void lcp_close __P((int, char *)); -void lcp_lowerup __P((int)); -void lcp_lowerdown __P((int)); -void lcp_sprotrej __P((int, u_char *, int)); /* send protocol reject */ +void lcp_open(int); +void lcp_close(int, char *); +void lcp_lowerup(int); +void lcp_lowerdown(int); +void lcp_sprotrej(int, u_char *, int); /* send protocol reject */ extern struct protent lcp_protent; diff -Nru ppp-2.4.7/pppd/magic.c ppp-2.4.9/pppd/magic.c --- ppp-2.4.7/pppd/magic.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/magic.c 2021-01-05 00:06:37.000000000 +0100 @@ -40,8 +40,6 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: magic.c,v 1.11 2003/06/11 23:56:26 paulus Exp $" - #include #include #include @@ -51,10 +49,9 @@ #include "pppd.h" #include "magic.h" -static const char rcsid[] = RCSID; -extern long mrand48 __P((void)); -extern void srand48 __P((long)); +extern long mrand48 (void); +extern void srand48 (long); /* * magic_init - Initialize the magic number generator. @@ -64,7 +61,7 @@ * and current time, currently. */ void -magic_init() +magic_init(void) { long seed; struct timeval t; @@ -78,7 +75,7 @@ * magic - Returns the next magic number. */ u_int32_t -magic() +magic(void) { return (u_int32_t) mrand48(); } @@ -102,20 +99,19 @@ */ double -drand48() +drand48(void) { return (double)random() / (double)0x7fffffffL; /* 2**31-1 */ } long -mrand48() +mrand48(void) { return random(); } void -srand48(seedval) -long seedval; +srand48(long seedval) { srandom((int)seedval); } diff -Nru ppp-2.4.7/pppd/magic.h ppp-2.4.9/pppd/magic.h --- ppp-2.4.7/pppd/magic.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/magic.h 2021-01-05 00:06:37.000000000 +0100 @@ -38,12 +38,10 @@ * 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. - * - * $Id: magic.h,v 1.5 2003/06/11 23:56:26 paulus Exp $ */ -void magic_init __P((void)); /* Initialize the magic number generator */ -u_int32_t magic __P((void)); /* Returns the next magic number */ +void magic_init (void); /* Initialize the magic number generator */ +u_int32_t magic (void); /* Returns the next magic number */ /* Fill buffer with random bytes */ -void random_bytes __P((unsigned char *buf, int len)); +void random_bytes (unsigned char *buf, int len); diff -Nru ppp-2.4.7/pppd/main.c ppp-2.4.9/pppd/main.c --- ppp-2.4.7/pppd/main.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/main.c 2021-01-05 00:06:37.000000000 +0100 @@ -39,7 +39,7 @@ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * Copyright (c) 1999-2004 Paul Mackerras. All rights reserved. + * Copyright (c) 1999-2020 Paul Mackerras. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -66,8 +66,6 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: main.c,v 1.156 2008/06/23 11:47:18 paulus Exp $" - #include #include #include @@ -80,7 +78,6 @@ #include #include #include -#include #include #include #include @@ -121,10 +118,9 @@ #include "atcp.h" #endif -static const char rcsid[] = RCSID; /* interface vars */ -char ifname[32]; /* Interface name */ +char ifname[MAXIFNAMELEN]; /* Interface name */ int ifunit; /* Interface unit number */ struct channel *the_channel; @@ -159,10 +155,10 @@ char db_key[32]; -int (*holdoff_hook) __P((void)) = NULL; -int (*new_phase_hook) __P((int)) = NULL; -void (*snoop_recv_hook) __P((unsigned char *p, int len)) = NULL; -void (*snoop_send_hook) __P((unsigned char *p, int len)) = NULL; +int (*holdoff_hook)(void) = NULL; +int (*new_phase_hook)(int) = NULL; +void (*snoop_recv_hook)(unsigned char *p, int len) = NULL; +void (*snoop_send_hook)(unsigned char *p, int len) = NULL; static int conn_running; /* we have a [dis]connector running */ static int fd_loop; /* fd for getting demand-dial packets */ @@ -181,7 +177,7 @@ static sigset_t signals_handled; static int waiting; -static sigjmp_buf sigjmp; +static int sigpipe[2]; char **script_env; /* Env. variable values for scripts */ int s_env_nalloc; /* # words avail at script_env */ @@ -218,7 +214,7 @@ struct subprocess { pid_t pid; char *prog; - void (*done) __P((void *)); + void (*done)(void *); void *arg; int killable; struct subprocess *next; @@ -228,47 +224,37 @@ /* Prototypes for procedures local to this file. */ -static void setup_signals __P((void)); -static void create_pidfile __P((int pid)); -static void create_linkpidfile __P((int pid)); -static void cleanup __P((void)); -static void get_input __P((void)); -static void calltimeout __P((void)); -static struct timeval *timeleft __P((struct timeval *)); -static void kill_my_pg __P((int)); -static void hup __P((int)); -static void term __P((int)); -static void chld __P((int)); -static void toggle_debug __P((int)); -static void open_ccp __P((int)); -static void bad_signal __P((int)); -static void holdoff_end __P((void *)); -static void forget_child __P((int pid, int status)); -static int reap_kids __P((void)); -static void childwait_end __P((void *)); +static void setup_signals(void); +static void create_pidfile(int pid); +static void create_linkpidfile(int pid); +static void cleanup(void); +static void get_input(void); +static void calltimeout(void); +static struct timeval *timeleft(struct timeval *); +static void kill_my_pg(int); +static void hup(int); +static void term(int); +static void chld(int); +static void toggle_debug(int); +static void open_ccp(int); +static void bad_signal(int); +static void holdoff_end(void *); +static void forget_child(int pid, int status); +static int reap_kids(void); +static void childwait_end(void *); #ifdef USE_TDB -static void update_db_entry __P((void)); -static void add_db_key __P((const char *)); -static void delete_db_key __P((const char *)); -static void cleanup_db __P((void)); +static void update_db_entry(void); +static void add_db_key(const char *); +static void delete_db_key(const char *); +static void cleanup_db(void); #endif -static void handle_events __P((void)); -void print_link_stats __P((void)); - -extern char *ttyname __P((int)); -extern char *getlogin __P((void)); -int main __P((int, char *[])); +static void handle_events(void); +void print_link_stats(void); -#ifdef ultrix -#undef O_NONBLOCK -#define O_NONBLOCK O_NDELAY -#endif - -#ifdef ULTRIX -#define setlogmask(x) -#endif +extern char *getlogin(void); +int main(int, char *[]); /* * PPP Data Link Layer "protocol" table. @@ -298,17 +284,8 @@ NULL }; -/* - * If PPP_DRV_NAME is not defined, use the default "ppp" as the device name. - */ -#if !defined(PPP_DRV_NAME) -#define PPP_DRV_NAME "ppp" -#endif /* !defined(PPP_DRV_NAME) */ - int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { int i, t; char *p; @@ -316,6 +293,9 @@ struct protent *protp; char numbuf[16]; + strlcpy(path_ipup, _PATH_IPUP, sizeof(path_ipup)); + strlcpy(path_ipdown, _PATH_IPDOWN, sizeof(path_ipdown)); + link_stats_valid = 0; new_phase(PHASE_INITIALIZE); @@ -530,7 +510,7 @@ info("Starting link"); } - gettimeofday(&start_time, NULL); + get_time(&start_time); script_unsetenv("CONNECT_TIME"); script_unsetenv("BYTES_SENT"); script_unsetenv("BYTES_RCVD"); @@ -604,22 +584,24 @@ * handle_events - wait for something to happen and respond to it. */ static void -handle_events() +handle_events(void) { struct timeval timo; + unsigned char buf[16]; kill_link = open_ccp_flag = 0; - if (sigsetjmp(sigjmp, 1) == 0) { - sigprocmask(SIG_BLOCK, &signals_handled, NULL); - if (got_sighup || got_sigterm || got_sigusr2 || got_sigchld) { - sigprocmask(SIG_UNBLOCK, &signals_handled, NULL); - } else { - waiting = 1; - sigprocmask(SIG_UNBLOCK, &signals_handled, NULL); - wait_input(timeleft(&timo)); - } - } + + /* alert via signal pipe */ + waiting = 1; + /* flush signal pipe */ + for (; read(sigpipe[0], buf, sizeof(buf)) > 0; ); + add_fd(sigpipe[0]); + /* wait if necessary */ + if (!(got_sighup || got_sigterm || got_sigusr2 || got_sigchld)) + wait_input(timeleft(&timo)); waiting = 0; + remove_fd(sigpipe[0]); + calltimeout(); if (got_sighup) { info("Hangup (SIGHUP)"); @@ -650,10 +632,18 @@ * setup_signals - initialize signal handling. */ static void -setup_signals() +setup_signals(void) { struct sigaction sa; + /* create pipe to wake up event handler from signal handler */ + if (pipe(sigpipe) < 0) + fatal("Couldn't create signal pipe: %m"); + fcntl(sigpipe[0], F_SETFD, fcntl(sigpipe[0], F_GETFD) | FD_CLOEXEC); + fcntl(sigpipe[1], F_SETFD, fcntl(sigpipe[1], F_GETFD) | FD_CLOEXEC); + fcntl(sigpipe[0], F_SETFL, fcntl(sigpipe[0], F_GETFL) | O_NONBLOCK); + fcntl(sigpipe[1], F_SETFL, fcntl(sigpipe[1], F_GETFL) | O_NONBLOCK); + /* * Compute mask of all interesting signals and install signal handlers * for each. Only one signal handler may be active at a time. Therefore, @@ -734,12 +724,18 @@ * unit we are using. */ void -set_ifunit(iskey) - int iskey; +set_ifunit(int iskey) { - info("Using interface %s%d", PPP_DRV_NAME, ifunit); - slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit); + char ifkey[32]; + + if (req_ifname[0] != '\0') + slprintf(ifname, sizeof(ifname), "%s", req_ifname); + else + slprintf(ifname, sizeof(ifname), "%s%d", PPP_DRV_NAME, ifunit); + info("Using interface %s", ifname); script_setenv("IFNAME", ifname, iskey); + slprintf(ifkey, sizeof(ifkey), "%d", ifunit); + script_setenv("UNIT", ifkey, iskey); if (iskey) { create_pidfile(getpid()); /* write pid to file */ create_linkpidfile(getpid()); @@ -750,7 +746,7 @@ * detach - detach us from the controlling terminal. */ void -detach() +detach(void) { int pid; char numbuf[16]; @@ -770,8 +766,7 @@ /* update pid files if they have been written already */ if (pidfilename[0]) create_pidfile(pid); - if (linkpidfile[0]) - create_linkpidfile(pid); + create_linkpidfile(pid); exit(0); /* parent dies */ } setsid(); @@ -795,7 +790,7 @@ * reopen_log - (re)open our connection to syslog. */ void -reopen_log() +reopen_log(void) { openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); setlogmask(LOG_UPTO(LOG_INFO)); @@ -805,8 +800,7 @@ * Create a file containing our process ID. */ static void -create_pidfile(pid) - int pid; +create_pidfile(int pid) { FILE *pidfile; @@ -822,8 +816,7 @@ } void -create_linkpidfile(pid) - int pid; +create_linkpidfile(int pid) { FILE *pidfile; @@ -846,7 +839,7 @@ /* * remove_pidfile - remove our pid files */ -void remove_pidfiles() +void remove_pidfiles(void) { if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) warn("unable to delete pid file %s: %m", pidfilename); @@ -860,8 +853,7 @@ * holdoff_end - called via a timeout when the holdoff period ends. */ static void -holdoff_end(arg) - void *arg; +holdoff_end(void *arg) { new_phase(PHASE_DORMANT); } @@ -1005,8 +997,7 @@ * protocol_name - find a name for a PPP protocol. */ const char * -protocol_name(proto) - int proto; +protocol_name(int proto) { struct protocol_list *lp; @@ -1020,7 +1011,7 @@ * get_input - called when incoming data is available. */ static void -get_input() +get_input(void) { int len, i; u_char *p; @@ -1112,10 +1103,7 @@ * itself), otherwise 0. */ int -ppp_send_config(unit, mtu, accm, pcomp, accomp) - int unit, mtu; - u_int32_t accm; - int pcomp, accomp; +ppp_send_config(int unit, int mtu, u_int32_t accm, int pcomp, int accomp) { int errs; @@ -1133,10 +1121,7 @@ * itself), otherwise 0. */ int -ppp_recv_config(unit, mru, accm, pcomp, accomp) - int unit, mru; - u_int32_t accm; - int pcomp, accomp; +ppp_recv_config(int unit, int mru, u_int32_t accm, int pcomp, int accomp) { int errs; @@ -1151,8 +1136,7 @@ * new_phase - signal the start of a new phase of pppd's operation. */ void -new_phase(p) - int p; +new_phase(int p) { phase = p; if (new_phase_hook) @@ -1164,8 +1148,7 @@ * die - clean up state and exit with the specified status. */ void -die(status) - int status; +die(int status) { if (!doing_multilink || multilink_master) print_link_stats(); @@ -1180,7 +1163,7 @@ */ /* ARGSUSED */ static void -cleanup() +cleanup(void) { sys_cleanup(); @@ -1198,7 +1181,7 @@ } void -print_link_stats() +print_link_stats(void) { /* * Print connect time and statistics. @@ -1216,26 +1199,24 @@ * reset_link_stats - "reset" stats when link goes up. */ void -reset_link_stats(u) - int u; +reset_link_stats(int u) { if (!get_ppp_stats(u, &old_link_stats)) return; - gettimeofday(&start_time, NULL); + get_time(&start_time); } /* * update_link_stats - get stats at link termination. */ void -update_link_stats(u) - int u; +update_link_stats(int u) { struct timeval now; char numbuf[32]; if (!get_ppp_stats(u, &link_stats) - || gettimeofday(&now, NULL) < 0) + || get_time(&now) < 0) return; link_connect_time = now.tv_sec - start_time.tv_sec; link_stats_valid = 1; @@ -1257,7 +1238,7 @@ struct callout { struct timeval c_time; /* time at which to call routine */ void *c_arg; /* argument to routine */ - void (*c_func) __P((void *)); /* routine */ + void (*c_func)(void *); /* routine */ struct callout *c_next; }; @@ -1268,10 +1249,7 @@ * timeout - Schedule a timeout. */ void -timeout(func, arg, secs, usecs) - void (*func) __P((void *)); - void *arg; - int secs, usecs; +timeout(void (*func)(void *), void *arg, int secs, int usecs) { struct callout *newp, *p, **pp; @@ -1282,7 +1260,7 @@ fatal("Out of memory in timeout()!"); newp->c_arg = arg; newp->c_func = func; - gettimeofday(&timenow, NULL); + get_time(&timenow); newp->c_time.tv_sec = timenow.tv_sec + secs; newp->c_time.tv_usec = timenow.tv_usec + usecs; if (newp->c_time.tv_usec >= 1000000) { @@ -1307,9 +1285,7 @@ * untimeout - Unschedule a timeout. */ void -untimeout(func, arg) - void (*func) __P((void *)); - void *arg; +untimeout(void (*func)(void *), void *arg) { struct callout **copp, *freep; @@ -1329,14 +1305,14 @@ * calltimeout - Call any timeout routines which are now due. */ static void -calltimeout() +calltimeout(void) { struct callout *p; while (callout != NULL) { p = callout; - if (gettimeofday(&timenow, NULL) < 0) + if (get_time(&timenow) < 0) fatal("Failed to get time of day: %m"); if (!(p->c_time.tv_sec < timenow.tv_sec || (p->c_time.tv_sec == timenow.tv_sec @@ -1355,13 +1331,12 @@ * timeleft - return the length of time until the next timeout is due. */ static struct timeval * -timeleft(tvp) - struct timeval *tvp; +timeleft(struct timeval *tvp) { if (callout == NULL) return NULL; - gettimeofday(&timenow, NULL); + get_time(&timenow); tvp->tv_sec = callout->c_time.tv_sec - timenow.tv_sec; tvp->tv_usec = callout->c_time.tv_usec - timenow.tv_usec; if (tvp->tv_usec < 0) { @@ -1380,8 +1355,7 @@ * We assume that sig is currently blocked. */ static void -kill_my_pg(sig) - int sig; +kill_my_pg(int sig) { struct sigaction act, oldact; struct subprocess *chp; @@ -1427,8 +1401,7 @@ * signal, we just take the link down. */ static void -hup(sig) - int sig; +hup(int sig) { /* can't log a message here, it can deadlock */ got_sighup = 1; @@ -1437,7 +1410,7 @@ kill_my_pg(sig); notify(sigreceived, sig); if (waiting) - siglongjmp(sigjmp, 1); + write(sigpipe[1], &sig, sizeof(sig)); } @@ -1448,8 +1421,7 @@ */ /*ARGSUSED*/ static void -term(sig) - int sig; +term(int sig) { /* can't log a message here, it can deadlock */ got_sigterm = sig; @@ -1458,7 +1430,7 @@ kill_my_pg(sig); notify(sigreceived, sig); if (waiting) - siglongjmp(sigjmp, 1); + write(sigpipe[1], &sig, sizeof(sig)); } @@ -1467,12 +1439,11 @@ * Sets a flag so we will call reap_kids in the mainline. */ static void -chld(sig) - int sig; +chld(int sig) { got_sigchld = 1; if (waiting) - siglongjmp(sigjmp, 1); + write(sigpipe[1], &sig, sizeof(sig)); } @@ -1483,8 +1454,7 @@ */ /*ARGSUSED*/ static void -toggle_debug(sig) - int sig; +toggle_debug(int sig) { debug = !debug; if (debug) { @@ -1502,12 +1472,11 @@ */ /*ARGSUSED*/ static void -open_ccp(sig) - int sig; +open_ccp(int sig) { got_sigusr2 = 1; if (waiting) - siglongjmp(sigjmp, 1); + write(sigpipe[1], &sig, sizeof(sig)); } @@ -1515,8 +1484,7 @@ * bad_signal - We've caught a fatal signal. Clean up state and exit. */ static void -bad_signal(sig) - int sig; +bad_signal(int sig) { static int crashed = 0; @@ -1571,7 +1539,8 @@ /* Executing in the child */ sys_close(); #ifdef USE_TDB - tdb_close(pppdb); + if (pppdb != NULL) + tdb_close(pppdb); #endif /* make sure infd, outfd and errfd won't get tromped on below */ @@ -1616,9 +1585,7 @@ } static bool -add_script_env(pos, newstring) - int pos; - char *newstring; +add_script_env(int pos, char *newstring) { if (pos + 1 >= s_env_nalloc) { int new_n = pos + 17; @@ -1636,8 +1603,7 @@ } static void -remove_script_env(pos) - int pos; +remove_script_env(int pos) { free(script_env[pos] - 1); while ((script_env[pos] = script_env[pos + 1]) != NULL) @@ -1649,7 +1615,7 @@ * and update the system environment. */ static void -update_system_environment() +update_system_environment(void) { struct userenv *uep; @@ -1667,10 +1633,7 @@ * stderr gets connected to the log fd or to the _PATH_CONNERRS file. */ int -device_script(program, in, out, dont_wait) - char *program; - int in, out; - int dont_wait; +device_script(char *program, int in, int out, int dont_wait) { int pid; int status = -1; @@ -1679,7 +1642,7 @@ if (log_to_fd >= 0) errfd = log_to_fd; else - errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600); + errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0644); ++conn_running; pid = safe_fork(in, out, errfd); @@ -1732,7 +1695,7 @@ * script_unsetenv() safely after this routine is run. */ static void -update_script_environment() +update_script_environment(void) { struct userenv *uep; @@ -1756,7 +1719,7 @@ script_env[i] = newstring; else add_script_env(i, newstring); - } else { + } else if (p != NULL) { remove_script_env(i); } } @@ -1773,13 +1736,7 @@ * reap_kids) iff the return value is > 0. */ pid_t -run_program(prog, args, must_exist, done, arg, wait) - char *prog; - char **args; - int must_exist; - void (*done) __P((void *)); - void *arg; - int wait; +run_program(char *prog, char **args, int must_exist, void (*done)(void *), void *arg, int wait) { int pid, status; struct stat sbuf; @@ -1850,12 +1807,7 @@ * to use. */ void -record_child(pid, prog, done, arg, killable) - int pid; - char *prog; - void (*done) __P((void *)); - void *arg; - int killable; +record_child(int pid, char *prog, void (*done)(void *), void *arg, int killable) { struct subprocess *chp; @@ -1880,8 +1832,7 @@ * exit, send them all a SIGTERM. */ static void -childwait_end(arg) - void *arg; +childwait_end(void *arg) { struct subprocess *chp; @@ -1897,8 +1848,7 @@ * forget_child - clean up after a dead child */ static void -forget_child(pid, status) - int pid, status; +forget_child(int pid, int status) { struct subprocess *chp, **prevp; @@ -1927,7 +1877,7 @@ * and log a message for abnormal terminations. */ static int -reap_kids() +reap_kids(void) { int pid, status; @@ -1949,10 +1899,7 @@ * add_notifier - add a new function to be called when something happens. */ void -add_notifier(notif, func, arg) - struct notifier **notif; - notify_func func; - void *arg; +add_notifier(struct notifier **notif, notify_func func, void *arg) { struct notifier *np; @@ -1970,10 +1917,7 @@ * be called when something happens. */ void -remove_notifier(notif, func, arg) - struct notifier **notif; - notify_func func; - void *arg; +remove_notifier(struct notifier **notif, notify_func func, void *arg) { struct notifier *np; @@ -1990,9 +1934,7 @@ * notify - call a set of functions registered with add_notifier. */ void -notify(notif, val) - struct notifier *notif; - int val; +notify(struct notifier *notif, int val) { struct notifier *np; @@ -2006,8 +1948,7 @@ * novm - log an error message saying we ran out of memory, and die. */ void -novm(msg) - char *msg; +novm(char *msg) { fatal("Virtual memory exhausted allocating %s\n", msg); } @@ -2017,9 +1958,7 @@ * for scripts that we run (e.g. ip-up, auth-up, etc.) */ void -script_setenv(var, value, iskey) - char *var, *value; - int iskey; +script_setenv(char *var, char *value, int iskey) { size_t varl = strlen(var); size_t vl = varl + strlen(value) + 2; @@ -2080,8 +2019,7 @@ * for scripts. */ void -script_unsetenv(var) - char *var; +script_unsetenv(char *var) { int vl = strlen(var); int i; @@ -2115,7 +2053,7 @@ * lock_db - get an exclusive lock on the TDB database. * Used to ensure atomicity of various lookup/modify operations. */ -void lock_db() +void lock_db(void) { #ifdef USE_TDB TDB_DATA key; @@ -2129,7 +2067,7 @@ /* * unlock_db - remove the exclusive lock obtained by lock_db. */ -void unlock_db() +void unlock_db(void) { #ifdef USE_TDB TDB_DATA key; @@ -2145,7 +2083,7 @@ * update_db_entry - update our entry in the database. */ static void -update_db_entry() +update_db_entry(void) { TDB_DATA key, dbuf; int vlen, i; @@ -2179,8 +2117,7 @@ * add_db_key - add a key that we can use to look up our database entry. */ static void -add_db_key(str) - const char *str; +add_db_key(const char *str) { TDB_DATA key, dbuf; @@ -2196,8 +2133,7 @@ * delete_db_key - delete a key for looking up our database entry. */ static void -delete_db_key(str) - const char *str; +delete_db_key(const char *str) { TDB_DATA key; @@ -2210,7 +2146,7 @@ * cleanup_db - delete all the entries we put in the database. */ static void -cleanup_db() +cleanup_db(void) { TDB_DATA key; int i; diff -Nru ppp-2.4.7/pppd/Makefile.linux ppp-2.4.9/pppd/Makefile.linux --- ppp-2.4.7/pppd/Makefile.linux 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/Makefile.linux 2021-01-05 00:06:37.000000000 +0100 @@ -1,8 +1,12 @@ # # pppd makefile for Linux -# $Id: Makefile.linux,v 1.70 2007/06/19 02:08:34 carlsonj Exp $ +# 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 @@ -30,15 +34,12 @@ include .depend endif -# CC = gcc -# -COPTS = -O2 -pipe -Wall -g -LIBS = +LIBS = -lrt -# Uncomment the next 2 lines to include support for Microsoft's +# 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 +#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 @@ -60,6 +61,11 @@ # 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 @@ -73,14 +79,19 @@ # Enable EAP SRP-SHA1 authentication (requires libsrp) #USE_SRP=y -# Use libutil +# Use libutil; test if logwtmp is declared in to detect +ifeq ($(shell echo '\#include ' | $(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 +COMPILE_FLAGS= -DHAVE_PATHS_H -DIPX_CHANGE -DHAVE_MMAP -pipe CFLAGS= $(COPTS) $(COMPILE_FLAGS) $(INCLUDE_DIRS) '-DDESTDIR="@DESTDIR@"' @@ -94,15 +105,17 @@ 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 -lcrypto +LIBS += -lsrp -L/usr/local/ssl/lib +NEEDCRYPTOLIB = y TARGETS += srp-entry -EXTRAINSTALL = $(INSTALL) -s -c -m 555 srp-entry $(BINDIR)/srp-entry +EXTRAINSTALL = $(INSTALL) -c -m 555 srp-entry $(BINDIR)/srp-entry MANPAGES += srp-entry.8 EXTRACLEAN += srp-entry.o NEEDDES=y @@ -115,12 +128,22 @@ 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 -ifneq ($(wildcard /usr/include/crypt.h),) +ifeq ($(shell echo '\#include ' | $(CC) -E - >/dev/null 2>&1 && echo yes),yes) CFLAGS += -DHAVE_CRYPT_H=1 LIBS += -lcrypt endif @@ -132,7 +155,8 @@ ifdef NEEDDES ifndef USE_CRYPT -LIBS += -ldes $(LIBS) +CFLAGS += -I$(shell $(CC) --print-sysroot)/usr/include/openssl +NEEDCRYPTOLIB = y else CFLAGS += -DUSE_CRYPT=1 endif @@ -140,6 +164,10 @@ 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 @@ -170,18 +198,21 @@ CFLAGS += -DLOCKLIB=1 endif +ifdef SYSTEMD +LIBS += -lsystemd +CFLAGS += -DSYSTEMD=1 +endif + ifdef PLUGIN CFLAGS += -DPLUGIN -LDFLAGS += -Wl,-E +LDFLAGS_PLUGIN += -Wl,-E LIBS += -ldl endif ifdef FILTER -ifneq ($(wildcard /usr/include/pcap-bpf.h),) LIBS += -lpcap CFLAGS += -DPPP_FILTER endif -endif ifdef HAVE_INET6 PPPDSRCS += ipv6cp.c eui64.c @@ -208,13 +239,13 @@ install: pppd mkdir -p $(BINDIR) $(MANDIR) $(EXTRAINSTALL) - $(INSTALL) -s -c -m 555 pppd $(BINDIR)/pppd + $(INSTALL) -c -m 555 pppd $(BINDIR)/pppd if chgrp pppusers $(BINDIR)/pppd 2>/dev/null; then \ chmod o-rx,u+s $(BINDIR)/pppd; fi $(INSTALL) -c -m 444 pppd.8 $(MANDIR) pppd: $(PPPDOBJS) - $(CC) $(CFLAGS) $(LDFLAGS) -o pppd $(PPPDOBJS) $(LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) $(LDFLAGS_PLUGIN) -o pppd $(PPPDOBJS) $(LIBS) srp-entry: srp-entry.c $(CC) $(CFLAGS) $(LDFLAGS) -o $@ srp-entry.c $(LIBS) diff -Nru ppp-2.4.7/pppd/Makefile.sol2 ppp-2.4.9/pppd/Makefile.sol2 --- ppp-2.4.7/pppd/Makefile.sol2 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/Makefile.sol2 2021-01-05 00:06:37.000000000 +0100 @@ -39,6 +39,14 @@ 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 diff -Nru ppp-2.4.7/pppd/md4.c ppp-2.4.9/pppd/md4.c --- ppp-2.4.7/pppd/md4.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/md4.c 2021-01-05 00:06:37.000000000 +0100 @@ -87,8 +87,7 @@ ** This is a user-callable routine. */ void -MD4Print(MDp) -MD4_CTX *MDp; +MD4Print(MD4_CTX *MDp) { int i,j; for (i=0;i<4;i++) @@ -101,8 +100,7 @@ ** This is a user-callable routine. */ void -MD4Init(MDp) -MD4_CTX *MDp; +MD4Init(MD4_CTX *MDp) { int i; MDp->buffer[0] = I0; @@ -120,9 +118,7 @@ ** This routine is not user-callable. */ static void -MDblock(MDp,Xb) -MD4_CTX *MDp; -unsigned char *Xb; +MDblock(MD4_CTX *MDp, unsigned char *Xb) { register unsigned int tmp, A, B, C, D; unsigned int X[16]; @@ -206,10 +202,7 @@ ** if desired. */ void -MD4Update(MDp,X,count) -MD4_CTX *MDp; -unsigned char *X; -unsigned int count; +MD4Update(MD4_CTX *MDp, unsigned char *X, unsigned int count) { unsigned int i, tmp, bit, byte, mask; unsigned char XX[64]; @@ -277,9 +270,7 @@ ** Finish up MD4 computation and return message digest. */ void -MD4Final(buf, MD) -unsigned char *buf; -MD4_CTX *MD; +MD4Final(unsigned char *buf, MD4_CTX *MD) { int i, j; unsigned int w; diff -Nru ppp-2.4.7/pppd/md4.h ppp-2.4.9/pppd/md4.h --- ppp-2.4.7/pppd/md4.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/md4.h 2021-01-05 00:06:37.000000000 +0100 @@ -8,15 +8,6 @@ ** ******************************************************************** */ -#ifndef __P -# if defined(__STDC__) || defined(__GNUC__) -# define __P(x) x -# else -# define __P(x) () -# endif -#endif - - /* MDstruct is the data structure for a message digest computation. */ typedef struct { @@ -29,7 +20,7 @@ ** Initialize the MD4_CTX prepatory to doing a message digest ** computation. */ -extern void MD4Init __P((MD4_CTX *MD)); +extern void MD4Init(MD4_CTX *MD); /* MD4Update(MD,X,count) ** Input: X -- a pointer to an array of unsigned characters. @@ -43,7 +34,7 @@ ** every MD computation should end with one call to MD4Update with a ** count less than 512. Zero is OK for a count. */ -extern void MD4Update __P((MD4_CTX *MD, unsigned char *X, unsigned int count)); +extern void MD4Update(MD4_CTX *MD, unsigned char *X, unsigned int count); /* MD4Print(MD) ** Prints message digest buffer MD as 32 hexadecimal digits. @@ -51,13 +42,13 @@ ** of buffer[3]. ** Each byte is printed with high-order hexadecimal digit first. */ -extern void MD4Print __P((MD4_CTX *)); +extern void MD4Print(MD4_CTX *); /* MD4Final(buf, MD) ** Returns message digest from MD and terminates the message ** digest computation. */ -extern void MD4Final __P((unsigned char *, MD4_CTX *)); +extern void MD4Final(unsigned char *, MD4_CTX *); /* ** End of md4.h diff -Nru ppp-2.4.7/pppd/md5.c ppp-2.4.9/pppd/md5.c --- ppp-2.4.7/pppd/md5.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/md5.c 2021-01-05 00:06:37.000000000 +0100 @@ -102,8 +102,7 @@ /* The routine MD5_Init initializes the message-digest context mdContext. All fields are set to zero. */ -void MD5_Init (mdContext) -MD5_CTX *mdContext; +void MD5_Init (MD5_CTX *mdContext) { mdContext->i[0] = mdContext->i[1] = (UINT4)0; @@ -119,10 +118,7 @@ account for the presence of each of the characters inBuf[0..inLen-1] in the message whose digest is being computed. */ -void MD5_Update (mdContext, inBuf, inLen) -MD5_CTX *mdContext; -unsigned char *inBuf; -unsigned int inLen; +void MD5_Update (MD5_CTX *mdContext, unsigned char *inBuf, unsigned int inLen) { UINT4 in[16]; int mdi; @@ -157,9 +153,7 @@ /* The routine MD5Final terminates the message-digest computation and ends with the desired message digest in mdContext->digest[0...15]. */ -void MD5_Final (hash, mdContext) -unsigned char hash[]; -MD5_CTX *mdContext; +void MD5_Final (unsigned char hash[], MD5_CTX *mdContext) { UINT4 in[16]; int mdi; @@ -200,9 +194,7 @@ /* Basic MD5 step. Transforms buf based on in. */ -static void Transform (buf, in) -UINT4 *buf; -UINT4 *in; +static void Transform (UINT4 *buf, UINT4 *in) { UINT4 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; diff -Nru ppp-2.4.7/pppd/multilink.c ppp-2.4.9/pppd/multilink.c --- ppp-2.4.7/pppd/multilink.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/multilink.c 2021-01-05 00:06:37.000000000 +0100 @@ -50,13 +50,13 @@ extern TDB_CONTEXT *pppdb; extern char db_key[]; -static void make_bundle_links __P((int append)); -static void remove_bundle_link __P((void)); -static void iterate_bundle_links __P((void (*func) __P((char *)))); - -static int get_default_epdisc __P((struct epdisc *)); -static int parse_num __P((char *str, const char *key, int *valp)); -static int owns_unit __P((TDB_DATA pid, int unit)); +static void make_bundle_links(int append); +static void remove_bundle_link(void); +static void iterate_bundle_links(void (*func)(char *)); + +static int get_default_epdisc(struct epdisc *); +static int parse_num(char *str, const char *key, int *valp); +static int owns_unit(TDB_DATA pid, int unit); #define set_ip_epdisc(ep, addr) do { \ ep->length = 4; \ @@ -74,7 +74,7 @@ #define process_exists(n) (kill((n), 0) == 0 || errno != ESRCH) void -mp_check_options() +mp_check_options(void) { lcp_options *wo = &lcp_wantoptions[0]; lcp_options *ao = &lcp_allowoptions[0]; @@ -102,7 +102,7 @@ * if we are doing multilink. */ int -mp_join_bundle() +mp_join_bundle(void) { lcp_options *go = &lcp_gotoptions[0]; lcp_options *ho = &lcp_hisoptions[0]; @@ -204,7 +204,7 @@ /* make sure the string is null-terminated */ rec.dptr[rec.dsize-1] = 0; /* parse the interface number */ - parse_num(rec.dptr, "IFNAME=ppp", &unit); + parse_num(rec.dptr, "UNIT=", &unit); /* check the pid value */ if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid) || !process_exists(pppd_pid) @@ -240,7 +240,7 @@ return 0; } -void mp_exit_bundle() +void mp_exit_bundle(void) { lock_db(); remove_bundle_link(); @@ -258,7 +258,7 @@ } } -void mp_bundle_terminated() +void mp_bundle_terminated(void) { TDB_DATA key; @@ -325,7 +325,7 @@ free(p); } -static void remove_bundle_link() +static void remove_bundle_link(void) { TDB_DATA key, rec; char entry[32]; @@ -388,10 +388,7 @@ } static int -parse_num(str, key, valp) - char *str; - const char *key; - int *valp; +parse_num(char *str, const char *key, int *valp) { char *p, *endp; int i; @@ -412,15 +409,13 @@ * Check whether the pppd identified by `key' still owns ppp unit `unit'. */ static int -owns_unit(key, unit) - TDB_DATA key; - int unit; +owns_unit(TDB_DATA key, int unit) { char ifkey[32]; TDB_DATA kd, vd; int ret = 0; - slprintf(ifkey, sizeof(ifkey), "IFNAME=ppp%d", unit); + slprintf(ifkey, sizeof(ifkey), "UNIT=%d", unit); kd.dptr = ifkey; kd.dsize = strlen(ifkey); vd = tdb_fetch(pppdb, kd); @@ -433,16 +428,13 @@ } static int -get_default_epdisc(ep) - struct epdisc *ep; +get_default_epdisc(struct epdisc *ep) { - char *p; struct hostent *hp; u_int32_t addr; /* First try for an ethernet MAC address */ - p = get_first_ethernet(); - if (p != 0 && get_if_hwaddr(ep->value, p) >= 0) { + if (get_first_ether_hwaddr(ep->value) >= 0) { ep->class = EPD_MAC; ep->length = 6; return 1; @@ -474,8 +466,7 @@ }; char * -epdisc_to_str(ep) - struct epdisc *ep; +epdisc_to_str(struct epdisc *ep) { static char str[MAX_ENDP_LEN*3+8]; u_char *p = ep->value; @@ -525,9 +516,7 @@ } int -str_to_epdisc(ep, str) - struct epdisc *ep; - char *str; +str_to_epdisc(struct epdisc *ep, char *str) { int i, l; char *p, *endp; @@ -589,4 +578,3 @@ ep->length = l; return 1; } - diff -Nru ppp-2.4.7/pppd/options.c ppp-2.4.9/pppd/options.c --- ppp-2.4.7/pppd/options.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/options.c 2021-01-05 00:06:37.000000000 +0100 @@ -40,9 +40,8 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: options.c,v 1.102 2008/06/15 06:53:06 paulus Exp $" - #include +#include #include #include #include @@ -76,10 +75,9 @@ #include "pathnames.h" #if defined(ultrix) || defined(NeXT) -char *strdup __P((char *)); +char *strdup(char *); #endif -static const char rcsid[] = RCSID; struct option_value { struct option_value *next; @@ -97,6 +95,9 @@ bool nodetach = 0; /* Don't detach from controlling tty */ bool updetach = 0; /* Detach once link is up */ bool master_detach; /* Detach when we're (only) multilink master */ +#ifdef SYSTEMD +bool up_sdnotify = 0; /* Notify systemd once link is up */ +#endif int maxconnect = 0; /* Maximum connect time */ char user[MAXNAMELEN]; /* Username for PAP */ char passwd[MAXSECRETLEN]; /* Password for PAP */ @@ -114,6 +115,9 @@ bool tune_kernel; /* may alter kernel settings */ int connect_delay = 1000; /* wait this many ms after connect script */ int req_unit = -1; /* requested interface unit */ +char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */ +char path_ipdown[MAXPATHLEN];/* pathname of ip-down script */ +char req_ifname[MAXIFNAMELEN]; /* requested interface name */ bool multilink = 0; /* Enable multilink operation */ char *bundle_name = NULL; /* bundle name for multilink */ bool dump_options; /* print out option values */ @@ -121,6 +125,7 @@ char *domain; /* domain name set by domain option */ int child_wait = 5; /* # seconds to wait for children at exit */ struct userenv *userenv_list; /* user environment variables */ +int dfl_route_metric = -1; /* metric of the default route to set over the PPP link */ #ifdef MAXOCTETS unsigned int maxoctets = 0; /* default - no limit */ @@ -150,35 +155,35 @@ /* * Prototypes */ -static int setdomain __P((char **)); -static int readfile __P((char **)); -static int callfile __P((char **)); -static int showversion __P((char **)); -static int showhelp __P((char **)); -static void usage __P((void)); -static int setlogfile __P((char **)); +static int setdomain(char **); +static int readfile(char **); +static int callfile(char **); +static int showversion(char **); +static int showhelp(char **); +static void usage(void); +static int setlogfile(char **); #ifdef PLUGIN -static int loadplugin __P((char **)); +static int loadplugin(char **); #endif #ifdef PPP_FILTER -static int setpassfilter __P((char **)); -static int setactivefilter __P((char **)); +static int setpassfilter(char **); +static int setactivefilter(char **); #endif #ifdef MAXOCTETS -static int setmodir __P((char **)); +static int setmodir(char **); #endif -static int user_setenv __P((char **)); -static void user_setprint __P((option_t *, printer_func, void *)); -static int user_unsetenv __P((char **)); -static void user_unsetprint __P((option_t *, printer_func, void *)); - -static option_t *find_option __P((const char *name)); -static int process_option __P((option_t *, char *, char **)); -static int n_arguments __P((option_t *)); -static int number_option __P((char *, u_int32_t *, int)); +static int user_setenv(char **); +static void user_setprint(option_t *, printer_func, void *); +static int user_unsetenv(char **); +static void user_unsetprint(option_t *, printer_func, void *); + +static option_t *find_option(char *name); +static int process_option(option_t *, char *, char **); +static int n_arguments(option_t *); +static int number_option(char *, u_int32_t *, int); /* * Structure to store extra lists of options. @@ -207,6 +212,11 @@ "Don't detach from controlling tty", OPT_PRIO | 1 }, { "-detach", o_bool, &nodetach, "Don't detach from controlling tty", OPT_ALIAS | OPT_PRIOSUB | 1 }, +#ifdef SYSTEMD + { "up_sdnotify", o_bool, &up_sdnotify, + "Notify systemd once link is up (implies nodetach)", + OPT_PRIOSUB | OPT_A2COPY | 1, &nodetach }, +#endif { "updetach", o_bool, &updetach, "Detach from controlling tty once link is up", OPT_PRIOSUB | OPT_A2CLR | 1, &nodetach }, @@ -283,6 +293,10 @@ "PPP interface unit number to use if possible", OPT_PRIO | OPT_LLIMIT, 0, 0 }, + { "ifname", o_string, req_ifname, + "Set PPP interface name", + OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXIFNAMELEN }, + { "dump", o_bool, &dump_options, "Print out option values after parsing all options", 1 }, { "dryrun", o_bool, &dryrun, @@ -299,6 +313,17 @@ "Unset user environment variable", OPT_A2PRINTER | OPT_NOPRINT, (void *)user_unsetprint }, + { "defaultroute-metric", o_int, &dfl_route_metric, + "Metric to use for the default route (Linux only; -1 for default behavior)", + OPT_PRIV|OPT_LLIMIT|OPT_INITONLY, NULL, 0, -1 }, + + { "ip-up-script", o_string, path_ipup, + "Set pathname of ip-up script", + OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN }, + { "ip-down-script", o_string, path_ipdown, + "Set pathname of ip-down script", + OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN }, + #ifdef HAVE_MULTILINK { "multilink", o_bool, &multilink, "Enable multilink operation", OPT_PRIO | 1 }, @@ -368,9 +393,7 @@ * parse_args - parse a string of arguments from the command line. */ int -parse_args(argc, argv) - int argc; - char **argv; +parse_args(int argc, char **argv) { char *arg; option_t *opt; @@ -406,11 +429,7 @@ * and interpret them. */ int -options_from_file(filename, must_exist, check_prot, priv) - char *filename; - int must_exist; - int check_prot; - int priv; +options_from_file(char *filename, int must_exist, int check_prot, int priv) { FILE *f; int i, newline, ret, err; @@ -483,7 +502,7 @@ * and if so, interpret options from it. */ int -options_from_user() +options_from_user(void) { char *user, *path, *file; int ret; @@ -514,7 +533,7 @@ * files a lower priority than the command line. */ int -options_for_tty() +options_for_tty(void) { char *dev, *path, *p; int ret; @@ -544,9 +563,7 @@ * options_from_list - process a string of options in a wordlist. */ int -options_from_list(w, priv) - struct wordlist *w; - int priv; +options_from_list(struct wordlist *w, int priv) { char *argv[MAXARGS]; option_t *opt; @@ -590,18 +607,15 @@ * match_option - see if this option matches an option_t structure. */ static int -match_option(name, opt, dowild) - char *name; - option_t *opt; - int dowild; +match_option(char *name, option_t *opt, int dowild) { - int (*match) __P((char *, char **, int)); + int (*match)(char *, char **, int); if (dowild != (opt->type == o_wild)) return 0; if (!dowild) return strcmp(name, opt->name) == 0; - match = (int (*) __P((char *, char **, int))) opt->addr; + match = (int (*)(char *, char **, int)) opt->addr; return (*match)(name, NULL, 0); } @@ -611,8 +625,7 @@ * This could be optimized by using a hash table. */ static option_t * -find_option(name) - const char *name; +find_option(char *name) { option_t *opt; struct option_list *list; @@ -645,16 +658,13 @@ * process_option - process one new-style option. */ static int -process_option(opt, cmd, argv) - option_t *opt; - char *cmd; - char **argv; +process_option(option_t *opt, char *cmd, char **argv) { u_int32_t v; int iv, a; char *sv; - int (*parser) __P((char **)); - int (*wildp) __P((char *, char **, int)); + int (*parser)(char **); + int (*wildp)(char *, char **, int); char *optopt = (opt->type == o_wild)? "": " option"; int prio = option_priority; option_t *mainopt = opt; @@ -784,11 +794,16 @@ free(*optptr); *optptr = sv; } + /* obfuscate original argument for things like password */ + if (opt->flags & OPT_HIDE) { + memset(*argv, '?', strlen(*argv)); + *argv = "********"; + } break; case o_special_noarg: case o_special: - parser = (int (*) __P((char **))) opt->addr; + parser = (int (*)(char **)) opt->addr; curopt = opt; if (!(*parser)(argv)) return 0; @@ -812,7 +827,7 @@ break; case o_wild: - wildp = (int (*) __P((char *, char **, int))) opt->addr; + wildp = (int (*)(char *, char **, int)) opt->addr; if (!(*wildp)(cmd, argv, 1)) return 0; break; @@ -839,10 +854,7 @@ * and source of the option value. Otherwise returns 0. */ int -override_value(option, priority, source) - const char *option; - int priority; - const char *source; +override_value(char *option, int priority, const char *source) { option_t *opt; @@ -863,8 +875,7 @@ * n_arguments - tell how many arguments an option takes */ static int -n_arguments(opt) - option_t *opt; +n_arguments(option_t *opt) { return (opt->type == o_bool || opt->type == o_special_noarg || (opt->flags & OPT_NOARG))? 0: 1; @@ -874,8 +885,7 @@ * add_options - add a list of options to the set we grok. */ void -add_options(opt) - option_t *opt; +add_options(option_t *opt) { struct option_list *list; @@ -891,7 +901,7 @@ * check_options - check that options are valid and consistent. */ void -check_options() +check_options(void) { if (logfile_fd >= 0 && logfile_fd != log_to_fd) close(logfile_fd); @@ -901,10 +911,7 @@ * print_option - print out an option and its value */ static void -print_option(opt, mainopt, printer, arg) - option_t *opt, *mainopt; - printer_func printer; - void *arg; +print_option(option_t *opt, option_t *mainopt, printer_func printer, void *arg) { int i, v; char *p; @@ -966,15 +973,15 @@ printer(arg, " "); } if (opt->flags & OPT_A2PRINTER) { - void (*oprt) __P((option_t *, printer_func, void *)); - oprt = (void (*) __P((option_t *, printer_func, - void *)))opt->addr2; + void (*oprt)(option_t *, printer_func, void *); + oprt = (void (*)(option_t *, printer_func, void *)) + opt->addr2; (*oprt)(opt, printer, arg); } else if (opt->flags & OPT_A2STRVAL) { p = (char *) opt->addr2; if ((opt->flags & OPT_STATIC) == 0) p = *(char **)p; - printer("%q", p); + printer(arg, "%q", p); } else if (opt->flags & OPT_A2LIST) { struct option_value *ovp; @@ -1003,10 +1010,7 @@ * array of options. */ static void -print_option_list(opt, printer, arg) - option_t *opt; - printer_func printer; - void *arg; +print_option_list(option_t *opt, printer_func printer, void *arg) { while (opt->name != NULL) { if (opt->priority != OPRIO_DEFAULT @@ -1022,9 +1026,7 @@ * print_options - print out what options are in effect. */ void -print_options(printer, arg) - printer_func printer; - void *arg; +print_options(printer_func printer, void *arg) { struct option_list *list; int i; @@ -1043,7 +1045,7 @@ * usage - print out a message telling how to use the program. */ static void -usage() +usage(void) { if (phase == PHASE_INITIALIZE) fprintf(stderr, usage_string, VERSION, progname); @@ -1053,8 +1055,7 @@ * showhelp - print out usage message and exit. */ static int -showhelp(argv) - char **argv; +showhelp(char **argv) { if (phase == PHASE_INITIALIZE) { usage(); @@ -1067,11 +1068,10 @@ * showversion - print out the version number and exit. */ static int -showversion(argv) - char **argv; +showversion(char **argv) { if (phase == PHASE_INITIALIZE) { - fprintf(stderr, "pppd version %s\n", VERSION); + fprintf(stdout, "pppd version %s\n", VERSION); exit(0); } return 0; @@ -1083,18 +1083,12 @@ * stderr if phase == PHASE_INITIALIZE. */ void -option_error __V((char *fmt, ...)) +option_error(char *fmt, ...) { va_list args; char buf[1024]; -#if defined(__STDC__) va_start(args, fmt); -#else - char *fmt; - va_start(args); - fmt = va_arg(args, char *); -#endif vslprintf(buf, sizeof(buf), fmt, args); va_end(args); if (phase == PHASE_INITIALIZE) @@ -1107,8 +1101,7 @@ * readable - check if a file is readable by the real user. */ int -readable(fd) - int fd; +readable(int fd) { uid_t uid; int i; @@ -1137,11 +1130,7 @@ * \ is ignored. */ int -getword(f, word, newlinep, filename) - FILE *f; - char *word; - int *newlinep; - char *filename; +getword(FILE *f, char *word, int *newlinep, char *filename) { int c, len, escape; int quoted, comment; @@ -1340,6 +1329,7 @@ c = getc(f); } + word[MAXWORDLEN-1] = 0; /* make sure word is null-terminated */ /* * End of the word: check for errors. @@ -1382,10 +1372,7 @@ * number_option - parse an unsigned numeric parameter for an option. */ static int -number_option(str, valp, base) - char *str; - u_int32_t *valp; - int base; +number_option(char *str, u_int32_t *valp, int base) { char *ptr; @@ -1405,9 +1392,7 @@ * if there is an error. */ int -int_option(str, valp) - char *str; - int *valp; +int_option(char *str, int *valp) { u_int32_t v; @@ -1426,8 +1411,7 @@ * readfile - take commands from a file. */ static int -readfile(argv) - char **argv; +readfile(char **argv) { return options_from_file(*argv, 1, 1, privileged_option); } @@ -1437,8 +1421,7 @@ * Name may not contain /../, start with / or ../, or end in /.. */ static int -callfile(argv) - char **argv; +callfile(char **argv) { char *fname, *arg, *p; int l, ok; @@ -1468,6 +1451,7 @@ if ((fname = (char *) malloc(l)) == NULL) novm("call file name"); slprintf(fname, l, "%s%s", _PATH_PEERFILES, arg); + script_setenv("CALL_FILE", arg, 0); ok = options_from_file(fname, 1, 1, 1); @@ -1480,8 +1464,7 @@ * setpassfilter - Set the pass filter for packets */ static int -setpassfilter(argv) - char **argv; +setpassfilter(char **argv) { pcap_t *pc; int ret = 1; @@ -1501,8 +1484,7 @@ * setactivefilter - Set the active filter for packets */ static int -setactivefilter(argv) - char **argv; +setactivefilter(char **argv) { pcap_t *pc; int ret = 1; @@ -1523,8 +1505,7 @@ * setdomain - Set domain name to append to hostname */ static int -setdomain(argv) - char **argv; +setdomain(char **argv) { gethostname(hostname, MAXNAMELEN); if (**argv != 0) { @@ -1538,8 +1519,7 @@ } static int -setlogfile(argv) - char **argv; +setlogfile(char **argv) { int fd, err; uid_t euid; @@ -1571,8 +1551,7 @@ #ifdef MAXOCTETS static int -setmodir(argv) - char **argv; +setmodir(char **argv) { if(*argv == NULL) return 0; @@ -1591,13 +1570,12 @@ #ifdef PLUGIN static int -loadplugin(argv) - char **argv; +loadplugin(char **argv) { char *arg = *argv; void *handle; const char *err; - void (*init) __P((void)); + void (*init)(void); char *path = arg; const char *vers; @@ -1649,8 +1627,7 @@ * Set an environment variable specified by the user. */ static int -user_setenv(argv) - char **argv; +user_setenv(char **argv) { char *arg = argv[0]; char *eqp; @@ -1702,10 +1679,7 @@ } static void -user_setprint(opt, printer, arg) - option_t *opt; - printer_func printer; - void *arg; +user_setprint(option_t *opt, printer_func printer, void *arg) { struct userenv *uep, *uepnext; @@ -1725,8 +1699,7 @@ } static int -user_unsetenv(argv) - char **argv; +user_unsetenv(char **argv) { struct userenv *uep, **insp; char *arg = argv[0]; @@ -1735,7 +1708,7 @@ option_error("unexpected = in name: %s", arg); return 0; } - if (arg == '\0') { + if (*arg == '\0') { option_error("missing variable name for unset"); return 0; } @@ -1774,10 +1747,7 @@ } static void -user_unsetprint(opt, printer, arg) - option_t *opt; - printer_func printer; - void *arg; +user_unsetprint(option_t *opt, printer_func printer, void *arg) { struct userenv *uep, *uepnext; diff -Nru ppp-2.4.7/pppd/patchlevel.h ppp-2.4.9/pppd/patchlevel.h --- ppp-2.4.7/pppd/patchlevel.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/patchlevel.h 2021-01-05 00:06:37.000000000 +0100 @@ -1,2 +1,2 @@ -#define VERSION "2.4.7" -#define DATE "9 August 2014" +#define VERSION "2.4.9" +#define DATE "5 January 2021" diff -Nru ppp-2.4.7/pppd/pathnames.h ppp-2.4.9/pppd/pathnames.h --- ppp-2.4.7/pppd/pathnames.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/pathnames.h 2021-01-05 00:06:37.000000000 +0100 @@ -1,7 +1,5 @@ /* * define path names - * - * $Id: pathnames.h,v 1.18 2005/08/25 23:59:34 paulus Exp $ */ #ifdef HAVE_PATHS_H @@ -21,6 +19,13 @@ #define _PATH_UPAPFILE _ROOT_PATH "/etc/ppp/pap-secrets" #define _PATH_CHAPFILE _ROOT_PATH "/etc/ppp/chap-secrets" #define _PATH_SRPFILE _ROOT_PATH "/etc/ppp/srp-secrets" + +#ifdef USE_EAPTLS +#define _PATH_EAPTLSCLIFILE _ROOT_PATH "/etc/ppp/eaptls-client" +#define _PATH_EAPTLSSERVFILE _ROOT_PATH "/etc/ppp/eaptls-server" +#define _PATH_OPENSSLCONFFILE _ROOT_PATH "/etc/ppp/openssl.cnf" +#endif /* USE_EAPTLS */ + #define _PATH_SYSOPTIONS _ROOT_PATH "/etc/ppp/options" #define _PATH_IPUP _ROOT_PATH "/etc/ppp/ip-up" #define _PATH_IPDOWN _ROOT_PATH "/etc/ppp/ip-down" diff -Nru ppp-2.4.7/pppd/plugins/Makefile.linux ppp-2.4.9/pppd/plugins/Makefile.linux --- ppp-2.4.7/pppd/plugins/Makefile.linux 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/Makefile.linux 2021-01-05 00:06:37.000000000 +0100 @@ -1,15 +1,20 @@ -#CC = gcc -COPTS = -O2 -g -CFLAGS = $(COPTS) -I.. -I../../include -fPIC -LDFLAGS = -shared -INSTALL = install +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) -SUBDIRS := rp-pppoe pppoatm pppol2tp +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 @@ -27,22 +32,22 @@ endif all: $(PLUGINS) - for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d all; done + for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d all || exit $$?; done %.so: %.c - $(CC) -o $@ $(LDFLAGS) $(CFLAGS) $^ + $(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; done + 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; done + 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; done + for d in $(SUBDIRS); do $(MAKE) $(MFLAGS) -C $$d depend || exit $$?; done diff -Nru ppp-2.4.7/pppd/plugins/passprompt.c ppp-2.4.9/pppd/plugins/passprompt.c --- ppp-2.4.7/pppd/plugins/passprompt.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/passprompt.c 2021-01-05 00:06:37.000000000 +0100 @@ -17,6 +17,7 @@ char pppd_version[] = VERSION; static char promptprog[PATH_MAX+1]; +static int promptprog_refused = 0; static option_t options[] = { { "promptprog", o_string, promptprog, @@ -32,7 +33,7 @@ int readgood, wstat; ssize_t red; - if (promptprog[0] == 0 || access(promptprog, X_OK) < 0) + if (promptprog_refused || promptprog[0] == 0 || access(promptprog, X_OK) < 0) return -1; /* sorry, can't help */ if (!passwd) @@ -74,7 +75,7 @@ if (red == 0) break; if (red < 0) { - if (errno == EINTR) + if (errno == EINTR && !got_sigterm) continue; error("Can't read secret from %s: %m", promptprog); readgood = -1; @@ -86,7 +87,7 @@ /* now wait for child to exit */ while (waitpid(kid, &wstat, 0) < 0) { - if (errno != EINTR) { + if (errno != EINTR || got_sigterm) { warn("error waiting for %s: %m", promptprog); break; } @@ -97,9 +98,14 @@ passwd[readgood] = 0; if (!WIFEXITED(wstat)) warn("%s terminated abnormally", promptprog); - if (WEXITSTATUS(wstat)) - warn("%s exited with code %d", promptprog, WEXITSTATUS(status)); - + if (WEXITSTATUS(wstat)) { + warn("%s exited with code %d", promptprog, WEXITSTATUS(wstat)); + /* code when cancel was hit in the prompt prog */ + if (WEXITSTATUS(wstat) == 128) { + promptprog_refused = 1; + } + return -1; + } return 1; } @@ -107,4 +113,7 @@ { add_options(options); pap_passwd_hook = promptpass; +#ifdef USE_EAPTLS + eaptls_passwd_hook = promptpass; +#endif } diff -Nru ppp-2.4.7/pppd/plugins/passwordfd.c ppp-2.4.9/pppd/plugins/passwordfd.c --- ppp-2.4.7/pppd/plugins/passwordfd.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/passwordfd.c 2021-01-05 00:06:37.000000000 +0100 @@ -79,4 +79,8 @@ chap_check_hook = pwfd_check; chap_passwd_hook = pwfd_passwd; + +#ifdef USE_EAPTLS + eaptls_passwd_hook = pwfd_passwd; +#endif } diff -Nru ppp-2.4.7/pppd/plugins/pppoatm/Makefile.linux ppp-2.4.9/pppd/plugins/pppoatm/Makefile.linux --- ppp-2.4.7/pppd/plugins/pppoatm/Makefile.linux 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/pppoatm/Makefile.linux 2021-01-05 00:06:37.000000000 +0100 @@ -1,16 +1,17 @@ -#CC = gcc -COPTS = -O2 -g -CFLAGS = $(COPTS) -I../.. -I../../../include -fPIC -LDFLAGS = -shared -INSTALL = install - #*********************************************************************** +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 @@ -33,7 +34,7 @@ all: $(PLUGIN) $(PLUGIN): $(PLUGIN_OBJS) - $(CC) $(CFLAGS) -o $@ -shared $^ $(LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(LDFLAGS_SHARED) $^ $(LIBS) install: all $(INSTALL) -d -m 755 $(LIBDIR) diff -Nru ppp-2.4.7/pppd/plugins/pppoatm/pppoatm.c ppp-2.4.9/pppd/plugins/pppoatm/pppoatm.c --- ppp-2.4.7/pppd/plugins/pppoatm/pppoatm.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/pppoatm/pppoatm.c 2021-01-05 00:06:37.000000000 +0100 @@ -70,18 +70,20 @@ { struct sockaddr_atmpvc addr; extern struct stat devstat; + if (device_got_set) return 0; - //info("PPPoATM setdevname_pppoatm: '%s'", cp); + memset(&addr, 0, sizeof addr); if (text2atm(cp, (struct sockaddr *) &addr, sizeof(addr), - T2A_PVC | T2A_NAME) < 0) { - if(doit) - info("atm does not recognize: %s", cp); + T2A_PVC | T2A_NAME | T2A_WILDCARD) < 0) { + if (doit) + info("cannot parse the ATM address: %s", cp); return 0; - } - if (!doit) return 1; - //if (!dev_set_ok()) return -1; + } + if (!doit) + return 1; + memcpy(&pvcaddr, &addr, sizeof pvcaddr); strlcpy(devnam, cp, sizeof devnam); devstat.st_mode = S_IFSOCK; @@ -93,7 +95,6 @@ lcp_allowoptions[0].neg_asyncmap = 0; lcp_wantoptions[0].neg_pcompression = 0; } - info("PPPoATM setdevname_pppoatm - SUCCESS:%s", cp); device_got_set = 1; return 1; } @@ -108,6 +109,7 @@ static void set_line_discipline_pppoatm(int fd) { struct atm_backend_ppp be; + be.backend_num = ATM_BACKEND_PPP; if (!llc_encaps) be.encaps = PPPOATM_ENCAPS_VC; @@ -115,6 +117,7 @@ be.encaps = PPPOATM_ENCAPS_LLC; else be.encaps = PPPOATM_ENCAPS_AUTODETECT; + if (ioctl(fd, ATM_SETBACKEND, &be) < 0) fatal("ioctl(ATM_SETBACKEND): %m"); } @@ -168,7 +171,7 @@ void plugin_init(void) { -#if defined(__linux__) +#ifdef linux extern int new_style_driver; /* From sys-linux.c */ if (!ppp_available() && !new_style_driver) fatal("Kernel doesn't support ppp_generic - " @@ -176,9 +179,9 @@ #else fatal("No PPPoATM support on this OS"); #endif - info("PPPoATM plugin_init"); add_options(pppoa_options); } + struct channel pppoa_channel = { options: pppoa_options, process_extra_options: NULL, diff -Nru ppp-2.4.7/pppd/plugins/pppoe/common.c ppp-2.4.9/pppd/plugins/pppoe/common.c --- ppp-2.4.7/pppd/plugins/pppoe/common.c 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/pppd/plugins/pppoe/common.c 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,282 @@ +/*********************************************************************** +* +* common.c +* +* Implementation of user-space PPPoE redirector for Linux. +* +* Common functions used by PPPoE client and server +* +* Copyright (C) 2000 by 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. +* +***********************************************************************/ + +static char const RCSID[] = +"$Id: common.c,v 1.3 2008/06/09 08:34:23 paulus Exp $"; + +#define _GNU_SOURCE 1 +#include "pppoe.h" +#include "pppd/pppd.h" + +#include +#include +#include +#include /* for LOG_DEBUG */ + +#ifdef HAVE_UNISTD_H +#include +#endif + +/********************************************************************** +*%FUNCTION: parsePacket +*%ARGUMENTS: +* packet -- the PPPoE discovery packet to parse +* func -- function called for each tag in the packet +* extra -- an opaque data pointer supplied to parsing function +*%RETURNS: +* 0 if everything went well; -1 if there was an error +*%DESCRIPTION: +* Parses a PPPoE discovery packet, calling "func" for each tag in the packet. +* "func" is passed the additional argument "extra". +***********************************************************************/ +int +parsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra) +{ + UINT16_t len = ntohs(packet->length); + unsigned char *curTag; + UINT16_t tagType, tagLen; + + if (PPPOE_VER(packet->vertype) != 1) { + error("Invalid PPPoE version (%d)", PPPOE_VER(packet->vertype)); + return -1; + } + if (PPPOE_TYPE(packet->vertype) != 1) { + error("Invalid PPPoE type (%d)", PPPOE_TYPE(packet->vertype)); + return -1; + } + + /* Do some sanity checks on packet */ + if (len > ETH_JUMBO_LEN - PPPOE_OVERHEAD) { /* 6-byte overhead for PPPoE header */ + error("Invalid PPPoE packet length (%u)", len); + return -1; + } + + /* Step through the tags */ + curTag = packet->payload; + while (curTag - packet->payload + TAG_HDR_SIZE <= len) { + /* Alignment is not guaranteed, so do this by hand... */ + tagType = (curTag[0] << 8) + curTag[1]; + tagLen = (curTag[2] << 8) + curTag[3]; + if (tagType == TAG_END_OF_LIST) { + return 0; + } + if ((curTag - packet->payload) + tagLen + TAG_HDR_SIZE > len) { + error("Invalid PPPoE tag length (%u)", tagLen); + return -1; + } + func(tagType, tagLen, curTag+TAG_HDR_SIZE, extra); + curTag = curTag + TAG_HDR_SIZE + tagLen; + } + return 0; +} + +/*********************************************************************** +*%FUNCTION: sendPADT +*%ARGUMENTS: +* conn -- PPPoE connection +* msg -- if non-NULL, extra error message to include in PADT packet. +*%RETURNS: +* Nothing +*%DESCRIPTION: +* Sends a PADT packet +***********************************************************************/ +void +sendPADT(PPPoEConnection *conn, char const *msg) +{ + PPPoEPacket packet; + unsigned char *cursor = packet.payload; + + UINT16_t plen = 0; + + /* Do nothing if no session established yet */ + if (!conn->session) return; + + /* Do nothing if no discovery socket */ + if (conn->discoverySocket < 0) return; + + memcpy(packet.ethHdr.h_dest, conn->peerEth, ETH_ALEN); + memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN); + + packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery); + packet.vertype = PPPOE_VER_TYPE(1, 1); + packet.code = CODE_PADT; + packet.session = conn->session; + + /* Reset Session to zero so there is no possibility of + recursive calls to this function by any signal handler */ + conn->session = 0; + + /* If we're using Host-Uniq, copy it over */ + if (conn->hostUniq.length) { + int len = ntohs(conn->hostUniq.length); + memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE); + cursor += len + TAG_HDR_SIZE; + plen += len + TAG_HDR_SIZE; + } + + /* Copy error message */ + if (msg) { + PPPoETag err; + size_t elen = strlen(msg); + err.type = htons(TAG_GENERIC_ERROR); + err.length = htons(elen); + strcpy(err.payload, msg); + memcpy(cursor, &err, elen + TAG_HDR_SIZE); + cursor += elen + TAG_HDR_SIZE; + plen += elen + TAG_HDR_SIZE; + } + + /* Copy cookie and relay-ID if needed */ + if (conn->cookie.type) { + CHECK_ROOM(cursor, packet.payload, + ntohs(conn->cookie.length) + TAG_HDR_SIZE); + memcpy(cursor, &conn->cookie, ntohs(conn->cookie.length) + TAG_HDR_SIZE); + cursor += ntohs(conn->cookie.length) + TAG_HDR_SIZE; + plen += ntohs(conn->cookie.length) + TAG_HDR_SIZE; + } + + if (conn->relayId.type) { + CHECK_ROOM(cursor, packet.payload, + ntohs(conn->relayId.length) + TAG_HDR_SIZE); + memcpy(cursor, &conn->relayId, ntohs(conn->relayId.length) + TAG_HDR_SIZE); + cursor += ntohs(conn->relayId.length) + TAG_HDR_SIZE; + plen += ntohs(conn->relayId.length) + TAG_HDR_SIZE; + } + + packet.length = htons(plen); + sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE)); + info("Sent PADT"); +} + +#define EH(x) (x)[0], (x)[1], (x)[2], (x)[3], (x)[4], (x)[5] + +/* Print out a PPPOE packet for debugging */ +void pppoe_printpkt(PPPoEPacket *packet, + void (*printer)(void *, char *, ...), void *arg) +{ + int len = ntohs(packet->length); + int i, tag, tlen, text; + + switch (ntohs(packet->ethHdr.h_proto)) { + case ETH_PPPOE_DISCOVERY: + printer(arg, "PPPOE Discovery V%dT%d ", PPPOE_VER(packet->vertype), + PPPOE_TYPE(packet->vertype)); + switch (packet->code) { + case CODE_PADI: + printer(arg, "PADI"); + break; + case CODE_PADO: + printer(arg, "PADO"); + break; + case CODE_PADR: + printer(arg, "PADR"); + break; + case CODE_PADS: + printer(arg, "PADS"); + break; + case CODE_PADT: + printer(arg, "PADT"); + break; + default: + printer(arg, "unknown code %x", packet->code); + } + printer(arg, " session 0x%x length %d\n", ntohs(packet->session), len); + break; + case ETH_PPPOE_SESSION: + printer(arg, "PPPOE Session V%dT%d", PPPOE_VER(packet->vertype), + PPPOE_TYPE(packet->vertype)); + printer(arg, " code 0x%x session 0x%x length %d\n", packet->code, + ntohs(packet->session), len); + break; + default: + printer(arg, "Unknown ethernet frame with proto = 0x%x\n", + ntohs(packet->ethHdr.h_proto)); + } + + printer(arg, " dst %02x:%02x:%02x:%02x:%02x:%02x ", EH(packet->ethHdr.h_dest)); + printer(arg, " src %02x:%02x:%02x:%02x:%02x:%02x\n", EH(packet->ethHdr.h_source)); + if (ntohs(packet->ethHdr.h_proto) != ETH_PPPOE_DISCOVERY) + return; + + for (i = 0; i + TAG_HDR_SIZE <= len; i += tlen) { + tag = (packet->payload[i] << 8) + packet->payload[i+1]; + tlen = (packet->payload[i+2] << 8) + packet->payload[i+3]; + if (i + tlen + TAG_HDR_SIZE > len) + break; + text = 0; + i += TAG_HDR_SIZE; + printer(arg, " ["); + switch (tag) { + case TAG_END_OF_LIST: + printer(arg, "end-of-list"); + break; + case TAG_SERVICE_NAME: + printer(arg, "service-name"); + text = 1; + break; + case TAG_AC_NAME: + printer(arg, "AC-name"); + text = 1; + break; + case TAG_HOST_UNIQ: + printer(arg, "host-uniq"); + break; + case TAG_AC_COOKIE: + printer(arg, "AC-cookie"); + break; + case TAG_VENDOR_SPECIFIC: + printer(arg, "vendor-specific"); + break; + case TAG_RELAY_SESSION_ID: + printer(arg, "relay-session-id"); + break; + case TAG_PPP_MAX_PAYLOAD: + printer(arg, "PPP-max-payload"); + break; + case TAG_SERVICE_NAME_ERROR: + printer(arg, "service-name-error"); + text = 1; + break; + case TAG_AC_SYSTEM_ERROR: + printer(arg, "AC-system-error"); + text = 1; + break; + case TAG_GENERIC_ERROR: + printer(arg, "generic-error"); + text = 1; + break; + default: + printer(arg, "unknown tag 0x%x", tag); + } + if (tlen) { + if (text) + printer(arg, " %.*v", tlen, &packet->payload[i]); + else if (tlen <= 32) + printer(arg, " %.*B", tlen, &packet->payload[i]); + else + printer(arg, " %.32B... (length %d)", + &packet->payload[i], tlen); + } + printer(arg, "]"); + } + printer(arg, "\n"); +} + +void pppoe_log_packet(const char *prefix, PPPoEPacket *packet) +{ + init_pr_log(prefix, LOG_DEBUG); + pppoe_printpkt(packet, pr_log, NULL); + end_pr_log(); +} diff -Nru ppp-2.4.7/pppd/plugins/pppoe/config.h ppp-2.4.9/pppd/plugins/pppoe/config.h --- ppp-2.4.7/pppd/plugins/pppoe/config.h 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/pppd/plugins/pppoe/config.h 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,129 @@ +/* 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 that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to `int' if 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 and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Define if your 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 header file. */ +#define HAVE_ASM_TYPES_H 1 + +/* Define if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_GETOPT_H 1 + +/* Define if you have the 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 header file. */ +#define HAVE_LINUX_IF_PACKET_H 1 + +/* Define if you have the header file. */ +#define HAVE_LINUX_IF_PPPOX_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_BPF_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_ARP_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_ETHERNET_H 1 + +/* Define if you have the header file. */ +#define HAVE_NET_IF_H 1 + +/* Define if you have the header file. */ +#define HAVE_LINUX_IF_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_NET_IF_DL_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NET_IF_ETHER_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_NET_IF_TYPES_H */ + +/* Define if you have the header file. */ +#define HAVE_NETINET_IF_ETHER_H 1 + +/* Define if you have the header file. */ +#define HAVE_NETPACKET_PACKET_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_SYS_DLPI_H */ + +/* Define if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define if you have the 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 diff -Nru ppp-2.4.7/pppd/plugins/pppoe/debug.c ppp-2.4.9/pppd/plugins/pppoe/debug.c --- ppp-2.4.7/pppd/plugins/pppoe/debug.c 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/pppd/plugins/pppoe/debug.c 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,145 @@ +/*********************************************************************** +* +* debug.c +* +* Implementation of user-space PPPoE redirector for Linux. +* +* Functions for printing debugging information +* +* Copyright (C) 2000 by 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. +* +***********************************************************************/ + +static char const RCSID[] = +"$Id: debug.c,v 1.2 2008/06/09 08:34:23 paulus Exp $"; + +#include "pppoe.h" +#include +#include +#include +#include + +/********************************************************************** +*%FUNCTION: dumpHex +*%ARGUMENTS: +* fp -- file to dump to +* buf -- buffer to dump +* len -- length of data +*%RETURNS: +* Nothing +*%DESCRIPTION: +* Dumps buffer to fp in an easy-to-read format +***********************************************************************/ +void +dumpHex(FILE *fp, unsigned char const *buf, int len) +{ + int i; + int base; + + if (!fp) return; + + /* do NOT dump PAP packets */ + if (len >= 2 && buf[0] == 0xC0 && buf[1] == 0x23) { + fprintf(fp, "(PAP Authentication Frame -- Contents not dumped)\n"); + return; + } + + for (base=0; baselength); + + /* Sheesh... printing times is a pain... */ + struct timeval tv; + time_t now; + int millisec; + struct tm *lt; + char timebuf[256]; + + UINT16_t type = etherType(packet); + if (!fp) return; + gettimeofday(&tv, NULL); + now = (time_t) tv.tv_sec; + millisec = tv.tv_usec / 1000; + lt = localtime(&now); + strftime(timebuf, 256, "%H:%M:%S", lt); + fprintf(fp, "%s.%03d %s PPPoE ", timebuf, millisec, dir); + if (type == Eth_PPPOE_Discovery) { + fprintf(fp, "Discovery (%x) ", (unsigned) type); + } else if (type == Eth_PPPOE_Session) { + fprintf(fp, "Session (%x) ", (unsigned) type); + } else { + fprintf(fp, "Unknown (%x) ", (unsigned) type); + } + + switch(packet->code) { + case CODE_PADI: fprintf(fp, "PADI "); break; + case CODE_PADO: fprintf(fp, "PADO "); break; + case CODE_PADR: fprintf(fp, "PADR "); break; + case CODE_PADS: fprintf(fp, "PADS "); break; + case CODE_PADT: fprintf(fp, "PADT "); break; + case CODE_PADM: fprintf(fp, "PADM "); break; + case CODE_PADN: fprintf(fp, "PADN "); break; + case CODE_SESS: fprintf(fp, "SESS "); break; + } + + fprintf(fp, "sess-id %d length %d\n", + (int) ntohs(packet->session), + len); + + /* Ugly... I apologize... */ + fprintf(fp, + "SourceAddr %02x:%02x:%02x:%02x:%02x:%02x " + "DestAddr %02x:%02x:%02x:%02x:%02x:%02x\n", + (unsigned) packet->ethHdr.h_source[0], + (unsigned) packet->ethHdr.h_source[1], + (unsigned) packet->ethHdr.h_source[2], + (unsigned) packet->ethHdr.h_source[3], + (unsigned) packet->ethHdr.h_source[4], + (unsigned) packet->ethHdr.h_source[5], + (unsigned) packet->ethHdr.h_dest[0], + (unsigned) packet->ethHdr.h_dest[1], + (unsigned) packet->ethHdr.h_dest[2], + (unsigned) packet->ethHdr.h_dest[3], + (unsigned) packet->ethHdr.h_dest[4], + (unsigned) packet->ethHdr.h_dest[5]); + dumpHex(fp, packet->payload, ntohs(packet->length)); +} diff -Nru ppp-2.4.7/pppd/plugins/pppoe/discovery.c ppp-2.4.9/pppd/plugins/pppoe/discovery.c --- ppp-2.4.7/pppd/plugins/pppoe/discovery.c 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/pppd/plugins/pppoe/discovery.c 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,666 @@ +/*********************************************************************** +* +* discovery.c +* +* Perform PPPoE discovery +* +* Copyright (C) 1999 by Roaring Penguin Software Inc. +* +***********************************************************************/ + +static char const RCSID[] = +"$Id: discovery.c,v 1.6 2008/06/15 04:35:50 paulus Exp $"; + +#define _GNU_SOURCE 1 +#include "pppoe.h" +#include "pppd/pppd.h" +#include "pppd/fsm.h" +#include "pppd/lcp.h" + +#include +#include +#include + +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#ifdef HAVE_SYS_UIO_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef USE_LINUX_PACKET +#include +#include +#endif + +#include + +/* Calculate time remaining until *exp, return 0 if now >= *exp */ +static int time_left(struct timeval *diff, struct timeval *exp) +{ + struct timeval now; + + if (get_time(&now) < 0) { + error("get_time: %m"); + return 0; + } + + if (now.tv_sec > exp->tv_sec + || (now.tv_sec == exp->tv_sec && now.tv_usec >= exp->tv_usec)) + return 0; + + diff->tv_sec = exp->tv_sec - now.tv_sec; + diff->tv_usec = exp->tv_usec - now.tv_usec; + if (diff->tv_usec < 0) { + diff->tv_usec += 1000000; + --diff->tv_sec; + } + + return 1; +} + +/********************************************************************** +*%FUNCTION: parseForHostUniq +*%ARGUMENTS: +* type -- tag type +* len -- tag length +* data -- tag data. +* extra -- user-supplied pointer. This is assumed to be a pointer to int. +*%RETURNS: +* Nothing +*%DESCRIPTION: +* If a HostUnique tag is found which matches our PID, sets *extra to 1. +***********************************************************************/ +static void +parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data, + void *extra) +{ + PPPoETag *tag = extra; + + if (type == TAG_HOST_UNIQ && len == ntohs(tag->length)) + tag->length = memcmp(data, tag->payload, len); +} + +/********************************************************************** +*%FUNCTION: packetIsForMe +*%ARGUMENTS: +* conn -- PPPoE connection info +* packet -- a received PPPoE packet +*%RETURNS: +* 1 if packet is for this PPPoE daemon; 0 otherwise. +*%DESCRIPTION: +* If we are using the Host-Unique tag, verifies that packet contains +* our unique identifier. +***********************************************************************/ +static int +packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet) +{ + PPPoETag hostUniq = conn->hostUniq; + + /* If packet is not directed to our MAC address, forget it */ + if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0; + + /* If we're not using the Host-Unique tag, then accept the packet */ + if (!conn->hostUniq.length) return 1; + + parsePacket(packet, parseForHostUniq, &hostUniq); + return !hostUniq.length; +} + +/********************************************************************** +*%FUNCTION: parsePADOTags +*%ARGUMENTS: +* type -- tag type +* len -- tag length +* data -- tag data +* extra -- extra user data. Should point to a PacketCriteria structure +* which gets filled in according to selected AC name and service +* name. +*%RETURNS: +* Nothing +*%DESCRIPTION: +* Picks interesting tags out of a PADO packet +***********************************************************************/ +static void +parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data, + void *extra) +{ + struct PacketCriteria *pc = (struct PacketCriteria *) extra; + PPPoEConnection *conn = pc->conn; + UINT16_t mru; + int i; + + switch(type) { + case TAG_AC_NAME: + pc->seenACName = 1; + if (conn->printACNames) { + info("Access-Concentrator: %.*s", (int) len, data); + } + if (conn->acName && len == strlen(conn->acName) && + !strncmp((char *) data, conn->acName, len)) { + pc->acNameOK = 1; + } + break; + case TAG_SERVICE_NAME: + pc->seenServiceName = 1; + if (conn->serviceName && len == strlen(conn->serviceName) && + !strncmp((char *) data, conn->serviceName, len)) { + pc->serviceNameOK = 1; + } + break; + case TAG_AC_COOKIE: + conn->cookie.type = htons(type); + conn->cookie.length = htons(len); + memcpy(conn->cookie.payload, data, len); + break; + case TAG_RELAY_SESSION_ID: + conn->relayId.type = htons(type); + conn->relayId.length = htons(len); + memcpy(conn->relayId.payload, data, len); + break; + case TAG_PPP_MAX_PAYLOAD: + if (len == sizeof(mru)) { + memcpy(&mru, data, sizeof(mru)); + mru = ntohs(mru); + if (mru >= ETH_PPPOE_MTU) { + if (lcp_allowoptions[0].mru > mru) + lcp_allowoptions[0].mru = mru; + if (lcp_wantoptions[0].mru > mru) + lcp_wantoptions[0].mru = mru; + conn->seenMaxPayload = 1; + } + } + break; + case TAG_SERVICE_NAME_ERROR: + error("PADO: Service-Name-Error: %.*s", (int) len, data); + conn->error = 1; + break; + case TAG_AC_SYSTEM_ERROR: + error("PADO: System-Error: %.*s", (int) len, data); + conn->error = 1; + break; + case TAG_GENERIC_ERROR: + error("PADO: Generic-Error: %.*s", (int) len, data); + conn->error = 1; + break; + } +} + +/********************************************************************** +*%FUNCTION: parsePADSTags +*%ARGUMENTS: +* type -- tag type +* len -- tag length +* data -- tag data +* extra -- extra user data (pointer to PPPoEConnection structure) +*%RETURNS: +* Nothing +*%DESCRIPTION: +* Picks interesting tags out of a PADS packet +***********************************************************************/ +static void +parsePADSTags(UINT16_t type, UINT16_t len, unsigned char *data, + void *extra) +{ + PPPoEConnection *conn = (PPPoEConnection *) extra; + UINT16_t mru; + switch(type) { + case TAG_SERVICE_NAME: + dbglog("PADS: Service-Name: '%.*s'", (int) len, data); + break; + case TAG_PPP_MAX_PAYLOAD: + if (len == sizeof(mru)) { + memcpy(&mru, data, sizeof(mru)); + mru = ntohs(mru); + if (mru >= ETH_PPPOE_MTU) { + if (lcp_allowoptions[0].mru > mru) + lcp_allowoptions[0].mru = mru; + if (lcp_wantoptions[0].mru > mru) + lcp_wantoptions[0].mru = mru; + conn->seenMaxPayload = 1; + } + } + break; + case TAG_SERVICE_NAME_ERROR: + error("PADS: Service-Name-Error: %.*s", (int) len, data); + conn->error = 1; + break; + case TAG_AC_SYSTEM_ERROR: + error("PADS: System-Error: %.*s", (int) len, data); + conn->error = 1; + break; + case TAG_GENERIC_ERROR: + error("PADS: Generic-Error: %.*s", (int) len, data); + conn->error = 1; + break; + case TAG_RELAY_SESSION_ID: + conn->relayId.type = htons(type); + conn->relayId.length = htons(len); + memcpy(conn->relayId.payload, data, len); + break; + } +} + +/*********************************************************************** +*%FUNCTION: sendPADI +*%ARGUMENTS: +* conn -- PPPoEConnection structure +*%RETURNS: +* Nothing +*%DESCRIPTION: +* Sends a PADI packet +***********************************************************************/ +static void +sendPADI(PPPoEConnection *conn) +{ + PPPoEPacket packet; + unsigned char *cursor = packet.payload; + PPPoETag *svc = (PPPoETag *) (&packet.payload); + UINT16_t namelen = 0; + UINT16_t plen; + int omit_service_name = 0; + + if (conn->serviceName) { + namelen = (UINT16_t) strlen(conn->serviceName); + if (!strcmp(conn->serviceName, "NO-SERVICE-NAME-NON-RFC-COMPLIANT")) { + omit_service_name = 1; + } + } + + /* Set destination to Ethernet broadcast address */ + memset(packet.ethHdr.h_dest, 0xFF, ETH_ALEN); + memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN); + + packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery); + packet.vertype = PPPOE_VER_TYPE(1, 1); + packet.code = CODE_PADI; + packet.session = 0; + + if (!omit_service_name) { + plen = TAG_HDR_SIZE + namelen; + CHECK_ROOM(cursor, packet.payload, plen); + + svc->type = TAG_SERVICE_NAME; + svc->length = htons(namelen); + + if (conn->serviceName) { + memcpy(svc->payload, conn->serviceName, strlen(conn->serviceName)); + } + cursor += namelen + TAG_HDR_SIZE; + } else { + plen = 0; + } + + /* If we're using Host-Uniq, copy it over */ + if (conn->hostUniq.length) { + int len = ntohs(conn->hostUniq.length); + CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE); + memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE); + cursor += len + TAG_HDR_SIZE; + plen += len + TAG_HDR_SIZE; + } + + /* Add our maximum MTU/MRU */ + if (MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru) > ETH_PPPOE_MTU) { + PPPoETag maxPayload; + UINT16_t mru = htons(MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru)); + maxPayload.type = htons(TAG_PPP_MAX_PAYLOAD); + maxPayload.length = htons(sizeof(mru)); + memcpy(maxPayload.payload, &mru, sizeof(mru)); + CHECK_ROOM(cursor, packet.payload, sizeof(mru) + TAG_HDR_SIZE); + memcpy(cursor, &maxPayload, sizeof(mru) + TAG_HDR_SIZE); + cursor += sizeof(mru) + TAG_HDR_SIZE; + plen += sizeof(mru) + TAG_HDR_SIZE; + } + + packet.length = htons(plen); + + sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE)); +} + +/********************************************************************** +*%FUNCTION: waitForPADO +*%ARGUMENTS: +* conn -- PPPoEConnection structure +* timeout -- how long to wait (in seconds) +*%RETURNS: +* Nothing +*%DESCRIPTION: +* Waits for a PADO packet and copies useful information +***********************************************************************/ +void +waitForPADO(PPPoEConnection *conn, int timeout) +{ + fd_set readable; + int r; + struct timeval tv; + struct timeval expire_at; + + PPPoEPacket packet; + int len; + + struct PacketCriteria pc; + pc.conn = conn; + pc.acNameOK = (conn->acName) ? 0 : 1; + pc.serviceNameOK = (conn->serviceName) ? 0 : 1; + pc.seenACName = 0; + pc.seenServiceName = 0; + conn->seenMaxPayload = 0; + conn->error = 0; + + if (get_time(&expire_at) < 0) { + error("get_time (waitForPADO): %m"); + return; + } + expire_at.tv_sec += timeout; + + do { + if (BPF_BUFFER_IS_EMPTY) { + if (!time_left(&tv, &expire_at)) + return; /* Timed out */ + + FD_ZERO(&readable); + FD_SET(conn->discoverySocket, &readable); + + while(1) { + r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); + if (r >= 0 || errno != EINTR || got_sigterm) break; + } + if (r < 0) { + error("select (waitForPADO): %m"); + return; + } + if (r == 0) + return; /* Timed out */ + } + + /* Get the packet */ + receivePacket(conn->discoverySocket, &packet, &len); + + /* Check length */ + if (ntohs(packet.length) + HDR_SIZE > len) { + error("Bogus PPPoE length field (%u)", + (unsigned int) ntohs(packet.length)); + continue; + } + +#ifdef USE_BPF + /* If it's not a Discovery packet, loop again */ + if (etherType(&packet) != Eth_PPPOE_Discovery) continue; +#endif + + /* If it's not for us, loop again */ + if (!packetIsForMe(conn, &packet)) continue; + + if (packet.code == CODE_PADO) { + if (NOT_UNICAST(packet.ethHdr.h_source)) { + error("Ignoring PADO packet from non-unicast MAC address"); + continue; + } + if (conn->req_peer + && memcmp(packet.ethHdr.h_source, conn->req_peer_mac, ETH_ALEN) != 0) { + warn("Ignoring PADO packet from wrong MAC address"); + continue; + } + if (parsePacket(&packet, parsePADOTags, &pc) < 0) + return; + if (conn->error) + return; + if (!pc.seenACName) { + error("Ignoring PADO packet with no AC-Name tag"); + continue; + } + if (!pc.seenServiceName) { + error("Ignoring PADO packet with no Service-Name tag"); + continue; + } + conn->numPADOs++; + if (pc.acNameOK && pc.serviceNameOK) { + memcpy(conn->peerEth, packet.ethHdr.h_source, ETH_ALEN); + conn->discoveryState = STATE_RECEIVED_PADO; + break; + } + } + } while (conn->discoveryState != STATE_RECEIVED_PADO); +} + +/*********************************************************************** +*%FUNCTION: sendPADR +*%ARGUMENTS: +* conn -- PPPoE connection structur +*%RETURNS: +* Nothing +*%DESCRIPTION: +* Sends a PADR packet +***********************************************************************/ +static void +sendPADR(PPPoEConnection *conn) +{ + PPPoEPacket packet; + PPPoETag *svc = (PPPoETag *) packet.payload; + unsigned char *cursor = packet.payload; + + UINT16_t namelen = 0; + UINT16_t plen; + + if (conn->serviceName) { + namelen = (UINT16_t) strlen(conn->serviceName); + } + plen = TAG_HDR_SIZE + namelen; + CHECK_ROOM(cursor, packet.payload, plen); + + memcpy(packet.ethHdr.h_dest, conn->peerEth, ETH_ALEN); + memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN); + + packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery); + packet.vertype = PPPOE_VER_TYPE(1, 1); + packet.code = CODE_PADR; + packet.session = 0; + + svc->type = TAG_SERVICE_NAME; + svc->length = htons(namelen); + if (conn->serviceName) { + memcpy(svc->payload, conn->serviceName, namelen); + } + cursor += namelen + TAG_HDR_SIZE; + + /* If we're using Host-Uniq, copy it over */ + if (conn->hostUniq.length) { + int len = ntohs(conn->hostUniq.length); + CHECK_ROOM(cursor, packet.payload, len+TAG_HDR_SIZE); + memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE); + cursor += len + TAG_HDR_SIZE; + plen += len + TAG_HDR_SIZE; + } + + /* Add our maximum MTU/MRU */ + if (MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru) > ETH_PPPOE_MTU) { + PPPoETag maxPayload; + UINT16_t mru = htons(MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru)); + maxPayload.type = htons(TAG_PPP_MAX_PAYLOAD); + maxPayload.length = htons(sizeof(mru)); + memcpy(maxPayload.payload, &mru, sizeof(mru)); + CHECK_ROOM(cursor, packet.payload, sizeof(mru) + TAG_HDR_SIZE); + memcpy(cursor, &maxPayload, sizeof(mru) + TAG_HDR_SIZE); + cursor += sizeof(mru) + TAG_HDR_SIZE; + plen += sizeof(mru) + TAG_HDR_SIZE; + } + + /* Copy cookie and relay-ID if needed */ + if (conn->cookie.type) { + CHECK_ROOM(cursor, packet.payload, + ntohs(conn->cookie.length) + TAG_HDR_SIZE); + memcpy(cursor, &conn->cookie, ntohs(conn->cookie.length) + TAG_HDR_SIZE); + cursor += ntohs(conn->cookie.length) + TAG_HDR_SIZE; + plen += ntohs(conn->cookie.length) + TAG_HDR_SIZE; + } + + if (conn->relayId.type) { + CHECK_ROOM(cursor, packet.payload, + ntohs(conn->relayId.length) + TAG_HDR_SIZE); + memcpy(cursor, &conn->relayId, ntohs(conn->relayId.length) + TAG_HDR_SIZE); + cursor += ntohs(conn->relayId.length) + TAG_HDR_SIZE; + plen += ntohs(conn->relayId.length) + TAG_HDR_SIZE; + } + + packet.length = htons(plen); + sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE)); +} + +/********************************************************************** +*%FUNCTION: waitForPADS +*%ARGUMENTS: +* conn -- PPPoE connection info +* timeout -- how long to wait (in seconds) +*%RETURNS: +* Nothing +*%DESCRIPTION: +* Waits for a PADS packet and copies useful information +***********************************************************************/ +static void +waitForPADS(PPPoEConnection *conn, int timeout) +{ + fd_set readable; + int r; + struct timeval tv; + struct timeval expire_at; + + PPPoEPacket packet; + int len; + + if (get_time(&expire_at) < 0) { + error("get_time (waitForPADS): %m"); + return; + } + expire_at.tv_sec += timeout; + + conn->error = 0; + do { + if (BPF_BUFFER_IS_EMPTY) { + if (!time_left(&tv, &expire_at)) + return; /* Timed out */ + + FD_ZERO(&readable); + FD_SET(conn->discoverySocket, &readable); + + while(1) { + r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); + if (r >= 0 || errno != EINTR || got_sigterm) break; + } + if (r < 0) { + error("select (waitForPADS): %m"); + return; + } + if (r == 0) + return; /* Timed out */ + } + + /* Get the packet */ + receivePacket(conn->discoverySocket, &packet, &len); + + /* Check length */ + if (ntohs(packet.length) + HDR_SIZE > len) { + error("Bogus PPPoE length field (%u)", + (unsigned int) ntohs(packet.length)); + continue; + } + +#ifdef USE_BPF + /* If it's not a Discovery packet, loop again */ + if (etherType(&packet) != Eth_PPPOE_Discovery) continue; +#endif + + /* If it's not from the AC, it's not for me */ + if (memcmp(packet.ethHdr.h_source, conn->peerEth, ETH_ALEN)) continue; + + /* If it's not for us, loop again */ + if (!packetIsForMe(conn, &packet)) continue; + + /* Is it PADS? */ + if (packet.code == CODE_PADS) { + /* Parse for goodies */ + if (parsePacket(&packet, parsePADSTags, conn) < 0) + return; + if (conn->error) + return; + conn->discoveryState = STATE_SESSION; + break; + } + } while (conn->discoveryState != STATE_SESSION); + + /* Don't bother with ntohs; we'll just end up converting it back... */ + conn->session = packet.session; + + info("PPP session is %d", (int) ntohs(conn->session)); + + /* RFC 2516 says session id MUST NOT be zero or 0xFFFF */ + if (ntohs(conn->session) == 0 || ntohs(conn->session) == 0xFFFF) { + error("Access concentrator used a session value of %x -- the AC is violating RFC 2516", (unsigned int) ntohs(conn->session)); + } +} + +/********************************************************************** +*%FUNCTION: discovery +*%ARGUMENTS: +* conn -- PPPoE connection info structure +*%RETURNS: +* Nothing +*%DESCRIPTION: +* Performs the PPPoE discovery phase +***********************************************************************/ +void +discovery(PPPoEConnection *conn) +{ + int padiAttempts = 0; + int padrAttempts = 0; + int timeout = conn->discoveryTimeout; + + do { + padiAttempts++; + if (got_sigterm || padiAttempts > conn->discoveryAttempts) { + warn("Timeout waiting for PADO packets"); + close(conn->discoverySocket); + conn->discoverySocket = -1; + return; + } + sendPADI(conn); + conn->discoveryState = STATE_SENT_PADI; + waitForPADO(conn, timeout); + + timeout *= 2; + } while (conn->discoveryState == STATE_SENT_PADI); + + timeout = conn->discoveryTimeout; + do { + padrAttempts++; + if (got_sigterm || padrAttempts > conn->discoveryAttempts) { + warn("Timeout waiting for PADS packets"); + close(conn->discoverySocket); + conn->discoverySocket = -1; + return; + } + sendPADR(conn); + conn->discoveryState = STATE_SENT_PADR; + waitForPADS(conn, timeout); + timeout *= 2; + } while (conn->discoveryState == STATE_SENT_PADR); + + if (!conn->seenMaxPayload) { + /* RFC 4638: MUST limit MTU/MRU to 1492 */ + if (lcp_allowoptions[0].mru > ETH_PPPOE_MTU) + lcp_allowoptions[0].mru = ETH_PPPOE_MTU; + if (lcp_wantoptions[0].mru > ETH_PPPOE_MTU) + lcp_wantoptions[0].mru = ETH_PPPOE_MTU; + } + + /* We're done. */ + close(conn->discoverySocket); + conn->discoverySocket = -1; + conn->discoveryState = STATE_SESSION; + return; +} diff -Nru ppp-2.4.7/pppd/plugins/pppoe/.gitignore ppp-2.4.9/pppd/plugins/pppoe/.gitignore --- ppp-2.4.7/pppd/plugins/pppoe/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/pppd/plugins/pppoe/.gitignore 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1 @@ +pppoe-discovery diff -Nru ppp-2.4.7/pppd/plugins/pppoe/if.c ppp-2.4.9/pppd/plugins/pppoe/if.c --- ppp-2.4.7/pppd/plugins/pppoe/if.c 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/pppd/plugins/pppoe/if.c 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,242 @@ +/*********************************************************************** +* +* if.c +* +* Implementation of user-space PPPoE redirector for Linux. +* +* Functions for opening a raw socket and reading/writing raw Ethernet frames. +* +* Copyright (C) 2000 by 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. +* +***********************************************************************/ + +static char const RCSID[] = +"$Id: if.c,v 1.2 2008/06/09 08:34:23 paulus Exp $"; + +#define _GNU_SOURCE 1 +#include "pppoe.h" +#include "pppd/pppd.h" + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_NETPACKET_PACKET_H +#include +#elif defined(HAVE_LINUX_IF_PACKET_H) +#include +#endif + +#ifdef HAVE_ASM_TYPES_H +#include +#endif + +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#include +#include +#include + +#ifdef HAVE_NET_IF_ARP_H +#include +#endif + +/* Initialize frame types to RFC 2516 values. Some broken peers apparently + use different frame types... sigh... */ + +UINT16_t Eth_PPPOE_Discovery = ETH_PPPOE_DISCOVERY; +UINT16_t Eth_PPPOE_Session = ETH_PPPOE_SESSION; + +/********************************************************************** +*%FUNCTION: etherType +*%ARGUMENTS: +* packet -- a received PPPoE packet +*%RETURNS: +* ethernet packet type (see /usr/include/net/ethertypes.h) +*%DESCRIPTION: +* Checks the ethernet packet header to determine its type. +* We should only be receveing DISCOVERY and SESSION types if the BPF +* is set up correctly. Logs an error if an unexpected type is received. +* Note that the ethernet type names come from "pppoe.h" and the packet +* packet structure names use the LINUX dialect to maintain consistency +* with the rest of this file. See the BSD section of "pppoe.h" for +* translations of the data structure names. +***********************************************************************/ +UINT16_t +etherType(PPPoEPacket *packet) +{ + UINT16_t type = (UINT16_t) ntohs(packet->ethHdr.h_proto); + if (type != Eth_PPPOE_Discovery && type != Eth_PPPOE_Session) { + error("Invalid ether type 0x%x", type); + } + return type; +} + +/********************************************************************** +*%FUNCTION: openInterface +*%ARGUMENTS: +* ifname -- name of interface +* type -- Ethernet frame type +* hwaddr -- if non-NULL, set to the hardware address +*%RETURNS: +* A raw socket for talking to the Ethernet card. Exits on error. +*%DESCRIPTION: +* Opens a raw Ethernet socket +***********************************************************************/ +int +openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr) +{ + int optval=1; + int fd; + struct ifreq ifr; + int domain, stype; + +#ifdef HAVE_STRUCT_SOCKADDR_LL + struct sockaddr_ll sa; +#else + struct sockaddr sa; +#endif + + memset(&sa, 0, sizeof(sa)); + +#ifdef HAVE_STRUCT_SOCKADDR_LL + domain = PF_PACKET; + stype = SOCK_RAW; +#else + domain = PF_INET; + stype = SOCK_PACKET; +#endif + + if ((fd = socket(domain, stype, htons(type))) < 0) { + /* Give a more helpful message for the common error case */ + if (errno == EPERM) { + fatal("Cannot create raw socket -- pppoe must be run as root."); + } + error("Can't open socket for pppoe: %m"); + return -1; + } + + if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) < 0) { + error("Can't set socket options for pppoe: %m"); + close(fd); + return -1; + } + + /* Fill in hardware address */ + if (hwaddr) { + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { + error("Can't get hardware address for %s: %m", ifname); + close(fd); + return -1; + } + memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); +#ifdef ARPHRD_ETHER + if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { + warn("Interface %.16s is not Ethernet", ifname); + } +#endif + if (NOT_UNICAST(hwaddr)) { + fatal("Can't use interface %.16s: it has broadcast/multicast MAC address", + ifname); + } + } + + /* Sanity check on MTU */ + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) { + error("Can't get MTU for %s: %m", ifname); + } else if (ifr.ifr_mtu < ETH_DATA_LEN) { + error("Interface %.16s has MTU of %d -- should be at least %d.", + ifname, ifr.ifr_mtu, ETH_DATA_LEN); + error("This may cause serious connection problems."); + } + +#ifdef HAVE_STRUCT_SOCKADDR_LL + /* Get interface index */ + sa.sll_family = AF_PACKET; + sa.sll_protocol = htons(type); + + strlcpy(ifr.ifr_name, ifname, IFNAMSIZ); + if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { + error("Could not get interface index for %s: %m", ifname); + close(fd); + return -1; + } + sa.sll_ifindex = ifr.ifr_ifindex; + +#else + strcpy(sa.sa_data, ifname); +#endif + + /* We're only interested in packets on specified interface */ + if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) { + error("Failed to bind to interface %s: %m", ifname); + close(fd); + return -1; + } + + return fd; +} + + +/*********************************************************************** +*%FUNCTION: sendPacket +*%ARGUMENTS: +* sock -- socket to send to +* pkt -- the packet to transmit +* size -- size of packet (in bytes) +*%RETURNS: +* 0 on success; -1 on failure +*%DESCRIPTION: +* Transmits a packet +***********************************************************************/ +int +sendPacket(PPPoEConnection *conn, int sock, PPPoEPacket *pkt, int size) +{ + int err; + + if (debug) + pppoe_log_packet("Send ", pkt); +#if defined(HAVE_STRUCT_SOCKADDR_LL) + err = send(sock, pkt, size, 0); +#else + struct sockaddr sa; + + strcpy(sa.sa_data, conn->ifName); + err = sendto(sock, pkt, size, 0, &sa, sizeof(sa)); +#endif + if (err < 0) { + error("error sending pppoe packet: %m"); + return -1; + } + return 0; +} + +/*********************************************************************** +*%FUNCTION: receivePacket +*%ARGUMENTS: +* sock -- socket to read from +* pkt -- place to store the received packet +* size -- set to size of packet in bytes +*%RETURNS: +* >= 0 if all OK; < 0 if error +*%DESCRIPTION: +* Receives a packet +***********************************************************************/ +int +receivePacket(int sock, PPPoEPacket *pkt, int *size) +{ + if ((*size = recv(sock, pkt, sizeof(PPPoEPacket), 0)) < 0) { + error("error receiving pppoe packet: %m"); + return -1; + } + if (debug) + pppoe_log_packet("Recv ", pkt); + return 0; +} diff -Nru ppp-2.4.7/pppd/plugins/pppoe/Makefile.linux ppp-2.4.9/pppd/plugins/pppoe/Makefile.linux --- ppp-2.4.7/pppd/plugins/pppoe/Makefile.linux 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/pppd/plugins/pppoe/Makefile.linux 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,65 @@ +#*********************************************************************** +# +# 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 +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 4550 pppoe.so $(LIBDIR) + # Symlink for backward compatibility + $(LN_S) pppoe.so $(LIBDIR)/rp-pppoe.so + $(INSTALL) -d -m 755 $(BINDIR) + $(INSTALL) -c -m 555 pppoe-discovery $(BINDIR) + +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 + diff -Nru ppp-2.4.7/pppd/plugins/pppoe/plugin.c ppp-2.4.9/pppd/plugins/pppoe/plugin.c --- ppp-2.4.7/pppd/plugins/pppoe/plugin.c 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/pppd/plugins/pppoe/plugin.c 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,476 @@ +/*********************************************************************** +* +* plugin.c +* +* pppd plugin for kernel-mode PPPoE on Linux +* +* Copyright (C) 2001 by Roaring Penguin Software Inc., Michal Ostrowski +* and Jamal Hadi Salim. +* +* Much code and many ideas derived from pppoe plugin by Michal +* Ostrowski and Jamal Hadi Salim, which carries this copyright: +* +* Copyright 2000 Michal Ostrowski , +* Jamal Hadi Salim +* Borrows heavily from the PPPoATM plugin by Mitchell Blank Jr., +* which is based in part on work from Jens Axboe and Paul Mackerras. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version +* 2 of the License, or (at your option) any later version. +* +***********************************************************************/ + +static char const RCSID[] = +"$Id: plugin.c,v 1.17 2008/06/15 04:35:50 paulus Exp $"; + +#define _GNU_SOURCE 1 +#include "pppoe.h" + +#include "pppd/pppd.h" +#include "pppd/fsm.h" +#include "pppd/lcp.h" +#include "pppd/ipcp.h" +#include "pppd/ccp.h" +/* #include "pppd/pathnames.h" */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _ROOT_PATH +#define _ROOT_PATH "" +#endif + +#define _PATH_ETHOPT _ROOT_PATH "/etc/ppp/options." + +char pppd_version[] = VERSION; + +/* From sys-linux.c in pppd -- MUST FIX THIS! */ +extern int new_style_driver; + +char *pppd_pppoe_service = NULL; +static char *acName = NULL; +static char *existingSession = NULL; +static int printACNames = 0; +static char *pppoe_reqd_mac = NULL; +unsigned char pppoe_reqd_mac_addr[6]; +static char *pppoe_host_uniq; +static int pppoe_padi_timeout = PADI_TIMEOUT; +static int pppoe_padi_attempts = MAX_PADI_ATTEMPTS; + +static int PPPoEDevnameHook(char *cmd, char **argv, int doit); +static option_t Options[] = { + { "device name", o_wild, (void *) &PPPoEDevnameHook, + "PPPoE device name", + OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, + devnam}, + { "pppoe-service", o_string, &pppd_pppoe_service, + "Desired PPPoE service name" }, + { "rp_pppoe_service", o_string, &pppd_pppoe_service, + "Legacy alias for pppoe-service", OPT_ALIAS }, + { "pppoe-ac", o_string, &acName, + "Desired PPPoE access concentrator name" }, + { "rp_pppoe_ac", o_string, &acName, + "Legacy alias for pppoe-ac", OPT_ALIAS }, + { "pppoe-sess", o_string, &existingSession, + "Attach to existing session (sessid:macaddr)" }, + { "rp_pppoe_sess", o_string, &existingSession, + "Legacy alias for pppoe-sess", OPT_ALIAS }, + { "pppoe-verbose", o_int, &printACNames, + "Be verbose about discovered access concentrators" }, + { "rp_pppoe_verbose", o_int, &printACNames, + "Legacy alias for pppoe-verbose", OPT_ALIAS }, + { "pppoe-mac", o_string, &pppoe_reqd_mac, + "Only connect to specified MAC address" }, + { "pppoe-host-uniq", o_string, &pppoe_host_uniq, + "Set the Host-Uniq to the supplied hex string" }, + { "host-uniq", o_string, &pppoe_host_uniq, + "Legacy alias for pppoe-host-uniq", OPT_ALIAS }, + { "pppoe-padi-timeout", o_int, &pppoe_padi_timeout, + "Initial timeout for discovery packets in seconds" }, + { "pppoe-padi-attempts", o_int, &pppoe_padi_attempts, + "Number of discovery attempts" }, + { NULL } +}; +int (*OldDevnameHook)(char *cmd, char **argv, int doit) = NULL; +static PPPoEConnection *conn = NULL; + +/********************************************************************** + * %FUNCTION: PPPOEInitDevice + * %ARGUMENTS: + * None + * %RETURNS: + * + * %DESCRIPTION: + * Initializes PPPoE device. + ***********************************************************************/ +static int +PPPOEInitDevice(void) +{ + conn = malloc(sizeof(PPPoEConnection)); + if (!conn) { + novm("PPPoE session data"); + } + memset(conn, 0, sizeof(PPPoEConnection)); + conn->ifName = devnam; + conn->discoverySocket = -1; + conn->sessionSocket = -1; + conn->printACNames = printACNames; + conn->discoveryTimeout = pppoe_padi_timeout; + conn->discoveryAttempts = pppoe_padi_attempts; + return 1; +} + +/********************************************************************** + * %FUNCTION: PPPOEConnectDevice + * %ARGUMENTS: + * None + * %RETURNS: + * Non-negative if all goes well; -1 otherwise + * %DESCRIPTION: + * Connects PPPoE device. + ***********************************************************************/ +static int +PPPOEConnectDevice(void) +{ + struct sockaddr_pppox sp; + struct ifreq ifr; + int s; + + /* Open session socket before discovery phase, to avoid losing session */ + /* packets sent by peer just after PADS packet (noted on some Cisco */ + /* server equipment). */ + /* Opening this socket just before waitForPADS in the discovery() */ + /* function would be more appropriate, but it would mess-up the code */ + conn->sessionSocket = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_OE); + if (conn->sessionSocket < 0) { + error("Failed to create PPPoE socket: %m"); + return -1; + } + + /* Restore configuration */ + lcp_allowoptions[0].mru = conn->mtu; + lcp_wantoptions[0].mru = conn->mru; + + /* Update maximum MRU */ + s = socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) { + error("Can't get MTU for %s: %m", conn->ifName); + goto errout; + } + strlcpy(ifr.ifr_name, conn->ifName, sizeof(ifr.ifr_name)); + if (ioctl(s, SIOCGIFMTU, &ifr) < 0) { + error("Can't get MTU for %s: %m", conn->ifName); + close(s); + goto errout; + } + close(s); + + if (lcp_allowoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD) + lcp_allowoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD; + if (lcp_wantoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD) + lcp_wantoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD; + + if (pppoe_host_uniq) { + if (!parseHostUniq(pppoe_host_uniq, &conn->hostUniq)) + fatal("Illegal value for pppoe-host-uniq option"); + } else { + /* if a custom host-uniq is not supplied, use our PID */ + pid_t pid = getpid(); + conn->hostUniq.type = htons(TAG_HOST_UNIQ); + conn->hostUniq.length = htons(sizeof(pid)); + memcpy(conn->hostUniq.payload, &pid, sizeof(pid)); + } + + conn->acName = acName; + conn->serviceName = pppd_pppoe_service; + strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam)); + if (existingSession) { + unsigned int mac[ETH_ALEN]; + int i, ses; + if (sscanf(existingSession, "%d:%x:%x:%x:%x:%x:%x", + &ses, &mac[0], &mac[1], &mac[2], + &mac[3], &mac[4], &mac[5]) != 7) { + fatal("Illegal value for pppoe-sess option"); + } + conn->session = htons(ses); + for (i=0; ipeerEth[i] = (unsigned char) mac[i]; + } + } else { + conn->discoverySocket = + openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth); + if (conn->discoverySocket < 0) { + error("Failed to create PPPoE discovery socket: %m"); + goto errout; + } + discovery(conn); + if (conn->discoveryState != STATE_SESSION) { + error("Unable to complete PPPoE Discovery"); + goto errout; + } + } + + /* Set PPPoE session-number for further consumption */ + ppp_session_number = ntohs(conn->session); + + sp.sa_family = AF_PPPOX; + sp.sa_protocol = PX_PROTO_OE; + sp.sa_addr.pppoe.sid = conn->session; + memcpy(sp.sa_addr.pppoe.dev, conn->ifName, IFNAMSIZ); + memcpy(sp.sa_addr.pppoe.remote, conn->peerEth, ETH_ALEN); + + /* Set remote_number for ServPoET */ + sprintf(remote_number, "%02X:%02X:%02X:%02X:%02X:%02X", + (unsigned) conn->peerEth[0], + (unsigned) conn->peerEth[1], + (unsigned) conn->peerEth[2], + (unsigned) conn->peerEth[3], + (unsigned) conn->peerEth[4], + (unsigned) conn->peerEth[5]); + + warn("Connected to %02X:%02X:%02X:%02X:%02X:%02X via interface %s", + (unsigned) conn->peerEth[0], + (unsigned) conn->peerEth[1], + (unsigned) conn->peerEth[2], + (unsigned) conn->peerEth[3], + (unsigned) conn->peerEth[4], + (unsigned) conn->peerEth[5], + conn->ifName); + + script_setenv("MACREMOTE", remote_number, 0); + + if (connect(conn->sessionSocket, (struct sockaddr *) &sp, + sizeof(struct sockaddr_pppox)) < 0) { + error("Failed to connect PPPoE socket: %d %m", errno); + goto errout; + } + + return conn->sessionSocket; + + errout: + if (conn->discoverySocket >= 0) { + sendPADT(conn, NULL); + close(conn->discoverySocket); + conn->discoverySocket = -1; + } + close(conn->sessionSocket); + return -1; +} + +static void +PPPOERecvConfig(int mru, + u_int32_t asyncmap, + int pcomp, + int accomp) +{ +#if 0 /* broken protocol, but no point harrassing the users I guess... */ + if (mru > MAX_PPPOE_MTU) + warn("Couldn't increase MRU to %d", mru); +#endif +} + +/********************************************************************** + * %FUNCTION: PPPOEDisconnectDevice + * %ARGUMENTS: + * None + * %RETURNS: + * Nothing + * %DESCRIPTION: + * Disconnects PPPoE device + ***********************************************************************/ +static void +PPPOEDisconnectDevice(void) +{ + struct sockaddr_pppox sp; + + sp.sa_family = AF_PPPOX; + sp.sa_protocol = PX_PROTO_OE; + sp.sa_addr.pppoe.sid = 0; + memcpy(sp.sa_addr.pppoe.dev, conn->ifName, IFNAMSIZ); + memcpy(sp.sa_addr.pppoe.remote, conn->peerEth, ETH_ALEN); + if (connect(conn->sessionSocket, (struct sockaddr *) &sp, + sizeof(struct sockaddr_pppox)) < 0 && errno != EALREADY) + error("Failed to disconnect PPPoE socket: %d %m", errno); + close(conn->sessionSocket); + if (conn->discoverySocket >= 0) { + sendPADT(conn, NULL); + close(conn->discoverySocket); + } +} + +static void +PPPOEDeviceOptions(void) +{ + char buf[MAXPATHLEN]; + + strlcpy(buf, _PATH_ETHOPT, MAXPATHLEN); + strlcat(buf, devnam, MAXPATHLEN); + if (!options_from_file(buf, 0, 0, 1)) + exit(EXIT_OPTION_ERROR); + +} + +struct channel pppoe_channel; + +/********************************************************************** + * %FUNCTION: PPPoEDevnameHook + * %ARGUMENTS: + * cmd -- the command (actually, the device name + * argv -- argument vector + * doit -- if non-zero, set device name. Otherwise, just check if possible + * %RETURNS: + * 1 if we will handle this device; 0 otherwise. + * %DESCRIPTION: + * Checks if name is a valid interface name; if so, returns 1. Also + * sets up devnam (string representation of device). + ***********************************************************************/ +static int +PPPoEDevnameHook(char *cmd, char **argv, int doit) +{ + int r = 1; + int fd; + struct ifreq ifr; + + /* + * Take any otherwise-unrecognized option as a possible device name, + * and test if it is the name of a network interface with a + * hardware address whose sa_family is ARPHRD_ETHER. + */ + if (strlen(cmd) > 4 && !strncmp(cmd, "nic-", 4)) { + /* Strip off "nic-" */ + cmd += 4; + } + + /* Open a socket */ + if ((fd = socket(PF_PACKET, SOCK_RAW, 0)) < 0) { + r = 0; + } + + /* Try getting interface index */ + if (r) { + strlcpy(ifr.ifr_name, cmd, sizeof(ifr.ifr_name)); + if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { + r = 0; + } else { + if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { + r = 0; + } else { + if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { + if (doit) + error("Interface %s not Ethernet", cmd); + r = 0; + } + } + } + } + + /* Close socket */ + close(fd); + if (r && doit) { + strlcpy(devnam, cmd, sizeof(devnam)); + if (the_channel != &pppoe_channel) { + + the_channel = &pppoe_channel; + modem = 0; + + PPPOEInitDevice(); + } + return 1; + } + + return r; +} + +/********************************************************************** + * %FUNCTION: plugin_init + * %ARGUMENTS: + * None + * %RETURNS: + * Nothing + * %DESCRIPTION: + * Initializes hooks for pppd plugin + ***********************************************************************/ +void +plugin_init(void) +{ + if (!ppp_available() && !new_style_driver) { + fatal("Linux kernel does not support PPPoE -- are you running 2.4.x?"); + } + + add_options(Options); + + info("PPPoE plugin from pppd %s", VERSION); +} + +void pppoe_check_options(void) +{ + unsigned int mac[6]; + int i; + + if (pppoe_reqd_mac != NULL) { + if (sscanf(pppoe_reqd_mac, "%x:%x:%x:%x:%x:%x", + &mac[0], &mac[1], &mac[2], &mac[3], + &mac[4], &mac[5]) != 6) { + option_error("cannot parse pppoe-mac option value"); + exit(EXIT_OPTION_ERROR); + } + for (i = 0; i < 6; ++i) + conn->req_peer_mac[i] = mac[i]; + conn->req_peer = 1; + } + + lcp_allowoptions[0].neg_accompression = 0; + lcp_wantoptions[0].neg_accompression = 0; + + lcp_allowoptions[0].neg_asyncmap = 0; + lcp_wantoptions[0].neg_asyncmap = 0; + + lcp_allowoptions[0].neg_pcompression = 0; + lcp_wantoptions[0].neg_pcompression = 0; + + if (lcp_allowoptions[0].mru > MAX_PPPOE_MTU) + lcp_allowoptions[0].mru = MAX_PPPOE_MTU; + if (lcp_wantoptions[0].mru > MAX_PPPOE_MTU) + lcp_wantoptions[0].mru = MAX_PPPOE_MTU; + + /* Save configuration */ + conn->mtu = lcp_allowoptions[0].mru; + conn->mru = lcp_wantoptions[0].mru; + + ccp_allowoptions[0].deflate = 0; + ccp_wantoptions[0].deflate = 0; + + ipcp_allowoptions[0].neg_vj = 0; + ipcp_wantoptions[0].neg_vj = 0; + + ccp_allowoptions[0].bsd_compress = 0; + ccp_wantoptions[0].bsd_compress = 0; +} + +struct channel pppoe_channel = { + .options = Options, + .process_extra_options = &PPPOEDeviceOptions, + .check_options = pppoe_check_options, + .connect = &PPPOEConnectDevice, + .disconnect = &PPPOEDisconnectDevice, + .establish_ppp = &generic_establish_ppp, + .disestablish_ppp = &generic_disestablish_ppp, + .send_config = NULL, + .recv_config = &PPPOERecvConfig, + .close = NULL, + .cleanup = NULL +}; diff -Nru ppp-2.4.7/pppd/plugins/pppoe/pppoe-discovery.c ppp-2.4.9/pppd/plugins/pppoe/pppoe-discovery.c --- ppp-2.4.7/pppd/plugins/pppoe/pppoe-discovery.c 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/pppd/plugins/pppoe/pppoe-discovery.c 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,784 @@ +/* + * Perform PPPoE discovery + * + * Copyright (C) 2000-2001 by Roaring Penguin Software Inc. + * Copyright (C) 2004 Marco d'Itri + * + * This program may be distributed according to the terms of the GNU + * General Public License, version 2 or (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "pppoe.h" + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_NETPACKET_PACKET_H +#include +#elif defined(HAVE_LINUX_IF_PACKET_H) +#include +#endif + +#ifdef HAVE_ASM_TYPES_H +#include +#endif + +#ifdef HAVE_SYS_IOCTL_H +#include +#endif + +#include +#include +#include + +#ifdef HAVE_NET_IF_ARP_H +#include +#endif + +char *xstrdup(const char *s); +void usage(void); + +void die(int status) +{ + exit(status); +} + +void error(char *fmt, ...) +{ + va_list pvar; + va_start(pvar, fmt); + vfprintf(stderr, fmt, pvar); + va_end(pvar); +} + +/* Initialize frame types to RFC 2516 values. Some broken peers apparently + use different frame types... sigh... */ + +UINT16_t Eth_PPPOE_Discovery = ETH_PPPOE_DISCOVERY; +UINT16_t Eth_PPPOE_Session = ETH_PPPOE_SESSION; + +/********************************************************************** +*%FUNCTION: etherType +*%ARGUMENTS: +* packet -- a received PPPoE packet +*%RETURNS: +* ethernet packet type (see /usr/include/net/ethertypes.h) +*%DESCRIPTION: +* Checks the ethernet packet header to determine its type. +* We should only be receveing DISCOVERY and SESSION types if the BPF +* is set up correctly. Logs an error if an unexpected type is received. +* Note that the ethernet type names come from "pppoe.h" and the packet +* packet structure names use the LINUX dialect to maintain consistency +* with the rest of this file. See the BSD section of "pppoe.h" for +* translations of the data structure names. +***********************************************************************/ +UINT16_t +etherType(PPPoEPacket *packet) +{ + UINT16_t type = (UINT16_t) ntohs(packet->ethHdr.h_proto); + if (type != Eth_PPPOE_Discovery && type != Eth_PPPOE_Session) { + fprintf(stderr, "Invalid ether type 0x%x\n", type); + } + return type; +} + +/********************************************************************** +*%FUNCTION: openInterface +*%ARGUMENTS: +* ifname -- name of interface +* type -- Ethernet frame type +* hwaddr -- if non-NULL, set to the hardware address +*%RETURNS: +* A raw socket for talking to the Ethernet card. Exits on error. +*%DESCRIPTION: +* Opens a raw Ethernet socket +***********************************************************************/ +int +openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr) +{ + int optval=1; + int fd; + struct ifreq ifr; + int domain, stype; + +#ifdef HAVE_STRUCT_SOCKADDR_LL + struct sockaddr_ll sa; +#else + struct sockaddr sa; +#endif + + memset(&sa, 0, sizeof(sa)); + +#ifdef HAVE_STRUCT_SOCKADDR_LL + domain = PF_PACKET; + stype = SOCK_RAW; +#else + domain = PF_INET; + stype = SOCK_PACKET; +#endif + + if ((fd = socket(domain, stype, htons(type))) < 0) { + /* Give a more helpful message for the common error case */ + if (errno == EPERM) { + fatal("Cannot create raw socket -- pppoe must be run as root."); + } + fatalSys("socket"); + } + + if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) < 0) { + fatalSys("setsockopt"); + } + + /* Fill in hardware address */ + if (hwaddr) { + strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { + fatalSys("ioctl(SIOCGIFHWADDR)"); + } + memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); +#ifdef ARPHRD_ETHER + if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { + fatal("Interface %.16s is not Ethernet", ifname); + } +#endif + if (NOT_UNICAST(hwaddr)) { + fatal("Interface %.16s has broadcast/multicast MAC address??", ifname); + } + } + + /* Sanity check on MTU */ + strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) { + fatalSys("ioctl(SIOCGIFMTU)"); + } + if (ifr.ifr_mtu < ETH_DATA_LEN) { + fprintf(stderr, "Interface %.16s has MTU of %d -- should be %d.\n", + ifname, ifr.ifr_mtu, ETH_DATA_LEN); + fprintf(stderr, "You may have serious connection problems.\n"); + } + +#ifdef HAVE_STRUCT_SOCKADDR_LL + /* Get interface index */ + sa.sll_family = AF_PACKET; + sa.sll_protocol = htons(type); + + strncpy(ifr.ifr_name, ifname, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ - 1] = 0; + if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { + fatalSys("ioctl(SIOCFIGINDEX): Could not get interface index"); + } + sa.sll_ifindex = ifr.ifr_ifindex; + +#else + strcpy(sa.sa_data, ifname); +#endif + + /* We're only interested in packets on specified interface */ + if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) { + fatalSys("bind"); + } + + return fd; +} + + +/*********************************************************************** +*%FUNCTION: sendPacket +*%ARGUMENTS: +* sock -- socket to send to +* pkt -- the packet to transmit +* size -- size of packet (in bytes) +*%RETURNS: +* 0 on success; -1 on failure +*%DESCRIPTION: +* Transmits a packet +***********************************************************************/ +int +sendPacket(PPPoEConnection *conn, int sock, PPPoEPacket *pkt, int size) +{ +#if defined(HAVE_STRUCT_SOCKADDR_LL) + if (send(sock, pkt, size, 0) < 0) { + fatalSys("send (sendPacket)"); + return -1; + } +#else + struct sockaddr sa; + + if (!conn) { + fatal("relay and server not supported on Linux 2.0 kernels"); + } + strcpy(sa.sa_data, conn->ifName); + if (sendto(sock, pkt, size, 0, &sa, sizeof(sa)) < 0) { + fatalSys("sendto (sendPacket)"); + return -1; + } +#endif + return 0; +} + +/*********************************************************************** +*%FUNCTION: receivePacket +*%ARGUMENTS: +* sock -- socket to read from +* pkt -- place to store the received packet +* size -- set to size of packet in bytes +*%RETURNS: +* >= 0 if all OK; < 0 if error +*%DESCRIPTION: +* Receives a packet +***********************************************************************/ +int +receivePacket(int sock, PPPoEPacket *pkt, int *size) +{ + if ((*size = recv(sock, pkt, sizeof(PPPoEPacket), 0)) < 0) { + fatalSys("recv (receivePacket)"); + return -1; + } + return 0; +} + +/********************************************************************** +*%FUNCTION: parsePacket +*%ARGUMENTS: +* packet -- the PPPoE discovery packet to parse +* func -- function called for each tag in the packet +* extra -- an opaque data pointer supplied to parsing function +*%RETURNS: +* 0 if everything went well; -1 if there was an error +*%DESCRIPTION: +* Parses a PPPoE discovery packet, calling "func" for each tag in the packet. +* "func" is passed the additional argument "extra". +***********************************************************************/ +int +parsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra) +{ + UINT16_t len = ntohs(packet->length); + unsigned char *curTag; + UINT16_t tagType, tagLen; + + if (PPPOE_VER(packet->vertype) != 1) { + fprintf(stderr, "Invalid PPPoE version (%d)\n", + PPPOE_VER(packet->vertype)); + return -1; + } + if (PPPOE_TYPE(packet->vertype) != 1) { + fprintf(stderr, "Invalid PPPoE type (%d)\n", + PPPOE_TYPE(packet->vertype)); + return -1; + } + + /* Do some sanity checks on packet */ + if (len > ETH_JUMBO_LEN - PPPOE_OVERHEAD) { /* 6-byte overhead for PPPoE header */ + fprintf(stderr, "Invalid PPPoE packet length (%u)\n", len); + return -1; + } + + /* Step through the tags */ + curTag = packet->payload; + while(curTag - packet->payload < len) { + /* Alignment is not guaranteed, so do this by hand... */ + tagType = (curTag[0] << 8) + curTag[1]; + tagLen = (curTag[2] << 8) + curTag[3]; + if (tagType == TAG_END_OF_LIST) { + return 0; + } + if ((curTag - packet->payload) + tagLen + TAG_HDR_SIZE > len) { + fprintf(stderr, "Invalid PPPoE tag length (%u)\n", tagLen); + return -1; + } + func(tagType, tagLen, curTag+TAG_HDR_SIZE, extra); + curTag = curTag + TAG_HDR_SIZE + tagLen; + } + return 0; +} + +/********************************************************************** +*%FUNCTION: parseForHostUniq +*%ARGUMENTS: +* type -- tag type +* len -- tag length +* data -- tag data. +* extra -- user-supplied pointer. This is assumed to be a pointer to int. +*%RETURNS: +* Nothing +*%DESCRIPTION: +* If a HostUnique tag is found which matches our PID, sets *extra to 1. +***********************************************************************/ +void +parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data, + void *extra) +{ + PPPoETag *tag = extra; + + if (type == TAG_HOST_UNIQ && len == ntohs(tag->length)) + tag->length = memcmp(data, tag->payload, len); +} + +/********************************************************************** +*%FUNCTION: packetIsForMe +*%ARGUMENTS: +* conn -- PPPoE connection info +* packet -- a received PPPoE packet +*%RETURNS: +* 1 if packet is for this PPPoE daemon; 0 otherwise. +*%DESCRIPTION: +* If we are using the Host-Unique tag, verifies that packet contains +* our unique identifier. +***********************************************************************/ +int +packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet) +{ + PPPoETag hostUniq = conn->hostUniq; + + /* If packet is not directed to our MAC address, forget it */ + if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0; + + /* If we're not using the Host-Unique tag, then accept the packet */ + if (!conn->hostUniq.length) return 1; + + parsePacket(packet, parseForHostUniq, &hostUniq); + return !hostUniq.length; +} + +/********************************************************************** +*%FUNCTION: parsePADOTags +*%ARGUMENTS: +* type -- tag type +* len -- tag length +* data -- tag data +* extra -- extra user data. Should point to a PacketCriteria structure +* which gets filled in according to selected AC name and service +* name. +*%RETURNS: +* Nothing +*%DESCRIPTION: +* Picks interesting tags out of a PADO packet +***********************************************************************/ +void +parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data, + void *extra) +{ + struct PacketCriteria *pc = (struct PacketCriteria *) extra; + PPPoEConnection *conn = pc->conn; + int i; + + switch(type) { + case TAG_AC_NAME: + pc->seenACName = 1; + if (conn->printACNames) { + printf("Access-Concentrator: %.*s\n", (int) len, data); + } + if (conn->acName && len == strlen(conn->acName) && + !strncmp((char *) data, conn->acName, len)) { + pc->acNameOK = 1; + } + break; + case TAG_SERVICE_NAME: + pc->seenServiceName = 1; + if (conn->printACNames && len > 0) { + printf(" Service-Name: %.*s\n", (int) len, data); + } + if (conn->serviceName && len == strlen(conn->serviceName) && + !strncmp((char *) data, conn->serviceName, len)) { + pc->serviceNameOK = 1; + } + break; + case TAG_AC_COOKIE: + if (conn->printACNames) { + printf("Got a cookie:"); + /* Print first 20 bytes of cookie */ + for (i=0; icookie.type = htons(type); + conn->cookie.length = htons(len); + memcpy(conn->cookie.payload, data, len); + break; + case TAG_RELAY_SESSION_ID: + if (conn->printACNames) { + printf("Got a Relay-ID:"); + /* Print first 20 bytes of relay ID */ + for (i=0; irelayId.type = htons(type); + conn->relayId.length = htons(len); + memcpy(conn->relayId.payload, data, len); + break; + case TAG_SERVICE_NAME_ERROR: + if (conn->printACNames) { + printf("Got a Service-Name-Error tag: %.*s\n", (int) len, data); + } + break; + case TAG_AC_SYSTEM_ERROR: + if (conn->printACNames) { + printf("Got a System-Error tag: %.*s\n", (int) len, data); + } + break; + case TAG_GENERIC_ERROR: + if (conn->printACNames) { + printf("Got a Generic-Error tag: %.*s\n", (int) len, data); + } + break; + } +} + +/*********************************************************************** +*%FUNCTION: sendPADI +*%ARGUMENTS: +* conn -- PPPoEConnection structure +*%RETURNS: +* Nothing +*%DESCRIPTION: +* Sends a PADI packet +***********************************************************************/ +void +sendPADI(PPPoEConnection *conn) +{ + PPPoEPacket packet; + unsigned char *cursor = packet.payload; + PPPoETag *svc = (PPPoETag *) (&packet.payload); + UINT16_t namelen = 0; + UINT16_t plen; + + if (conn->serviceName) { + namelen = (UINT16_t) strlen(conn->serviceName); + } + plen = TAG_HDR_SIZE + namelen; + CHECK_ROOM(cursor, packet.payload, plen); + + /* Set destination to Ethernet broadcast address */ + memset(packet.ethHdr.h_dest, 0xFF, ETH_ALEN); + memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN); + + packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery); + packet.vertype = PPPOE_VER_TYPE(1, 1); + packet.code = CODE_PADI; + packet.session = 0; + + svc->type = TAG_SERVICE_NAME; + svc->length = htons(namelen); + CHECK_ROOM(cursor, packet.payload, namelen+TAG_HDR_SIZE); + + if (conn->serviceName) { + memcpy(svc->payload, conn->serviceName, strlen(conn->serviceName)); + } + cursor += namelen + TAG_HDR_SIZE; + + /* If we're using Host-Uniq, copy it over */ + if (conn->hostUniq.length) { + int len = ntohs(conn->hostUniq.length); + CHECK_ROOM(cursor, packet.payload, len + TAG_HDR_SIZE); + memcpy(cursor, &conn->hostUniq, len + TAG_HDR_SIZE); + cursor += len + TAG_HDR_SIZE; + plen += len + TAG_HDR_SIZE; + } + + packet.length = htons(plen); + + sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE)); + if (conn->debugFile) { + dumpPacket(conn->debugFile, &packet, "SENT"); + fprintf(conn->debugFile, "\n"); + fflush(conn->debugFile); + } +} + +/********************************************************************** +*%FUNCTION: waitForPADO +*%ARGUMENTS: +* conn -- PPPoEConnection structure +* timeout -- how long to wait (in seconds) +*%RETURNS: +* Nothing +*%DESCRIPTION: +* Waits for a PADO packet and copies useful information +***********************************************************************/ +void +waitForPADO(PPPoEConnection *conn, int timeout) +{ + fd_set readable; + int r; + struct timeval tv; + PPPoEPacket packet; + int len; + + struct PacketCriteria pc; + pc.conn = conn; + pc.acNameOK = (conn->acName) ? 0 : 1; + pc.serviceNameOK = (conn->serviceName) ? 0 : 1; + pc.seenACName = 0; + pc.seenServiceName = 0; + conn->error = 0; + + do { + if (BPF_BUFFER_IS_EMPTY) { + tv.tv_sec = timeout; + tv.tv_usec = 0; + + FD_ZERO(&readable); + FD_SET(conn->discoverySocket, &readable); + + while(1) { + r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); + if (r >= 0 || errno != EINTR) break; + } + if (r < 0) { + perror("select (waitForPADO)"); + return; + } + if (r == 0) return; /* Timed out */ + } + + /* Get the packet */ + receivePacket(conn->discoverySocket, &packet, &len); + + /* Check length */ + if (ntohs(packet.length) + HDR_SIZE > len) { + fprintf(stderr, "Bogus PPPoE length field (%u)\n", + (unsigned int) ntohs(packet.length)); + continue; + } + +#ifdef USE_BPF + /* If it's not a Discovery packet, loop again */ + if (etherType(&packet) != Eth_PPPOE_Discovery) continue; +#endif + + if (conn->debugFile) { + dumpPacket(conn->debugFile, &packet, "RCVD"); + fprintf(conn->debugFile, "\n"); + fflush(conn->debugFile); + } + /* If it's not for us, loop again */ + if (!packetIsForMe(conn, &packet)) continue; + + if (packet.code == CODE_PADO) { + if (BROADCAST(packet.ethHdr.h_source)) { + fprintf(stderr, "Ignoring PADO packet from broadcast MAC address\n"); + continue; + } + parsePacket(&packet, parsePADOTags, &pc); + if (conn->error) + return; + if (!pc.seenACName) { + fprintf(stderr, "Ignoring PADO packet with no AC-Name tag\n"); + continue; + } + if (!pc.seenServiceName) { + fprintf(stderr, "Ignoring PADO packet with no Service-Name tag\n"); + continue; + } + conn->numPADOs++; + if (pc.acNameOK && pc.serviceNameOK) { + memcpy(conn->peerEth, packet.ethHdr.h_source, ETH_ALEN); + if (conn->printACNames) { + printf("AC-Ethernet-Address: %02x:%02x:%02x:%02x:%02x:%02x\n", + (unsigned) conn->peerEth[0], + (unsigned) conn->peerEth[1], + (unsigned) conn->peerEth[2], + (unsigned) conn->peerEth[3], + (unsigned) conn->peerEth[4], + (unsigned) conn->peerEth[5]); + printf("--------------------------------------------------\n"); + continue; + } + conn->discoveryState = STATE_RECEIVED_PADO; + break; + } + } + } while (conn->discoveryState != STATE_RECEIVED_PADO); +} + +/********************************************************************** +*%FUNCTION: discovery +*%ARGUMENTS: +* conn -- PPPoE connection info structure +*%RETURNS: +* Nothing +*%DESCRIPTION: +* Performs the PPPoE discovery phase +***********************************************************************/ +void +discovery(PPPoEConnection *conn) +{ + int padiAttempts = 0; + int timeout = conn->discoveryTimeout; + + conn->discoverySocket = + openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth); + + do { + padiAttempts++; + if (padiAttempts > conn->discoveryAttempts) { + fprintf(stderr, "Timeout waiting for PADO packets\n"); + close(conn->discoverySocket); + conn->discoverySocket = -1; + return; + } + sendPADI(conn); + conn->discoveryState = STATE_SENT_PADI; + waitForPADO(conn, timeout); + } while (!conn->numPADOs); +} + +int main(int argc, char *argv[]) +{ + int opt; + PPPoEConnection *conn; + + conn = malloc(sizeof(PPPoEConnection)); + if (!conn) + fatalSys("malloc"); + + memset(conn, 0, sizeof(PPPoEConnection)); + + conn->printACNames = 1; + conn->discoveryTimeout = PADI_TIMEOUT; + conn->discoveryAttempts = MAX_PADI_ATTEMPTS; + + while ((opt = getopt(argc, argv, "I:D:VUQS:C:W:t:a:h")) > 0) { + switch(opt) { + case 'S': + conn->serviceName = xstrdup(optarg); + break; + case 'C': + conn->acName = xstrdup(optarg); + break; + case 't': + if (sscanf(optarg, "%d", &conn->discoveryTimeout) != 1) { + fprintf(stderr, "Illegal argument to -t: Should be -t timeout\n"); + exit(EXIT_FAILURE); + } + if (conn->discoveryTimeout < 1) { + conn->discoveryTimeout = 1; + } + break; + case 'a': + if (sscanf(optarg, "%d", &conn->discoveryAttempts) != 1) { + fprintf(stderr, "Illegal argument to -a: Should be -a attempts\n"); + exit(EXIT_FAILURE); + } + if (conn->discoveryAttempts < 1) { + conn->discoveryAttempts = 1; + } + break; + case 'U': + if(conn->hostUniq.length) { + fprintf(stderr, "-U and -W are mutually exclusive\n"); + exit(EXIT_FAILURE); + } else { + pid_t pid = getpid(); + conn->hostUniq.type = htons(TAG_HOST_UNIQ); + conn->hostUniq.length = htons(sizeof(pid)); + memcpy(conn->hostUniq.payload, &pid, sizeof(pid)); + } + break; + case 'W': + if(conn->hostUniq.length) { + fprintf(stderr, "-U and -W are mutually exclusive\n"); + exit(EXIT_FAILURE); + } + if (!parseHostUniq(optarg, &conn->hostUniq)) { + fprintf(stderr, "Invalid host-uniq argument: %s\n", optarg); + exit(EXIT_FAILURE); + } + break; + case 'D': + conn->debugFile = fopen(optarg, "w"); + if (!conn->debugFile) { + fprintf(stderr, "Could not open %s: %s\n", + optarg, strerror(errno)); + exit(1); + } + fprintf(conn->debugFile, "pppoe-discovery from pppd %s\n", VERSION); + break; + case 'I': + conn->ifName = xstrdup(optarg); + break; + case 'Q': + conn->printACNames = 0; + break; + case 'V': + case 'h': + usage(); + exit(0); + default: + usage(); + exit(1); + } + } + + /* default interface name */ + if (!conn->ifName) + conn->ifName = strdup("eth0"); + + conn->discoverySocket = -1; + conn->sessionSocket = -1; + + discovery(conn); + + if (!conn->numPADOs) + exit(1); + else + exit(0); +} + +void fatal(char * fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fputc('\n', stderr); + exit(1); +} + +void fatalSys(char const *str) +{ + perror(str); + exit(1); +} + +char *xstrdup(const char *s) +{ + register char *ret = strdup(s); + if (!ret) + fatalSys("strdup"); + return ret; +} + +void usage(void) +{ + fprintf(stderr, "Usage: pppoe-discovery [options]\n"); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -I if_name -- Specify interface (default eth0)\n"); + fprintf(stderr, " -D filename -- Log debugging information in filename.\n"); + fprintf(stderr, + " -t timeout -- Initial timeout for discovery packets in seconds\n" + " -a attempts -- Number of discovery attempts\n" + " -V -- Print version and exit.\n" + " -Q -- Quit Mode: Do not print access concentrator names\n" + " -S name -- Set desired service name.\n" + " -C name -- Set desired access concentrator name.\n" + " -U -- Use Host-Unique to allow multiple PPPoE sessions.\n" + " -W hexvalue -- Set the Host-Unique to the supplied hex string.\n" + " -h -- Print usage information.\n"); + fprintf(stderr, "\npppoe-discovery from pppd " VERSION "\n"); +} diff -Nru ppp-2.4.7/pppd/plugins/pppoe/pppoe.h ppp-2.4.9/pppd/plugins/pppoe/pppoe.h --- ppp-2.4.7/pppd/plugins/pppoe/pppoe.h 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/pppd/plugins/pppoe/pppoe.h 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,328 @@ +/*********************************************************************** +* +* pppoe.h +* +* Declaration of various PPPoE constants +* +* Copyright (C) 2000 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. +* +* $Id: pppoe.h,v 1.4 2008/06/15 04:35:50 paulus Exp $ +* +***********************************************************************/ + +#include "config.h" + +#include /* For FILE */ +#include /* For pid_t */ +#include +#include + +#include "pppd/pppd.h" /* For error */ + +/* How do we access raw Ethernet devices? */ +#undef USE_LINUX_PACKET +#undef USE_BPF + +#if defined(HAVE_NETPACKET_PACKET_H) || defined(HAVE_LINUX_IF_PACKET_H) +#define USE_LINUX_PACKET 1 +#elif defined(HAVE_SYS_DLPI_H) +#define USE_DLPI +#elif defined(HAVE_NET_BPF_H) +#define USE_BPF 1 +#endif + +/* Sanity check */ +#if !defined(USE_BPF) && !defined(USE_LINUX_PACKET) && !defined(USE_DLPI) +#error Unknown method for accessing raw Ethernet frames +#endif + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif + +/* This has to be included before Linux 4.8's linux/in.h + * gets dragged in. */ +#include + +/* Ugly header files on some Linux boxes... */ +#if defined(HAVE_LINUX_IF_H) +#include +#elif defined(HAVE_NET_IF_H) +#include +#endif + +#ifdef HAVE_NET_IF_TYPES_H +#include +#endif + +#define BPF_BUFFER_IS_EMPTY 1 +#define BPF_BUFFER_HAS_DATA 0 + +/* Define various integer types -- assumes a char is 8 bits */ +#if SIZEOF_UNSIGNED_SHORT == 2 +typedef unsigned short UINT16_t; +#elif SIZEOF_UNSIGNED_INT == 2 +typedef unsigned int UINT16_t; +#else +#error Could not find a 16-bit integer type +#endif + +#if SIZEOF_UNSIGNED_SHORT == 4 +typedef unsigned short UINT32_t; +#elif SIZEOF_UNSIGNED_INT == 4 +typedef unsigned int UINT32_t; +#elif SIZEOF_UNSIGNED_LONG == 4 +typedef unsigned long UINT32_t; +#else +#error Could not find a 32-bit integer type +#endif + +#ifdef HAVE_LINUX_IF_ETHER_H +#include +#else + +#ifdef HAVE_NETINET_IF_ETHER_H +#include + +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +#ifndef HAVE_SYS_DLPI_H +#include +#endif +#endif +#endif + +/* Ethernet frame types according to RFC 2516 */ +#define ETH_PPPOE_DISCOVERY 0x8863 +#define ETH_PPPOE_SESSION 0x8864 + +/* But some brain-dead peers disobey the RFC, so frame types are variables */ +extern UINT16_t Eth_PPPOE_Discovery; +extern UINT16_t Eth_PPPOE_Session; + +/* PPPoE codes */ +#define CODE_PADI 0x09 +#define CODE_PADO 0x07 +#define CODE_PADR 0x19 +#define CODE_PADS 0x65 +#define CODE_PADT 0xA7 + +/* Extensions from draft-carrel-info-pppoe-ext-00 */ +/* I do NOT like PADM or PADN, but they are here for completeness */ +#define CODE_PADM 0xD3 +#define CODE_PADN 0xD4 + +#define CODE_SESS 0x00 + +/* PPPoE Tags */ +#define TAG_END_OF_LIST 0x0000 +#define TAG_SERVICE_NAME 0x0101 +#define TAG_AC_NAME 0x0102 +#define TAG_HOST_UNIQ 0x0103 +#define TAG_AC_COOKIE 0x0104 +#define TAG_VENDOR_SPECIFIC 0x0105 +#define TAG_RELAY_SESSION_ID 0x0110 +#define TAG_PPP_MAX_PAYLOAD 0x0120 +#define TAG_SERVICE_NAME_ERROR 0x0201 +#define TAG_AC_SYSTEM_ERROR 0x0202 +#define TAG_GENERIC_ERROR 0x0203 + +/* Extensions from draft-carrel-info-pppoe-ext-00 */ +/* I do NOT like these tags one little bit */ +#define TAG_HURL 0x111 +#define TAG_MOTM 0x112 +#define TAG_IP_ROUTE_ADD 0x121 + +/* Discovery phase states */ +#define STATE_SENT_PADI 0 +#define STATE_RECEIVED_PADO 1 +#define STATE_SENT_PADR 2 +#define STATE_SESSION 3 +#define STATE_TERMINATED 4 + +/* How many PADI/PADS attempts? */ +#define MAX_PADI_ATTEMPTS 3 + +/* Initial timeout for PADO/PADS */ +#define PADI_TIMEOUT 5 + +/* States for scanning PPP frames */ +#define STATE_WAITFOR_FRAME_ADDR 0 +#define STATE_DROP_PROTO 1 +#define STATE_BUILDING_PACKET 2 + +/* Special PPP frame characters */ +#define FRAME_ESC 0x7D +#define FRAME_FLAG 0x7E +#define FRAME_ADDR 0xFF +#define FRAME_CTRL 0x03 +#define FRAME_ENC 0x20 + +#define IPV4ALEN 4 +#define SMALLBUF 256 + +/* There are other fixed-size buffers preventing + this from being increased to 16110. The buffer + sizes would need to be properly de-coupled from + the default MRU. For now, getting up to 1500 is + enough. */ +#define ETH_JUMBO_LEN 1508 + +/* A PPPoE Packet, including Ethernet headers */ +typedef struct PPPoEPacketStruct { + struct ethhdr ethHdr; /* Ethernet header */ + unsigned int vertype:8; /* PPPoE Version and Type (must both be 1) */ + unsigned int code:8; /* PPPoE code */ + unsigned int session:16; /* PPPoE session */ + unsigned int length:16; /* Payload length */ + unsigned char payload[ETH_JUMBO_LEN]; /* A bit of room to spare */ +} PPPoEPacket; + +#define PPPOE_VER(vt) ((vt) >> 4) +#define PPPOE_TYPE(vt) ((vt) & 0xf) +#define PPPOE_VER_TYPE(v, t) (((v) << 4) | (t)) + +/* Header size of a PPPoE packet */ +#define PPPOE_OVERHEAD 6 /* type, code, session, length */ +#define HDR_SIZE (sizeof(struct ethhdr) + PPPOE_OVERHEAD) +#define MAX_PPPOE_PAYLOAD (ETH_JUMBO_LEN - PPPOE_OVERHEAD) +#define PPP_OVERHEAD 2 /* protocol */ +#define MAX_PPPOE_MTU (MAX_PPPOE_PAYLOAD - PPP_OVERHEAD) +#define TOTAL_OVERHEAD (PPPOE_OVERHEAD + PPP_OVERHEAD) +#define ETH_PPPOE_MTU (ETH_DATA_LEN - TOTAL_OVERHEAD) + +/* PPPoE Tag */ + +typedef struct PPPoETagStruct { + unsigned int type:16; /* tag type */ + unsigned int length:16; /* Length of payload */ + unsigned char payload[ETH_JUMBO_LEN]; /* A LOT of room to spare */ +} PPPoETag; +/* Header size of a PPPoE tag */ +#define TAG_HDR_SIZE 4 + +/* Chunk to read from stdin */ +#define READ_CHUNK 4096 + +/* Function passed to parsePacket */ +typedef void ParseFunc(UINT16_t type, + UINT16_t len, + unsigned char *data, + void *extra); + +#define PPPINITFCS16 0xffff /* Initial FCS value */ + +/* Keep track of the state of a connection -- collect everything in + one spot */ + +typedef struct PPPoEConnectionStruct { + int discoveryState; /* Where we are in discovery */ + int discoverySocket; /* Raw socket for discovery frames */ + int sessionSocket; /* Raw socket for session frames */ + unsigned char myEth[ETH_ALEN]; /* My MAC address */ + unsigned char peerEth[ETH_ALEN]; /* Peer's MAC address */ + unsigned char req_peer_mac[ETH_ALEN]; /* required peer MAC address */ + unsigned char req_peer; /* require mac addr to match req_peer_mac */ + UINT16_t session; /* Session ID */ + char *ifName; /* Interface name */ + char *serviceName; /* Desired service name, if any */ + char *acName; /* Desired AC name, if any */ + int synchronous; /* Use synchronous PPP */ + PPPoETag hostUniq; /* Use Host-Uniq tag */ + int printACNames; /* Just print AC names */ + FILE *debugFile; /* Debug file for dumping packets */ + int numPADOs; /* Number of PADO packets received */ + PPPoETag cookie; /* We have to send this if we get it */ + PPPoETag relayId; /* Ditto */ + int error; /* Error packet received */ + int debug; /* Set to log packets sent and received */ + int discoveryTimeout; /* Timeout for discovery packets */ + int discoveryAttempts; /* Number of discovery attempts */ + int seenMaxPayload; + int mtu; /* Stored MTU */ + int mru; /* Stored MRU */ +} PPPoEConnection; + +/* Structure used to determine acceptable PADO or PADS packet */ +struct PacketCriteria { + PPPoEConnection *conn; + int acNameOK; + int serviceNameOK; + int seenACName; + int seenServiceName; +}; + +/* Function Prototypes */ +UINT16_t etherType(PPPoEPacket *packet); +int openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr); +int sendPacket(PPPoEConnection *conn, int sock, PPPoEPacket *pkt, int size); +int receivePacket(int sock, PPPoEPacket *pkt, int *size); +void fatalSys(char const *str); +void dumpPacket(FILE *fp, PPPoEPacket *packet, char const *dir); +void dumpHex(FILE *fp, unsigned char const *buf, int len); +int parsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra); +void parseLogErrs(UINT16_t typ, UINT16_t len, unsigned char *data, void *xtra); +void syncReadFromPPP(PPPoEConnection *conn, PPPoEPacket *packet); +void asyncReadFromPPP(PPPoEConnection *conn, PPPoEPacket *packet); +void asyncReadFromEth(PPPoEConnection *conn, int sock, int clampMss); +void syncReadFromEth(PPPoEConnection *conn, int sock, int clampMss); +char *strDup(char const *str); +void sendPADT(PPPoEConnection *conn, char const *msg); +void sendSessionPacket(PPPoEConnection *conn, + PPPoEPacket *packet, int len); +void initPPP(void); +void clampMSS(PPPoEPacket *packet, char const *dir, int clampMss); +UINT16_t computeTCPChecksum(unsigned char *ipHdr, unsigned char *tcpHdr); +UINT16_t pppFCS16(UINT16_t fcs, unsigned char *cp, int len); +void discovery(PPPoEConnection *conn); +unsigned char *findTag(PPPoEPacket *packet, UINT16_t tagType, + PPPoETag *tag); + +void pppoe_printpkt(PPPoEPacket *packet, + void (*printer)(void *, char *, ...), void *arg); +void pppoe_log_packet(const char *prefix, PPPoEPacket *packet); + +static inline int parseHostUniq(const char *uniq, PPPoETag *tag) +{ + unsigned i, len = strlen(uniq); + +#define hex(x) \ + (((x) <= '9') ? ((x) - '0') : \ + (((x) <= 'F') ? ((x) - 'A' + 10) : \ + ((x) - 'a' + 10))) + + if (!len || len % 2 || len / 2 > sizeof(tag->payload)) + return 0; + + for (i = 0; i < len; i += 2) { + if (!isxdigit(uniq[i]) || !isxdigit(uniq[i+1])) + return 0; + + tag->payload[i / 2] = (char)(hex(uniq[i]) << 4 | hex(uniq[i+1])); + } + +#undef hex + + tag->type = htons(TAG_HOST_UNIQ); + tag->length = htons(len / 2); + return 1; +} + +#define SET_STRING(var, val) do { if (var) free(var); var = strDup(val); } while(0); + +#define CHECK_ROOM(cursor, start, len) \ +do {\ + if (((cursor)-(start))+(len) > MAX_PPPOE_PAYLOAD) { \ + error("Would create too-long packet"); \ + return; \ + } \ +} while(0) + +/* True if Ethernet address is broadcast or multicast */ +#define NOT_UNICAST(e) ((e[0] & 0x01) != 0) +#define BROADCAST(e) ((e[0] & e[1] & e[2] & e[3] & e[4] & e[5]) == 0xFF) +#define NOT_BROADCAST(e) ((e[0] & e[1] & e[2] & e[3] & e[4] & e[5]) != 0xFF) diff -Nru ppp-2.4.7/pppd/plugins/pppol2tp/Makefile.linux ppp-2.4.9/pppd/plugins/pppol2tp/Makefile.linux --- ppp-2.4.7/pppd/plugins/pppol2tp/Makefile.linux 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/pppol2tp/Makefile.linux 2021-01-05 00:06:37.000000000 +0100 @@ -1,22 +1,23 @@ -#CC = gcc -COPTS = -O2 -g -CFLAGS = $(COPTS) -I. -I../.. -I../../../include -fPIC -LDFLAGS = -shared -INSTALL = install - #*********************************************************************** +CROSS_COMPILE=@CROSS_COMPILE@ +CC=$(CROSS_COMPILE)@CC@ +COPTS=@CFLAGS@ -DESTDIR = @DESTDIR@ +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) -o $@ -shared $^ $(LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(LDFLAGS_SHARED) $^ $(LIBS) install: all $(INSTALL) -d -m 755 $(LIBDIR) diff -Nru ppp-2.4.7/pppd/plugins/pppol2tp/openl2tp.c ppp-2.4.9/pppd/plugins/pppol2tp/openl2tp.c --- ppp-2.4.7/pppd/plugins/pppol2tp/openl2tp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/pppol2tp/openl2tp.c 2021-01-05 00:06:37.000000000 +0100 @@ -246,6 +246,9 @@ (*old_pppol2tp_ip_updown_hook)(tunnel_id, session_id, up); } + if (user_name != NULL) + free(user_name); + return; } diff -Nru ppp-2.4.7/pppd/plugins/pppol2tp/pppol2tp.c ppp-2.4.9/pppd/plugins/pppol2tp/pppol2tp.c --- ppp-2.4.7/pppd/plugins/pppol2tp/pppol2tp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/pppol2tp/pppol2tp.c 2021-01-05 00:06:37.000000000 +0100 @@ -148,6 +148,10 @@ fatal("PPPoL2TP kernel driver not installed"); } + pppol2tp_fd_str = strdup(*argv); + if (pppol2tp_fd_str == NULL) + novm("PPPoL2TP FD"); + /* Setup option defaults. Compression options are disabled! */ modem = 0; diff -Nru ppp-2.4.7/pppd/plugins/radius/avpair.c ppp-2.4.9/pppd/plugins/radius/avpair.c --- ppp-2.4.7/pppd/plugins/radius/avpair.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/radius/avpair.c 2021-01-05 00:06:37.000000000 +0100 @@ -121,7 +121,7 @@ if ((vp = (VALUE_PAIR *) malloc (sizeof (VALUE_PAIR))) != (VALUE_PAIR *) NULL) { - strncpy (vp->name, pda->name, sizeof (vp->name)); + strlcpy (vp->name, pda->name, NAME_LENGTH); vp->attribute = attrid; vp->vendorcode = vendorcode; vp->next = (VALUE_PAIR *) NULL; @@ -175,12 +175,12 @@ { attribute = *ptr++; attrlen = *ptr++; - attrlen -= 2; - if (attrlen < 0) + if (attrlen < 2 || attrlen > length) { error("rc_avpair_gen: received attribute with invalid length"); break; } + attrlen -= 2; /* Handle vendor-specific specially */ if (attribute == PW_VENDOR_SPECIFIC) { @@ -222,6 +222,9 @@ { case PW_TYPE_STRING: + case PW_TYPE_IFID: + case PW_TYPE_IPV6ADDR: + case PW_TYPE_IPV6PREFIX: memcpy (pair->strvalue, (char *) ptr, (size_t) attrlen); pair->strvalue[attrlen] = '\0'; pair->lvalue = attrlen; @@ -692,9 +695,10 @@ int rc_avpair_tostr (VALUE_PAIR *pair, char *name, int ln, char *value, int lv) { DICT_VALUE *dval; - char buffer[32]; + char buffer[INET6_ADDRSTRLEN + 4]; // for a prefix: addr + '/' + prefixlen struct in_addr inad; unsigned char *ptr; + char *str; *name = *value = '\0'; @@ -737,7 +741,7 @@ } else { - sprintf (buffer, "%ld", pair->lvalue); + sprintf (buffer, "%d", pair->lvalue); strncpy(value, buffer, (size_t) lv); } break; @@ -753,6 +757,26 @@ strncpy(value, buffer, lv-1); break; + case PW_TYPE_IFID: + ptr = pair->strvalue; + snprintf(buffer, sizeof (buffer), "%x:%x:%x:%x", + (ptr[0] << 8) + ptr[1], (ptr[2] << 8) + ptr[3], + (ptr[4] << 8) + ptr[5], (ptr[6] << 8) + ptr[7]); + strncpy(value, buffer, lv-1); + break; + + case PW_TYPE_IPV6ADDR: + inet_ntop(AF_INET6, pair->strvalue, buffer, sizeof (buffer)); + strncpy(value, buffer, lv-1); + break; + + case PW_TYPE_IPV6PREFIX: + inet_ntop(AF_INET6, pair->strvalue + 2, buffer, sizeof (buffer)); + str = buffer + strlen(buffer); + snprintf(str, sizeof (buffer) - (str - buffer), "/%d", *(pair->strvalue + 1)); + strncpy(value, buffer, lv-1); + break; + default: error("rc_avpair_tostr: unknown attribute type %d", pair->type); return (-1); diff -Nru ppp-2.4.7/pppd/plugins/radius/buildreq.c ppp-2.4.9/pppd/plugins/radius/buildreq.c --- ppp-2.4.7/pppd/plugins/radius/buildreq.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/radius/buildreq.c 2021-01-05 00:06:37.000000000 +0100 @@ -293,7 +293,7 @@ SEND_DATA data; VALUE_PAIR *adt_vp; int result; - time_t start_time, dtime; + struct timeval start_time, dtime; char msg[4096]; int i; int timeout = rc_conf_int("radius_timeout"); @@ -320,11 +320,11 @@ * Fill in Acct-Delay-Time */ - dtime = 0; - if ((adt_vp = rc_avpair_add(&(data.send_pairs), PW_ACCT_DELAY_TIME, &dtime, 0, VENDOR_NONE)) == NULL) + dtime.tv_sec = 0; + if ((adt_vp = rc_avpair_add(&(data.send_pairs), PW_ACCT_DELAY_TIME, &dtime.tv_sec, 0, VENDOR_NONE)) == NULL) return (ERROR_RC); - start_time = time(NULL); + get_time(&start_time); result = ERROR_RC; for(i=0; (imax) && (result != OK_RC) && (result != BADRESP_RC) ; i++) @@ -336,8 +336,9 @@ rc_buildreq(&data, PW_ACCOUNTING_REQUEST, acctserver->name[i], acctserver->port[i], timeout, retries); - dtime = time(NULL) - start_time; - rc_avpair_assign(adt_vp, &dtime, 0); + get_time(&dtime); + dtime.tv_sec -= start_time.tv_sec; + rc_avpair_assign(adt_vp, &dtime.tv_sec, 0); result = rc_send_server (&data, msg, NULL); } diff -Nru ppp-2.4.7/pppd/plugins/radius/clientid.c ppp-2.4.9/pppd/plugins/radius/clientid.c --- ppp-2.4.7/pppd/plugins/radius/clientid.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/radius/clientid.c 2021-01-05 00:06:37.000000000 +0100 @@ -110,7 +110,7 @@ if (*name != '/') strcpy(ttyname, "/dev/"); - strncat(ttyname, name, sizeof(ttyname)); + strncat(ttyname, name, sizeof(ttyname) - strlen(ttyname) -1); for(p = map2id_list; p; p = p->next) if (!strcmp(ttyname, p->name)) return p->id; diff -Nru ppp-2.4.7/pppd/plugins/radius/config.c ppp-2.4.9/pppd/plugins/radius/config.c --- ppp-2.4.7/pppd/plugins/radius/config.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/radius/config.c 2021-01-05 00:06:37.000000000 +0100 @@ -153,6 +153,7 @@ *iptr = AUTH_RADIUS_FST; else { error("%s: auth_order: unknown keyword: %s", filename, p); + free(iptr); return (-1); } @@ -165,6 +166,7 @@ *iptr = (*iptr) | AUTH_RADIUS_SND; else { error("%s: auth_order: unknown or unexpected keyword: %s", filename, p); + free(iptr); return (-1); } } @@ -271,8 +273,8 @@ option = find_option(optname, OT_STR); if (option == NULL) - fatal("rc_conf_str: unkown config option requested: %s", optname); - return (char *)option->val; + fatal("rc_conf_str: unknown config option requested: %s", optname); + return (char *)option->val; } int rc_conf_int(char *optname) @@ -282,7 +284,7 @@ option = find_option(optname, OT_INT|OT_AUO); if (option == NULL) - fatal("rc_conf_int: unkown config option requested: %s", optname); + fatal("rc_conf_int: unknown config option requested: %s", optname); return *((int *)option->val); } @@ -293,7 +295,7 @@ option = find_option(optname, OT_SRV); if (option == NULL) - fatal("rc_conf_srv: unkown config option requested: %s", optname); + fatal("rc_conf_srv: unknown config option requested: %s", optname); return (SERVER *)option->val; } @@ -480,26 +482,14 @@ if ((h = strtok (buffer, " \t\n")) == NULL) /* first hostname */ continue; - memset (hostnm, '\0', AUTH_ID_LEN); - len = strlen (h); - if (len > AUTH_ID_LEN) - { - len = AUTH_ID_LEN; - } - strncpy (hostnm, h, (size_t) len); - hostnm[AUTH_ID_LEN] = '\0'; + memset (hostnm, '\0', AUTH_ID_LEN + 1); + strlcpy (hostnm, h, AUTH_ID_LEN + 1); if ((s = strtok (NULL, " \t\n")) == NULL) /* and secret field */ continue; - memset (secret, '\0', MAX_SECRET_LENGTH); - len = strlen (s); - if (len > MAX_SECRET_LENGTH) - { - len = MAX_SECRET_LENGTH; - } - strncpy (secret, s, (size_t) len); - secret[MAX_SECRET_LENGTH] = '\0'; + memset (secret, '\0', MAX_SECRET_LENGTH + 1); + strlcpy (secret, s, MAX_SECRET_LENGTH + 1); if (!strchr (hostnm, '/')) /* If single name form */ { diff -Nru ppp-2.4.7/pppd/plugins/radius/dict.c ppp-2.4.9/pppd/plugins/radius/dict.c --- ppp-2.4.7/pppd/plugins/radius/dict.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/radius/dict.c 2021-01-05 00:06:37.000000000 +0100 @@ -158,6 +158,18 @@ { type = PW_TYPE_DATE; } + else if (strcmp (typestr, "ifid") == 0) + { + type = PW_TYPE_IFID; + } + else if (strcmp (typestr, "ipv6addr") == 0) + { + type = PW_TYPE_IPV6ADDR; + } + else if (strcmp (typestr, "ipv6prefix") == 0) + { + type = PW_TYPE_IPV6PREFIX; + } else { error("rc_read_dictionary: invalid type on line %d of dictionary %s", diff -Nru ppp-2.4.7/pppd/plugins/radius/Makefile.linux ppp-2.4.9/pppd/plugins/radius/Makefile.linux --- ppp-2.4.7/pppd/plugins/radius/Makefile.linux 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/radius/Makefile.linux 2021-01-05 00:06:37.000000000 +0100 @@ -3,6 +3,10 @@ # 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) @@ -12,7 +16,7 @@ INSTALL = install PLUGIN=radius.so radattr.so radrealms.so -CFLAGS=-I. -I../.. -I../../../include -O2 -fPIC -DRC_LOG_FACILITY=LOG_DAEMON +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. @@ -36,20 +40,20 @@ install: all $(INSTALL) -d -m 755 $(LIBDIR) - $(INSTALL) -s -c -m 755 radius.so $(LIBDIR) - $(INSTALL) -s -c -m 755 radattr.so $(LIBDIR) - $(INSTALL) -s -c -m 755 radrealms.so $(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) -o radius.so -shared radius.o libradiusclient.a + $(CC) $(LDFLAGS) -o radius.so -shared radius.o libradiusclient.a radattr.so: radattr.o - $(CC) -o radattr.so -shared radattr.o + $(CC) $(LDFLAGS) -o radattr.so -shared radattr.o radrealms.so: radrealms.o - $(CC) -o radrealms.so -shared 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 diff -Nru ppp-2.4.7/pppd/plugins/radius/radius.c ppp-2.4.9/pppd/plugins/radius/radius.c --- ppp-2.4.7/pppd/plugins/radius/radius.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/radius/radius.c 2021-01-05 00:06:37.000000000 +0100 @@ -651,6 +651,9 @@ memcpy(rstate.class, vp->strvalue, rstate.class_len); } /* else too big for our buffer - ignore it */ break; + case PW_FRAMED_MTU: + netif_set_mtu(rstate.client_port,MIN(netif_get_mtu(rstate.client_port),vp->lvalue)); + break; } @@ -898,7 +901,7 @@ rstate.start_time = time(NULL); - strncpy(rstate.session_id, rc_mksid(), sizeof(rstate.session_id)); + strlcpy(rstate.session_id, rc_mksid(), MAXSESSIONID); rc_avpair_add(&send, PW_ACCT_SESSION_ID, rstate.session_id, 0, VENDOR_NONE); @@ -996,6 +999,10 @@ rc_avpair_add(&send, PW_USER_NAME, rstate.user, 0, VENDOR_NONE); + if (rstate.class_len > 0) + rc_avpair_add(&send, PW_CLASS, + rstate.class, rstate.class_len, VENDOR_NONE); + av_type = PW_STATUS_STOP; rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE); @@ -1140,6 +1147,10 @@ rc_avpair_add(&send, PW_USER_NAME, rstate.user, 0, VENDOR_NONE); + if (rstate.class_len > 0) + rc_avpair_add(&send, PW_CLASS, + rstate.class, rstate.class_len, VENDOR_NONE); + av_type = PW_STATUS_ALIVE; rc_avpair_add(&send, PW_ACCT_STATUS_TYPE, &av_type, 0, VENDOR_NONE); diff -Nru ppp-2.4.7/pppd/plugins/radius/radiusclient.h ppp-2.4.9/pppd/plugins/radius/radiusclient.h --- ppp-2.4.7/pppd/plugins/radius/radiusclient.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/radius/radiusclient.h 2021-01-05 00:06:37.000000000 +0100 @@ -31,7 +31,7 @@ #define AUTH_VECTOR_LEN 16 #define AUTH_PASS_LEN (3 * 16) /* multiple of 16 */ #define AUTH_ID_LEN 64 -#define AUTH_STRING_LEN 128 /* maximum of 253 */ +#define AUTH_STRING_LEN 253 /* maximum of 253 */ #define BUFFER_LEN 8192 @@ -77,6 +77,17 @@ #define PW_TYPE_INTEGER 1 #define PW_TYPE_IPADDR 2 #define PW_TYPE_DATE 3 +#define PW_TYPE_ABINARY 4 +#define PW_TYPE_OCTETS 5 +#define PW_TYPE_IFID 6 +#define PW_TYPE_IPV6ADDR 7 +#define PW_TYPE_IPV6PREFIX 8 +#define PW_TYPE_BYTE 9 +#define PW_TYPE_SHORT 10 +#define PW_TYPE_ETHERNET 11 +#define PW_TYPE_SIGNED 12 +#define PW_TYPE_COMBO_IP 13 +#define PW_TYPE_TLV 14 /* standard RADIUS codes */ @@ -386,74 +397,75 @@ /* avpair.c */ -VALUE_PAIR *rc_avpair_add __P((VALUE_PAIR **, int, void *, int, int)); -int rc_avpair_assign __P((VALUE_PAIR *, void *, int)); -VALUE_PAIR *rc_avpair_new __P((int, void *, int, int)); -VALUE_PAIR *rc_avpair_gen __P((AUTH_HDR *)); -VALUE_PAIR *rc_avpair_get __P((VALUE_PAIR *, UINT4)); -VALUE_PAIR *rc_avpair_copy __P((VALUE_PAIR *)); -void rc_avpair_insert __P((VALUE_PAIR **, VALUE_PAIR *, VALUE_PAIR *)); -void rc_avpair_free __P((VALUE_PAIR *)); -int rc_avpair_parse __P((char *, VALUE_PAIR **)); -int rc_avpair_tostr __P((VALUE_PAIR *, char *, int, char *, int)); -VALUE_PAIR *rc_avpair_readin __P((FILE *)); +VALUE_PAIR *rc_avpair_add(VALUE_PAIR **, int, void *, int, int); +int rc_avpair_assign(VALUE_PAIR *, void *, int); +VALUE_PAIR *rc_avpair_new(int, void *, int, int); +VALUE_PAIR *rc_avpair_gen(AUTH_HDR *); +VALUE_PAIR *rc_avpair_get(VALUE_PAIR *, UINT4); +VALUE_PAIR *rc_avpair_copy(VALUE_PAIR *); +void rc_avpair_insert(VALUE_PAIR **, VALUE_PAIR *, VALUE_PAIR *); +void rc_avpair_free(VALUE_PAIR *); +int rc_avpair_parse(char *, VALUE_PAIR **); +int rc_avpair_tostr(VALUE_PAIR *, char *, int, char *, int); +VALUE_PAIR *rc_avpair_readin(FILE *); /* buildreq.c */ -void rc_buildreq __P((SEND_DATA *, int, char *, unsigned short, int, int)); -unsigned char rc_get_seqnbr __P((void)); -int rc_auth __P((UINT4, VALUE_PAIR *, VALUE_PAIR **, char *, REQUEST_INFO *)); -int rc_auth_using_server __P((SERVER *, UINT4, VALUE_PAIR *, VALUE_PAIR **, - char *, REQUEST_INFO *)); -int rc_auth_proxy __P((VALUE_PAIR *, VALUE_PAIR **, char *)); -int rc_acct __P((UINT4, VALUE_PAIR *)); -int rc_acct_using_server __P((SERVER *, UINT4, VALUE_PAIR *)); -int rc_acct_proxy __P((VALUE_PAIR *)); -int rc_check __P((char *, unsigned short, char *)); +void rc_buildreq(SEND_DATA *, int, char *, unsigned short, int, int); +unsigned char rc_get_seqnbr(void); +int rc_auth(UINT4, VALUE_PAIR *, VALUE_PAIR **, char *, REQUEST_INFO *); +int rc_auth_using_server(SERVER *, UINT4, VALUE_PAIR *, VALUE_PAIR **, + char *, REQUEST_INFO *); +int rc_auth_proxy(VALUE_PAIR *, VALUE_PAIR **, char *); +int rc_acct(UINT4, VALUE_PAIR *); +int rc_acct_using_server(SERVER *, UINT4, VALUE_PAIR *); +int rc_acct_proxy(VALUE_PAIR *); +int rc_check(char *, unsigned short, char *); /* clientid.c */ -int rc_read_mapfile __P((char *)); -UINT4 rc_map2id __P((char *)); +int rc_read_mapfile(char *); +UINT4 rc_map2id(char *); /* config.c */ -int rc_read_config __P((char *)); -char *rc_conf_str __P((char *)); -int rc_conf_int __P((char *)); -SERVER *rc_conf_srv __P((char *)); -int rc_find_server __P((char *, UINT4 *, char *)); +int rc_read_config(char *); +char *rc_conf_str(char *); +int rc_conf_int(char *); +SERVER *rc_conf_srv(char *); +int rc_find_server(char *, UINT4 *, char *); /* dict.c */ -int rc_read_dictionary __P((char *)); -DICT_ATTR *rc_dict_getattr __P((int, int)); -DICT_ATTR *rc_dict_findattr __P((char *)); -DICT_VALUE *rc_dict_findval __P((char *)); -DICT_VALUE * rc_dict_getval __P((UINT4, char *)); -VENDOR_DICT * rc_dict_findvendor __P((char *)); -VENDOR_DICT * rc_dict_getvendor __P((int)); +int rc_read_dictionary(char *); +DICT_ATTR *rc_dict_getattr(int, int); +DICT_ATTR *rc_dict_findattr(char *); +DICT_VALUE *rc_dict_findval(char *); +DICT_VALUE * rc_dict_getval(UINT4, char *); +VENDOR_DICT * rc_dict_findvendor(char *); +VENDOR_DICT * rc_dict_getvendor(int); /* ip_util.c */ -UINT4 rc_get_ipaddr __P((char *)); -int rc_good_ipaddr __P((char *)); -const char *rc_ip_hostname __P((UINT4)); -UINT4 rc_own_ipaddress __P((void)); +UINT4 rc_get_ipaddr(char *); +int rc_good_ipaddr(char *); +const char *rc_ip_hostname(UINT4); +UINT4 rc_own_ipaddress(void); +UINT4 rc_own_bind_ipaddress(void); /* sendserver.c */ -int rc_send_server __P((SEND_DATA *, char *, REQUEST_INFO *)); +int rc_send_server(SEND_DATA *, char *, REQUEST_INFO *); /* util.c */ -void rc_str2tm __P((char *, struct tm *)); -char *rc_mksid __P((void)); -void rc_mdelay __P((int)); +void rc_str2tm(char *, struct tm *); +char *rc_mksid(void); +void rc_mdelay(int); /* md5.c */ -void rc_md5_calc __P((unsigned char *, unsigned char *, unsigned int)); +void rc_md5_calc(unsigned char *, unsigned char *, unsigned int); #endif /* RADIUSCLIENT_H */ diff -Nru ppp-2.4.7/pppd/plugins/radius/radrealms.c ppp-2.4.9/pppd/plugins/radius/radrealms.c --- ppp-2.4.7/pppd/plugins/radius/radrealms.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/radius/radrealms.c 2021-01-05 00:06:37.000000000 +0100 @@ -68,10 +68,12 @@ if ((fd = fopen(radrealms_config, "r")) == NULL) { option_error("cannot open %s", radrealms_config); + free(auths); + free(accts); return; - } + } info("Reading %s", radrealms_config); - + while ((fgets(buffer, sizeof(buffer), fd) != NULL)) { line++; @@ -87,6 +89,8 @@ fclose(fd); option_error("%s: invalid line %d: %s", radrealms_config, line, buffer); + free(auths); + free(accts); return; } info("Parsing '%s' entry:", p); @@ -101,6 +105,8 @@ fclose(fd); option_error("%s: realm name missing on line %d: %s", radrealms_config, line, buffer); + free(auths); + free(accts); return; } @@ -111,6 +117,8 @@ fclose(fd); option_error("%s: server address missing on line %d: %s", radrealms_config, line, buffer); + free(auths); + free(accts); return; } s->name[s->max] = strdup(p); @@ -119,6 +127,8 @@ fclose(fd); option_error("%s: server port missing on line %d: %s", radrealms_config, line, buffer); + free(auths); + free(accts); return; } s->port[s->max] = atoi(p); diff -Nru ppp-2.4.7/pppd/plugins/radius/sendserver.c ppp-2.4.9/pppd/plugins/radius/sendserver.c --- ppp-2.4.7/pppd/plugins/radius/sendserver.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/radius/sendserver.c 2021-01-05 00:06:37.000000000 +0100 @@ -302,7 +302,7 @@ FD_SET (sockfd, &readfds); if (select (sockfd + 1, &readfds, NULL, NULL, &authtime) < 0) { - if (errno == EINTR) + if (errno == EINTR && !got_sigterm) continue; error("rc_send_server: select: %m"); memset (secret, '\0', sizeof (secret)); diff -Nru ppp-2.4.7/pppd/plugins/radius/util.c ppp-2.4.9/pppd/plugins/radius/util.c --- ppp-2.4.7/pppd/plugins/radius/util.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/radius/util.c 2021-01-05 00:06:37.000000000 +0100 @@ -73,9 +73,9 @@ char * rc_mksid (void) { - static char buf[15]; + static char buf[32]; static unsigned short int cnt = 0; - sprintf (buf, "%08lX%04X%02hX", + slprintf(buf, sizeof(buf), "%08lX%04X%02hX", (unsigned long int) time (NULL), (unsigned int) getpid (), cnt & 0xFF); diff -Nru ppp-2.4.7/pppd/plugins/rp-pppoe/common.c ppp-2.4.9/pppd/plugins/rp-pppoe/common.c --- ppp-2.4.7/pppd/plugins/rp-pppoe/common.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/rp-pppoe/common.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,286 +0,0 @@ -/*********************************************************************** -* -* common.c -* -* Implementation of user-space PPPoE redirector for Linux. -* -* Common functions used by PPPoE client and server -* -* Copyright (C) 2000 by 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. -* -***********************************************************************/ - -static char const RCSID[] = -"$Id: common.c,v 1.3 2008/06/09 08:34:23 paulus Exp $"; - -#define _GNU_SOURCE 1 -#include "pppoe.h" -#include "pppd/pppd.h" - -#include -#include -#include -#include /* for LOG_DEBUG */ - -#ifdef HAVE_UNISTD_H -#include -#endif - -/********************************************************************** -*%FUNCTION: parsePacket -*%ARGUMENTS: -* packet -- the PPPoE discovery packet to parse -* func -- function called for each tag in the packet -* extra -- an opaque data pointer supplied to parsing function -*%RETURNS: -* 0 if everything went well; -1 if there was an error -*%DESCRIPTION: -* Parses a PPPoE discovery packet, calling "func" for each tag in the packet. -* "func" is passed the additional argument "extra". -***********************************************************************/ -int -parsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra) -{ - UINT16_t len = ntohs(packet->length); - unsigned char *curTag; - UINT16_t tagType, tagLen; - - if (PPPOE_VER(packet->vertype) != 1) { - error("Invalid PPPoE version (%d)", PPPOE_VER(packet->vertype)); - return -1; - } - if (PPPOE_TYPE(packet->vertype) != 1) { - error("Invalid PPPoE type (%d)", PPPOE_TYPE(packet->vertype)); - return -1; - } - - /* Do some sanity checks on packet */ - if (len > ETH_JUMBO_LEN - PPPOE_OVERHEAD) { /* 6-byte overhead for PPPoE header */ - error("Invalid PPPoE packet length (%u)", len); - return -1; - } - - /* Step through the tags */ - curTag = packet->payload; - while(curTag - packet->payload < len) { - /* Alignment is not guaranteed, so do this by hand... */ - tagType = (curTag[0] << 8) + curTag[1]; - tagLen = (curTag[2] << 8) + curTag[3]; - if (tagType == TAG_END_OF_LIST) { - return 0; - } - if ((curTag - packet->payload) + tagLen + TAG_HDR_SIZE > len) { - error("Invalid PPPoE tag length (%u)", tagLen); - return -1; - } - func(tagType, tagLen, curTag+TAG_HDR_SIZE, extra); - curTag = curTag + TAG_HDR_SIZE + tagLen; - } - return 0; -} - -/*********************************************************************** -*%FUNCTION: sendPADT -*%ARGUMENTS: -* conn -- PPPoE connection -* msg -- if non-NULL, extra error message to include in PADT packet. -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Sends a PADT packet -***********************************************************************/ -void -sendPADT(PPPoEConnection *conn, char const *msg) -{ - PPPoEPacket packet; - unsigned char *cursor = packet.payload; - - UINT16_t plen = 0; - - /* Do nothing if no session established yet */ - if (!conn->session) return; - - /* Do nothing if no discovery socket */ - if (conn->discoverySocket < 0) return; - - memcpy(packet.ethHdr.h_dest, conn->peerEth, ETH_ALEN); - memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN); - - packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery); - packet.vertype = PPPOE_VER_TYPE(1, 1); - packet.code = CODE_PADT; - packet.session = conn->session; - - /* Reset Session to zero so there is no possibility of - recursive calls to this function by any signal handler */ - conn->session = 0; - - /* If we're using Host-Uniq, copy it over */ - if (conn->useHostUniq) { - PPPoETag hostUniq; - pid_t pid = getpid(); - hostUniq.type = htons(TAG_HOST_UNIQ); - hostUniq.length = htons(sizeof(pid)); - memcpy(hostUniq.payload, &pid, sizeof(pid)); - memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE); - cursor += sizeof(pid) + TAG_HDR_SIZE; - plen += sizeof(pid) + TAG_HDR_SIZE; - } - - /* Copy error message */ - if (msg) { - PPPoETag err; - size_t elen = strlen(msg); - err.type = htons(TAG_GENERIC_ERROR); - err.length = htons(elen); - strcpy(err.payload, msg); - memcpy(cursor, &err, elen + TAG_HDR_SIZE); - cursor += elen + TAG_HDR_SIZE; - plen += elen + TAG_HDR_SIZE; - } - - /* Copy cookie and relay-ID if needed */ - if (conn->cookie.type) { - CHECK_ROOM(cursor, packet.payload, - ntohs(conn->cookie.length) + TAG_HDR_SIZE); - memcpy(cursor, &conn->cookie, ntohs(conn->cookie.length) + TAG_HDR_SIZE); - cursor += ntohs(conn->cookie.length) + TAG_HDR_SIZE; - plen += ntohs(conn->cookie.length) + TAG_HDR_SIZE; - } - - if (conn->relayId.type) { - CHECK_ROOM(cursor, packet.payload, - ntohs(conn->relayId.length) + TAG_HDR_SIZE); - memcpy(cursor, &conn->relayId, ntohs(conn->relayId.length) + TAG_HDR_SIZE); - cursor += ntohs(conn->relayId.length) + TAG_HDR_SIZE; - plen += ntohs(conn->relayId.length) + TAG_HDR_SIZE; - } - - packet.length = htons(plen); - sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE)); - info("Sent PADT"); -} - -#define EH(x) (x)[0], (x)[1], (x)[2], (x)[3], (x)[4], (x)[5] - -/* Print out a PPPOE packet for debugging */ -void pppoe_printpkt(PPPoEPacket *packet, - void (*printer)(void *, char *, ...), void *arg) -{ - int len = ntohs(packet->length); - int i, tag, tlen, text; - - switch (ntohs(packet->ethHdr.h_proto)) { - case ETH_PPPOE_DISCOVERY: - printer(arg, "PPPOE Discovery V%dT%d ", PPPOE_VER(packet->vertype), - PPPOE_TYPE(packet->vertype)); - switch (packet->code) { - case CODE_PADI: - printer(arg, "PADI"); - break; - case CODE_PADO: - printer(arg, "PADO"); - break; - case CODE_PADR: - printer(arg, "PADR"); - break; - case CODE_PADS: - printer(arg, "PADS"); - break; - case CODE_PADT: - printer(arg, "PADT"); - break; - default: - printer(arg, "unknown code %x", packet->code); - } - printer(arg, " session 0x%x length %d\n", ntohs(packet->session), len); - break; - case ETH_PPPOE_SESSION: - printer(arg, "PPPOE Session V%dT%d", PPPOE_VER(packet->vertype), - PPPOE_TYPE(packet->vertype)); - printer(arg, " code 0x%x session 0x%x length %d\n", packet->code, - ntohs(packet->session), len); - break; - default: - printer(arg, "Unknown ethernet frame with proto = 0x%x\n", - ntohs(packet->ethHdr.h_proto)); - } - - printer(arg, " dst %02x:%02x:%02x:%02x:%02x:%02x ", EH(packet->ethHdr.h_dest)); - printer(arg, " src %02x:%02x:%02x:%02x:%02x:%02x\n", EH(packet->ethHdr.h_source)); - if (ntohs(packet->ethHdr.h_proto) != ETH_PPPOE_DISCOVERY) - return; - - for (i = 0; i + TAG_HDR_SIZE <= len; i += tlen) { - tag = (packet->payload[i] << 8) + packet->payload[i+1]; - tlen = (packet->payload[i+2] << 8) + packet->payload[i+3]; - if (i + tlen + TAG_HDR_SIZE > len) - break; - text = 0; - i += TAG_HDR_SIZE; - printer(arg, " ["); - switch (tag) { - case TAG_END_OF_LIST: - printer(arg, "end-of-list"); - break; - case TAG_SERVICE_NAME: - printer(arg, "service-name"); - text = 1; - break; - case TAG_AC_NAME: - printer(arg, "AC-name"); - text = 1; - break; - case TAG_HOST_UNIQ: - printer(arg, "host-uniq"); - break; - case TAG_AC_COOKIE: - printer(arg, "AC-cookie"); - break; - case TAG_VENDOR_SPECIFIC: - printer(arg, "vendor-specific"); - break; - case TAG_RELAY_SESSION_ID: - printer(arg, "relay-session-id"); - break; - case TAG_PPP_MAX_PAYLOAD: - printer(arg, "PPP-max-payload"); - break; - case TAG_SERVICE_NAME_ERROR: - printer(arg, "service-name-error"); - text = 1; - break; - case TAG_AC_SYSTEM_ERROR: - printer(arg, "AC-system-error"); - text = 1; - break; - case TAG_GENERIC_ERROR: - printer(arg, "generic-error"); - text = 1; - break; - default: - printer(arg, "unknown tag 0x%x", tag); - } - if (tlen) { - if (text) - printer(arg, " %.*v", tlen, &packet->payload[i]); - else if (tlen <= 32) - printer(arg, " %.*B", tlen, &packet->payload[i]); - else - printer(arg, " %.32B... (length %d)", - &packet->payload[i], tlen); - } - printer(arg, "]"); - } - printer(arg, "\n"); -} - -void pppoe_log_packet(const char *prefix, PPPoEPacket *packet) -{ - init_pr_log(prefix, LOG_DEBUG); - pppoe_printpkt(packet, pr_log, NULL); - end_pr_log(); -} diff -Nru ppp-2.4.7/pppd/plugins/rp-pppoe/config.h ppp-2.4.9/pppd/plugins/rp-pppoe/config.h --- ppp-2.4.7/pppd/plugins/rp-pppoe/config.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/rp-pppoe/config.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,132 +0,0 @@ -/* config.h. Generated automatically by configure. */ -/* config.h.in. Generated automatically from configure.in by autoheader. */ - -/* Define to empty if the keyword does not work. */ -/* #undef const */ - -/* Define if you have that is POSIX.1 compatible. */ -#define HAVE_SYS_WAIT_H 1 - -/* Define to `int' if 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 and . */ -#define TIME_WITH_SYS_TIME 1 - -/* Define if your 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 header file. */ -#define HAVE_ASM_TYPES_H 1 - -/* Define if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define if you have the header file. */ -#define HAVE_GETOPT_H 1 - -/* Define if you have the 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 header file. */ -#define HAVE_LINUX_IF_PACKET_H 1 - -/* Define if you have the header file. */ -#define HAVE_LINUX_IF_PPPOX_H 1 - -/* Define if you have the header file. */ -#define HAVE_NET_BPF_H 1 - -/* Define if you have the header file. */ -#define HAVE_NET_IF_ARP_H 1 - -/* Define if you have the header file. */ -#define HAVE_NET_ETHERNET_H 1 - -/* Define if you have the header file. */ -#define HAVE_NET_IF_H 1 - -/* Define if you have the header file. */ -#define HAVE_LINUX_IF_H 1 - -/* Define if you have the header file. */ -/* #undef HAVE_NET_IF_DL_H */ - -/* Define if you have the header file. */ -/* #undef HAVE_NET_IF_ETHER_H */ - -/* Define if you have the header file. */ -/* #undef HAVE_NET_IF_TYPES_H */ - -/* Define if you have the header file. */ -#define HAVE_NETINET_IF_ETHER_H 1 - -/* Define if you have the header file. */ -#define HAVE_NETPACKET_PACKET_H 1 - -/* Define if you have the header file. */ -#define HAVE_SYS_CDEFS_H 1 - -/* Define if you have the header file. */ -/* #undef HAVE_SYS_DLPI_H */ - -/* Define if you have the header file. */ -#define HAVE_SYS_IOCTL_H 1 - -/* Define if you have the header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define if you have the header file. */ -#define HAVE_SYS_SOCKET_H 1 - -/* Define if you have the header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define if you have the header file. */ -#define HAVE_SYS_UIO_H 1 - -/* Define if you have the header file. */ -#define HAVE_SYSLOG_H 1 - -/* Define if you have the 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 diff -Nru ppp-2.4.7/pppd/plugins/rp-pppoe/debug.c ppp-2.4.9/pppd/plugins/rp-pppoe/debug.c --- ppp-2.4.7/pppd/plugins/rp-pppoe/debug.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/rp-pppoe/debug.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,145 +0,0 @@ -/*********************************************************************** -* -* debug.c -* -* Implementation of user-space PPPoE redirector for Linux. -* -* Functions for printing debugging information -* -* Copyright (C) 2000 by 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. -* -***********************************************************************/ - -static char const RCSID[] = -"$Id: debug.c,v 1.2 2008/06/09 08:34:23 paulus Exp $"; - -#include "pppoe.h" -#include -#include -#include -#include - -/********************************************************************** -*%FUNCTION: dumpHex -*%ARGUMENTS: -* fp -- file to dump to -* buf -- buffer to dump -* len -- length of data -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Dumps buffer to fp in an easy-to-read format -***********************************************************************/ -void -dumpHex(FILE *fp, unsigned char const *buf, int len) -{ - int i; - int base; - - if (!fp) return; - - /* do NOT dump PAP packets */ - if (len >= 2 && buf[0] == 0xC0 && buf[1] == 0x23) { - fprintf(fp, "(PAP Authentication Frame -- Contents not dumped)\n"); - return; - } - - for (base=0; baselength); - - /* Sheesh... printing times is a pain... */ - struct timeval tv; - time_t now; - int millisec; - struct tm *lt; - char timebuf[256]; - - UINT16_t type = etherType(packet); - if (!fp) return; - gettimeofday(&tv, NULL); - now = (time_t) tv.tv_sec; - millisec = tv.tv_usec / 1000; - lt = localtime(&now); - strftime(timebuf, 256, "%H:%M:%S", lt); - fprintf(fp, "%s.%03d %s PPPoE ", timebuf, millisec, dir); - if (type == Eth_PPPOE_Discovery) { - fprintf(fp, "Discovery (%x) ", (unsigned) type); - } else if (type == Eth_PPPOE_Session) { - fprintf(fp, "Session (%x) ", (unsigned) type); - } else { - fprintf(fp, "Unknown (%x) ", (unsigned) type); - } - - switch(packet->code) { - case CODE_PADI: fprintf(fp, "PADI "); break; - case CODE_PADO: fprintf(fp, "PADO "); break; - case CODE_PADR: fprintf(fp, "PADR "); break; - case CODE_PADS: fprintf(fp, "PADS "); break; - case CODE_PADT: fprintf(fp, "PADT "); break; - case CODE_PADM: fprintf(fp, "PADM "); break; - case CODE_PADN: fprintf(fp, "PADN "); break; - case CODE_SESS: fprintf(fp, "SESS "); break; - } - - fprintf(fp, "sess-id %d length %d\n", - (int) ntohs(packet->session), - len); - - /* Ugly... I apologize... */ - fprintf(fp, - "SourceAddr %02x:%02x:%02x:%02x:%02x:%02x " - "DestAddr %02x:%02x:%02x:%02x:%02x:%02x\n", - (unsigned) packet->ethHdr.h_source[0], - (unsigned) packet->ethHdr.h_source[1], - (unsigned) packet->ethHdr.h_source[2], - (unsigned) packet->ethHdr.h_source[3], - (unsigned) packet->ethHdr.h_source[4], - (unsigned) packet->ethHdr.h_source[5], - (unsigned) packet->ethHdr.h_dest[0], - (unsigned) packet->ethHdr.h_dest[1], - (unsigned) packet->ethHdr.h_dest[2], - (unsigned) packet->ethHdr.h_dest[3], - (unsigned) packet->ethHdr.h_dest[4], - (unsigned) packet->ethHdr.h_dest[5]); - dumpHex(fp, packet->payload, ntohs(packet->length)); -} diff -Nru ppp-2.4.7/pppd/plugins/rp-pppoe/discovery.c ppp-2.4.9/pppd/plugins/rp-pppoe/discovery.c --- ppp-2.4.7/pppd/plugins/rp-pppoe/discovery.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/rp-pppoe/discovery.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,676 +0,0 @@ -/*********************************************************************** -* -* discovery.c -* -* Perform PPPoE discovery -* -* Copyright (C) 1999 by Roaring Penguin Software Inc. -* -***********************************************************************/ - -static char const RCSID[] = -"$Id: discovery.c,v 1.6 2008/06/15 04:35:50 paulus Exp $"; - -#define _GNU_SOURCE 1 -#include "pppoe.h" -#include "pppd/pppd.h" -#include "pppd/fsm.h" -#include "pppd/lcp.h" - -#include -#include -#include - -#ifdef HAVE_SYS_TIME_H -#include -#endif - -#ifdef HAVE_SYS_UIO_H -#include -#endif - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef USE_LINUX_PACKET -#include -#include -#endif - -#include - -/* Calculate time remaining until *exp, return 0 if now >= *exp */ -static int time_left(struct timeval *diff, struct timeval *exp) -{ - struct timeval now; - - if (gettimeofday(&now, NULL) < 0) { - error("gettimeofday: %m"); - return 0; - } - - if (now.tv_sec > exp->tv_sec - || (now.tv_sec == exp->tv_sec && now.tv_usec >= exp->tv_usec)) - return 0; - - diff->tv_sec = exp->tv_sec - now.tv_sec; - diff->tv_usec = exp->tv_usec - now.tv_usec; - if (diff->tv_usec < 0) { - diff->tv_usec += 1000000; - --diff->tv_sec; - } - - return 1; -} - -/********************************************************************** -*%FUNCTION: parseForHostUniq -*%ARGUMENTS: -* type -- tag type -* len -- tag length -* data -- tag data. -* extra -- user-supplied pointer. This is assumed to be a pointer to int. -*%RETURNS: -* Nothing -*%DESCRIPTION: -* If a HostUnique tag is found which matches our PID, sets *extra to 1. -***********************************************************************/ -static void -parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data, - void *extra) -{ - int *val = (int *) extra; - if (type == TAG_HOST_UNIQ && len == sizeof(pid_t)) { - pid_t tmp; - memcpy(&tmp, data, len); - if (tmp == getpid()) { - *val = 1; - } - } -} - -/********************************************************************** -*%FUNCTION: packetIsForMe -*%ARGUMENTS: -* conn -- PPPoE connection info -* packet -- a received PPPoE packet -*%RETURNS: -* 1 if packet is for this PPPoE daemon; 0 otherwise. -*%DESCRIPTION: -* If we are using the Host-Unique tag, verifies that packet contains -* our unique identifier. -***********************************************************************/ -static int -packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet) -{ - int forMe = 0; - - /* If packet is not directed to our MAC address, forget it */ - if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0; - - /* If we're not using the Host-Unique tag, then accept the packet */ - if (!conn->useHostUniq) return 1; - - parsePacket(packet, parseForHostUniq, &forMe); - return forMe; -} - -/********************************************************************** -*%FUNCTION: parsePADOTags -*%ARGUMENTS: -* type -- tag type -* len -- tag length -* data -- tag data -* extra -- extra user data. Should point to a PacketCriteria structure -* which gets filled in according to selected AC name and service -* name. -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Picks interesting tags out of a PADO packet -***********************************************************************/ -static void -parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data, - void *extra) -{ - struct PacketCriteria *pc = (struct PacketCriteria *) extra; - PPPoEConnection *conn = pc->conn; - UINT16_t mru; - int i; - - switch(type) { - case TAG_AC_NAME: - pc->seenACName = 1; - if (conn->printACNames) { - info("Access-Concentrator: %.*s", (int) len, data); - } - if (conn->acName && len == strlen(conn->acName) && - !strncmp((char *) data, conn->acName, len)) { - pc->acNameOK = 1; - } - break; - case TAG_SERVICE_NAME: - pc->seenServiceName = 1; - if (conn->serviceName && len == strlen(conn->serviceName) && - !strncmp((char *) data, conn->serviceName, len)) { - pc->serviceNameOK = 1; - } - break; - case TAG_AC_COOKIE: - conn->cookie.type = htons(type); - conn->cookie.length = htons(len); - memcpy(conn->cookie.payload, data, len); - break; - case TAG_RELAY_SESSION_ID: - conn->relayId.type = htons(type); - conn->relayId.length = htons(len); - memcpy(conn->relayId.payload, data, len); - break; - case TAG_PPP_MAX_PAYLOAD: - if (len == sizeof(mru)) { - memcpy(&mru, data, sizeof(mru)); - mru = ntohs(mru); - if (mru >= ETH_PPPOE_MTU) { - if (lcp_allowoptions[0].mru > mru) - lcp_allowoptions[0].mru = mru; - if (lcp_wantoptions[0].mru > mru) - lcp_wantoptions[0].mru = mru; - conn->seenMaxPayload = 1; - } - } - break; - case TAG_SERVICE_NAME_ERROR: - error("PADO: Service-Name-Error: %.*s", (int) len, data); - conn->error = 1; - break; - case TAG_AC_SYSTEM_ERROR: - error("PADO: System-Error: %.*s", (int) len, data); - conn->error = 1; - break; - case TAG_GENERIC_ERROR: - error("PADO: Generic-Error: %.*s", (int) len, data); - conn->error = 1; - break; - } -} - -/********************************************************************** -*%FUNCTION: parsePADSTags -*%ARGUMENTS: -* type -- tag type -* len -- tag length -* data -- tag data -* extra -- extra user data (pointer to PPPoEConnection structure) -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Picks interesting tags out of a PADS packet -***********************************************************************/ -static void -parsePADSTags(UINT16_t type, UINT16_t len, unsigned char *data, - void *extra) -{ - PPPoEConnection *conn = (PPPoEConnection *) extra; - UINT16_t mru; - switch(type) { - case TAG_SERVICE_NAME: - dbglog("PADS: Service-Name: '%.*s'", (int) len, data); - break; - case TAG_PPP_MAX_PAYLOAD: - if (len == sizeof(mru)) { - memcpy(&mru, data, sizeof(mru)); - mru = ntohs(mru); - if (mru >= ETH_PPPOE_MTU) { - if (lcp_allowoptions[0].mru > mru) - lcp_allowoptions[0].mru = mru; - if (lcp_wantoptions[0].mru > mru) - lcp_wantoptions[0].mru = mru; - conn->seenMaxPayload = 1; - } - } - break; - case TAG_SERVICE_NAME_ERROR: - error("PADS: Service-Name-Error: %.*s", (int) len, data); - conn->error = 1; - break; - case TAG_AC_SYSTEM_ERROR: - error("PADS: System-Error: %.*s", (int) len, data); - conn->error = 1; - break; - case TAG_GENERIC_ERROR: - error("PADS: Generic-Error: %.*s", (int) len, data); - conn->error = 1; - break; - case TAG_RELAY_SESSION_ID: - conn->relayId.type = htons(type); - conn->relayId.length = htons(len); - memcpy(conn->relayId.payload, data, len); - break; - } -} - -/*********************************************************************** -*%FUNCTION: sendPADI -*%ARGUMENTS: -* conn -- PPPoEConnection structure -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Sends a PADI packet -***********************************************************************/ -static void -sendPADI(PPPoEConnection *conn) -{ - PPPoEPacket packet; - unsigned char *cursor = packet.payload; - PPPoETag *svc = (PPPoETag *) (&packet.payload); - UINT16_t namelen = 0; - UINT16_t plen; - int omit_service_name = 0; - - if (conn->serviceName) { - namelen = (UINT16_t) strlen(conn->serviceName); - if (!strcmp(conn->serviceName, "NO-SERVICE-NAME-NON-RFC-COMPLIANT")) { - omit_service_name = 1; - } - } - - /* Set destination to Ethernet broadcast address */ - memset(packet.ethHdr.h_dest, 0xFF, ETH_ALEN); - memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN); - - packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery); - packet.vertype = PPPOE_VER_TYPE(1, 1); - packet.code = CODE_PADI; - packet.session = 0; - - if (!omit_service_name) { - plen = TAG_HDR_SIZE + namelen; - CHECK_ROOM(cursor, packet.payload, plen); - - svc->type = TAG_SERVICE_NAME; - svc->length = htons(namelen); - - if (conn->serviceName) { - memcpy(svc->payload, conn->serviceName, strlen(conn->serviceName)); - } - cursor += namelen + TAG_HDR_SIZE; - } else { - plen = 0; - } - - /* If we're using Host-Uniq, copy it over */ - if (conn->useHostUniq) { - PPPoETag hostUniq; - pid_t pid = getpid(); - hostUniq.type = htons(TAG_HOST_UNIQ); - hostUniq.length = htons(sizeof(pid)); - memcpy(hostUniq.payload, &pid, sizeof(pid)); - CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE); - memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE); - cursor += sizeof(pid) + TAG_HDR_SIZE; - plen += sizeof(pid) + TAG_HDR_SIZE; - } - - /* Add our maximum MTU/MRU */ - if (MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru) > ETH_PPPOE_MTU) { - PPPoETag maxPayload; - UINT16_t mru = htons(MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru)); - maxPayload.type = htons(TAG_PPP_MAX_PAYLOAD); - maxPayload.length = htons(sizeof(mru)); - memcpy(maxPayload.payload, &mru, sizeof(mru)); - CHECK_ROOM(cursor, packet.payload, sizeof(mru) + TAG_HDR_SIZE); - memcpy(cursor, &maxPayload, sizeof(mru) + TAG_HDR_SIZE); - cursor += sizeof(mru) + TAG_HDR_SIZE; - plen += sizeof(mru) + TAG_HDR_SIZE; - } - - packet.length = htons(plen); - - sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE)); -} - -/********************************************************************** -*%FUNCTION: waitForPADO -*%ARGUMENTS: -* conn -- PPPoEConnection structure -* timeout -- how long to wait (in seconds) -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Waits for a PADO packet and copies useful information -***********************************************************************/ -void -waitForPADO(PPPoEConnection *conn, int timeout) -{ - fd_set readable; - int r; - struct timeval tv; - struct timeval expire_at; - - PPPoEPacket packet; - int len; - - struct PacketCriteria pc; - pc.conn = conn; - pc.acNameOK = (conn->acName) ? 0 : 1; - pc.serviceNameOK = (conn->serviceName) ? 0 : 1; - pc.seenACName = 0; - pc.seenServiceName = 0; - conn->seenMaxPayload = 0; - conn->error = 0; - - if (gettimeofday(&expire_at, NULL) < 0) { - error("gettimeofday (waitForPADO): %m"); - return; - } - expire_at.tv_sec += timeout; - - do { - if (BPF_BUFFER_IS_EMPTY) { - if (!time_left(&tv, &expire_at)) - return; /* Timed out */ - - FD_ZERO(&readable); - FD_SET(conn->discoverySocket, &readable); - - while(1) { - r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); - if (r >= 0 || errno != EINTR) break; - } - if (r < 0) { - error("select (waitForPADO): %m"); - return; - } - if (r == 0) - return; /* Timed out */ - } - - /* Get the packet */ - receivePacket(conn->discoverySocket, &packet, &len); - - /* Check length */ - if (ntohs(packet.length) + HDR_SIZE > len) { - error("Bogus PPPoE length field (%u)", - (unsigned int) ntohs(packet.length)); - continue; - } - -#ifdef USE_BPF - /* If it's not a Discovery packet, loop again */ - if (etherType(&packet) != Eth_PPPOE_Discovery) continue; -#endif - - /* If it's not for us, loop again */ - if (!packetIsForMe(conn, &packet)) continue; - - if (packet.code == CODE_PADO) { - if (NOT_UNICAST(packet.ethHdr.h_source)) { - error("Ignoring PADO packet from non-unicast MAC address"); - continue; - } - if (conn->req_peer - && memcmp(packet.ethHdr.h_source, conn->req_peer_mac, ETH_ALEN) != 0) { - warn("Ignoring PADO packet from wrong MAC address"); - continue; - } - if (parsePacket(&packet, parsePADOTags, &pc) < 0) - return; - if (conn->error) - return; - if (!pc.seenACName) { - error("Ignoring PADO packet with no AC-Name tag"); - continue; - } - if (!pc.seenServiceName) { - error("Ignoring PADO packet with no Service-Name tag"); - continue; - } - conn->numPADOs++; - if (pc.acNameOK && pc.serviceNameOK) { - memcpy(conn->peerEth, packet.ethHdr.h_source, ETH_ALEN); - conn->discoveryState = STATE_RECEIVED_PADO; - break; - } - } - } while (conn->discoveryState != STATE_RECEIVED_PADO); -} - -/*********************************************************************** -*%FUNCTION: sendPADR -*%ARGUMENTS: -* conn -- PPPoE connection structur -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Sends a PADR packet -***********************************************************************/ -static void -sendPADR(PPPoEConnection *conn) -{ - PPPoEPacket packet; - PPPoETag *svc = (PPPoETag *) packet.payload; - unsigned char *cursor = packet.payload; - - UINT16_t namelen = 0; - UINT16_t plen; - - if (conn->serviceName) { - namelen = (UINT16_t) strlen(conn->serviceName); - } - plen = TAG_HDR_SIZE + namelen; - CHECK_ROOM(cursor, packet.payload, plen); - - memcpy(packet.ethHdr.h_dest, conn->peerEth, ETH_ALEN); - memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN); - - packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery); - packet.vertype = PPPOE_VER_TYPE(1, 1); - packet.code = CODE_PADR; - packet.session = 0; - - svc->type = TAG_SERVICE_NAME; - svc->length = htons(namelen); - if (conn->serviceName) { - memcpy(svc->payload, conn->serviceName, namelen); - } - cursor += namelen + TAG_HDR_SIZE; - - /* If we're using Host-Uniq, copy it over */ - if (conn->useHostUniq) { - PPPoETag hostUniq; - pid_t pid = getpid(); - hostUniq.type = htons(TAG_HOST_UNIQ); - hostUniq.length = htons(sizeof(pid)); - memcpy(hostUniq.payload, &pid, sizeof(pid)); - CHECK_ROOM(cursor, packet.payload, sizeof(pid)+TAG_HDR_SIZE); - memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE); - cursor += sizeof(pid) + TAG_HDR_SIZE; - plen += sizeof(pid) + TAG_HDR_SIZE; - } - - /* Add our maximum MTU/MRU */ - if (MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru) > ETH_PPPOE_MTU) { - PPPoETag maxPayload; - UINT16_t mru = htons(MIN(lcp_allowoptions[0].mru, lcp_wantoptions[0].mru)); - maxPayload.type = htons(TAG_PPP_MAX_PAYLOAD); - maxPayload.length = htons(sizeof(mru)); - memcpy(maxPayload.payload, &mru, sizeof(mru)); - CHECK_ROOM(cursor, packet.payload, sizeof(mru) + TAG_HDR_SIZE); - memcpy(cursor, &maxPayload, sizeof(mru) + TAG_HDR_SIZE); - cursor += sizeof(mru) + TAG_HDR_SIZE; - plen += sizeof(mru) + TAG_HDR_SIZE; - } - - /* Copy cookie and relay-ID if needed */ - if (conn->cookie.type) { - CHECK_ROOM(cursor, packet.payload, - ntohs(conn->cookie.length) + TAG_HDR_SIZE); - memcpy(cursor, &conn->cookie, ntohs(conn->cookie.length) + TAG_HDR_SIZE); - cursor += ntohs(conn->cookie.length) + TAG_HDR_SIZE; - plen += ntohs(conn->cookie.length) + TAG_HDR_SIZE; - } - - if (conn->relayId.type) { - CHECK_ROOM(cursor, packet.payload, - ntohs(conn->relayId.length) + TAG_HDR_SIZE); - memcpy(cursor, &conn->relayId, ntohs(conn->relayId.length) + TAG_HDR_SIZE); - cursor += ntohs(conn->relayId.length) + TAG_HDR_SIZE; - plen += ntohs(conn->relayId.length) + TAG_HDR_SIZE; - } - - packet.length = htons(plen); - sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE)); -} - -/********************************************************************** -*%FUNCTION: waitForPADS -*%ARGUMENTS: -* conn -- PPPoE connection info -* timeout -- how long to wait (in seconds) -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Waits for a PADS packet and copies useful information -***********************************************************************/ -static void -waitForPADS(PPPoEConnection *conn, int timeout) -{ - fd_set readable; - int r; - struct timeval tv; - struct timeval expire_at; - - PPPoEPacket packet; - int len; - - if (gettimeofday(&expire_at, NULL) < 0) { - error("gettimeofday (waitForPADS): %m"); - return; - } - expire_at.tv_sec += timeout; - - conn->error = 0; - do { - if (BPF_BUFFER_IS_EMPTY) { - if (!time_left(&tv, &expire_at)) - return; /* Timed out */ - - FD_ZERO(&readable); - FD_SET(conn->discoverySocket, &readable); - - while(1) { - r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); - if (r >= 0 || errno != EINTR) break; - } - if (r < 0) { - error("select (waitForPADS): %m"); - return; - } - if (r == 0) - return; /* Timed out */ - } - - /* Get the packet */ - receivePacket(conn->discoverySocket, &packet, &len); - - /* Check length */ - if (ntohs(packet.length) + HDR_SIZE > len) { - error("Bogus PPPoE length field (%u)", - (unsigned int) ntohs(packet.length)); - continue; - } - -#ifdef USE_BPF - /* If it's not a Discovery packet, loop again */ - if (etherType(&packet) != Eth_PPPOE_Discovery) continue; -#endif - - /* If it's not from the AC, it's not for me */ - if (memcmp(packet.ethHdr.h_source, conn->peerEth, ETH_ALEN)) continue; - - /* If it's not for us, loop again */ - if (!packetIsForMe(conn, &packet)) continue; - - /* Is it PADS? */ - if (packet.code == CODE_PADS) { - /* Parse for goodies */ - if (parsePacket(&packet, parsePADSTags, conn) < 0) - return; - if (conn->error) - return; - conn->discoveryState = STATE_SESSION; - break; - } - } while (conn->discoveryState != STATE_SESSION); - - /* Don't bother with ntohs; we'll just end up converting it back... */ - conn->session = packet.session; - - info("PPP session is %d", (int) ntohs(conn->session)); - - /* RFC 2516 says session id MUST NOT be zero or 0xFFFF */ - if (ntohs(conn->session) == 0 || ntohs(conn->session) == 0xFFFF) { - error("Access concentrator used a session value of %x -- the AC is violating RFC 2516", (unsigned int) ntohs(conn->session)); - } -} - -/********************************************************************** -*%FUNCTION: discovery -*%ARGUMENTS: -* conn -- PPPoE connection info structure -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Performs the PPPoE discovery phase -***********************************************************************/ -void -discovery(PPPoEConnection *conn) -{ - int padiAttempts = 0; - int padrAttempts = 0; - int timeout = conn->discoveryTimeout; - - do { - padiAttempts++; - if (padiAttempts > MAX_PADI_ATTEMPTS) { - warn("Timeout waiting for PADO packets"); - close(conn->discoverySocket); - conn->discoverySocket = -1; - return; - } - sendPADI(conn); - conn->discoveryState = STATE_SENT_PADI; - waitForPADO(conn, timeout); - - timeout *= 2; - } while (conn->discoveryState == STATE_SENT_PADI); - - timeout = conn->discoveryTimeout; - do { - padrAttempts++; - if (padrAttempts > MAX_PADI_ATTEMPTS) { - warn("Timeout waiting for PADS packets"); - close(conn->discoverySocket); - conn->discoverySocket = -1; - return; - } - sendPADR(conn); - conn->discoveryState = STATE_SENT_PADR; - waitForPADS(conn, timeout); - timeout *= 2; - } while (conn->discoveryState == STATE_SENT_PADR); - - if (!conn->seenMaxPayload) { - /* RFC 4638: MUST limit MTU/MRU to 1492 */ - if (lcp_allowoptions[0].mru > ETH_PPPOE_MTU) - lcp_allowoptions[0].mru = ETH_PPPOE_MTU; - if (lcp_wantoptions[0].mru > ETH_PPPOE_MTU) - lcp_wantoptions[0].mru = ETH_PPPOE_MTU; - } - - /* We're done. */ - conn->discoveryState = STATE_SESSION; - return; -} diff -Nru ppp-2.4.7/pppd/plugins/rp-pppoe/.gitignore ppp-2.4.9/pppd/plugins/rp-pppoe/.gitignore --- ppp-2.4.7/pppd/plugins/rp-pppoe/.gitignore 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/rp-pppoe/.gitignore 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -pppoe-discovery diff -Nru ppp-2.4.7/pppd/plugins/rp-pppoe/if.c ppp-2.4.9/pppd/plugins/rp-pppoe/if.c --- ppp-2.4.7/pppd/plugins/rp-pppoe/if.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/rp-pppoe/if.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,246 +0,0 @@ -/*********************************************************************** -* -* if.c -* -* Implementation of user-space PPPoE redirector for Linux. -* -* Functions for opening a raw socket and reading/writing raw Ethernet frames. -* -* Copyright (C) 2000 by 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. -* -***********************************************************************/ - -static char const RCSID[] = -"$Id: if.c,v 1.2 2008/06/09 08:34:23 paulus Exp $"; - -#define _GNU_SOURCE 1 -#include "pppoe.h" -#include "pppd/pppd.h" - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_NETPACKET_PACKET_H -#include -#elif defined(HAVE_LINUX_IF_PACKET_H) -#include -#endif - -#ifdef HAVE_NET_ETHERNET_H -#include -#endif - -#ifdef HAVE_ASM_TYPES_H -#include -#endif - -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#include -#include -#include - -#ifdef HAVE_NET_IF_ARP_H -#include -#endif - -/* Initialize frame types to RFC 2516 values. Some broken peers apparently - use different frame types... sigh... */ - -UINT16_t Eth_PPPOE_Discovery = ETH_PPPOE_DISCOVERY; -UINT16_t Eth_PPPOE_Session = ETH_PPPOE_SESSION; - -/********************************************************************** -*%FUNCTION: etherType -*%ARGUMENTS: -* packet -- a received PPPoE packet -*%RETURNS: -* ethernet packet type (see /usr/include/net/ethertypes.h) -*%DESCRIPTION: -* Checks the ethernet packet header to determine its type. -* We should only be receveing DISCOVERY and SESSION types if the BPF -* is set up correctly. Logs an error if an unexpected type is received. -* Note that the ethernet type names come from "pppoe.h" and the packet -* packet structure names use the LINUX dialect to maintain consistency -* with the rest of this file. See the BSD section of "pppoe.h" for -* translations of the data structure names. -***********************************************************************/ -UINT16_t -etherType(PPPoEPacket *packet) -{ - UINT16_t type = (UINT16_t) ntohs(packet->ethHdr.h_proto); - if (type != Eth_PPPOE_Discovery && type != Eth_PPPOE_Session) { - error("Invalid ether type 0x%x", type); - } - return type; -} - -/********************************************************************** -*%FUNCTION: openInterface -*%ARGUMENTS: -* ifname -- name of interface -* type -- Ethernet frame type -* hwaddr -- if non-NULL, set to the hardware address -*%RETURNS: -* A raw socket for talking to the Ethernet card. Exits on error. -*%DESCRIPTION: -* Opens a raw Ethernet socket -***********************************************************************/ -int -openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr) -{ - int optval=1; - int fd; - struct ifreq ifr; - int domain, stype; - -#ifdef HAVE_STRUCT_SOCKADDR_LL - struct sockaddr_ll sa; -#else - struct sockaddr sa; -#endif - - memset(&sa, 0, sizeof(sa)); - -#ifdef HAVE_STRUCT_SOCKADDR_LL - domain = PF_PACKET; - stype = SOCK_RAW; -#else - domain = PF_INET; - stype = SOCK_PACKET; -#endif - - if ((fd = socket(domain, stype, htons(type))) < 0) { - /* Give a more helpful message for the common error case */ - if (errno == EPERM) { - fatal("Cannot create raw socket -- pppoe must be run as root."); - } - error("Can't open socket for pppoe: %m"); - return -1; - } - - if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) < 0) { - error("Can't set socket options for pppoe: %m"); - close(fd); - return -1; - } - - /* Fill in hardware address */ - if (hwaddr) { - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { - error("Can't get hardware address for %s: %m", ifname); - close(fd); - return -1; - } - memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); -#ifdef ARPHRD_ETHER - if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { - warn("Interface %.16s is not Ethernet", ifname); - } -#endif - if (NOT_UNICAST(hwaddr)) { - fatal("Can't use interface %.16s: it has broadcast/multicast MAC address", - ifname); - } - } - - /* Sanity check on MTU */ - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) { - error("Can't get MTU for %s: %m", ifname); - } else if (ifr.ifr_mtu < ETH_DATA_LEN) { - error("Interface %.16s has MTU of %d -- should be at least %d.", - ifname, ifr.ifr_mtu, ETH_DATA_LEN); - error("This may cause serious connection problems."); - } - -#ifdef HAVE_STRUCT_SOCKADDR_LL - /* Get interface index */ - sa.sll_family = AF_PACKET; - sa.sll_protocol = htons(type); - - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { - error("Could not get interface index for %s: %m", ifname); - close(fd); - return -1; - } - sa.sll_ifindex = ifr.ifr_ifindex; - -#else - strcpy(sa.sa_data, ifname); -#endif - - /* We're only interested in packets on specified interface */ - if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) { - error("Failed to bind to interface %s: %m", ifname); - close(fd); - return -1; - } - - return fd; -} - - -/*********************************************************************** -*%FUNCTION: sendPacket -*%ARGUMENTS: -* sock -- socket to send to -* pkt -- the packet to transmit -* size -- size of packet (in bytes) -*%RETURNS: -* 0 on success; -1 on failure -*%DESCRIPTION: -* Transmits a packet -***********************************************************************/ -int -sendPacket(PPPoEConnection *conn, int sock, PPPoEPacket *pkt, int size) -{ - int err; - - if (debug) - pppoe_log_packet("Send ", pkt); -#if defined(HAVE_STRUCT_SOCKADDR_LL) - err = send(sock, pkt, size, 0); -#else - struct sockaddr sa; - - strcpy(sa.sa_data, conn->ifName); - err = sendto(sock, pkt, size, 0, &sa, sizeof(sa)); -#endif - if (err < 0) { - error("error sending pppoe packet: %m"); - return -1; - } - return 0; -} - -/*********************************************************************** -*%FUNCTION: receivePacket -*%ARGUMENTS: -* sock -- socket to read from -* pkt -- place to store the received packet -* size -- set to size of packet in bytes -*%RETURNS: -* >= 0 if all OK; < 0 if error -*%DESCRIPTION: -* Receives a packet -***********************************************************************/ -int -receivePacket(int sock, PPPoEPacket *pkt, int *size) -{ - if ((*size = recv(sock, pkt, sizeof(PPPoEPacket), 0)) < 0) { - error("error receiving pppoe packet: %m"); - return -1; - } - if (debug) - pppoe_log_packet("Recv ", pkt); - return 0; -} diff -Nru ppp-2.4.7/pppd/plugins/rp-pppoe/Makefile.linux ppp-2.4.9/pppd/plugins/rp-pppoe/Makefile.linux --- ppp-2.4.7/pppd/plugins/rp-pppoe/Makefile.linux 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/rp-pppoe/Makefile.linux 1970-01-01 01:00:00.000000000 +0100 @@ -1,64 +0,0 @@ -# Generated automatically from Makefile.in by configure. -#*********************************************************************** -# -# 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. -# -# $Id: Makefile.linux,v 1.8 2008/06/09 08:34:23 paulus Exp $ -#*********************************************************************** - -DESTDIR = $(INSTROOT)@DESTDIR@ -BINDIR = $(DESTDIR)/sbin -LIBDIR = $(DESTDIR)/lib/pppd/$(PPPDVERSION) - -PPPDVERSION = $(shell awk -F '"' '/VERSION/ { print $$2; }' ../../patchlevel.h) - -INSTALL = install - -# Version is set ONLY IN THE MAKEFILE! Don't delete this! -RP_VERSION=3.8p - -COPTS=-O2 -g -CFLAGS=$(COPTS) -I../../../include '-DRP_VERSION="$(RP_VERSION)"' -all: rp-pppoe.so pppoe-discovery - -pppoe-discovery: pppoe-discovery.o debug.o - $(CC) -o pppoe-discovery pppoe-discovery.o debug.o - -pppoe-discovery.o: pppoe-discovery.c - $(CC) $(CFLAGS) -c -o pppoe-discovery.o pppoe-discovery.c - -debug.o: debug.c - $(CC) $(CFLAGS) -c -o debug.o debug.c - -rp-pppoe.so: plugin.o discovery.o if.o common.o - $(CC) -o rp-pppoe.so -shared plugin.o discovery.o if.o common.o - -install: all - $(INSTALL) -d -m 755 $(LIBDIR) - $(INSTALL) -s -c -m 4550 rp-pppoe.so $(LIBDIR) - $(INSTALL) -d -m 755 $(BINDIR) - $(INSTALL) -s -c -m 555 pppoe-discovery $(BINDIR) - -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 - diff -Nru ppp-2.4.7/pppd/plugins/rp-pppoe/plugin.c ppp-2.4.9/pppd/plugins/rp-pppoe/plugin.c --- ppp-2.4.7/pppd/plugins/rp-pppoe/plugin.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/rp-pppoe/plugin.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,441 +0,0 @@ -/*********************************************************************** -* -* plugin.c -* -* pppd plugin for kernel-mode PPPoE on Linux -* -* Copyright (C) 2001 by Roaring Penguin Software Inc., Michal Ostrowski -* and Jamal Hadi Salim. -* -* Much code and many ideas derived from pppoe plugin by Michal -* Ostrowski and Jamal Hadi Salim, which carries this copyright: -* -* Copyright 2000 Michal Ostrowski , -* Jamal Hadi Salim -* Borrows heavily from the PPPoATM plugin by Mitchell Blank Jr., -* which is based in part on work from Jens Axboe and Paul Mackerras. -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version -* 2 of the License, or (at your option) any later version. -* -***********************************************************************/ - -static char const RCSID[] = -"$Id: plugin.c,v 1.17 2008/06/15 04:35:50 paulus Exp $"; - -#define _GNU_SOURCE 1 -#include "pppoe.h" - -#include "pppd/pppd.h" -#include "pppd/fsm.h" -#include "pppd/lcp.h" -#include "pppd/ipcp.h" -#include "pppd/ccp.h" -/* #include "pppd/pathnames.h" */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef _ROOT_PATH -#define _ROOT_PATH "" -#endif - -#define _PATH_ETHOPT _ROOT_PATH "/etc/ppp/options." - -char pppd_version[] = VERSION; - -/* From sys-linux.c in pppd -- MUST FIX THIS! */ -extern int new_style_driver; - -char *pppd_pppoe_service = NULL; -static char *acName = NULL; -static char *existingSession = NULL; -static int printACNames = 0; -static char *pppoe_reqd_mac = NULL; -unsigned char pppoe_reqd_mac_addr[6]; - -static int PPPoEDevnameHook(char *cmd, char **argv, int doit); -static option_t Options[] = { - { "device name", o_wild, (void *) &PPPoEDevnameHook, - "PPPoE device name", - OPT_DEVNAM | OPT_PRIVFIX | OPT_NOARG | OPT_A2STRVAL | OPT_STATIC, - devnam}, - { "rp_pppoe_service", o_string, &pppd_pppoe_service, - "Desired PPPoE service name" }, - { "rp_pppoe_ac", o_string, &acName, - "Desired PPPoE access concentrator name" }, - { "rp_pppoe_sess", o_string, &existingSession, - "Attach to existing session (sessid:macaddr)" }, - { "rp_pppoe_verbose", o_int, &printACNames, - "Be verbose about discovered access concentrators"}, - { "pppoe-mac", o_string, &pppoe_reqd_mac, - "Only connect to specified MAC address" }, - { NULL } -}; -int (*OldDevnameHook)(char *cmd, char **argv, int doit) = NULL; -static PPPoEConnection *conn = NULL; - -/********************************************************************** - * %FUNCTION: PPPOEInitDevice - * %ARGUMENTS: - * None - * %RETURNS: - * - * %DESCRIPTION: - * Initializes PPPoE device. - ***********************************************************************/ -static int -PPPOEInitDevice(void) -{ - conn = malloc(sizeof(PPPoEConnection)); - if (!conn) { - novm("PPPoE session data"); - } - memset(conn, 0, sizeof(PPPoEConnection)); - conn->ifName = devnam; - conn->discoverySocket = -1; - conn->sessionSocket = -1; - conn->useHostUniq = 1; - conn->printACNames = printACNames; - conn->discoveryTimeout = PADI_TIMEOUT; - return 1; -} - -/********************************************************************** - * %FUNCTION: PPPOEConnectDevice - * %ARGUMENTS: - * None - * %RETURNS: - * Non-negative if all goes well; -1 otherwise - * %DESCRIPTION: - * Connects PPPoE device. - ***********************************************************************/ -static int -PPPOEConnectDevice(void) -{ - struct sockaddr_pppox sp; - struct ifreq ifr; - int s; - - /* Open session socket before discovery phase, to avoid losing session */ - /* packets sent by peer just after PADS packet (noted on some Cisco */ - /* server equipment). */ - /* Opening this socket just before waitForPADS in the discovery() */ - /* function would be more appropriate, but it would mess-up the code */ - conn->sessionSocket = socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_OE); - if (conn->sessionSocket < 0) { - error("Failed to create PPPoE socket: %m"); - return -1; - } - - /* Restore configuration */ - lcp_allowoptions[0].mru = conn->mtu; - lcp_wantoptions[0].mru = conn->mru; - - /* Update maximum MRU */ - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s < 0) { - error("Can't get MTU for %s: %m", conn->ifName); - goto errout; - } - strncpy(ifr.ifr_name, conn->ifName, sizeof(ifr.ifr_name)); - if (ioctl(s, SIOCGIFMTU, &ifr) < 0) { - error("Can't get MTU for %s: %m", conn->ifName); - close(s); - goto errout; - } - close(s); - - if (lcp_allowoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD) - lcp_allowoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD; - if (lcp_wantoptions[0].mru > ifr.ifr_mtu - TOTAL_OVERHEAD) - lcp_wantoptions[0].mru = ifr.ifr_mtu - TOTAL_OVERHEAD; - - conn->acName = acName; - conn->serviceName = pppd_pppoe_service; - strlcpy(ppp_devnam, devnam, sizeof(ppp_devnam)); - if (existingSession) { - unsigned int mac[ETH_ALEN]; - int i, ses; - if (sscanf(existingSession, "%d:%x:%x:%x:%x:%x:%x", - &ses, &mac[0], &mac[1], &mac[2], - &mac[3], &mac[4], &mac[5]) != 7) { - fatal("Illegal value for rp_pppoe_sess option"); - } - conn->session = htons(ses); - for (i=0; ipeerEth[i] = (unsigned char) mac[i]; - } - } else { - conn->discoverySocket = - openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth); - discovery(conn); - if (conn->discoveryState != STATE_SESSION) { - error("Unable to complete PPPoE Discovery"); - goto errout; - } - } - - /* Set PPPoE session-number for further consumption */ - ppp_session_number = ntohs(conn->session); - - sp.sa_family = AF_PPPOX; - sp.sa_protocol = PX_PROTO_OE; - sp.sa_addr.pppoe.sid = conn->session; - memcpy(sp.sa_addr.pppoe.dev, conn->ifName, IFNAMSIZ); - memcpy(sp.sa_addr.pppoe.remote, conn->peerEth, ETH_ALEN); - - /* Set remote_number for ServPoET */ - sprintf(remote_number, "%02X:%02X:%02X:%02X:%02X:%02X", - (unsigned) conn->peerEth[0], - (unsigned) conn->peerEth[1], - (unsigned) conn->peerEth[2], - (unsigned) conn->peerEth[3], - (unsigned) conn->peerEth[4], - (unsigned) conn->peerEth[5]); - - warn("Connected to %02X:%02X:%02X:%02X:%02X:%02X via interface %s", - (unsigned) conn->peerEth[0], - (unsigned) conn->peerEth[1], - (unsigned) conn->peerEth[2], - (unsigned) conn->peerEth[3], - (unsigned) conn->peerEth[4], - (unsigned) conn->peerEth[5], - conn->ifName); - - script_setenv("MACREMOTE", remote_number, 0); - - if (connect(conn->sessionSocket, (struct sockaddr *) &sp, - sizeof(struct sockaddr_pppox)) < 0) { - error("Failed to connect PPPoE socket: %d %m", errno); - goto errout; - } - - return conn->sessionSocket; - - errout: - if (conn->discoverySocket >= 0) { - sendPADT(conn, NULL); - close(conn->discoverySocket); - conn->discoverySocket = -1; - } - close(conn->sessionSocket); - return -1; -} - -static void -PPPOERecvConfig(int mru, - u_int32_t asyncmap, - int pcomp, - int accomp) -{ -#if 0 /* broken protocol, but no point harrassing the users I guess... */ - if (mru > MAX_PPPOE_MTU) - warn("Couldn't increase MRU to %d", mru); -#endif -} - -/********************************************************************** - * %FUNCTION: PPPOEDisconnectDevice - * %ARGUMENTS: - * None - * %RETURNS: - * Nothing - * %DESCRIPTION: - * Disconnects PPPoE device - ***********************************************************************/ -static void -PPPOEDisconnectDevice(void) -{ - struct sockaddr_pppox sp; - - sp.sa_family = AF_PPPOX; - sp.sa_protocol = PX_PROTO_OE; - sp.sa_addr.pppoe.sid = 0; - memcpy(sp.sa_addr.pppoe.dev, conn->ifName, IFNAMSIZ); - memcpy(sp.sa_addr.pppoe.remote, conn->peerEth, ETH_ALEN); - if (connect(conn->sessionSocket, (struct sockaddr *) &sp, - sizeof(struct sockaddr_pppox)) < 0) - error("Failed to disconnect PPPoE socket: %d %m", errno); - close(conn->sessionSocket); - /* don't send PADT?? */ - if (conn->discoverySocket >= 0) - close(conn->discoverySocket); -} - -static void -PPPOEDeviceOptions(void) -{ - char buf[256]; - snprintf(buf, 256, _PATH_ETHOPT "%s", devnam); - if (!options_from_file(buf, 0, 0, 1)) - exit(EXIT_OPTION_ERROR); - -} - -struct channel pppoe_channel; - -/********************************************************************** - * %FUNCTION: PPPoEDevnameHook - * %ARGUMENTS: - * cmd -- the command (actually, the device name - * argv -- argument vector - * doit -- if non-zero, set device name. Otherwise, just check if possible - * %RETURNS: - * 1 if we will handle this device; 0 otherwise. - * %DESCRIPTION: - * Checks if name is a valid interface name; if so, returns 1. Also - * sets up devnam (string representation of device). - ***********************************************************************/ -static int -PPPoEDevnameHook(char *cmd, char **argv, int doit) -{ - int r = 1; - int fd; - struct ifreq ifr; - - /* - * Take any otherwise-unrecognized option as a possible device name, - * and test if it is the name of a network interface with a - * hardware address whose sa_family is ARPHRD_ETHER. - */ - if (strlen(cmd) > 4 && !strncmp(cmd, "nic-", 4)) { - /* Strip off "nic-" */ - cmd += 4; - } - - /* Open a socket */ - if ((fd = socket(PF_PACKET, SOCK_RAW, 0)) < 0) { - r = 0; - } - - /* Try getting interface index */ - if (r) { - strncpy(ifr.ifr_name, cmd, sizeof(ifr.ifr_name)); - if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { - r = 0; - } else { - if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { - r = 0; - } else { - if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { - if (doit) - error("Interface %s not Ethernet", cmd); - r = 0; - } - } - } - } - - /* Close socket */ - close(fd); - if (r && doit) { - strncpy(devnam, cmd, sizeof(devnam)); - if (the_channel != &pppoe_channel) { - - the_channel = &pppoe_channel; - modem = 0; - - PPPOEInitDevice(); - } - return 1; - } - - return r; -} - -/********************************************************************** - * %FUNCTION: plugin_init - * %ARGUMENTS: - * None - * %RETURNS: - * Nothing - * %DESCRIPTION: - * Initializes hooks for pppd plugin - ***********************************************************************/ -void -plugin_init(void) -{ - if (!ppp_available() && !new_style_driver) { - fatal("Linux kernel does not support PPPoE -- are you running 2.4.x?"); - } - - add_options(Options); - - info("RP-PPPoE plugin version %s compiled against pppd %s", - RP_VERSION, VERSION); -} - -void pppoe_check_options(void) -{ - unsigned int mac[6]; - int i; - - if (pppoe_reqd_mac != NULL) { - if (sscanf(pppoe_reqd_mac, "%x:%x:%x:%x:%x:%x", - &mac[0], &mac[1], &mac[2], &mac[3], - &mac[4], &mac[5]) != 6) { - option_error("cannot parse pppoe-mac option value"); - exit(EXIT_OPTION_ERROR); - } - for (i = 0; i < 6; ++i) - conn->req_peer_mac[i] = mac[i]; - conn->req_peer = 1; - } - - lcp_allowoptions[0].neg_accompression = 0; - lcp_wantoptions[0].neg_accompression = 0; - - lcp_allowoptions[0].neg_asyncmap = 0; - lcp_wantoptions[0].neg_asyncmap = 0; - - lcp_allowoptions[0].neg_pcompression = 0; - lcp_wantoptions[0].neg_pcompression = 0; - - if (lcp_allowoptions[0].mru > MAX_PPPOE_MTU) - lcp_allowoptions[0].mru = MAX_PPPOE_MTU; - if (lcp_wantoptions[0].mru > MAX_PPPOE_MTU) - lcp_wantoptions[0].mru = MAX_PPPOE_MTU; - - /* Save configuration */ - conn->mtu = lcp_allowoptions[0].mru; - conn->mru = lcp_wantoptions[0].mru; - - ccp_allowoptions[0].deflate = 0; - ccp_wantoptions[0].deflate = 0; - - ipcp_allowoptions[0].neg_vj = 0; - ipcp_wantoptions[0].neg_vj = 0; - - ccp_allowoptions[0].bsd_compress = 0; - ccp_wantoptions[0].bsd_compress = 0; -} - -struct channel pppoe_channel = { - .options = Options, - .process_extra_options = &PPPOEDeviceOptions, - .check_options = pppoe_check_options, - .connect = &PPPOEConnectDevice, - .disconnect = &PPPOEDisconnectDevice, - .establish_ppp = &generic_establish_ppp, - .disestablish_ppp = &generic_disestablish_ppp, - .send_config = NULL, - .recv_config = &PPPOERecvConfig, - .close = NULL, - .cleanup = NULL -}; diff -Nru ppp-2.4.7/pppd/plugins/rp-pppoe/pppoe-discovery.c ppp-2.4.9/pppd/plugins/rp-pppoe/pppoe-discovery.c --- ppp-2.4.7/pppd/plugins/rp-pppoe/pppoe-discovery.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/rp-pppoe/pppoe-discovery.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,724 +0,0 @@ -/* - * Perform PPPoE discovery - * - * Copyright (C) 2000-2001 by Roaring Penguin Software Inc. - * Copyright (C) 2004 Marco d'Itri - * - * This program may be distributed according to the terms of the GNU - * General Public License, version 2 or (at your option) any later version. - * - */ - -#include -#include -#include -#include -#include - -#include "pppoe.h" - -#ifdef HAVE_UNISTD_H -#include -#endif - -#ifdef HAVE_NETPACKET_PACKET_H -#include -#elif defined(HAVE_LINUX_IF_PACKET_H) -#include -#endif - -#ifdef HAVE_NET_ETHERNET_H -#include -#endif - -#ifdef HAVE_ASM_TYPES_H -#include -#endif - -#ifdef HAVE_SYS_IOCTL_H -#include -#endif - -#include -#include -#include - -#ifdef HAVE_NET_IF_ARP_H -#include -#endif - -char *xstrdup(const char *s); -void usage(void); - -void die(int status) -{ - exit(status); -} - -/* Initialize frame types to RFC 2516 values. Some broken peers apparently - use different frame types... sigh... */ - -UINT16_t Eth_PPPOE_Discovery = ETH_PPPOE_DISCOVERY; -UINT16_t Eth_PPPOE_Session = ETH_PPPOE_SESSION; - -/********************************************************************** -*%FUNCTION: etherType -*%ARGUMENTS: -* packet -- a received PPPoE packet -*%RETURNS: -* ethernet packet type (see /usr/include/net/ethertypes.h) -*%DESCRIPTION: -* Checks the ethernet packet header to determine its type. -* We should only be receveing DISCOVERY and SESSION types if the BPF -* is set up correctly. Logs an error if an unexpected type is received. -* Note that the ethernet type names come from "pppoe.h" and the packet -* packet structure names use the LINUX dialect to maintain consistency -* with the rest of this file. See the BSD section of "pppoe.h" for -* translations of the data structure names. -***********************************************************************/ -UINT16_t -etherType(PPPoEPacket *packet) -{ - UINT16_t type = (UINT16_t) ntohs(packet->ethHdr.h_proto); - if (type != Eth_PPPOE_Discovery && type != Eth_PPPOE_Session) { - fprintf(stderr, "Invalid ether type 0x%x\n", type); - } - return type; -} - -/********************************************************************** -*%FUNCTION: openInterface -*%ARGUMENTS: -* ifname -- name of interface -* type -- Ethernet frame type -* hwaddr -- if non-NULL, set to the hardware address -*%RETURNS: -* A raw socket for talking to the Ethernet card. Exits on error. -*%DESCRIPTION: -* Opens a raw Ethernet socket -***********************************************************************/ -int -openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr) -{ - int optval=1; - int fd; - struct ifreq ifr; - int domain, stype; - -#ifdef HAVE_STRUCT_SOCKADDR_LL - struct sockaddr_ll sa; -#else - struct sockaddr sa; -#endif - - memset(&sa, 0, sizeof(sa)); - -#ifdef HAVE_STRUCT_SOCKADDR_LL - domain = PF_PACKET; - stype = SOCK_RAW; -#else - domain = PF_INET; - stype = SOCK_PACKET; -#endif - - if ((fd = socket(domain, stype, htons(type))) < 0) { - /* Give a more helpful message for the common error case */ - if (errno == EPERM) { - rp_fatal("Cannot create raw socket -- pppoe must be run as root."); - } - fatalSys("socket"); - } - - if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(optval)) < 0) { - fatalSys("setsockopt"); - } - - /* Fill in hardware address */ - if (hwaddr) { - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) { - fatalSys("ioctl(SIOCGIFHWADDR)"); - } - memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN); -#ifdef ARPHRD_ETHER - if (ifr.ifr_hwaddr.sa_family != ARPHRD_ETHER) { - char buffer[256]; - sprintf(buffer, "Interface %.16s is not Ethernet", ifname); - rp_fatal(buffer); - } -#endif - if (NOT_UNICAST(hwaddr)) { - char buffer[256]; - sprintf(buffer, - "Interface %.16s has broadcast/multicast MAC address??", - ifname); - rp_fatal(buffer); - } - } - - /* Sanity check on MTU */ - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) { - fatalSys("ioctl(SIOCGIFMTU)"); - } - if (ifr.ifr_mtu < ETH_DATA_LEN) { - fprintf(stderr, "Interface %.16s has MTU of %d -- should be %d.\n", - ifname, ifr.ifr_mtu, ETH_DATA_LEN); - fprintf(stderr, "You may have serious connection problems.\n"); - } - -#ifdef HAVE_STRUCT_SOCKADDR_LL - /* Get interface index */ - sa.sll_family = AF_PACKET; - sa.sll_protocol = htons(type); - - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - if (ioctl(fd, SIOCGIFINDEX, &ifr) < 0) { - fatalSys("ioctl(SIOCFIGINDEX): Could not get interface index"); - } - sa.sll_ifindex = ifr.ifr_ifindex; - -#else - strcpy(sa.sa_data, ifname); -#endif - - /* We're only interested in packets on specified interface */ - if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) { - fatalSys("bind"); - } - - return fd; -} - - -/*********************************************************************** -*%FUNCTION: sendPacket -*%ARGUMENTS: -* sock -- socket to send to -* pkt -- the packet to transmit -* size -- size of packet (in bytes) -*%RETURNS: -* 0 on success; -1 on failure -*%DESCRIPTION: -* Transmits a packet -***********************************************************************/ -int -sendPacket(PPPoEConnection *conn, int sock, PPPoEPacket *pkt, int size) -{ -#if defined(HAVE_STRUCT_SOCKADDR_LL) - if (send(sock, pkt, size, 0) < 0) { - sysErr("send (sendPacket)"); - return -1; - } -#else - struct sockaddr sa; - - if (!conn) { - rp_fatal("relay and server not supported on Linux 2.0 kernels"); - } - strcpy(sa.sa_data, conn->ifName); - if (sendto(sock, pkt, size, 0, &sa, sizeof(sa)) < 0) { - sysErr("sendto (sendPacket)"); - return -1; - } -#endif - return 0; -} - -/*********************************************************************** -*%FUNCTION: receivePacket -*%ARGUMENTS: -* sock -- socket to read from -* pkt -- place to store the received packet -* size -- set to size of packet in bytes -*%RETURNS: -* >= 0 if all OK; < 0 if error -*%DESCRIPTION: -* Receives a packet -***********************************************************************/ -int -receivePacket(int sock, PPPoEPacket *pkt, int *size) -{ - if ((*size = recv(sock, pkt, sizeof(PPPoEPacket), 0)) < 0) { - sysErr("recv (receivePacket)"); - return -1; - } - return 0; -} - -/********************************************************************** -*%FUNCTION: parsePacket -*%ARGUMENTS: -* packet -- the PPPoE discovery packet to parse -* func -- function called for each tag in the packet -* extra -- an opaque data pointer supplied to parsing function -*%RETURNS: -* 0 if everything went well; -1 if there was an error -*%DESCRIPTION: -* Parses a PPPoE discovery packet, calling "func" for each tag in the packet. -* "func" is passed the additional argument "extra". -***********************************************************************/ -int -parsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra) -{ - UINT16_t len = ntohs(packet->length); - unsigned char *curTag; - UINT16_t tagType, tagLen; - - if (PPPOE_VER(packet->vertype) != 1) { - fprintf(stderr, "Invalid PPPoE version (%d)\n", - PPPOE_VER(packet->vertype)); - return -1; - } - if (PPPOE_TYPE(packet->vertype) != 1) { - fprintf(stderr, "Invalid PPPoE type (%d)\n", - PPPOE_TYPE(packet->vertype)); - return -1; - } - - /* Do some sanity checks on packet */ - if (len > ETH_JUMBO_LEN - PPPOE_OVERHEAD) { /* 6-byte overhead for PPPoE header */ - fprintf(stderr, "Invalid PPPoE packet length (%u)\n", len); - return -1; - } - - /* Step through the tags */ - curTag = packet->payload; - while(curTag - packet->payload < len) { - /* Alignment is not guaranteed, so do this by hand... */ - tagType = (curTag[0] << 8) + curTag[1]; - tagLen = (curTag[2] << 8) + curTag[3]; - if (tagType == TAG_END_OF_LIST) { - return 0; - } - if ((curTag - packet->payload) + tagLen + TAG_HDR_SIZE > len) { - fprintf(stderr, "Invalid PPPoE tag length (%u)\n", tagLen); - return -1; - } - func(tagType, tagLen, curTag+TAG_HDR_SIZE, extra); - curTag = curTag + TAG_HDR_SIZE + tagLen; - } - return 0; -} - -/********************************************************************** -*%FUNCTION: parseForHostUniq -*%ARGUMENTS: -* type -- tag type -* len -- tag length -* data -- tag data. -* extra -- user-supplied pointer. This is assumed to be a pointer to int. -*%RETURNS: -* Nothing -*%DESCRIPTION: -* If a HostUnique tag is found which matches our PID, sets *extra to 1. -***********************************************************************/ -void -parseForHostUniq(UINT16_t type, UINT16_t len, unsigned char *data, - void *extra) -{ - int *val = (int *) extra; - if (type == TAG_HOST_UNIQ && len == sizeof(pid_t)) { - pid_t tmp; - memcpy(&tmp, data, len); - if (tmp == getpid()) { - *val = 1; - } - } -} - -/********************************************************************** -*%FUNCTION: packetIsForMe -*%ARGUMENTS: -* conn -- PPPoE connection info -* packet -- a received PPPoE packet -*%RETURNS: -* 1 if packet is for this PPPoE daemon; 0 otherwise. -*%DESCRIPTION: -* If we are using the Host-Unique tag, verifies that packet contains -* our unique identifier. -***********************************************************************/ -int -packetIsForMe(PPPoEConnection *conn, PPPoEPacket *packet) -{ - int forMe = 0; - - /* If packet is not directed to our MAC address, forget it */ - if (memcmp(packet->ethHdr.h_dest, conn->myEth, ETH_ALEN)) return 0; - - /* If we're not using the Host-Unique tag, then accept the packet */ - if (!conn->useHostUniq) return 1; - - parsePacket(packet, parseForHostUniq, &forMe); - return forMe; -} - -/********************************************************************** -*%FUNCTION: parsePADOTags -*%ARGUMENTS: -* type -- tag type -* len -- tag length -* data -- tag data -* extra -- extra user data. Should point to a PacketCriteria structure -* which gets filled in according to selected AC name and service -* name. -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Picks interesting tags out of a PADO packet -***********************************************************************/ -void -parsePADOTags(UINT16_t type, UINT16_t len, unsigned char *data, - void *extra) -{ - struct PacketCriteria *pc = (struct PacketCriteria *) extra; - PPPoEConnection *conn = pc->conn; - int i; - - switch(type) { - case TAG_AC_NAME: - pc->seenACName = 1; - printf("Access-Concentrator: %.*s\n", (int) len, data); - if (conn->acName && len == strlen(conn->acName) && - !strncmp((char *) data, conn->acName, len)) { - pc->acNameOK = 1; - } - break; - case TAG_SERVICE_NAME: - pc->seenServiceName = 1; - if (len > 0) { - printf(" Service-Name: %.*s\n", (int) len, data); - } - if (conn->serviceName && len == strlen(conn->serviceName) && - !strncmp((char *) data, conn->serviceName, len)) { - pc->serviceNameOK = 1; - } - break; - case TAG_AC_COOKIE: - printf("Got a cookie:"); - /* Print first 20 bytes of cookie */ - for (i=0; icookie.type = htons(type); - conn->cookie.length = htons(len); - memcpy(conn->cookie.payload, data, len); - break; - case TAG_RELAY_SESSION_ID: - printf("Got a Relay-ID:"); - /* Print first 20 bytes of relay ID */ - for (i=0; irelayId.type = htons(type); - conn->relayId.length = htons(len); - memcpy(conn->relayId.payload, data, len); - break; - case TAG_SERVICE_NAME_ERROR: - printf("Got a Service-Name-Error tag: %.*s\n", (int) len, data); - break; - case TAG_AC_SYSTEM_ERROR: - printf("Got a System-Error tag: %.*s\n", (int) len, data); - break; - case TAG_GENERIC_ERROR: - printf("Got a Generic-Error tag: %.*s\n", (int) len, data); - break; - } -} - -/*********************************************************************** -*%FUNCTION: sendPADI -*%ARGUMENTS: -* conn -- PPPoEConnection structure -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Sends a PADI packet -***********************************************************************/ -void -sendPADI(PPPoEConnection *conn) -{ - PPPoEPacket packet; - unsigned char *cursor = packet.payload; - PPPoETag *svc = (PPPoETag *) (&packet.payload); - UINT16_t namelen = 0; - UINT16_t plen; - - if (conn->serviceName) { - namelen = (UINT16_t) strlen(conn->serviceName); - } - plen = TAG_HDR_SIZE + namelen; - CHECK_ROOM(cursor, packet.payload, plen); - - /* Set destination to Ethernet broadcast address */ - memset(packet.ethHdr.h_dest, 0xFF, ETH_ALEN); - memcpy(packet.ethHdr.h_source, conn->myEth, ETH_ALEN); - - packet.ethHdr.h_proto = htons(Eth_PPPOE_Discovery); - packet.vertype = PPPOE_VER_TYPE(1, 1); - packet.code = CODE_PADI; - packet.session = 0; - - svc->type = TAG_SERVICE_NAME; - svc->length = htons(namelen); - CHECK_ROOM(cursor, packet.payload, namelen+TAG_HDR_SIZE); - - if (conn->serviceName) { - memcpy(svc->payload, conn->serviceName, strlen(conn->serviceName)); - } - cursor += namelen + TAG_HDR_SIZE; - - /* If we're using Host-Uniq, copy it over */ - if (conn->useHostUniq) { - PPPoETag hostUniq; - pid_t pid = getpid(); - hostUniq.type = htons(TAG_HOST_UNIQ); - hostUniq.length = htons(sizeof(pid)); - memcpy(hostUniq.payload, &pid, sizeof(pid)); - CHECK_ROOM(cursor, packet.payload, sizeof(pid) + TAG_HDR_SIZE); - memcpy(cursor, &hostUniq, sizeof(pid) + TAG_HDR_SIZE); - cursor += sizeof(pid) + TAG_HDR_SIZE; - plen += sizeof(pid) + TAG_HDR_SIZE; - } - - packet.length = htons(plen); - - sendPacket(conn, conn->discoverySocket, &packet, (int) (plen + HDR_SIZE)); - if (conn->debugFile) { - dumpPacket(conn->debugFile, &packet, "SENT"); - fprintf(conn->debugFile, "\n"); - fflush(conn->debugFile); - } -} - -/********************************************************************** -*%FUNCTION: waitForPADO -*%ARGUMENTS: -* conn -- PPPoEConnection structure -* timeout -- how long to wait (in seconds) -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Waits for a PADO packet and copies useful information -***********************************************************************/ -void -waitForPADO(PPPoEConnection *conn, int timeout) -{ - fd_set readable; - int r; - struct timeval tv; - PPPoEPacket packet; - int len; - - struct PacketCriteria pc; - pc.conn = conn; - pc.acNameOK = (conn->acName) ? 0 : 1; - pc.serviceNameOK = (conn->serviceName) ? 0 : 1; - pc.seenACName = 0; - pc.seenServiceName = 0; - conn->error = 0; - - do { - if (BPF_BUFFER_IS_EMPTY) { - tv.tv_sec = timeout; - tv.tv_usec = 0; - - FD_ZERO(&readable); - FD_SET(conn->discoverySocket, &readable); - - while(1) { - r = select(conn->discoverySocket+1, &readable, NULL, NULL, &tv); - if (r >= 0 || errno != EINTR) break; - } - if (r < 0) { - perror("select (waitForPADO)"); - return; - } - if (r == 0) return; /* Timed out */ - } - - /* Get the packet */ - receivePacket(conn->discoverySocket, &packet, &len); - - /* Check length */ - if (ntohs(packet.length) + HDR_SIZE > len) { - fprintf(stderr, "Bogus PPPoE length field (%u)\n", - (unsigned int) ntohs(packet.length)); - continue; - } - -#ifdef USE_BPF - /* If it's not a Discovery packet, loop again */ - if (etherType(&packet) != Eth_PPPOE_Discovery) continue; -#endif - - if (conn->debugFile) { - dumpPacket(conn->debugFile, &packet, "RCVD"); - fprintf(conn->debugFile, "\n"); - fflush(conn->debugFile); - } - /* If it's not for us, loop again */ - if (!packetIsForMe(conn, &packet)) continue; - - if (packet.code == CODE_PADO) { - if (BROADCAST(packet.ethHdr.h_source)) { - fprintf(stderr, "Ignoring PADO packet from broadcast MAC address\n"); - continue; - } - parsePacket(&packet, parsePADOTags, &pc); - if (conn->error) - return; - if (!pc.seenACName) { - fprintf(stderr, "Ignoring PADO packet with no AC-Name tag\n"); - continue; - } - if (!pc.seenServiceName) { - fprintf(stderr, "Ignoring PADO packet with no Service-Name tag\n"); - continue; - } - conn->numPADOs++; - printf("--------------------------------------------------\n"); - if (pc.acNameOK && pc.serviceNameOK) { - memcpy(conn->peerEth, packet.ethHdr.h_source, ETH_ALEN); - if (conn->printACNames) { - printf("AC-Ethernet-Address: %02x:%02x:%02x:%02x:%02x:%02x\n", - (unsigned) conn->peerEth[0], - (unsigned) conn->peerEth[1], - (unsigned) conn->peerEth[2], - (unsigned) conn->peerEth[3], - (unsigned) conn->peerEth[4], - (unsigned) conn->peerEth[5]); - continue; - } - conn->discoveryState = STATE_RECEIVED_PADO; - break; - } - } - } while (conn->discoveryState != STATE_RECEIVED_PADO); -} - -/********************************************************************** -*%FUNCTION: discovery -*%ARGUMENTS: -* conn -- PPPoE connection info structure -*%RETURNS: -* Nothing -*%DESCRIPTION: -* Performs the PPPoE discovery phase -***********************************************************************/ -void -discovery(PPPoEConnection *conn) -{ - int padiAttempts = 0; - int timeout = PADI_TIMEOUT; - - conn->discoverySocket = - openInterface(conn->ifName, Eth_PPPOE_Discovery, conn->myEth); - - do { - padiAttempts++; - if (padiAttempts > MAX_PADI_ATTEMPTS) { - fprintf(stderr, "Timeout waiting for PADO packets\n"); - close(conn->discoverySocket); - conn->discoverySocket = -1; - return; - } - sendPADI(conn); - conn->discoveryState = STATE_SENT_PADI; - waitForPADO(conn, timeout); - } while (!conn->numPADOs); -} - -int main(int argc, char *argv[]) -{ - int opt; - PPPoEConnection *conn; - - conn = malloc(sizeof(PPPoEConnection)); - if (!conn) - fatalSys("malloc"); - - memset(conn, 0, sizeof(PPPoEConnection)); - - while ((opt = getopt(argc, argv, "I:D:VUAS:C:h")) > 0) { - switch(opt) { - case 'S': - conn->serviceName = xstrdup(optarg); - break; - case 'C': - conn->acName = xstrdup(optarg); - break; - case 'U': - conn->useHostUniq = 1; - break; - case 'D': - conn->debugFile = fopen(optarg, "w"); - if (!conn->debugFile) { - fprintf(stderr, "Could not open %s: %s\n", - optarg, strerror(errno)); - exit(1); - } - fprintf(conn->debugFile, "pppoe-discovery %s\n", RP_VERSION); - break; - case 'I': - conn->ifName = xstrdup(optarg); - break; - case 'A': - /* this is the default */ - break; - case 'V': - case 'h': - usage(); - exit(0); - default: - usage(); - exit(1); - } - } - - /* default interface name */ - if (!conn->ifName) - conn->ifName = strdup("eth0"); - - conn->discoverySocket = -1; - conn->sessionSocket = -1; - conn->printACNames = 1; - - discovery(conn); - exit(0); -} - -void rp_fatal(char const *str) -{ - fprintf(stderr, "%s\n", str); - exit(1); -} - -void fatalSys(char const *str) -{ - perror(str); - exit(1); -} - -void sysErr(char const *str) -{ - rp_fatal(str); -} - -char *xstrdup(const char *s) -{ - register char *ret = strdup(s); - if (!ret) - sysErr("strdup"); - return ret; -} - -void usage(void) -{ - fprintf(stderr, "Usage: pppoe-discovery [options]\n"); - fprintf(stderr, "\nVersion " RP_VERSION "\n"); -} diff -Nru ppp-2.4.7/pppd/plugins/rp-pppoe/pppoe.h ppp-2.4.9/pppd/plugins/rp-pppoe/pppoe.h --- ppp-2.4.7/pppd/plugins/rp-pppoe/pppoe.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/rp-pppoe/pppoe.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,307 +0,0 @@ -/*********************************************************************** -* -* pppoe.h -* -* Declaration of various PPPoE constants -* -* Copyright (C) 2000 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. -* -* $Id: pppoe.h,v 1.4 2008/06/15 04:35:50 paulus Exp $ -* -***********************************************************************/ - -#include "config.h" - -#if defined(HAVE_NETPACKET_PACKET_H) || defined(HAVE_LINUX_IF_PACKET_H) -#define _POSIX_SOURCE 1 /* For sigaction defines */ -#endif - -#include /* For FILE */ -#include /* For pid_t */ - -/* How do we access raw Ethernet devices? */ -#undef USE_LINUX_PACKET -#undef USE_BPF - -#if defined(HAVE_NETPACKET_PACKET_H) || defined(HAVE_LINUX_IF_PACKET_H) -#define USE_LINUX_PACKET 1 -#elif defined(HAVE_SYS_DLPI_H) -#define USE_DLPI -#elif defined(HAVE_NET_BPF_H) -#define USE_BPF 1 -#endif - -/* Sanity check */ -#if !defined(USE_BPF) && !defined(USE_LINUX_PACKET) && !defined(USE_DLPI) -#error Unknown method for accessing raw Ethernet frames -#endif - -#ifdef HAVE_SYS_CDEFS_H -#include -#endif - -#ifdef HAVE_SYS_SOCKET_H -#include -#endif - -/* Ugly header files on some Linux boxes... */ -#if defined(HAVE_LINUX_IF_H) -#include -#elif defined(HAVE_NET_IF_H) -#include -#endif - -#ifdef HAVE_NET_IF_TYPES_H -#include -#endif - -#define BPF_BUFFER_IS_EMPTY 1 -#define BPF_BUFFER_HAS_DATA 0 - -/* Define various integer types -- assumes a char is 8 bits */ -#if SIZEOF_UNSIGNED_SHORT == 2 -typedef unsigned short UINT16_t; -#elif SIZEOF_UNSIGNED_INT == 2 -typedef unsigned int UINT16_t; -#else -#error Could not find a 16-bit integer type -#endif - -#if SIZEOF_UNSIGNED_SHORT == 4 -typedef unsigned short UINT32_t; -#elif SIZEOF_UNSIGNED_INT == 4 -typedef unsigned int UINT32_t; -#elif SIZEOF_UNSIGNED_LONG == 4 -typedef unsigned long UINT32_t; -#else -#error Could not find a 32-bit integer type -#endif - -#ifdef HAVE_LINUX_IF_ETHER_H -#include -#endif - -#include - -#ifdef HAVE_NETINET_IF_ETHER_H -#include - -#ifdef HAVE_SYS_SOCKET_H -#include -#endif -#ifndef HAVE_SYS_DLPI_H -#include -#endif -#endif - - - -/* Ethernet frame types according to RFC 2516 */ -#define ETH_PPPOE_DISCOVERY 0x8863 -#define ETH_PPPOE_SESSION 0x8864 - -/* But some brain-dead peers disobey the RFC, so frame types are variables */ -extern UINT16_t Eth_PPPOE_Discovery; -extern UINT16_t Eth_PPPOE_Session; - -/* PPPoE codes */ -#define CODE_PADI 0x09 -#define CODE_PADO 0x07 -#define CODE_PADR 0x19 -#define CODE_PADS 0x65 -#define CODE_PADT 0xA7 - -/* Extensions from draft-carrel-info-pppoe-ext-00 */ -/* I do NOT like PADM or PADN, but they are here for completeness */ -#define CODE_PADM 0xD3 -#define CODE_PADN 0xD4 - -#define CODE_SESS 0x00 - -/* PPPoE Tags */ -#define TAG_END_OF_LIST 0x0000 -#define TAG_SERVICE_NAME 0x0101 -#define TAG_AC_NAME 0x0102 -#define TAG_HOST_UNIQ 0x0103 -#define TAG_AC_COOKIE 0x0104 -#define TAG_VENDOR_SPECIFIC 0x0105 -#define TAG_RELAY_SESSION_ID 0x0110 -#define TAG_PPP_MAX_PAYLOAD 0x0120 -#define TAG_SERVICE_NAME_ERROR 0x0201 -#define TAG_AC_SYSTEM_ERROR 0x0202 -#define TAG_GENERIC_ERROR 0x0203 - -/* Extensions from draft-carrel-info-pppoe-ext-00 */ -/* I do NOT like these tags one little bit */ -#define TAG_HURL 0x111 -#define TAG_MOTM 0x112 -#define TAG_IP_ROUTE_ADD 0x121 - -/* Discovery phase states */ -#define STATE_SENT_PADI 0 -#define STATE_RECEIVED_PADO 1 -#define STATE_SENT_PADR 2 -#define STATE_SESSION 3 -#define STATE_TERMINATED 4 - -/* How many PADI/PADS attempts? */ -#define MAX_PADI_ATTEMPTS 3 - -/* Initial timeout for PADO/PADS */ -#define PADI_TIMEOUT 5 - -/* States for scanning PPP frames */ -#define STATE_WAITFOR_FRAME_ADDR 0 -#define STATE_DROP_PROTO 1 -#define STATE_BUILDING_PACKET 2 - -/* Special PPP frame characters */ -#define FRAME_ESC 0x7D -#define FRAME_FLAG 0x7E -#define FRAME_ADDR 0xFF -#define FRAME_CTRL 0x03 -#define FRAME_ENC 0x20 - -#define IPV4ALEN 4 -#define SMALLBUF 256 - -/* There are other fixed-size buffers preventing - this from being increased to 16110. The buffer - sizes would need to be properly de-coupled from - the default MRU. For now, getting up to 1500 is - enough. */ -#define ETH_JUMBO_LEN 1508 - -/* A PPPoE Packet, including Ethernet headers */ -typedef struct PPPoEPacketStruct { - struct ethhdr ethHdr; /* Ethernet header */ - unsigned int vertype:8; /* PPPoE Version and Type (must both be 1) */ - unsigned int code:8; /* PPPoE code */ - unsigned int session:16; /* PPPoE session */ - unsigned int length:16; /* Payload length */ - unsigned char payload[ETH_JUMBO_LEN]; /* A bit of room to spare */ -} PPPoEPacket; - -#define PPPOE_VER(vt) ((vt) >> 4) -#define PPPOE_TYPE(vt) ((vt) & 0xf) -#define PPPOE_VER_TYPE(v, t) (((v) << 4) | (t)) - -/* Header size of a PPPoE packet */ -#define PPPOE_OVERHEAD 6 /* type, code, session, length */ -#define HDR_SIZE (sizeof(struct ethhdr) + PPPOE_OVERHEAD) -#define MAX_PPPOE_PAYLOAD (ETH_JUMBO_LEN - PPPOE_OVERHEAD) -#define PPP_OVERHEAD 2 /* protocol */ -#define MAX_PPPOE_MTU (MAX_PPPOE_PAYLOAD - PPP_OVERHEAD) -#define TOTAL_OVERHEAD (PPPOE_OVERHEAD + PPP_OVERHEAD) -#define ETH_PPPOE_MTU (ETH_DATA_LEN - TOTAL_OVERHEAD) - -/* PPPoE Tag */ - -typedef struct PPPoETagStruct { - unsigned int type:16; /* tag type */ - unsigned int length:16; /* Length of payload */ - unsigned char payload[ETH_JUMBO_LEN]; /* A LOT of room to spare */ -} PPPoETag; -/* Header size of a PPPoE tag */ -#define TAG_HDR_SIZE 4 - -/* Chunk to read from stdin */ -#define READ_CHUNK 4096 - -/* Function passed to parsePacket */ -typedef void ParseFunc(UINT16_t type, - UINT16_t len, - unsigned char *data, - void *extra); - -#define PPPINITFCS16 0xffff /* Initial FCS value */ - -/* Keep track of the state of a connection -- collect everything in - one spot */ - -typedef struct PPPoEConnectionStruct { - int discoveryState; /* Where we are in discovery */ - int discoverySocket; /* Raw socket for discovery frames */ - int sessionSocket; /* Raw socket for session frames */ - unsigned char myEth[ETH_ALEN]; /* My MAC address */ - unsigned char peerEth[ETH_ALEN]; /* Peer's MAC address */ - unsigned char req_peer_mac[ETH_ALEN]; /* required peer MAC address */ - unsigned char req_peer; /* require mac addr to match req_peer_mac */ - UINT16_t session; /* Session ID */ - char *ifName; /* Interface name */ - char *serviceName; /* Desired service name, if any */ - char *acName; /* Desired AC name, if any */ - int synchronous; /* Use synchronous PPP */ - int useHostUniq; /* Use Host-Uniq tag */ - int printACNames; /* Just print AC names */ - FILE *debugFile; /* Debug file for dumping packets */ - int numPADOs; /* Number of PADO packets received */ - PPPoETag cookie; /* We have to send this if we get it */ - PPPoETag relayId; /* Ditto */ - int error; /* Error packet received */ - int debug; /* Set to log packets sent and received */ - int discoveryTimeout; /* Timeout for discovery packets */ - int seenMaxPayload; - int mtu; /* Stored MTU */ - int mru; /* Stored MRU */ -} PPPoEConnection; - -/* Structure used to determine acceptable PADO or PADS packet */ -struct PacketCriteria { - PPPoEConnection *conn; - int acNameOK; - int serviceNameOK; - int seenACName; - int seenServiceName; -}; - -/* Function Prototypes */ -UINT16_t etherType(PPPoEPacket *packet); -int openInterface(char const *ifname, UINT16_t type, unsigned char *hwaddr); -int sendPacket(PPPoEConnection *conn, int sock, PPPoEPacket *pkt, int size); -int receivePacket(int sock, PPPoEPacket *pkt, int *size); -void fatalSys(char const *str); -void rp_fatal(char const *str); -void printErr(char const *str); -void sysErr(char const *str); -void dumpPacket(FILE *fp, PPPoEPacket *packet, char const *dir); -void dumpHex(FILE *fp, unsigned char const *buf, int len); -int parsePacket(PPPoEPacket *packet, ParseFunc *func, void *extra); -void parseLogErrs(UINT16_t typ, UINT16_t len, unsigned char *data, void *xtra); -void syncReadFromPPP(PPPoEConnection *conn, PPPoEPacket *packet); -void asyncReadFromPPP(PPPoEConnection *conn, PPPoEPacket *packet); -void asyncReadFromEth(PPPoEConnection *conn, int sock, int clampMss); -void syncReadFromEth(PPPoEConnection *conn, int sock, int clampMss); -char *strDup(char const *str); -void sendPADT(PPPoEConnection *conn, char const *msg); -void sendSessionPacket(PPPoEConnection *conn, - PPPoEPacket *packet, int len); -void initPPP(void); -void clampMSS(PPPoEPacket *packet, char const *dir, int clampMss); -UINT16_t computeTCPChecksum(unsigned char *ipHdr, unsigned char *tcpHdr); -UINT16_t pppFCS16(UINT16_t fcs, unsigned char *cp, int len); -void discovery(PPPoEConnection *conn); -unsigned char *findTag(PPPoEPacket *packet, UINT16_t tagType, - PPPoETag *tag); - -void pppoe_printpkt(PPPoEPacket *packet, - void (*printer)(void *, char *, ...), void *arg); -void pppoe_log_packet(const char *prefix, PPPoEPacket *packet); - -#define SET_STRING(var, val) do { if (var) free(var); var = strDup(val); } while(0); - -#define CHECK_ROOM(cursor, start, len) \ -do {\ - if (((cursor)-(start))+(len) > MAX_PPPOE_PAYLOAD) { \ - error("Would create too-long packet"); \ - return; \ - } \ -} while(0) - -/* True if Ethernet address is broadcast or multicast */ -#define NOT_UNICAST(e) ((e[0] & 0x01) != 0) -#define BROADCAST(e) ((e[0] & e[1] & e[2] & e[3] & e[4] & e[5]) == 0xFF) -#define NOT_BROADCAST(e) ((e[0] & e[1] & e[2] & e[3] & e[4] & e[5]) != 0xFF) diff -Nru ppp-2.4.7/pppd/plugins/winbind.c ppp-2.4.9/pppd/plugins/winbind.c --- ppp-2.4.7/pppd/plugins/winbind.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/plugins/winbind.c 2021-01-05 00:06:37.000000000 +0100 @@ -432,6 +432,7 @@ /* parent */ if (close(child_out[0]) == -1) { + close(child_in[1]); notice("error closing pipe?!? for child OUT[0]"); return NOT_AUTHENTICATED; } @@ -442,7 +443,7 @@ return NOT_AUTHENTICATED; } - while ((wait(&status) == -1) && errno == EINTR) + while ((wait(&status) == -1) && errno == EINTR && !got_sigterm) ; if ((authenticated == AUTHENTICATED) && nt_key && !got_user_session_key) { diff -Nru ppp-2.4.7/pppd/pppcrypt.c ppp-2.4.9/pppd/pppcrypt.c --- ppp-2.4.7/pppd/pppcrypt.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/pppcrypt.c 2021-01-05 00:06:37.000000000 +0100 @@ -35,9 +35,7 @@ #include "pppcrypt.h" static u_char -Get7Bits(input, startBit) -u_char *input; -int startBit; +Get7Bits(u_char *input, int startBit) { unsigned int word; @@ -50,10 +48,10 @@ } static void -MakeKey(key, des_key) -u_char *key; /* IN 56 bit DES key missing parity bits */ -u_char *des_key; /* OUT 64 bit DES key with parity bits added */ +MakeKey(u_char *key, u_char *des_key) { + /* key IN 56 bit DES key missing parity bits */ + /* des_key OUT 64 bit DES key with parity bits added */ des_key[0] = Get7Bits(key, 0); des_key[1] = Get7Bits(key, 7); des_key[2] = Get7Bits(key, 14); @@ -64,7 +62,7 @@ des_key[7] = Get7Bits(key, 49); #ifndef USE_CRYPT - des_set_odd_parity((des_cblock *)des_key); + DES_set_odd_parity((DES_cblock *)des_key); #endif } @@ -75,9 +73,7 @@ * Note that the low-order "bit" is always ignored by by setkey() */ static void -Expand(in, out) -u_char *in; -u_char *out; +Expand(u_char *in, u_char *out) { int j, c; int i; @@ -93,9 +89,7 @@ /* The inverse of Expand */ static void -Collapse(in, out) -u_char *in; -u_char *out; +Collapse(u_char *in, u_char *out) { int j; int i; @@ -110,8 +104,7 @@ } bool -DesSetkey(key) -u_char *key; +DesSetkey(u_char *key) { u_char des_key[8]; u_char crypt_key[66]; @@ -126,9 +119,7 @@ } bool -DesEncrypt(clear, cipher) -u_char *clear; /* IN 8 octets */ -u_char *cipher; /* OUT 8 octets */ +DesEncrypt(u_char *clear, u_char *cipher) { u_char des_input[66]; @@ -142,9 +133,7 @@ } bool -DesDecrypt(cipher, clear) -u_char *cipher; /* IN 8 octets */ -u_char *clear; /* OUT 8 octets */ +DesDecrypt(u_char *cipher, u_char *clear) { u_char des_input[66]; @@ -158,35 +147,30 @@ } #else /* USE_CRYPT */ -static des_key_schedule key_schedule; +static DES_key_schedule key_schedule; bool -DesSetkey(key) -u_char *key; +DesSetkey(u_char *key) { - des_cblock des_key; + DES_cblock des_key; MakeKey(key, des_key); - des_set_key(&des_key, key_schedule); + DES_set_key(&des_key, &key_schedule); return (1); } bool -DesEncrypt(clear, key, cipher) -u_char *clear; /* IN 8 octets */ -u_char *cipher; /* OUT 8 octets */ +DesEncrypt(u_char *clear, u_char *cipher) { - des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, - key_schedule, 1); + DES_ecb_encrypt((DES_cblock *)clear, (DES_cblock *)cipher, + &key_schedule, 1); return (1); } bool -DesDecrypt(cipher, clear) -u_char *cipher; /* IN 8 octets */ -u_char *clear; /* OUT 8 octets */ +DesDecrypt(u_char *cipher, u_char *clear) { - des_ecb_encrypt((des_cblock *)cipher, (des_cblock *)clear, - key_schedule, 0); + DES_ecb_encrypt((DES_cblock *)cipher, (DES_cblock *)clear, + &key_schedule, 0); return (1); } diff -Nru ppp-2.4.7/pppd/pppcrypt.h ppp-2.4.9/pppd/pppcrypt.h --- ppp-2.4.7/pppd/pppcrypt.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/pppcrypt.h 2021-01-05 00:06:37.000000000 +0100 @@ -41,8 +41,8 @@ #include #endif -extern bool DesSetkey __P((u_char *)); -extern bool DesEncrypt __P((u_char *, u_char *)); -extern bool DesDecrypt __P((u_char *, u_char *)); +extern bool DesSetkey(u_char *); +extern bool DesEncrypt(u_char *, u_char *); +extern bool DesDecrypt(u_char *, u_char *); #endif /* PPPCRYPT_H */ diff -Nru ppp-2.4.7/pppd/pppd.8 ppp-2.4.9/pppd/pppd.8 --- ppp-2.4.7/pppd/pppd.8 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/pppd.8 2021-01-05 00:06:37.000000000 +0100 @@ -121,6 +121,23 @@ This entry is removed when the PPP connection is broken. This option is privileged if the \fInodefaultroute\fR option has been specified. .TP +.B defaultroute-metric +Define the metric of the \fIdefaultroute\fR and only add it if there +is no other default route with the same metric. With the default +value of -1, the route is only added if there is no default route at +all. +.TP +.B defaultroute6 +Add a default IPv6 route to the system routing tables, using the peer as +the gateway, when IPv6CP negotiation is successfully completed. +This entry is removed when the PPP connection is broken. This option +is privileged if the \fInodefaultroute6\fR option has been specified. +.TP +.B replacedefaultroute +This option is a flag to the defaultroute option. If defaultroute is +set and this flag is also set, pppd replaces an existing default route +with the new default route. This option is privileged. +.TP .B disconnect \fIscript Execute the command specified by \fIscript\fR, by passing it to a shell, after @@ -248,6 +265,12 @@ compression in the corresponding direction. Use \fInobsdcomp\fR or \fIbsdcomp 0\fR to disable BSD-Compress compression entirely. .TP +.B ca \fIca-file +(EAP-TLS) Use the file \fIca-file\fR as the X.509 Certificate Authority +(CA) file (in PEM format), needed for setting up an EAP-TLS connection. +This option is used on the client-side in conjunction with the \fBcert\fR +and \fBkey\fR options. +.TP .B cdtrcts Use a non-standard hardware flow control (i.e. DTR/CTS) to control the flow of data on the serial port. If neither the \fIcrtscts\fR, @@ -259,6 +282,12 @@ bi-directional flow control. The sacrifice is that this flow control mode does not permit using DTR as a modem control line. .TP +.B cert \fIcertfile +(EAP-TLS) Use the file \fIcertfile\fR as the X.509 certificate (in PEM +format), needed for setting up an EAP-TLS connection. This option is +used on the client-side in conjunction with the \fBca\fR and +\fBkey\fR options. +.TP .B chap\-interval \fIn If this option is given, pppd will rechallenge the peer every \fIn\fR seconds. @@ -271,6 +300,15 @@ Set the CHAP restart interval (retransmission timeout for challenges) to \fIn\fR seconds (default 3). .TP +.B chap-timeout \fIn +Set timeout for CHAP authentication by peer to \fIn\fR seconds (default 60). +.TP +.B chapms\-strip\-domain +Some Windows 9x/ME clients might be transmitting the MS domain before the +username in the provided client name. This option enables stripping the domain +from the client name on the server side before matching it against the secret +file. +.TP .B child\-timeout \fIn When exiting, wait for up to \fIn\fR seconds for any child processes (such as the command specified with the \fBpty\fR command) to exit @@ -287,6 +325,18 @@ 1000 (1 second). This wait period only applies if the \fBconnect\fR or \fBpty\fR option is used. .TP +.B crl \fIfilename +(EAP-TLS) Use the file \fIfilename\fR as the Certificate Revocation List +to check for the validity of the peer's certificate. This option is not +mandatory for setting up an EAP-TLS connection. Also see the \fBcrl-dir\fR +option. +.TP +.B crl-dir \fIdirectory +(EAP-TLS) Use the directory \fIdirectory\fR to scan for CRL files in +has format ($hash.r0) to check for the validity of the peer's certificate. +This option is not mandatory for setting up an EAP-TLS connection. +Also see the \fBcrl\fR option. +.TP .B debug Enables connection debugging facilities. If this option is given, pppd will log the contents of all @@ -458,6 +508,11 @@ interface identifier, even if the local IPv6 interface identifier was specified in an option. .TP +.B ipv6cp\-accept\-remote +With this option, pppd will accept the peer's idea of its (remote) +IPv6 interface identifier, even if the remote IPv6 interface +identifier was specified in an option. +.TP .B ipv6cp\-max\-configure \fIn Set the maximum number of IPv6CP configure-request transmissions to \fIn\fR (default 10). @@ -551,6 +606,12 @@ the kernel are logged by syslog(1) to a file as directed in the /etc/syslog.conf configuration file. .TP +.B key \fIkeyfile +(EAP-TLS) Use the file \fIkeyfile\fR as the private key file (in PEM +format), needed for setting up an EAP-TLS connection. This option is +used on the client-side in conjunction with the \fBca\fR and +\fBcert\fR options. +.TP .B ktune Enables pppd to alter kernel settings as appropriate. Under Linux, pppd will enable IP forwarding (i.e. set /proc/sys/net/ipv4/ip_forward @@ -558,6 +619,11 @@ dynamic IP address option (i.e. set /proc/sys/net/ipv4/ip_dynaddr to 1) in demand mode if the local address changes. .TP +.B lcp\-echo\-adaptive +If this option is used with the \fIlcp\-echo\-failure\fR option then +pppd will send LCP echo\-request frames only if no traffic was received +from the peer since the last echo\-request was sent. +.TP .B lcp\-echo\-failure \fIn If this option is given, pppd will presume the peer to be dead if \fIn\fR LCP echo\-requests are sent without receiving a valid LCP @@ -709,6 +775,9 @@ Disable Address/Control compression in both directions (send and receive). .TP +.B need-peer-eap +(EAP-TLS) Require the peer to verify our authentication credentials. +.TP .B noauth Do not require the peer to authenticate itself. This option is privileged. @@ -734,7 +803,16 @@ .TP .B nodefaultroute Disable the \fIdefaultroute\fR option. The system administrator who -wishes to prevent users from creating default routes with pppd +wishes to prevent users from adding a default route with pppd +can do so by placing this option in the /etc/ppp/options file. +.TP +.B noreplacedefaultroute +Disable the \fIreplacedefaultroute\fR option. This allows to disable a +\fIreplacedefaultroute\fR option set previously in the configuration. +.TP +.B nodefaultroute6 +Disable the \fIdefaultroute6\fR option. The system administrator who +wishes to prevent users from adding a default route with pppd can do so by placing this option in the /etc/ppp/options file. .TP .B nodeflate @@ -1065,6 +1143,10 @@ stored in ~/.ppp_pseudonym first as the identity, and save in this file any pseudonym offered by the peer during authentication. .TP +.B stop\-bits \fIn +Set the number of stop bits for the serial port. Valid values are 1 or 2. +The default value is 1. +.TP .B sync Use synchronous HDLC serial encoding instead of asynchronous. The device used by pppd with this option must have sync support. @@ -1073,7 +1155,13 @@ .TP .B unit \fInum Sets the ppp unit number (for a ppp0 or ppp1 etc interface name) for outbound -connections. +connections. If the unit is already in use a dynamically allocated number will +be used. +.TP +.B ifname \fIstring +Set the ppp interface name for outbound connections. If the interface name is +already in use, or if the name cannot be used for any other reason, pppd will +terminate. .TP .B unset \fIname Remove a variable from the environment variable for scripts that are @@ -1088,6 +1176,15 @@ the first network control protocol, usually the IP control protocol, has come up). .TP +.B up_sdnotify +Use this option to run pppd in systemd service units of Type=notify +(\fBup_sdnotify\fR implies \fBnodetach\fR). +When \fBup_sdnotify\fR is enabled, pppd will notify systemd once +it has successfully established the ppp connection (to the point where +the first network control protocl, usually the IP control protocol, +has come up). This option is only availble when pppd is compiled with +systemd support. +.TP .B usehostname Enforce the use of the hostname (with domain name appended, if given) as the name of the local system for authentication purposes (overrides @@ -1120,6 +1217,49 @@ .B xonxoff Use software flow control (i.e. XON/XOFF) to control the flow of data on the serial port. +.SH PPPOE OPTIONS +To establish PPP link over Ethernet (PPPoE) it is needed to load pppd's +\fBplugin pppoe.so\fR and then specify option \fBnic-\fIinterface\fR +instead of modem options \fIttyname\fR and \fIspeed\fR. +Recognized pppd's PPPoE options are: +.TP +.B nic-\fIinterface +Use the ethernet device \fIinterface\fR to communicate with the peer. +For example, establishing PPPoE link on \fIeth0\fR interface is done +by specifying ppp'd option \fBnic-eth0\fR. Prefix \fBnic-\fR for this +option may be avoided if interface name is unambiguous and does not +look like any other pppd's option. +.TP +.B pppoe-service \fIname +Connect to specified PPPoE service name. For backward compatibility also +\fBrp_pppoe_service\fP option name is supported. +.TP +.B pppoe-ac \fIname +Connect to specified PPPoE access concentrator name. For backward +compatibility also \fBrp_pppoe_ac\fP option name is supported. +.TP +.B pppoe-sess \fIsessid\fP:\fImacaddr +Attach to existing PPPoE session. For backward compatibility also +\fBrp_pppoe_sess\fP option name is supported. +.TP +.B pppoe-verbose \fIn +Be verbose about discovered access concentrators. For backward +compatibility also \fBrp_pppoe_verbose\fP option name is supported. +.TP +.B pppoe-mac \fImacaddr +Connect to specified MAC address. +.TP +.B pppoe-host-uniq \fIstring +Set the PPPoE Host-Uniq tag to the supplied hex string. +By default PPPoE Host-Uniq tag is set to the pppd's process PID. +For backward compatibility this option may be specified without +\fBpppoe-\fP prefix. +.TP +.B pppoe-padi-timeout \fIn +Initial timeout for discovery packets in seconds (default 5). +.TP +.B pppoe-padi-attempts \fIn +Number of discovery attempts (default 3). .SH OPTIONS FILES Options can be taken from files as well as the command line. Pppd reads options from the files /etc/ppp/options, ~/.ppprc and @@ -1641,6 +1781,9 @@ .B LINKNAME The logical name of the link, set with the \fIlinkname\fR option. .TP +.B CALL_FILE +The value of the \fIcall\fR option. +.TP .B DNS1 If the peer supplies DNS server addresses, this variable is set to the first DNS server address supplied (whether or not the usepeerdns @@ -1822,6 +1965,11 @@ .I PPP in HDLC-like Framing. July 1994. .TP +.B RFC1990 +Sklower, K.; et al., +.I The PPP Multilink Protocol (MP). +August 1996. +.TP .B RFC2284 Blunk, L.; Vollbrecht, J., .I PPP Extensible Authentication Protocol (EAP). diff -Nru ppp-2.4.7/pppd/pppd.h ppp-2.4.9/pppd/pppd.h --- ppp-2.4.7/pppd/pppd.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/pppd.h 2021-01-05 00:06:37.000000000 +0100 @@ -50,6 +50,9 @@ #define __PPPD_H__ #include /* for FILE */ +#include /* for encrypt */ +#include /* for setkey */ +#include #include /* for NGROUPS_MAX */ #include /* for MAXPATHLEN and BSD4_4, if defined */ #include /* for u_int32_t, if defined */ @@ -57,16 +60,6 @@ #include #include "patchlevel.h" -#if defined(__STDC__) -#include -#define __V(x) x -#else -#include -#define __V(x) (va_alist) va_dcl -#define const -#define volatile -#endif - #ifdef INET6 #include "eui64.h" #endif @@ -80,6 +73,16 @@ #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. + * Where should PPP_DRV_NAME come from? Do we include it here? + */ +#if !defined(PPP_DRV_NAME) +#define PPP_DRV_NAME "ppp" +#endif /* !defined(PPP_DRV_NAME) */ /* * Option descriptor structure. @@ -198,8 +201,8 @@ #define EPD_MAGIC 4 #define EPD_PHONENUM 5 -typedef void (*notify_func) __P((void *, int)); -typedef void (*printer_func) __P((void *, char *, ...)); +typedef void (*notify_func)(void *, int); +typedef void (*printer_func)(void *, char *, ...); struct notifier { struct notifier *next; @@ -211,6 +214,7 @@ * Global variables. */ +extern int got_sigterm; /* SIGINT or SIGTERM was received */ extern int hungup; /* Physical layer has disconnected */ extern int ifunit; /* Interface unit number */ extern char ifname[]; /* Interface name */ @@ -285,6 +289,9 @@ extern u_int32_t netmask; /* IP netmask to set on interface */ extern bool lockflag; /* Create lock file to lock the serial dev */ extern bool nodetach; /* Don't detach from controlling tty */ +#ifdef SYSTEMD +extern bool up_sdnotify; /* Notify systemd once link is up (implies nodetach) */ +#endif extern bool updetach; /* Detach from controlling tty when link up */ extern bool master_detach; /* Detach when multilink master without link */ extern char *initializer; /* Script to initialize physical link */ @@ -318,6 +325,9 @@ extern int connect_delay; /* Time to delay after connect script */ extern int max_data_rate; /* max bytes/sec through charshunt */ extern int req_unit; /* interface unit number to use */ +extern char path_ipup[MAXPATHLEN]; /* pathname of ip-up script */ +extern char path_ipdown[MAXPATHLEN]; /* pathname of ip-down script */ +extern char req_ifname[MAXIFNAMELEN]; /* interface name to use */ extern bool multilink; /* enable multilink operation */ extern bool noendpoint; /* don't send or accept endpt. discrim. */ extern char *bundle_name; /* bundle name for multilink */ @@ -325,6 +335,12 @@ 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; +extern char *max_tls_version; +#endif /* USE_EAPTLS */ + #ifdef MAXOCTETS extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ extern int maxoctets_dir; /* Direction : @@ -397,34 +413,33 @@ struct protent { u_short protocol; /* PPP protocol number */ /* Initialization procedure */ - void (*init) __P((int unit)); + void (*init)(int unit); /* Process a received packet */ - void (*input) __P((int unit, u_char *pkt, int len)); + void (*input)(int unit, u_char *pkt, int len); /* Process a received protocol-reject */ - void (*protrej) __P((int unit)); + void (*protrej)(int unit); /* Lower layer has come up */ - void (*lowerup) __P((int unit)); + void (*lowerup)(int unit); /* Lower layer has gone down */ - void (*lowerdown) __P((int unit)); + void (*lowerdown)(int unit); /* Open the protocol */ - void (*open) __P((int unit)); + void (*open)(int unit); /* Close the protocol */ - void (*close) __P((int unit, char *reason)); + void (*close)(int unit, char *reason); /* Print a packet in readable form */ - int (*printpkt) __P((u_char *pkt, int len, printer_func printer, - void *arg)); + int (*printpkt)(u_char *pkt, int len, printer_func printer, void *arg); /* Process a received data packet */ - void (*datainput) __P((int unit, u_char *pkt, int len)); + void (*datainput)(int unit, u_char *pkt, int len); bool enabled_flag; /* 0 iff protocol is disabled */ char *name; /* Text name of protocol */ char *data_name; /* Text name of corresponding data protocol */ option_t *options; /* List of command-line options */ /* Check requested options, assign defaults */ - void (*check_options) __P((void)); + void (*check_options)(void); /* Configure interface for demand-dial */ - int (*demand_conf) __P((int unit)); + int (*demand_conf)(int unit); /* Say whether to bring up link for this pkt */ - int (*active_pkt) __P((u_char *pkt, int len)); + int (*active_pkt)(u_char *pkt, int len); }; /* Table of pointers to supported protocols */ @@ -441,25 +456,25 @@ /* set of options for this channel */ option_t *options; /* find and process a per-channel options file */ - void (*process_extra_options) __P((void)); + void (*process_extra_options)(void); /* check all the options that have been given */ - void (*check_options) __P((void)); + void (*check_options)(void); /* get the channel ready to do PPP, return a file descriptor */ - int (*connect) __P((void)); + int (*connect)(void); /* we're finished with the channel */ - void (*disconnect) __P((void)); + void (*disconnect)(void); /* put the channel into PPP `mode' */ - int (*establish_ppp) __P((int)); + int (*establish_ppp)(int); /* take the channel out of PPP `mode', restore loopback if demand */ - void (*disestablish_ppp) __P((int)); + void (*disestablish_ppp)(int); /* set the transmit-side PPP parameters of the channel */ - void (*send_config) __P((int, u_int32_t, int, int)); + void (*send_config)(int, u_int32_t, int, int); /* set the receive-side PPP parameters of the channel */ - void (*recv_config) __P((int, u_int32_t, int, int)); + void (*recv_config)(int, u_int32_t, int, int); /* cleanup on error or normal exit */ - void (*cleanup) __P((void)); + void (*cleanup)(void); /* close the device, called in children after fork */ - void (*close) __P((void)); + void (*close)(void); }; extern struct channel *the_channel; @@ -484,117 +499,117 @@ */ /* Procedures exported from main.c. */ -void set_ifunit __P((int)); /* set stuff that depends on ifunit */ -void detach __P((void)); /* Detach from controlling tty */ -void die __P((int)); /* Cleanup and exit */ -void quit __P((void)); /* like die(1) */ -void novm __P((char *)); /* Say we ran out of memory, and die */ -void timeout __P((void (*func)(void *), void *arg, int s, int us)); +void set_ifunit(int); /* set stuff that depends on ifunit */ +void detach(void); /* Detach from controlling tty */ +void die(int); /* Cleanup and exit */ +void quit(void); /* like die(1) */ +void novm(char *); /* Say we ran out of memory, and die */ +void timeout(void (*func)(void *), void *arg, int s, int us); /* Call func(arg) after s.us seconds */ -void untimeout __P((void (*func)(void *), void *arg)); +void untimeout(void (*func)(void *), void *arg); /* Cancel call to func(arg) */ -void record_child __P((int, char *, void (*) (void *), void *, int)); -pid_t safe_fork __P((int, int, int)); /* Fork & close stuff in child */ -int device_script __P((char *cmd, int in, int out, int dont_wait)); +void record_child(int, char *, void (*) (void *), void *, int); +pid_t safe_fork(int, int, int); /* Fork & close stuff in child */ +int device_script(char *cmd, int in, int out, int dont_wait); /* Run `cmd' with given stdin and stdout */ -pid_t run_program __P((char *prog, char **args, int must_exist, - void (*done)(void *), void *arg, int wait)); +pid_t run_program(char *prog, char **args, int must_exist, + void (*done)(void *), void *arg, int wait); /* Run program prog with args in child */ -void reopen_log __P((void)); /* (re)open the connection to syslog */ -void print_link_stats __P((void)); /* Print stats, if available */ -void reset_link_stats __P((int)); /* Reset (init) stats when link goes up */ -void update_link_stats __P((int)); /* Get stats at link termination */ -void script_setenv __P((char *, char *, int)); /* set script env var */ -void script_unsetenv __P((char *)); /* unset script env var */ -void new_phase __P((int)); /* signal start of new phase */ -void add_notifier __P((struct notifier **, notify_func, void *)); -void remove_notifier __P((struct notifier **, notify_func, void *)); -void notify __P((struct notifier *, int)); -int ppp_send_config __P((int, int, u_int32_t, int, int)); -int ppp_recv_config __P((int, int, u_int32_t, int, int)); -const char *protocol_name __P((int)); -void remove_pidfiles __P((void)); -void lock_db __P((void)); -void unlock_db __P((void)); +void reopen_log(void); /* (re)open the connection to syslog */ +void print_link_stats(void); /* Print stats, if available */ +void reset_link_stats(int); /* Reset (init) stats when link goes up */ +void update_link_stats(int); /* Get stats at link termination */ +void script_setenv(char *, char *, int); /* set script env var */ +void script_unsetenv(char *); /* unset script env var */ +void new_phase(int); /* signal start of new phase */ +void add_notifier(struct notifier **, notify_func, void *); +void remove_notifier(struct notifier **, notify_func, void *); +void notify(struct notifier *, int); +int ppp_send_config(int, int, u_int32_t, int, int); +int ppp_recv_config(int, int, u_int32_t, int, int); +const char *protocol_name(int); +void remove_pidfiles(void); +void lock_db(void); +void unlock_db(void); /* Procedures exported from tty.c. */ -void tty_init __P((void)); +void tty_init(void); /* Procedures exported from utils.c. */ -void log_packet __P((u_char *, int, char *, int)); +void log_packet(u_char *, int, char *, int); /* Format a packet and log it with syslog */ -void print_string __P((char *, int, printer_func, void *)); +void print_string(char *, int, printer_func, void *); /* Format a string for output */ -int slprintf __P((char *, int, char *, ...)); /* sprintf++ */ -int vslprintf __P((char *, int, char *, va_list)); /* vsprintf++ */ -size_t strlcpy __P((char *, const char *, size_t)); /* safe strcpy */ -size_t strlcat __P((char *, const char *, size_t)); /* safe strncpy */ -void dbglog __P((char *, ...)); /* log a debug message */ -void info __P((char *, ...)); /* log an informational message */ -void notice __P((char *, ...)); /* log a notice-level message */ -void warn __P((char *, ...)); /* log a warning message */ -void error __P((char *, ...)); /* log an error message */ -void fatal __P((char *, ...)); /* log an error message and die(1) */ -void init_pr_log __P((const char *, int)); /* initialize for using pr_log */ -void pr_log __P((void *, char *, ...)); /* printer fn, output to syslog */ -void end_pr_log __P((void)); /* finish up after using pr_log */ -void dump_packet __P((const char *, u_char *, int)); +int slprintf(char *, int, char *, ...); /* sprintf++ */ +int vslprintf(char *, int, char *, va_list); /* vsprintf++ */ +size_t strlcpy(char *, const char *, size_t); /* safe strcpy */ +size_t strlcat(char *, const char *, size_t); /* safe strncpy */ +void dbglog(char *, ...); /* log a debug message */ +void info(char *, ...); /* log an informational message */ +void notice(char *, ...); /* log a notice-level message */ +void warn(char *, ...); /* log a warning message */ +void error(char *, ...); /* log an error message */ +void fatal(char *, ...); /* log an error message and die(1) */ +void init_pr_log(const char *, int); /* initialize for using pr_log */ +void pr_log(void *, char *, ...); /* printer fn, output to syslog */ +void end_pr_log(void); /* finish up after using pr_log */ +void dump_packet(const char *, u_char *, int); /* dump packet to debug log if interesting */ -ssize_t complete_read __P((int, void *, size_t)); +ssize_t complete_read(int, void *, size_t); /* read a complete buffer */ /* Procedures exported from auth.c */ -void link_required __P((int)); /* we are starting to use the link */ -void start_link __P((int)); /* bring the link up now */ -void link_terminated __P((int)); /* we are finished with the link */ -void link_down __P((int)); /* the LCP layer has left the Opened state */ -void upper_layers_down __P((int));/* take all NCPs down */ -void link_established __P((int)); /* the link is up; authenticate now */ -void start_networks __P((int)); /* start all the network control protos */ -void continue_networks __P((int)); /* start network [ip, etc] control protos */ -void np_up __P((int, int)); /* a network protocol has come up */ -void np_down __P((int, int)); /* a network protocol has gone down */ -void np_finished __P((int, int)); /* a network protocol no longer needs link */ -void auth_peer_fail __P((int, int)); +void link_required(int); /* we are starting to use the link */ +void start_link(int); /* bring the link up now */ +void link_terminated(int); /* we are finished with the link */ +void link_down(int); /* the LCP layer has left the Opened state */ +void upper_layers_down(int);/* take all NCPs down */ +void link_established(int); /* the link is up; authenticate now */ +void start_networks(int); /* start all the network control protos */ +void continue_networks(int); /* start network [ip, etc] control protos */ +void np_up(int, int); /* a network protocol has come up */ +void np_down(int, int); /* a network protocol has gone down */ +void np_finished(int, int); /* a network protocol no longer needs link */ +void auth_peer_fail(int, int); /* peer failed to authenticate itself */ -void auth_peer_success __P((int, int, int, char *, int)); +void auth_peer_success(int, int, int, char *, int); /* peer successfully authenticated itself */ -void auth_withpeer_fail __P((int, int)); +void auth_withpeer_fail(int, int); /* we failed to authenticate ourselves */ -void auth_withpeer_success __P((int, int, int)); +void auth_withpeer_success(int, int, int); /* we successfully authenticated ourselves */ -void auth_check_options __P((void)); +void auth_check_options(void); /* check authentication options supplied */ -void auth_reset __P((int)); /* check what secrets we have */ -int check_passwd __P((int, char *, int, char *, int, char **)); +void auth_reset(int); /* check what secrets we have */ +int check_passwd(int, char *, int, char *, int, char **); /* Check peer-supplied username/password */ -int get_secret __P((int, char *, char *, char *, int *, int)); +int get_secret(int, char *, char *, char *, int *, int); /* get "secret" for chap */ -int get_srp_secret __P((int unit, char *client, char *server, char *secret, - int am_server)); -int auth_ip_addr __P((int, u_int32_t)); +int get_srp_secret(int unit, char *client, char *server, char *secret, + int am_server); +int auth_ip_addr(int, u_int32_t); /* check if IP address is authorized */ -int auth_number __P((void)); /* check if remote number is authorized */ -int bad_ip_adrs __P((u_int32_t)); +int auth_number(void); /* check if remote number is authorized */ +int bad_ip_adrs(u_int32_t); /* check if IP address is unreasonable */ /* Procedures exported from demand.c */ -void demand_conf __P((void)); /* config interface(s) for demand-dial */ -void demand_block __P((void)); /* set all NPs to queue up packets */ -void demand_unblock __P((void)); /* set all NPs to pass packets */ -void demand_discard __P((void)); /* set all NPs to discard packets */ -void demand_rexmit __P((int)); /* retransmit saved frames for an NP */ -int loop_chars __P((unsigned char *, int)); /* process chars from loopback */ -int loop_frame __P((unsigned char *, int)); /* should we bring link up? */ +void demand_conf(void); /* config interface(s) for demand-dial */ +void demand_block(void); /* set all NPs to queue up packets */ +void demand_unblock(void); /* set all NPs to pass packets */ +void demand_discard(void); /* set all NPs to discard packets */ +void demand_rexmit(int); /* retransmit saved frames for an NP */ +int loop_chars(unsigned char *, int); /* process chars from loopback */ +int loop_frame(unsigned char *, int); /* should we bring link up? */ /* Procedures exported from multilink.c */ #ifdef HAVE_MULTILINK -void mp_check_options __P((void)); /* Check multilink-related options */ -int mp_join_bundle __P((void)); /* join our link to an appropriate bundle */ -void mp_exit_bundle __P((void)); /* have disconnected our link from bundle */ -void mp_bundle_terminated __P((void)); -char *epdisc_to_str __P((struct epdisc *)); /* string from endpoint discrim. */ -int str_to_epdisc __P((struct epdisc *, char *)); /* endpt disc. from str */ +void mp_check_options(void); /* Check multilink-related options */ +int mp_join_bundle(void); /* join our link to an appropriate bundle */ +void mp_exit_bundle(void); /* have disconnected our link from bundle */ +void mp_bundle_terminated(void); +char *epdisc_to_str(struct epdisc *); /* string from endpoint discrim. */ +int str_to_epdisc(struct epdisc *, char *); /* endpt disc. from str */ #else #define mp_bundle_terminated() /* nothing */ #define mp_exit_bundle() /* nothing */ @@ -603,147 +618,158 @@ #endif /* Procedures exported from sys-*.c */ -void sys_init __P((void)); /* Do system-dependent initialization */ -void sys_cleanup __P((void)); /* Restore system state before exiting */ -int sys_check_options __P((void)); /* Check options specified */ -void sys_close __P((void)); /* Clean up in a child before execing */ -int ppp_available __P((void)); /* Test whether ppp kernel support exists */ -int get_pty __P((int *, int *, char *, int)); /* Get pty master/slave */ -int open_ppp_loopback __P((void)); /* Open loopback for demand-dialling */ -int tty_establish_ppp __P((int)); /* Turn serial port into a ppp interface */ -void tty_disestablish_ppp __P((int)); /* Restore port to normal operation */ -void generic_disestablish_ppp __P((int dev_fd)); /* Restore device setting */ -int generic_establish_ppp __P((int dev_fd)); /* Make a ppp interface */ -void make_new_bundle __P((int, int, int, int)); /* Create new bundle */ -int bundle_attach __P((int)); /* Attach link to existing bundle */ -void cfg_bundle __P((int, int, int, int)); /* Configure existing bundle */ -void destroy_bundle __P((void)); /* Tell driver to destroy bundle */ -void clean_check __P((void)); /* Check if line was 8-bit clean */ -void set_up_tty __P((int, int)); /* Set up port's speed, parameters, etc. */ -void restore_tty __P((int)); /* Restore port's original parameters */ -void setdtr __P((int, int)); /* Raise or lower port's DTR line */ -void output __P((int, u_char *, int)); /* Output a PPP packet */ -void wait_input __P((struct timeval *)); +void sys_init(void); /* Do system-dependent initialization */ +void sys_cleanup(void); /* Restore system state before exiting */ +int sys_check_options(void); /* Check options specified */ +void sys_close(void); /* Clean up in a child before execing */ +int ppp_available(void); /* Test whether ppp kernel support exists */ +int get_pty(int *, int *, char *, int); /* Get pty master/slave */ +int open_ppp_loopback(void); /* Open loopback for demand-dialling */ +int tty_establish_ppp(int); /* Turn serial port into a ppp interface */ +void tty_disestablish_ppp(int); /* Restore port to normal operation */ +void generic_disestablish_ppp(int dev_fd); /* Restore device setting */ +int generic_establish_ppp(int dev_fd); /* Make a ppp interface */ +void make_new_bundle(int, int, int, int); /* Create new bundle */ +int bundle_attach(int); /* Attach link to existing bundle */ +void cfg_bundle(int, int, int, int); /* Configure existing bundle */ +void destroy_bundle(void); /* Tell driver to destroy bundle */ +void clean_check(void); /* Check if line was 8-bit clean */ +void set_up_tty(int, int); /* Set up port's speed, parameters, etc. */ +void restore_tty(int); /* Restore port's original parameters */ +void setdtr(int, int); /* Raise or lower port's DTR line */ +void output(int, u_char *, int); /* Output a PPP packet */ +void wait_input(struct timeval *); /* Wait for input, with timeout */ -void add_fd __P((int)); /* Add fd to set to wait for */ -void remove_fd __P((int)); /* Remove fd from set to wait for */ -int read_packet __P((u_char *)); /* Read PPP packet */ -int get_loop_output __P((void)); /* Read pkts from loopback */ -void tty_send_config __P((int, u_int32_t, int, int)); +void add_fd(int); /* Add fd to set to wait for */ +void remove_fd(int); /* Remove fd from set to wait for */ +int read_packet(u_char *); /* Read PPP packet */ +int get_loop_output(void); /* Read pkts from loopback */ +void tty_send_config(int, u_int32_t, int, int); /* Configure i/f transmit parameters */ -void tty_set_xaccm __P((ext_accm)); +void tty_set_xaccm(ext_accm); /* Set extended transmit ACCM */ -void tty_recv_config __P((int, u_int32_t, int, int)); +void tty_recv_config(int, u_int32_t, int, int); /* Configure i/f receive parameters */ -int ccp_test __P((int, u_char *, int, int)); +int ccp_test(int, u_char *, int, int); /* Test support for compression scheme */ -void ccp_flags_set __P((int, int, int)); +void ccp_flags_set(int, int, int); /* Set kernel CCP state */ -int ccp_fatal_error __P((int)); /* Test for fatal decomp error in kernel */ -int get_idle_time __P((int, struct ppp_idle *)); +int ccp_fatal_error(int); /* Test for fatal decomp error in kernel */ +int get_idle_time(int, struct ppp_idle *); /* Find out how long link has been idle */ -int get_ppp_stats __P((int, struct pppd_stats *)); +int get_ppp_stats(int, struct pppd_stats *); /* Return link statistics */ -void netif_set_mtu __P((int, int)); /* Set PPP interface MTU */ -int netif_get_mtu __P((int)); /* Get PPP interface MTU */ -int sifvjcomp __P((int, int, int, int)); +void netif_set_mtu(int, int); /* Set PPP interface MTU */ +int netif_get_mtu(int); /* Get PPP interface MTU */ +int sifvjcomp(int, int, int, int); /* Configure VJ TCP header compression */ -int sifup __P((int)); /* Configure i/f up for one protocol */ -int sifnpmode __P((int u, int proto, enum NPmode mode)); +int sifup(int); /* Configure i/f up for one protocol */ +int sifnpmode(int u, int proto, enum NPmode mode); /* Set mode for handling packets for proto */ -int sifdown __P((int)); /* Configure i/f down for one protocol */ -int sifaddr __P((int, u_int32_t, u_int32_t, u_int32_t)); +int sifdown(int); /* Configure i/f down for one protocol */ +int sifaddr(int, u_int32_t, u_int32_t, u_int32_t); /* Configure IPv4 addresses for i/f */ -int cifaddr __P((int, u_int32_t, u_int32_t)); +int cifaddr(int, u_int32_t, u_int32_t); /* Reset i/f IP addresses */ #ifdef INET6 -int ether_to_eui64(eui64_t *p_eui64); /* convert eth0 hw address to EUI64 */ -int sif6up __P((int)); /* Configure i/f up for IPv6 */ -int sif6down __P((int)); /* Configure i/f down for IPv6 */ -int sif6addr __P((int, eui64_t, eui64_t)); +int sif6up(int); /* Configure i/f up for IPv6 */ +int sif6down(int); /* Configure i/f down for IPv6 */ +int sif6addr(int, eui64_t, eui64_t); /* Configure IPv6 addresses for i/f */ -int cif6addr __P((int, eui64_t, eui64_t)); +int cif6addr(int, eui64_t, eui64_t); /* Remove an IPv6 address from i/f */ #endif -int sifdefaultroute __P((int, u_int32_t, u_int32_t)); +int sifdefaultroute(int, u_int32_t, u_int32_t, bool replace_default_rt); /* Create default route through i/f */ -int cifdefaultroute __P((int, u_int32_t, u_int32_t)); +int cifdefaultroute(int, u_int32_t, u_int32_t); /* Delete default route through i/f */ -int sifproxyarp __P((int, u_int32_t)); +#ifdef INET6 +int sif6defaultroute(int, eui64_t, eui64_t); + /* Create default IPv6 route through i/f */ +int cif6defaultroute(int, eui64_t, eui64_t); + /* Delete default IPv6 route through i/f */ +#endif +int sifproxyarp(int, u_int32_t); /* Add proxy ARP entry for peer */ -int cifproxyarp __P((int, u_int32_t)); +int cifproxyarp(int, u_int32_t); /* Delete proxy ARP entry for peer */ -u_int32_t GetMask __P((u_int32_t)); /* Get appropriate netmask for address */ -int lock __P((char *)); /* Create lock file for device */ -int relock __P((int)); /* Rewrite lock file with new pid */ -void unlock __P((void)); /* Delete previously-created lock file */ -void logwtmp __P((const char *, const char *, const char *)); +u_int32_t GetMask(u_int32_t); /* Get appropriate netmask for address */ +int lock(char *); /* Create lock file for device */ +int relock(int); /* Rewrite lock file with new pid */ +void unlock(void); /* Delete previously-created lock file */ +void logwtmp(const char *, const char *, const char *); /* Write entry to wtmp file */ -int get_host_seed __P((void)); /* Get host-dependent random number seed */ -int have_route_to __P((u_int32_t)); /* Check if route to addr exists */ +int get_host_seed(void); /* Get host-dependent random number seed */ +int have_route_to(u_int32_t); /* Check if route to addr exists */ #ifdef PPP_FILTER -int set_filters __P((struct bpf_program *pass, struct bpf_program *active)); +int set_filters(struct bpf_program *pass, struct bpf_program *active); /* Set filter programs in kernel */ #endif #ifdef IPX_CHANGE -int sipxfaddr __P((int, unsigned long, unsigned char *)); -int cipxfaddr __P((int)); +int sipxfaddr(int, unsigned long, unsigned char *); +int cipxfaddr(int); #endif -int get_if_hwaddr __P((u_char *addr, char *name)); -char *get_first_ethernet __P((void)); +int get_if_hwaddr(u_char *addr, char *name); +int get_first_ether_hwaddr(u_char *addr); +int get_time(struct timeval *); + /* Get current time, monotonic if possible. */ /* Procedures exported from options.c */ -int setipaddr __P((char *, char **, int)); /* Set local/remote ip addresses */ -int parse_args __P((int argc, char **argv)); +int setipaddr(char *, char **, int); /* Set local/remote ip addresses */ +int parse_args(int argc, char **argv); /* Parse options from arguments given */ -int options_from_file __P((char *filename, int must_exist, int check_prot, - int privileged)); +int options_from_file(char *filename, int must_exist, int check_prot, + int privileged); /* Parse options from an options file */ -int options_from_user __P((void)); /* Parse options from user's .ppprc */ -int options_for_tty __P((void)); /* Parse options from /etc/ppp/options.tty */ -int options_from_list __P((struct wordlist *, int privileged)); +int options_from_user(void); /* Parse options from user's .ppprc */ +int options_for_tty(void); /* Parse options from /etc/ppp/options.tty */ +int options_from_list(struct wordlist *, int privileged); /* Parse options from a wordlist */ -int getword __P((FILE *f, char *word, int *newlinep, char *filename)); +int getword(FILE *f, char *word, int *newlinep, char *filename); /* Read a word from a file */ -void option_error __P((char *fmt, ...)); +void option_error(char *fmt, ...); /* Print an error message about an option */ -int int_option __P((char *, int *)); +int int_option(char *, int *); /* Simplified number_option for decimal ints */ -void add_options __P((option_t *)); /* Add extra options */ -void check_options __P((void)); /* check values after all options parsed */ -int override_value __P((const char *, int, const char *)); +void add_options(option_t *); /* Add extra options */ +void check_options(void); /* check values after all options parsed */ +int override_value(char *, int, const char *); /* override value if permitted by priority */ -void print_options __P((printer_func, void *)); +void print_options(printer_func, void *); /* print out values of all options */ -int parse_dotted_ip __P((char *, u_int32_t *)); +int parse_dotted_ip(char *, u_int32_t *); /* * Hooks to enable plugins to change various things. */ -extern int (*new_phase_hook) __P((int)); -extern int (*idle_time_hook) __P((struct ppp_idle *)); -extern int (*holdoff_hook) __P((void)); -extern int (*pap_check_hook) __P((void)); -extern int (*pap_auth_hook) __P((char *user, char *passwd, char **msgp, - struct wordlist **paddrs, - struct wordlist **popts)); -extern void (*pap_logout_hook) __P((void)); -extern int (*pap_passwd_hook) __P((char *user, char *passwd)); -extern int (*allowed_address_hook) __P((u_int32_t addr)); -extern void (*ip_up_hook) __P((void)); -extern void (*ip_down_hook) __P((void)); -extern void (*ip_choose_hook) __P((u_int32_t *)); -extern void (*ipv6_up_hook) __P((void)); -extern void (*ipv6_down_hook) __P((void)); - -extern int (*chap_check_hook) __P((void)); -extern int (*chap_passwd_hook) __P((char *user, char *passwd)); -extern void (*multilink_join_hook) __P((void)); +extern int (*new_phase_hook)(int); +extern int (*idle_time_hook)(struct ppp_idle *); +extern int (*holdoff_hook)(void); +extern int (*pap_check_hook)(void); +extern int (*pap_auth_hook)(char *user, char *passwd, char **msgp, + struct wordlist **paddrs, + struct wordlist **popts); +extern void (*pap_logout_hook)(void); +extern int (*pap_passwd_hook)(char *user, char *passwd); +extern int (*allowed_address_hook)(u_int32_t addr); +extern void (*ip_up_hook)(void); +extern void (*ip_down_hook)(void); +extern void (*ip_choose_hook)(u_int32_t *); +extern void (*ipv6_up_hook)(void); +extern void (*ipv6_down_hook)(void); + +extern int (*chap_check_hook)(void); +extern int (*chap_passwd_hook)(char *user, char *passwd); +extern void (*multilink_join_hook)(void); + +#ifdef USE_EAPTLS +extern int (*eaptls_passwd_hook)(char *user, char *passwd); +#endif /* Let a plugin snoop sent and received packets. Useful for L2TP */ -extern void (*snoop_recv_hook) __P((unsigned char *p, int len)); -extern void (*snoop_send_hook) __P((unsigned char *p, int len)); +extern void (*snoop_recv_hook)(unsigned char *p, int len); +extern void (*snoop_send_hook)(unsigned char *p, int len); /* * Inline versions of get/put char/short/long. diff -Nru ppp-2.4.7/pppd/session.c ppp-2.4.9/pppd/session.c --- ppp-2.4.7/pppd/session.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/session.c 2021-01-05 00:06:37.000000000 +0100 @@ -116,10 +116,7 @@ */ static int conversation (int num_msg, -#ifndef SOL2 - const -#endif - struct pam_message **msg, + const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { int replies = 0; @@ -164,12 +161,7 @@ #endif /* #ifdef USE_PAM */ int -session_start(flags, user, passwd, ttyName, msg) - const int flags; - const char *user; - const char *passwd; - const char *ttyName; - char **msg; +session_start(const int flags, const char *user, const char *passwd, const char *ttyName, char **msg) { #ifdef USE_PAM bool ok = 1; @@ -384,8 +376,8 @@ memset((void *)&ll, 0, sizeof(ll)); (void)time(&tnow); ll.ll_time = tnow; - (void)strncpy(ll.ll_line, ttyName, sizeof(ll.ll_line)); - (void)strncpy(ll.ll_host, ifname, sizeof(ll.ll_host)); + strlcpy(ll.ll_line, ttyName, sizeof(ll.ll_line)); + strlcpy(ll.ll_host, ifname, sizeof(ll.ll_host)); (void)write(fd, (char *)&ll, sizeof(ll)); (void)close(fd); } diff -Nru ppp-2.4.7/pppd/sha1.c ppp-2.4.9/pppd/sha1.c --- ppp-2.4.7/pppd/sha1.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/sha1.c 2021-01-05 00:06:37.000000000 +0100 @@ -17,6 +17,7 @@ /* #define SHA1HANDSOFF * Copies data before messing with it. */ #include +#include #include /* htonl() */ #include #include "sha1.h" diff -Nru ppp-2.4.7/pppd/sys-linux.c ppp-2.4.9/pppd/sys-linux.c --- ppp-2.4.7/pppd/sys-linux.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/sys-linux.c 2021-01-05 00:06:37.000000000 +0100 @@ -73,12 +73,12 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -102,7 +102,7 @@ #define MAX_ADDR_LEN 7 #endif -#if __GLIBC__ >= 2 +#if !defined(__GLIBC__) || __GLIBC__ >= 2 #include /* glibc 2 conflicts with linux/types.h */ #include #include @@ -121,6 +121,12 @@ #include #include +#ifdef INET6 +#include +#include +#include +#endif + #include "pppd.h" #include "fsm.h" #include "ipcp.h" @@ -163,6 +169,7 @@ eui64_copy(eui64, sin6.s6_addr32[2]); \ } while (0) +static const eui64_t nulleui64; #endif /* INET6 */ /* We can get an EIO error on an ioctl if the modem has hung up */ @@ -207,6 +214,9 @@ static int if_is_up; /* Interface has been marked up */ static int if6_is_up; /* Interface has been marked up for IPv6, to help differentiate */ static int have_default_route; /* Gateway for default route added */ +static int have_default_route6; /* Gateway for default IPv6 route added */ +static struct rtentry old_def_rt; /* Old default route */ +static int default_rt_repl_rest; /* replace and restore old default rt */ static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ static char proxy_arp_dev[16]; /* Device for proxy arp entry */ static u_int32_t our_old_addr; /* for detecting address changes */ @@ -233,7 +243,8 @@ static void close_route_table (void); static int open_route_table (void); static int read_route_table (struct rtentry *rt); -static int defaultroute_exists (struct rtentry *rt); +static int defaultroute_exists (struct rtentry *rt, int metric); +static int defaultroute6_exists (struct in6_rtmsg *rt, int metric); static int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr, char *name, int namelen); static void decode_version (char *buf, int *version, int *mod, int *patch); @@ -244,6 +255,8 @@ extern u_char inpacket_buf[]; /* borrowed from main.c */ +extern int dfl_route_metric; + /* * SET_SA_FAMILY - set the sa_family field of a struct sockaddr, * if it exists. @@ -348,6 +361,10 @@ */ if (have_default_route) cifdefaultroute(0, 0, 0); +#ifdef INET6 + if (have_default_route6) + cif6defaultroute(0, nulleui64, nulleui64); +#endif if (has_proxy_arp) cifproxyarp(0, proxy_arp_addr); @@ -458,6 +475,13 @@ if (new_style_driver) { int flags; + /* If a ppp_fd is already open, close it first */ + if (ppp_fd >= 0) { + close(ppp_fd); + remove_fd(ppp_fd); + ppp_fd = -1; + } + /* Open an instance of /dev/ppp and connect the channel to it */ if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) { error("Couldn't get channel number: %m"); @@ -616,7 +640,7 @@ * make_ppp_unit - make a new ppp unit for ppp_dev_fd. * Assumes new_style_driver. */ -static int make_ppp_unit() +static int make_ppp_unit(void) { int x, flags; @@ -641,6 +665,21 @@ } if (x < 0) error("Couldn't create new ppp unit: %m"); + + if (x == 0 && req_ifname[0] != '\0') { + struct ifreq ifr; + char t[MAXIFNAMELEN]; + 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); + x = ioctl(sock_fd, SIOCSIFNAME, &ifr); + if (x < 0) + error("Couldn't rename interface %s to %s: %m", t, req_ifname); + else + info("Renamed interface %s to %s", t, req_ifname); + } + return x; } @@ -1353,9 +1392,7 @@ * get_idle_time - return how long the link has been idle. */ int -get_idle_time(u, ip) - int u; - struct ppp_idle *ip; +get_idle_time(int u, struct ppp_idle *ip) { return ioctl(ppp_dev_fd, PPPIOCGIDLE, ip) >= 0; } @@ -1365,9 +1402,7 @@ * get_ppp_stats - return statistics for the link. */ int -get_ppp_stats(u, stats) - int u; - struct pppd_stats *stats; +get_ppp_stats(int u, struct pppd_stats *stats) { struct ifpppstatsreq req; @@ -1447,7 +1482,7 @@ FILE *route_fd = (FILE *) 0; static char route_buffer[512]; static int route_dev_col, route_dest_col, route_gw_col; -static int route_flags_col, route_mask_col; +static int route_flags_col, route_metric_col, route_mask_col; static int route_num_cols; static int open_route_table (void); @@ -1490,6 +1525,7 @@ route_dest_col = 1; route_gw_col = 2; route_flags_col = 3; + route_metric_col = 6; route_mask_col = 7; route_num_cols = 8; @@ -1545,11 +1581,15 @@ p = NULL; } + SET_SA_FAMILY (rt->rt_dst, AF_INET); + SET_SA_FAMILY (rt->rt_gateway, AF_INET); + SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16); SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16); SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16); rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16); + rt->rt_metric = (short) strtoul(cols[route_metric_col], NULL, 10); rt->rt_dev = cols[route_dev_col]; return 1; @@ -1558,9 +1598,10 @@ /******************************************************************** * * defaultroute_exists - determine if there is a default route + * with the given metric (or negative for any) */ -static int defaultroute_exists (struct rtentry *rt) +static int defaultroute_exists (struct rtentry *rt, int metric) { int result = 0; @@ -1573,7 +1614,8 @@ if (kernel_version > KVERSION(2,1,0) && SIN_ADDR(rt->rt_genmask) != 0) continue; - if (SIN_ADDR(rt->rt_dst) == 0L) { + if (SIN_ADDR(rt->rt_dst) == 0L && (metric < 0 + || rt->rt_metric == metric)) { result = 1; break; } @@ -1614,26 +1656,60 @@ /******************************************************************** * * sifdefaultroute - assign a default route through the address given. - */ - -int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) -{ - struct rtentry rt; + * + * If the global default_rt_repl_rest flag is set, then this function + * already replaced the original system defaultroute with some other + * route and it should just replace the current defaultroute with + * another one, without saving the current route. Use: demand mode, + * when pppd sets first a defaultroute it it's temporary ppp0 addresses + * and then changes the temporary addresses to the addresses for the real + * ppp connection when it has come up. + */ + +int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace) +{ + struct rtentry rt, tmp_rt; + struct rtentry *del_rt = NULL; + + if (default_rt_repl_rest) { + /* We have already replaced the original defaultroute, if we + * are called again, we will delete the current default route + * and set the new default route in this function. + * - this is normally only the case the doing demand: */ + if (defaultroute_exists(&tmp_rt, -1)) + del_rt = &tmp_rt; + } else if (defaultroute_exists(&old_def_rt, -1 ) && + strcmp( old_def_rt.rt_dev, ifname) != 0) { + /* + * We did not yet replace an existing default route, let's + * check if we should save and replace a default route: + */ + u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway); - if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) { - if (rt.rt_flags & RTF_GATEWAY) - error("not replacing existing default route via %I", - SIN_ADDR(rt.rt_gateway)); - else - error("not replacing existing default route through %s", - rt.rt_dev); - return 0; + if (old_gateway != gateway) { + if (!replace) { + error("not replacing default route to %s [%I]", + old_def_rt.rt_dev, old_gateway); + return 0; + } else { + /* we need to copy rt_dev because we need it permanent too: */ + char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1); + strcpy(tmp_dev, old_def_rt.rt_dev); + old_def_rt.rt_dev = tmp_dev; + + notice("replacing old default route to %s [%I]", + old_def_rt.rt_dev, old_gateway); + default_rt_repl_rest = 1; + del_rt = &old_def_rt; + } + } } memset (&rt, 0, sizeof (rt)); SET_SA_FAMILY (rt.rt_dst, AF_INET); rt.rt_dev = ifname; + rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */ if (kernel_version > KVERSION(2,1,0)) { SET_SA_FAMILY (rt.rt_genmask, AF_INET); @@ -1646,6 +1722,12 @@ error("default route ioctl(SIOCADDRT): %m"); return 0; } + if (default_rt_repl_rest && del_rt) + if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) { + if ( ! ok_error ( errno )) + error("del old default route ioctl(SIOCDELRT): %m(%d)", errno); + return 0; + } have_default_route = 1; return 1; @@ -1668,6 +1750,9 @@ rt.rt_dev = ifname; + rt.rt_dev = ifname; + rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */ + if (kernel_version > KVERSION(2,1,0)) { SET_SA_FAMILY (rt.rt_genmask, AF_INET); SIN_ADDR(rt.rt_genmask) = 0L; @@ -1681,9 +1766,211 @@ return 0; } } + if (default_rt_repl_rest) { + notice("restoring old default route to %s [%I]", + old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway)); + if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) { + if ( ! ok_error ( errno )) + error("restore default route ioctl(SIOCADDRT): %m(%d)", errno); + return 0; + } + default_rt_repl_rest = 0; + } + + return 1; +} + +#ifdef INET6 +/* + * /proc/net/ipv6_route parsing stuff. + */ +static int route_dest_plen_col; +static int open_route6_table (void); +static int read_route6_table (struct in6_rtmsg *rt); + +/******************************************************************** + * + * open_route6_table - open the interface to the route table + */ +static int open_route6_table (void) +{ + char *path; + + close_route_table(); + + path = path_to_procfs("/net/ipv6_route"); + route_fd = fopen (path, "r"); + if (route_fd == NULL) { + error("can't open routing table %s: %m", path); + return 0; + } + + /* default to usual columns */ + route_dest_col = 0; + route_dest_plen_col = 1; + route_gw_col = 4; + route_metric_col = 5; + route_flags_col = 8; + route_dev_col = 9; + route_num_cols = 10; + + return 1; +} + +/******************************************************************** + * + * read_route6_table - read the next entry from the route table + */ + +static void hex_to_in6_addr(struct in6_addr *addr, const char *s) +{ + char hex8[9]; + unsigned i; + uint32_t v; + + hex8[8] = 0; + for (i = 0; i < 4; i++) { + memcpy(hex8, s + 8*i, 8); + v = strtoul(hex8, NULL, 16); + addr->s6_addr32[i] = v; + } +} + +static int read_route6_table(struct in6_rtmsg *rt) +{ + char *cols[ROUTE_MAX_COLS], *p; + int col; + + memset (rt, '\0', sizeof (struct in6_rtmsg)); + + if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0) + return 0; + + p = route_buffer; + for (col = 0; col < route_num_cols; ++col) { + cols[col] = strtok(p, route_delims); + if (cols[col] == NULL) + return 0; /* didn't get enough columns */ + p = NULL; + } + + hex_to_in6_addr(&rt->rtmsg_dst, cols[route_dest_col]); + rt->rtmsg_dst_len = strtoul(cols[route_dest_plen_col], NULL, 16); + hex_to_in6_addr(&rt->rtmsg_gateway, cols[route_gw_col]); + + rt->rtmsg_metric = strtoul(cols[route_metric_col], NULL, 16); + rt->rtmsg_flags = strtoul(cols[route_flags_col], NULL, 16); + rt->rtmsg_ifindex = if_nametoindex(cols[route_dev_col]); + + return 1; +} + +/******************************************************************** + * + * defaultroute6_exists - determine if there is a default route + */ + +static int defaultroute6_exists (struct in6_rtmsg *rt, int metric) +{ + int result = 0; + + if (!open_route6_table()) + return 0; + + while (read_route6_table(rt) != 0) { + if ((rt->rtmsg_flags & RTF_UP) == 0) + continue; + + if (rt->rtmsg_dst_len != 0) + continue; + if (rt->rtmsg_dst.s6_addr32[0] == 0L + && rt->rtmsg_dst.s6_addr32[1] == 0L + && rt->rtmsg_dst.s6_addr32[2] == 0L + && rt->rtmsg_dst.s6_addr32[3] == 0L + && (metric < 0 || rt->rtmsg_metric == metric)) { + result = 1; + break; + } + } + + close_route_table(); + return result; +} + +/******************************************************************** + * + * sif6defaultroute - assign a default route through the address given. + * + * If the global default_rt_repl_rest flag is set, then this function + * already replaced the original system defaultroute with some other + * route and it should just replace the current defaultroute with + * another one, without saving the current route. Use: demand mode, + * when pppd sets first a defaultroute it it's temporary ppp0 addresses + * and then changes the temporary addresses to the addresses for the real + * ppp connection when it has come up. + */ + +int sif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway) +{ + struct in6_rtmsg rt; + char buf[IF_NAMESIZE]; + + if (defaultroute6_exists(&rt, dfl_route_metric) && + rt.rtmsg_ifindex != if_nametoindex(ifname)) { + if (rt.rtmsg_flags & RTF_GATEWAY) + error("not replacing existing default route via gateway"); + else + error("not replacing existing default route through %s", + if_indextoname(rt.rtmsg_ifindex, buf)); + return 0; + } + + memset (&rt, 0, sizeof (rt)); + + rt.rtmsg_ifindex = if_nametoindex(ifname); + rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */ + rt.rtmsg_dst_len = 0; + + rt.rtmsg_flags = RTF_UP; + if (ioctl(sock6_fd, SIOCADDRT, &rt) < 0) { + if ( ! ok_error ( errno )) + error("default route ioctl(SIOCADDRT): %m"); + return 0; + } + + have_default_route6 = 1; + return 1; +} + +/******************************************************************** + * + * cif6defaultroute - delete a default route through the address given. + */ + +int cif6defaultroute (int unit, eui64_t ouraddr, eui64_t gateway) +{ + struct in6_rtmsg rt; + + have_default_route6 = 0; + + memset (&rt, '\0', sizeof (rt)); + + rt.rtmsg_ifindex = if_nametoindex(ifname); + rt.rtmsg_metric = dfl_route_metric + 1; /* +1 for binary compatibility */ + rt.rtmsg_dst_len = 0; + + rt.rtmsg_flags = RTF_UP; + if (ioctl(sock6_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { + if (still_ppp()) { + if ( ! ok_error ( errno )) + error("default route ioctl(SIOCDELRT): %m"); + return 0; + } + } return 1; } +#endif /* INET6 */ /******************************************************************** * @@ -1867,7 +2154,7 @@ sock_fd = socket(AF_INET, SOCK_DGRAM, 0); if (sock_fd < 0) - return 0; + return -1; memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr)); strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name)); ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq); @@ -1878,13 +2165,43 @@ } /* - * get_first_ethernet - return the name of the first ethernet-style - * interface on this system. + * get_first_ether_hwaddr - get the hardware address for the first + * ethernet-style interface on this system. */ -char * -get_first_ethernet() +int +get_first_ether_hwaddr(u_char *addr) { - return "eth0"; + struct if_nameindex *if_ni, *i; + struct ifreq ifreq; + int ret, sock_fd; + + sock_fd = socket(AF_INET, SOCK_DGRAM, 0); + if (sock_fd < 0) + return -1; + + if_ni = if_nameindex(); + if (!if_ni) { + close(sock_fd); + return -1; + } + + ret = -1; + + for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) { + memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr)); + strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name)); + ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq); + if (ret >= 0 && ifreq.ifr_hwaddr.sa_family == ARPHRD_ETHER) { + memcpy(addr, ifreq.ifr_hwaddr.sa_data, 6); + break; + } + ret = -1; + } + + if_freenameindex(if_ni); + close(sock_fd); + + return ret; } /******************************************************************** @@ -2142,7 +2459,6 @@ } } - close (s); if (!ok) { slprintf(route_buffer, sizeof(route_buffer), "Sorry - PPP driver version %d.%d.%d is out of date\n", @@ -2152,6 +2468,7 @@ } } } + close(s); return ok; } @@ -2507,6 +2824,135 @@ } #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; + 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; + int one; + int fd; + + fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if (fd < 0) + return 0; + + /* do not ask for error message content */ + 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; + + if (bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) { + 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(&iov, 0, sizeof(iov)); + iov.iov_base = nlmsg; + iov.iov_len = nlmsg->nlmsg_len; + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = &sa; + msg.msg_namelen = sizeof(sa); + 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) { + close(fd); + return 0; + } + + memset(&iov, 0, sizeof(iov)); + iov.iov_base = buf; + iov.iov_len = sizeof(buf); + + memset(&msg, 0, sizeof(msg)); + msg.msg_name = NULL; + msg.msg_namelen = 0; + 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); + + if (nlmsg_len < 0) + return 0; + + if ((size_t)nlmsg_len < sizeof(*nlmsg)) { + errno = EINVAL; + return 0; + } + + nlmsg = (struct nlmsghdr *)buf; + + /* acknowledgment packet for NLM_F_ACK is NLMSG_ERROR */ + if (nlmsg->nlmsg_type != NLMSG_ERROR) { + errno = EINVAL; + return 0; + } + + if ((size_t)nlmsg_len < NLMSG_LENGTH(sizeof(*errmsg))) { + errno = EINVAL; + return 0; + } + + errmsg = NLMSG_DATA(nlmsg); + + /* error == 0 indicates success */ + if (errmsg->error == 0) + return 1; + + errno = -errmsg->error; + return 0; +} + /******************************************************************** * * sif6addr - Config the interface with an IPv6 link-local address @@ -2516,6 +2962,7 @@ struct in6_ifreq ifr6; struct ifreq ifr; struct in6_rtmsg rt6; + struct in6_addr remote_addr; if (sock6_fd < 0) { errno = -sock6_fd; @@ -2533,24 +2980,35 @@ memset(&ifr6, 0, sizeof(ifr6)); IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); ifr6.ifr6_ifindex = ifr.ifr_ifindex; - ifr6.ifr6_prefixlen = 10; + ifr6.ifr6_prefixlen = 128; if (ioctl(sock6_fd, SIOCSIFADDR, &ifr6) < 0) { error("sif6addr: ioctl(SIOCSIFADDR): %m (line %d)", __LINE__); return 0; } - /* Route to remote host */ - memset(&rt6, 0, sizeof(rt6)); - IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64); - rt6.rtmsg_flags = RTF_UP; - rt6.rtmsg_dst_len = 10; - rt6.rtmsg_ifindex = ifr.ifr_ifindex; - rt6.rtmsg_metric = 1; + 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"); + return 0; + } + } - if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) { - error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__); - return 0; + if (kernel_version < KVERSION(2,1,16)) { + /* Route to remote host */ + memset(&rt6, 0, sizeof(rt6)); + IN6_LLADDR_FROM_EUI64(rt6.rtmsg_dst, his_eui64); + rt6.rtmsg_flags = RTF_UP; + rt6.rtmsg_dst_len = 128; + rt6.rtmsg_ifindex = ifr.ifr_ifindex; + rt6.rtmsg_metric = 1; + + if (ioctl(sock6_fd, SIOCADDRT, &rt6) < 0) { + error("sif6addr: ioctl(SIOCADDRT): %m (line %d)", __LINE__); + return 0; + } } return 1; @@ -2581,7 +3039,7 @@ memset(&ifr6, 0, sizeof(ifr6)); IN6_LLADDR_FROM_EUI64(ifr6.ifr6_addr, our_eui64); ifr6.ifr6_ifindex = ifr.ifr_ifindex; - ifr6.ifr6_prefixlen = 10; + ifr6.ifr6_prefixlen = 128; if (ioctl(sock6_fd, SIOCDIFADDR, &ifr6) < 0) { if (errno != EADDRNOTAVAIL) { @@ -2602,11 +3060,7 @@ * to the uid given. Assumes slave_name points to >= 16 bytes of space. */ int -get_pty(master_fdp, slave_fdp, slave_name, uid) - int *master_fdp; - int *slave_fdp; - char *slave_name; - int uid; +get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid) { int i, mfd, sfd = -1; char pty_name[16]; @@ -2628,7 +3082,10 @@ warn("Couldn't unlock pty slave %s: %m", pty_name); #endif if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0) + { warn("Couldn't open pty slave %s: %m", pty_name); + close(mfd); + } } } #endif /* TIOCGPTN */ @@ -2729,10 +3186,7 @@ */ int -sifnpmode(u, proto, mode) - int u; - int proto; - enum NPmode mode; +sifnpmode(int u, int proto, enum NPmode mode) { struct npioctl npi; @@ -2843,7 +3297,7 @@ * Use the hostname as part of the random number seed. */ int -get_host_seed() +get_host_seed(void) { int h; char *p = hostname; @@ -2891,50 +3345,37 @@ return 1; } -#ifdef INET6 -/* - * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI +/******************************************************************** * - * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes - * that the system has a properly configured Ethernet interface for this - * function to return non-zero. + * get_time - Get current time, monotonic if possible. */ int -ether_to_eui64(eui64_t *p_eui64) +get_time(struct timeval *tv) { - struct ifreq ifr; - int skfd; - const unsigned char *ptr; +/* Old glibc (< 2.3.4) does define CLOCK_MONOTONIC, but kernel may have it. + * Runtime checking makes it safe. */ +#ifndef CLOCK_MONOTONIC +#define CLOCK_MONOTONIC 1 +#endif + static int monotonic = -1; + struct timespec ts; + int ret; - skfd = socket(PF_INET6, SOCK_DGRAM, 0); - if(skfd == -1) - { - warn("could not open IPv6 socket"); - return 0; - } + if (monotonic) { + ret = clock_gettime(CLOCK_MONOTONIC, &ts); + if (ret == 0) { + monotonic = 1; + if (tv) { + tv->tv_sec = ts.tv_sec; + tv->tv_usec = ts.tv_nsec / 1000; + } + return ret; + } else if (monotonic > 0) + return ret; - strcpy(ifr.ifr_name, "eth0"); - if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0) - { - close(skfd); - warn("could not obtain hardware address for eth0"); - return 0; + monotonic = 0; + warn("Couldn't use monotonic clock source: %m"); } - close(skfd); - - /* - * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1] - */ - ptr = (unsigned char *) ifr.ifr_hwaddr.sa_data; - p_eui64->e8[0] = ptr[0] | 0x02; - p_eui64->e8[1] = ptr[1]; - p_eui64->e8[2] = ptr[2]; - p_eui64->e8[3] = 0xFF; - p_eui64->e8[4] = 0xFE; - p_eui64->e8[5] = ptr[3]; - p_eui64->e8[6] = ptr[4]; - p_eui64->e8[7] = ptr[5]; - return 1; + return gettimeofday(tv, NULL); } -#endif diff -Nru ppp-2.4.7/pppd/sys-solaris.c ppp-2.4.9/pppd/sys-solaris.c --- ppp-2.4.7/pppd/sys-solaris.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/sys-solaris.c 2021-01-05 00:06:37.000000000 +0100 @@ -85,8 +85,6 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: sys-solaris.c,v 1.16 2008/01/30 14:26:53 carlsonj Exp $" - #include #include #include @@ -114,6 +112,7 @@ #include #include #include +#include #include #include #include @@ -166,7 +165,6 @@ #define UDP6_DEV_NAME "/dev/udp6" #endif /* !defined(UDP6_DEV_NAME) && defined(SOL2) */ -static const char rcsid[] = RCSID; #if defined(SOL2) /* @@ -189,6 +187,12 @@ static int ip6muxid = -1; /* Multiplexer file descriptor */ static int if6_is_up = 0; /* IPv6 interface has been marked up */ +#define IN6_SOCKADDR_FROM_EUI64(s, eui64) do { \ + (s)->sin6_family = AF_INET6; \ + (s)->sin6_addr.s6_addr32[0] = htonl(0xfe800000); \ + eui64_copy(eui64, (s)->sin6_addr.s6_addr32[2]); \ + } while(0) + #define _IN6_LLX_FROM_EUI64(l, s, eui64, as) do { \ s->sin6_addr.s6_addr32[0] = htonl(as); \ eui64_copy(eui64, s->sin6_addr.s6_addr32[2]); \ @@ -198,18 +202,23 @@ l.lifr_addr = laddr; \ } while (0) +#define _IN6A_LLX_FROM_EUI64(s, eui64, as) do { \ + s->s6_addr32[0] = htonl(as); \ + eui64_copy(eui64, s->s6_addr32[2]); \ + } while (0) + #define IN6_LLADDR_FROM_EUI64(l, s, eui64) \ _IN6_LLX_FROM_EUI64(l, s, eui64, 0xfe800000) #define IN6_LLTOKEN_FROM_EUI64(l, s, eui64) \ _IN6_LLX_FROM_EUI64(l, s, eui64, 0) +#define IN6A_LLADDR_FROM_EUI64(s, eui64) \ + _IN6A_LLX_FROM_EUI64(s, eui64, 0xfe800000) + #endif /* defined(INET6) && defined(SOL2) */ -#if defined(INET6) && defined(SOL2) -static char first_ether_name[LIFNAMSIZ]; /* Solaris 8 and above */ -#else -static char first_ether_name[IFNAMSIZ]; /* Before Solaris 8 */ +#if !defined(INET6) || !defined(SOL2) #define MAXIFS 256 /* Max # of interfaces */ #endif /* defined(INET6) && defined(SOL2) */ @@ -238,18 +247,19 @@ static int if_is_up; /* Interface has been marked up */ static u_int32_t remote_addr; /* IP address of peer */ static u_int32_t default_route_gateway; /* Gateway for default route added */ +static eui64_t default_route_gateway6; /* Gateway for default IPv6 route added */ static u_int32_t proxy_arp_addr; /* Addr for proxy arp entry added */ /* Prototypes for procedures local to this file. */ -static int translate_speed __P((int)); -static int baud_rate_of __P((int)); -static int get_ether_addr __P((u_int32_t, struct sockaddr *)); -static int get_hw_addr __P((char *, u_int32_t, struct sockaddr *)); -static int get_hw_addr_dlpi __P((char *, struct sockaddr *)); -static int dlpi_attach __P((int, int)); -static int dlpi_info_req __P((int)); -static int dlpi_get_reply __P((int, union DL_primitives *, int, int)); -static int strioctl __P((int, int, void *, int, int)); +static int translate_speed(int); +static int baud_rate_of(int); +static int get_ether_addr(u_int32_t, struct sockaddr *); +static int get_hw_addr(char *, u_int32_t, struct sockaddr *); +static int get_hw_addr_dlpi(char *, struct sockaddr *); +static int dlpi_attach(int, int); +static int dlpi_info_req(int); +static int dlpi_get_reply(int, union DL_primitives *, int, size_t); +static int strioctl(int, int, void *, int, int); #ifdef SOL2 /* @@ -281,13 +291,13 @@ #if defined(SOL2) && defined(INET6) /* - * get_first_ethernet - returns the first Ethernet interface name found in - * the system, or NULL if none is found + * get_first_ether_hwaddr - get the hardware address for the first + * ethernet-style interface on this system. * * NOTE: This is the lifreq version (Solaris 8 and above) */ -char * -get_first_ethernet() +int +get_first_ether_hwaddr(u_char *addr) { struct lifnum lifn; struct lifconf lifc; @@ -299,7 +309,7 @@ fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { - return 0; + return -1; } /* @@ -310,7 +320,7 @@ if (ioctl(fd, SIOCGLIFNUM, &lifn) < 0) { close(fd); error("could not determine number of interfaces: %m"); - return 0; + return -1; } num_ifs = lifn.lifn_count; @@ -319,7 +329,7 @@ if (req == NULL) { close(fd); error("out of memory"); - return 0; + return -1; } /* @@ -333,7 +343,7 @@ close(fd); free(req); error("SIOCGLIFCONF: %m"); - return 0; + return -1; } /* @@ -350,10 +360,8 @@ memset(&lifr, 0, sizeof(lifr)); strncpy(lifr.lifr_name, plifreq->lifr_name, sizeof(lifr.lifr_name)); if (ioctl(fd, SIOCGLIFFLAGS, &lifr) < 0) { - close(fd); - free(req); error("SIOCGLIFFLAGS: %m"); - return 0; + break; } fl = lifr.lifr_flags; @@ -361,27 +369,29 @@ != (IFF_UP | IFF_BROADCAST)) continue; + if (get_if_hwaddr(addr, lifr.lifr_name) < 0) + continue; + found = 1; break; } free(req); close(fd); - if (found) { - strncpy(first_ether_name, lifr.lifr_name, sizeof(first_ether_name)); - return (char *)first_ether_name; - } else - return NULL; + if (found) + return 0; + else + return -1; } #else /* - * get_first_ethernet - returns the first Ethernet interface name found in - * the system, or NULL if none is found + * get_first_ether_hwaddr - get the hardware address for the first + * ethernet-style interface on this system. * * NOTE: This is the ifreq version (before Solaris 8). */ -char * -get_first_ethernet() +int +get_first_ether_hwaddr(u_char *addr) { struct ifconf ifc; struct ifreq *pifreq; @@ -392,7 +402,7 @@ fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd < 0) { - return 0; + return -1; } /* @@ -407,7 +417,7 @@ if (req == NULL) { close(fd); error("out of memory"); - return 0; + return -1; } /* @@ -419,7 +429,7 @@ close(fd); free(req); error("SIOCGIFCONF: %m"); - return 0; + return -1; } /* @@ -436,10 +446,8 @@ memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, pifreq->ifr_name, sizeof(ifr.ifr_name)); if (ioctl(fd, SIOCGIFFLAGS, &ifr) < 0) { - close(fd); - free(req); error("SIOCGIFFLAGS: %m"); - return 0; + break; } fl = ifr.ifr_flags; @@ -447,17 +455,19 @@ != (IFF_UP | IFF_BROADCAST)) continue; + if (get_if_hwaddr(addr, ifr.ifr_name) < 0) + continue; + found = 1; break; } free(req); close(fd); - if (found) { - strncpy(first_ether_name, ifr.ifr_name, sizeof(first_ether_name)); - return (char *)first_ether_name; - } else - return NULL; + if (found) + return 0; + else + return -1; } #endif /* defined(SOL2) && defined(INET6) */ @@ -496,9 +506,7 @@ * be set in order to declare this as an IPv6 interface */ static int -slifname(fd, ppa) - int fd; - int ppa; +slifname(int fd, int ppa) { struct lifreq lifr; int ret; @@ -520,57 +528,13 @@ } - - -/* - * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI - * - * walks the list of valid ethernet interfaces, and convert the first - * found 48-bit MAC address into EUI 64. caller also assumes that - * the system has a properly configured Ethernet interface for this - * function to return non-zero. - */ -int -ether_to_eui64(eui64_t *p_eui64) -{ - struct sockaddr s_eth_addr; - struct ether_addr *eth_addr = (struct ether_addr *)&s_eth_addr.sa_data; - char *if_name; - - if ((if_name = get_first_ethernet()) == NULL) { - error("no persistent id can be found"); - return 0; - } - - /* - * Send DL_INFO_REQ to the driver to solicit its MAC address - */ - if (!get_hw_addr_dlpi(if_name, &s_eth_addr)) { - error("could not obtain hardware address for %s", if_name); - return 0; - } - - /* - * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1] - */ - p_eui64->e8[0] = (eth_addr->ether_addr_octet[0] & 0xFF) | 0x02; - p_eui64->e8[1] = (eth_addr->ether_addr_octet[1] & 0xFF); - p_eui64->e8[2] = (eth_addr->ether_addr_octet[2] & 0xFF); - p_eui64->e8[3] = 0xFF; - p_eui64->e8[4] = 0xFE; - p_eui64->e8[5] = (eth_addr->ether_addr_octet[3] & 0xFF); - p_eui64->e8[6] = (eth_addr->ether_addr_octet[4] & 0xFF); - p_eui64->e8[7] = (eth_addr->ether_addr_octet[5] & 0xFF); - - return 1; -} #endif /* defined(SOL2) && defined(INET6) */ /* * sys_init - System-dependent initialization. */ void -sys_init() +sys_init(void) { int ifd, x; struct ifreq ifr; @@ -770,7 +734,7 @@ * This should call die() because it's called from die(). */ void -sys_cleanup() +sys_cleanup(void) { #if defined(SOL2) struct ifreq ifr; @@ -787,6 +751,8 @@ sifdown(0); if (default_route_gateway) cifdefaultroute(0, default_route_gateway, default_route_gateway); + if (default_route_gateway6.e32[0] != 0 || default_route_gateway6.e32[1] != 0) + cif6defaultroute(0, default_route_gateway6, default_route_gateway6); if (proxy_arp_addr) cifproxyarp(0, proxy_arp_addr); #if defined(SOL2) @@ -842,7 +808,7 @@ * sys_close - Clean up in a child process before execing. */ void -sys_close() +sys_close(void) { close(ipfd); #if defined(INET6) && defined(SOL2) @@ -856,7 +822,7 @@ * sys_check_options - check the options that the user specified */ int -sys_check_options() +sys_check_options(void) { return 1; } @@ -866,8 +832,7 @@ * daemon - Detach us from controlling terminal session. */ int -daemon(nochdir, noclose) - int nochdir, noclose; +daemon(int nochdir, int noclose) { int pid; @@ -891,7 +856,7 @@ * ppp_available - check whether the system has any ppp interfaces */ int -ppp_available() +ppp_available(void) { struct stat buf; @@ -908,7 +873,7 @@ * no point of having the comp module be pushed on the stream. */ static int -any_compressions() +any_compressions(void) { if ((!lcp_wantoptions[0].neg_accompression) && (!lcp_wantoptions[0].neg_pcompression) && @@ -923,8 +888,7 @@ * tty_establish_ppp - Turn the serial port into a ppp interface. */ int -tty_establish_ppp(fd) - int fd; +tty_establish_ppp(int fd) { int i; @@ -983,8 +947,7 @@ * modules. This shouldn't call die() because it's called from die(). */ void -tty_disestablish_ppp(fd) - int fd; +tty_disestablish_ppp(int fd) { int i; @@ -1020,7 +983,7 @@ * Check whether the link seems not to be 8-bit clean. */ void -clean_check() +clean_check(void) { int x; char *s; @@ -1142,8 +1105,7 @@ * Translate from bits/second to a speed_t. */ static int -translate_speed(bps) - int bps; +translate_speed(int bps) { struct speed *speedp; @@ -1160,8 +1122,7 @@ * Translate from a speed_t to bits/second. */ static int -baud_rate_of(speed) - int speed; +baud_rate_of(int speed) { struct speed *speedp; @@ -1179,8 +1140,7 @@ * regardless of whether the modem option was specified. */ void -set_up_tty(fd, local) - int fd, local; +set_up_tty(int fd, int local) { int speed; struct termios tios; @@ -1275,8 +1235,7 @@ * restore_tty - restore the terminal to the saved settings. */ void -restore_tty(fd) - int fd; +restore_tty(int fd) { if (restore_term) { if (!default_device) { @@ -1308,8 +1267,7 @@ * This is called from die(), so it shouldn't call die(). */ void -setdtr(fd, on) -int fd, on; +setdtr(int fd, int on) { int modembits = TIOCM_DTR; @@ -1322,7 +1280,7 @@ * to the ppp driver. */ int -open_ppp_loopback() +open_ppp_loopback(void) { return pppfd; } @@ -1331,10 +1289,7 @@ * output - Output PPP packet. */ void -output(unit, p, len) - int unit; - u_char *p; - int len; +output(int unit, u_char *p, int len) { struct strbuf data; int retries; @@ -1365,8 +1320,7 @@ * if timo is NULL). */ void -wait_input(timo) - struct timeval *timo; +wait_input(struct timeval *timo) { int t; @@ -1378,8 +1332,7 @@ /* * add_fd - add an fd to the set that wait_input waits for. */ -void add_fd(fd) - int fd; +void add_fd(int fd) { int n; @@ -1397,8 +1350,7 @@ /* * remove_fd - remove an fd from the set that wait_input waits for. */ -void remove_fd(fd) - int fd; +void remove_fd(int fd) { int n; @@ -1419,8 +1371,7 @@ * if timo is NULL). */ void -wait_loop_output(timo) - struct timeval *timo; +wait_loop_output(struct timeval *timo) { wait_input(timo); } @@ -1430,8 +1381,7 @@ * signal is received. */ void -wait_time(timo) - struct timeval *timo; +wait_time(struct timeval *timo) { int n; @@ -1446,8 +1396,7 @@ * read_packet - get a PPP packet from the serial device. */ int -read_packet(buf) - u_char *buf; +read_packet(u_char *buf) { struct strbuf ctrl, data; int flags, len; @@ -1486,7 +1435,7 @@ * Return value is 1 if we need to bring up the link, 0 otherwise. */ int -get_loop_output() +get_loop_output(void) { int len; int rv = 0; @@ -1502,8 +1451,7 @@ * netif_set_mtu - set the MTU on the PPP network interface. */ void -netif_set_mtu(unit, mtu) - int unit, mtu; +netif_set_mtu(int unit, int mtu) { struct ifreq ifr; #if defined(INET6) && defined(SOL2) @@ -1513,7 +1461,7 @@ memset(&ifr, 0, sizeof(ifr)); strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); - ifr.ifr_metric = link_mtu; + ifr.ifr_metric = mtu; if (ioctl(ipfd, SIOCSIFMTU, &ifr) < 0) { error("Couldn't set IP MTU (%s): %m", ifr.ifr_name); } @@ -1525,7 +1473,7 @@ memset(&lifr, 0, sizeof(lifr)); strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name)); - lifr.lifr_mtu = link_mtu; + lifr.lifr_mtu = mtu; if (ioctl(fd, SIOCSLIFMTU, &lifr) < 0) { close(fd); error("Couldn't set IPv6 MTU (%s): %m", ifr.ifr_name); @@ -1534,15 +1482,32 @@ #endif /* defined(INET6) && defined(SOL2) */ } + + +/* + * netif_get_mtu - get the MTU on the PPP network interface. + */ +int +netif_get_mtu(int unit) +{ + struct ifreq ifr; + + memset (&ifr, '\0', sizeof (ifr)); + strlcpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + + if (ioctl(ipfd, SIOCGIFMTU, (caddr_t) &ifr) < 0) { + error("ioctl(SIOCGIFMTU): %m (line %d)", __LINE__); + return 0; + } + return ifr.ifr_metric; +} + /* * tty_send_config - configure the transmit characteristics of * the ppp interface. */ void -tty_send_config(mtu, asyncmap, pcomp, accomp) - int mtu; - u_int32_t asyncmap; - int pcomp, accomp; +tty_send_config(int mtu, u_int32_t asyncmap, int pcomp, int accomp) { int cf[2]; @@ -1571,8 +1536,7 @@ * tty_set_xaccm - set the extended transmit ACCM for the interface. */ void -tty_set_xaccm(accm) - ext_accm accm; +tty_set_xaccm(ext_accm accm) { if (sync_serial) return; @@ -1589,10 +1553,7 @@ * the ppp interface. */ void -tty_recv_config(mru, asyncmap, pcomp, accomp) - int mru; - u_int32_t asyncmap; - int pcomp, accomp; +tty_recv_config(int mru, u_int32_t asyncmap, int pcomp, int accomp) { int cf[2]; @@ -1622,9 +1583,7 @@ * is acceptable for use. */ int -ccp_test(unit, opt_ptr, opt_len, for_transmit) - int unit, opt_len, for_transmit; - u_char *opt_ptr; +ccp_test(int unit, u_char *opt_ptr, int opt_len, int for_transmit) { if (strioctl(pppfd, (for_transmit? PPPIO_XCOMP: PPPIO_RCOMP), opt_ptr, opt_len, 0) >= 0) @@ -1636,8 +1595,7 @@ * ccp_flags_set - inform kernel about the current state of CCP. */ void -ccp_flags_set(unit, isopen, isup) - int unit, isopen, isup; +ccp_flags_set(int unit, int isopen, int isup) { int cf[2]; @@ -1653,9 +1611,7 @@ * get_idle_time - return how long the link has been idle. */ int -get_idle_time(u, ip) - int u; - struct ppp_idle *ip; +get_idle_time(int u, struct ppp_idle *ip) { return strioctl(pppfd, PPPIO_GIDLE, ip, 0, sizeof(struct ppp_idle)) >= 0; } @@ -1664,9 +1620,7 @@ * get_ppp_stats - return statistics for the link. */ int -get_ppp_stats(u, stats) - int u; - struct pppd_stats *stats; +get_ppp_stats(int u, struct pppd_stats *stats) { struct ppp_stats s; @@ -1687,8 +1641,7 @@ * set_filters - transfer the pass and active filters to the kernel. */ int -set_filters(pass, active) - struct bpf_program *pass, *active; +set_filters(struct bpf_program *pass, struct bpf_program *active) { int ret = 1; @@ -1716,8 +1669,7 @@ * 0 otherwise. This is necessary because of patent nonsense. */ int -ccp_fatal_error(unit) - int unit; +ccp_fatal_error(int unit) { int cf[2]; @@ -1734,8 +1686,7 @@ * sifvjcomp - config tcp header compression */ int -sifvjcomp(u, vjcomp, xcidcomp, xmaxcid) - int u, vjcomp, xcidcomp, xmaxcid; +sifvjcomp(int u, int vjcomp, int xcidcomp, int xmaxcid) { int cf[2]; char maxcid[2]; @@ -1763,8 +1714,7 @@ * sifup - Config the interface up and enable IP packets to pass. */ int -sifup(u) - int u; +sifup(int u) { struct ifreq ifr; @@ -1786,8 +1736,7 @@ * sifdown - Config the interface down and disable IP. */ int -sifdown(u) - int u; +sifdown(int u) { struct ifreq ifr; @@ -1811,10 +1760,7 @@ * sifnpmode - Set the mode for handling packets for a given NP. */ int -sifnpmode(u, proto, mode) - int u; - int proto; - enum NPmode mode; +sifnpmode(int u, int proto, enum NPmode mode) { int npi[2]; @@ -1832,8 +1778,7 @@ * sif6up - Config the IPv6 interface up and enable IPv6 packets to pass. */ int -sif6up(u) - int u; +sif6up(int u) { struct lifreq lifr; int fd; @@ -1866,8 +1811,7 @@ * sifdown - Config the IPv6 interface down and disable IPv6. */ int -sif6down(u) - int u; +sif6down(int u) { struct lifreq lifr; int fd; @@ -1899,9 +1843,7 @@ * sif6addr - Config the interface with an IPv6 link-local address */ int -sif6addr(u, o, h) - int u; - eui64_t o, h; +sif6addr(int u, eui64_t o, eui64_t h) { struct lifreq lifr; struct sockaddr_storage laddr; @@ -1950,10 +1892,68 @@ * cif6addr - Remove the IPv6 address from interface */ int -cif6addr(u, o, h) - int u; - eui64_t o, h; +cif6addr(int u, eui64_t o, eui64_t h) +{ + return 1; +} + +/* + * sif6defaultroute - assign a default route through the address given. + */ +int +sif6defaultroute(int u, eui64_t l, eui64_t g) +{ + struct { + struct rt_msghdr rtm; + struct sockaddr_in6 dst; + struct sockaddr_in6 gw; + } rmsg; + static int seq; + int rtsock; + +#if defined(__USLC__) + g = l; /* use the local address as gateway */ +#endif + memset(&rmsg, 0, sizeof(rmsg)); + + rmsg.rtm.rtm_msglen = sizeof (rmsg); + rmsg.rtm.rtm_version = RTM_VERSION; + rmsg.rtm.rtm_type = RTM_ADD; + rmsg.rtm.rtm_flags = RTF_GATEWAY; + rmsg.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY; + rmsg.rtm.rtm_pid = getpid(); + rmsg.rtm.rtm_seq = seq++; + + rmsg.dst.sin6_family = AF_INET6; + + rmsg.gw.sin6_family = AF_INET6; + IN6_SOCKADDR_FROM_EUI64(&rmsg.gw, g); + + rtsock = socket(PF_ROUTE, SOCK_RAW, 0); + + if (rtsock < 0) { + error("Can't add default route: %m"); + return 0; + } + + if (write(rtsock, &rmsg, sizeof(rmsg)) < 0) + error("Can't add default route: %m"); + + close(rtsock); + + default_route_gateway6 = g; + return 1; +} + +/* + * cif6defaultroute - delete a default route through the address given. + */ +int +cif6defaultroute(int u, eui64_t l, eui64_t g) { + /* No need to do this on Solaris; the kernel deletes the + route when the interface goes down. */ + memset(&default_route_gateway6, 0, sizeof(default_route_gateway6)); return 1; } @@ -1966,9 +1966,7 @@ * sifaddr - Config the interface IP addresses and netmask. */ int -sifaddr(u, o, h, m) - int u; - u_int32_t o, h, m; +sifaddr(int u, u_int32_t o, u_int32_t h, u_int32_t m) { struct ifreq ifr; int ret = 1; @@ -2016,9 +2014,7 @@ * through the interface if possible. */ int -cifaddr(u, o, h) - int u; - u_int32_t o, h; +cifaddr(int u, u_int32_t o, u_int32_t h) { #if defined(__USLC__) /* was: #if 0 */ cifroute(unit, ouraddr, hisaddr); @@ -2039,12 +2035,15 @@ * sifdefaultroute - assign a default route through the address given. */ int -sifdefaultroute(u, l, g) - int u; - u_int32_t l, g; +sifdefaultroute(int u, u_int32_t l, u_int32_t g, bool replace) { struct rtentry rt; + if (replace) { + error("Replacing the default route is not implemented on Solaris yet"); + return 0; + } + #if defined(__USLC__) g = l; /* use the local address as gateway */ #endif @@ -2068,9 +2067,7 @@ * cifdefaultroute - delete a default route through the address given. */ int -cifdefaultroute(u, l, g) - int u; - u_int32_t l, g; +cifdefaultroute(int u, u_int32_t l, u_int32_t g) { struct rtentry rt; @@ -2097,9 +2094,7 @@ * sifproxyarp - Make a proxy ARP entry for the peer. */ int -sifproxyarp(unit, hisaddr) - int unit; - u_int32_t hisaddr; +sifproxyarp(int unit, u_int32_t hisaddr) { struct arpreq arpreq; @@ -2123,9 +2118,7 @@ * cifproxyarp - Delete the proxy ARP entry for the peer. */ int -cifproxyarp(unit, hisaddr) - int unit; - u_int32_t hisaddr; +cifproxyarp(int unit, u_int32_t hisaddr) { struct arpreq arpreq; @@ -2148,9 +2141,7 @@ #define MAX_IFS 32 static int -get_ether_addr(ipaddr, hwaddr) - u_int32_t ipaddr; - struct sockaddr *hwaddr; +get_ether_addr(u_int32_t ipaddr, struct sockaddr *hwaddr) { struct ifreq *ifr, *ifend, ifreq; int nif; @@ -2219,9 +2210,7 @@ * get_hw_addr_dlpi - obtain the hardware address using DLPI */ static int -get_hw_addr_dlpi(name, hwaddr) - char *name; - struct sockaddr *hwaddr; +get_hw_addr_dlpi(char *name, struct sockaddr *hwaddr) { char *q; int unit, iffd, adrlen; @@ -2278,10 +2267,7 @@ * get_hw_addr - obtain the hardware address for a named interface. */ static int -get_hw_addr(name, ina, hwaddr) - char *name; - u_int32_t ina; - struct sockaddr *hwaddr; +get_hw_addr(char *name, u_int32_t ina, struct sockaddr *hwaddr) { /* New way - get the address by doing an arp request. */ int s; @@ -2304,8 +2290,7 @@ } static int -dlpi_attach(fd, ppa) - int fd, ppa; +dlpi_attach(int fd, int ppa) { dl_attach_req_t req; struct strbuf buf; @@ -2318,8 +2303,7 @@ } static int -dlpi_info_req(fd) - int fd; +dlpi_info_req(int fd) { dl_info_req_t req; struct strbuf buf; @@ -2331,9 +2315,7 @@ } static int -dlpi_get_reply(fd, reply, expected_prim, maxlen) - union DL_primitives *reply; - int fd, expected_prim, maxlen; +dlpi_get_reply(int fd, union DL_primitives *reply, int expected_prim, size_t maxlen) { struct strbuf buf; int flags, n; @@ -2346,7 +2328,7 @@ pfd.events = POLLIN | POLLPRI; do { n = poll(&pfd, 1, 1000); - } while (n == -1 && errno == EINTR); + } while (n == -1 && errno == EINTR && !got_sigterm); if (n <= 0) return -1; @@ -2391,8 +2373,7 @@ * user-specified netmask. */ u_int32_t -GetMask(addr) - u_int32_t addr; +GetMask(u_int32_t addr) { u_int32_t mask, nmask, ina; struct ifreq *ifr, *ifend, ifreq; @@ -2460,8 +2441,7 @@ * logwtmp - write an accounting record to the /var/adm/wtmp file. */ void -logwtmp(line, name, host) - const char *line, *name, *host; +logwtmp(const char *line, const char *name, const char *host) { static struct utmpx utmpx; @@ -2488,7 +2468,7 @@ * get_host_seed - return the serial number of this machine. */ int -get_host_seed() +get_host_seed(void) { char buf[32]; @@ -2500,9 +2480,7 @@ } static int -strioctl(fd, cmd, ptr, ilen, olen) - int fd, cmd, ilen, olen; - void *ptr; +strioctl(int fd, int cmd, void *ptr, int ilen, int olen) { struct strioctl str; @@ -2527,8 +2505,7 @@ static char lock_file[40]; /* name of lock file created */ int -lock(dev) - char *dev; +lock(char *dev) { int n, fd, pid; struct stat sbuf; @@ -2589,7 +2566,7 @@ * unlock - remove our lockfile */ void -unlock() +unlock(void) { if (lock_file[0]) { unlink(lock_file); @@ -2602,9 +2579,7 @@ * cifroute - delete a route through the addresses given. */ int -cifroute(u, our, his) - int u; - u_int32_t our, his; +cifroute(int u, u_int32_t our, u_int32_t his) { struct rtentry rt; @@ -2635,8 +2610,7 @@ #endif int -have_route_to(addr) - u_int32_t addr; +have_route_to(u_int32_t addr) { #ifdef SOL2 int fd, r, flags, i; @@ -2739,11 +2713,7 @@ * the uid given. Assumes slave_name points to MAXPATHLEN bytes of space. */ int -get_pty(master_fdp, slave_fdp, slave_name, uid) - int *master_fdp; - int *slave_fdp; - char *slave_name; - int uid; +get_pty(int *master_fdp, int *slave_fdp, char *slave_name, int uid) { int mfd, sfd; char *pty_name; @@ -2783,3 +2753,13 @@ return 1; } + +/******************************************************************** + * + * get_time - Get current time, monotonic if possible. + */ +int +get_time(struct timeval *tv) +{ + return gettimeofday(tv, NULL); +} diff -Nru ppp-2.4.7/pppd/tty.c ppp-2.4.9/pppd/tty.c --- ppp-2.4.7/pppd/tty.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/tty.c 2021-01-05 00:06:37.000000000 +0100 @@ -68,8 +68,6 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: tty.c,v 1.27 2008/07/01 12:27:56 paulus Exp $" - #include #include #include @@ -83,7 +81,6 @@ #include #include #include -#include #include #include #include @@ -98,28 +95,28 @@ #include "fsm.h" #include "lcp.h" -void tty_process_extra_options __P((void)); -void tty_check_options __P((void)); -int connect_tty __P((void)); -void disconnect_tty __P((void)); -void tty_close_fds __P((void)); -void cleanup_tty __P((void)); -void tty_do_send_config __P((int, u_int32_t, int, int)); - -static int setdevname __P((char *, char **, int)); -static int setspeed __P((char *, char **, int)); -static int setxonxoff __P((char **)); -static int setescape __P((char **)); -static void printescape __P((option_t *, void (*)(void *, char *,...),void *)); -static void finish_tty __P((void)); -static int start_charshunt __P((int, int)); -static void stop_charshunt __P((void *, int)); -static void charshunt_done __P((void *)); -static void charshunt __P((int, int, char *)); -static int record_write __P((FILE *, int code, u_char *buf, int nb, - struct timeval *)); -static int open_socket __P((char *)); -static void maybe_relock __P((void *, int)); +void tty_process_extra_options(void); +void tty_check_options(void); +int connect_tty(void); +void disconnect_tty(void); +void tty_close_fds(void); +void cleanup_tty(void); +void tty_do_send_config(int, u_int32_t, int, int); + +static int setdevname(char *, char **, int); +static int setspeed(char *, char **, int); +static int setxonxoff(char **); +static int setescape(char **); +static void printescape(option_t *, void (*)(void *, char *,...),void *); +static void finish_tty(void); +static int start_charshunt(int, int); +static void stop_charshunt(void *, int); +static void charshunt_done(void *); +static void charshunt(int, int, char *); +static int record_write(FILE *, int code, u_char *buf, int nb, + struct timeval *); +static int open_socket(char *); +static void maybe_relock(void *, int); static int pty_master; /* fd for master side of pty */ static int pty_slave; /* fd for slave side of pty */ @@ -266,10 +263,7 @@ * potentially a speed value. */ static int -setspeed(arg, argv, doit) - char *arg; - char **argv; - int doit; +setspeed(char *arg, char **argv, int doit) { char *ptr; int spd; @@ -291,10 +285,7 @@ * potentially a device name. */ static int -setdevname(cp, argv, doit) - char *cp; - char **argv; - int doit; +setdevname(char *cp, char **argv, int doit) { struct stat statbuf; char dev[MAXPATHLEN]; @@ -333,8 +324,7 @@ } static int -setxonxoff(argv) - char **argv; +setxonxoff(char **argv) { lcp_wantoptions[0].asyncmap |= 0x000A0000; /* escape ^S and ^Q */ lcp_wantoptions[0].neg_asyncmap = 1; @@ -347,8 +337,7 @@ * setescape - add chars to the set we escape on transmission. */ static int -setescape(argv) - char **argv; +setescape(char **argv) { int n, ret; char *p, *endp; @@ -376,10 +365,7 @@ } static void -printescape(opt, printer, arg) - option_t *opt; - void (*printer) __P((void *, char *, ...)); - void *arg; +printescape(option_t *opt, void (*printer)(void *, char *, ...), void *arg) { int n; int first = 1; @@ -402,7 +388,7 @@ /* * tty_init - do various tty-related initializations. */ -void tty_init() +void tty_init(void) { add_notifier(&pidchange, maybe_relock, 0); the_channel = &tty_channel; @@ -413,7 +399,7 @@ * tty_process_extra_options - work out which tty device we are using * and read its options file. */ -void tty_process_extra_options() +void tty_process_extra_options(void) { using_pty = notty || ptycommand != NULL || pty_socket != NULL; if (using_pty) @@ -445,7 +431,7 @@ * tty_check_options - do consistency checks on the options we were given. */ void -tty_check_options() +tty_check_options(void) { struct stat statbuf; int fdflags; @@ -515,7 +501,7 @@ * That is, open the serial port, set its speed and mode, and run * the connector and/or welcomer. */ -int connect_tty() +int connect_tty(void) { char *connector; int fdflags; @@ -773,7 +759,7 @@ } -void disconnect_tty() +void disconnect_tty(void) { if (disconnect_script == NULL || hungup) return; @@ -787,7 +773,7 @@ stop_charshunt(NULL, 0); } -void tty_close_fds() +void tty_close_fds(void) { if (pty_slave >= 0) close(pty_slave); @@ -798,7 +784,7 @@ /* N.B. ttyfd will == either pty_slave or real_ttyfd */ } -void cleanup_tty() +void cleanup_tty(void) { if (real_ttyfd >= 0) finish_tty(); @@ -814,10 +800,7 @@ * We set the extended transmit ACCM here as well. */ void -tty_do_send_config(mtu, accm, pcomp, accomp) - int mtu; - u_int32_t accm; - int pcomp, accomp; +tty_do_send_config(int mtu, u_int32_t accm, int pcomp, int accomp) { tty_set_xaccm(xmit_accm); tty_send_config(mtu, accm, pcomp, accomp); @@ -827,7 +810,7 @@ * finish_tty - restore the terminal device to its original settings */ static void -finish_tty() +finish_tty(void) { /* drop dtr to hang up */ if (!default_device && modem) { @@ -856,9 +839,7 @@ * maybe_relock - our PID has changed, maybe update the lock file. */ static void -maybe_relock(arg, pid) - void *arg; - int pid; +maybe_relock(void *arg, int pid) { if (locked) relock(pid); @@ -869,8 +850,7 @@ * host and port. */ static int -open_socket(dest) - char *dest; +open_socket(char *dest) { char *sep, *endp = NULL; int sock, port = -1; @@ -923,8 +903,7 @@ * start_charshunt - create a child process to run the character shunt. */ static int -start_charshunt(ifd, ofd) - int ifd, ofd; +start_charshunt(int ifd, int ofd) { int cpid; @@ -953,16 +932,13 @@ } static void -charshunt_done(arg) - void *arg; +charshunt_done(void *arg) { charshunt_pid = 0; } static void -stop_charshunt(arg, sig) - void *arg; - int sig; +stop_charshunt(void *arg, int sig) { if (charshunt_pid) kill(charshunt_pid, (sig == SIGINT? sig: SIGTERM)); @@ -975,9 +951,7 @@ * (We assume ofd >= ifd which is true the way this gets called. :-). */ static void -charshunt(ifd, ofd, record_file) - int ifd, ofd; - char *record_file; +charshunt(int ifd, int ofd, char *record_file) { int n, nfds; fd_set ready, writey; @@ -1072,7 +1046,7 @@ pty_readable = stdin_readable = 1; ilevel = olevel = 0; - gettimeofday(&levelt, NULL); + get_time(&levelt); if (max_data_rate) { max_level = max_data_rate / 10; if (max_level < 100) @@ -1121,7 +1095,7 @@ int nbt; struct timeval now; - gettimeofday(&now, NULL); + get_time(&now); dt = (now.tv_sec - levelt.tv_sec + (now.tv_usec - levelt.tv_usec) / 1e6); nbt = (int)(dt * max_data_rate); @@ -1225,12 +1199,7 @@ } static int -record_write(f, code, buf, nb, tp) - FILE *f; - int code; - u_char *buf; - int nb; - struct timeval *tp; +record_write(FILE *f, int code, u_char *buf, int nb, struct timeval *tp) { struct timeval now; int diff; diff -Nru ppp-2.4.7/pppd/upap.c ppp-2.4.9/pppd/upap.c --- ppp-2.4.7/pppd/upap.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/upap.c 2021-01-05 00:06:37.000000000 +0100 @@ -40,8 +40,6 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: upap.c,v 1.30 2005/07/13 10:41:58 paulus Exp $" - /* * TODO: */ @@ -52,7 +50,6 @@ #include "pppd.h" #include "upap.h" -static const char rcsid[] = RCSID; static bool hide_password = 1; @@ -78,13 +75,13 @@ /* * Protocol entry points. */ -static void upap_init __P((int)); -static void upap_lowerup __P((int)); -static void upap_lowerdown __P((int)); -static void upap_input __P((int, u_char *, int)); -static void upap_protrej __P((int)); -static int upap_printpkt __P((u_char *, int, - void (*) __P((void *, char *, ...)), void *)); +static void upap_init(int); +static void upap_lowerup(int); +static void upap_lowerdown(int); +static void upap_input(int, u_char *, int); +static void upap_protrej(int); +static int upap_printpkt(u_char *, int, + void (*)(void *, char *, ...), void *); struct protent pap_protent = { PPP_PAP, @@ -108,21 +105,20 @@ upap_state upap[NUM_PPP]; /* UPAP state; one for each unit */ -static void upap_timeout __P((void *)); -static void upap_reqtimeout __P((void *)); -static void upap_rauthreq __P((upap_state *, u_char *, int, int)); -static void upap_rauthack __P((upap_state *, u_char *, int, int)); -static void upap_rauthnak __P((upap_state *, u_char *, int, int)); -static void upap_sauthreq __P((upap_state *)); -static void upap_sresp __P((upap_state *, int, int, char *, int)); +static void upap_timeout(void *); +static void upap_reqtimeout(void *); +static void upap_rauthreq(upap_state *, u_char *, int, int); +static void upap_rauthack(upap_state *, u_char *, int, int); +static void upap_rauthnak(upap_state *, u_char *, int, int); +static void upap_sauthreq(upap_state *); +static void upap_sresp(upap_state *, int, int, char *, int); /* * upap_init - Initialize a UPAP unit. */ static void -upap_init(unit) - int unit; +upap_init(int unit) { upap_state *u = &upap[unit]; @@ -146,9 +142,7 @@ * Set new state and send authenticate's. */ void -upap_authwithpeer(unit, user, password) - int unit; - char *user, *password; +upap_authwithpeer(int unit, char *user, char *password) { upap_state *u = &upap[unit]; @@ -176,8 +170,7 @@ * Set new state. */ void -upap_authpeer(unit) - int unit; +upap_authpeer(int unit) { upap_state *u = &upap[unit]; @@ -198,8 +191,7 @@ * upap_timeout - Retransmission timer for sending auth-reqs expired. */ static void -upap_timeout(arg) - void *arg; +upap_timeout(void *arg) { upap_state *u = (upap_state *) arg; @@ -222,8 +214,7 @@ * upap_reqtimeout - Give up waiting for the peer to send an auth-req. */ static void -upap_reqtimeout(arg) - void *arg; +upap_reqtimeout(void *arg) { upap_state *u = (upap_state *) arg; @@ -241,8 +232,7 @@ * Start authenticating if pending. */ static void -upap_lowerup(unit) - int unit; +upap_lowerup(int unit) { upap_state *u = &upap[unit]; @@ -268,8 +258,7 @@ * Cancel all timeouts. */ static void -upap_lowerdown(unit) - int unit; +upap_lowerdown(int unit) { upap_state *u = &upap[unit]; @@ -289,8 +278,7 @@ * This shouldn't happen. In any case, pretend lower layer went down. */ static void -upap_protrej(unit) - int unit; +upap_protrej(int unit) { upap_state *u = &upap[unit]; @@ -310,10 +298,7 @@ * upap_input - Input UPAP packet. */ static void -upap_input(unit, inpacket, l) - int unit; - u_char *inpacket; - int l; +upap_input(int unit, u_char *inpacket, int l) { upap_state *u = &upap[unit]; u_char *inp; @@ -368,11 +353,7 @@ * upap_rauth - Receive Authenticate. */ static void -upap_rauthreq(u, inp, id, len) - upap_state *u; - u_char *inp; - int id; - int len; +upap_rauthreq(upap_state *u, u_char *inp, int id, int len) { u_char ruserlen, rpasswdlen; char *ruser, *rpasswd; @@ -466,11 +447,7 @@ * upap_rauthack - Receive Authenticate-Ack. */ static void -upap_rauthack(u, inp, id, len) - upap_state *u; - u_char *inp; - int id; - int len; +upap_rauthack(upap_state *u, u_char *inp, int id, int len) { u_char msglen; char *msg; @@ -506,11 +483,7 @@ * upap_rauthnak - Receive Authenticate-Nak. */ static void -upap_rauthnak(u, inp, id, len) - upap_state *u; - u_char *inp; - int id; - int len; +upap_rauthnak(upap_state *u, u_char *inp, int id, int len) { u_char msglen; char *msg; @@ -547,8 +520,7 @@ * upap_sauthreq - Send an Authenticate-Request. */ static void -upap_sauthreq(u) - upap_state *u; +upap_sauthreq(upap_state *u) { u_char *outp; int outlen; @@ -580,11 +552,7 @@ * upap_sresp - Send a response (ack or nak). */ static void -upap_sresp(u, code, id, msg, msglen) - upap_state *u; - u_char code, id; - char *msg; - int msglen; +upap_sresp(upap_state *u, int code, int id, char *msg, int msglen) { u_char *outp; int outlen; @@ -609,11 +577,7 @@ }; static int -upap_printpkt(p, plen, printer, arg) - u_char *p; - int plen; - void (*printer) __P((void *, char *, ...)); - void *arg; +upap_printpkt(u_char *p, int plen, void (*printer)(void *, char *, ...), void *arg) { int code, id, len; int mlen, ulen, wlen; diff -Nru ppp-2.4.7/pppd/upap.h ppp-2.4.9/pppd/upap.h --- ppp-2.4.7/pppd/upap.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/upap.h 2021-01-05 00:06:37.000000000 +0100 @@ -38,8 +38,6 @@ * 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. - * - * $Id: upap.h,v 1.8 2002/12/04 23:03:33 paulus Exp $ */ /* @@ -104,7 +102,7 @@ extern upap_state upap[]; -void upap_authwithpeer __P((int, char *, char *)); -void upap_authpeer __P((int)); +void upap_authwithpeer(int, char *, char *); +void upap_authpeer(int); extern struct protent pap_protent; diff -Nru ppp-2.4.7/pppd/utils.c ppp-2.4.9/pppd/utils.c --- ppp-2.4.7/pppd/utils.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppd/utils.c 2021-01-05 00:06:37.000000000 +0100 @@ -28,8 +28,7 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RCSID "$Id: utils.c,v 1.25 2008/06/03 12:06:37 paulus Exp $" - +#include #include #include #include @@ -59,16 +58,15 @@ #include "fsm.h" #include "lcp.h" -static const char rcsid[] = RCSID; #if defined(SUNOS4) extern char *strerror(); #endif -static void logit __P((int, char *, va_list)); -static void log_write __P((int, char *)); -static void vslp_printer __P((void *, char *, ...)); -static void format_packet __P((u_char *, int, printer_func, void *)); +static void logit(int, char *, va_list); +static void log_write(int, char *); +static void vslp_printer(void *, char *, ...); +static void format_packet(u_char *, int, printer_func, void *); struct buffer_info { char *ptr; @@ -80,10 +78,7 @@ * always leaves destination null-terminated (for len > 0). */ size_t -strlcpy(dest, src, len) - char *dest; - const char *src; - size_t len; +strlcpy(char *dest, const char *src, size_t len) { size_t ret = strlen(src); @@ -103,10 +98,7 @@ * always leaves destination null-terminated (for len > 0). */ size_t -strlcat(dest, src, len) - char *dest; - const char *src; - size_t len; +strlcat(char *dest, const char *src, size_t len) { size_t dlen = strlen(dest); @@ -123,22 +115,12 @@ * Returns the number of chars put into buf. */ int -slprintf __V((char *buf, int buflen, char *fmt, ...)) +slprintf(char *buf, int buflen, char *fmt, ...) { va_list args; int n; -#if defined(__STDC__) va_start(args, fmt); -#else - char *buf; - int buflen; - char *fmt; - va_start(args); - buf = va_arg(args, char *); - buflen = va_arg(args, int); - fmt = va_arg(args, char *); -#endif n = vslprintf(buf, buflen, fmt, args); va_end(args); return n; @@ -150,11 +132,7 @@ #define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) int -vslprintf(buf, buflen, fmt, args) - char *buf; - int buflen; - char *fmt; - va_list args; +vslprintf(char *buf, int buflen, char *fmt, va_list args) { int c, i, n; int width, prec, fillch; @@ -167,6 +145,7 @@ u_int32_t ip; static char hexchars[] = "0123456789abcdef"; struct buffer_info bufinfo; + int termch; buf0 = buf; --buflen; @@ -300,13 +279,17 @@ p = (unsigned char *)""; if (fillch == '0' && prec >= 0) { n = prec; + termch = -1; /* matches no unsigned char value */ } else { - n = strlen((char *)p); - if (prec >= 0 && n > prec) + n = buflen; + if (prec != -1 && n > prec) n = prec; + termch = 0; /* stop on null byte */ } while (n > 0 && buflen > 0) { c = *p++; + if (c == termch) + break; --n; if (!quoted && c >= 0x80) { OUTCHAR('M'); @@ -386,9 +369,9 @@ } len = num + sizeof(num) - 1 - str; } else { - len = strlen(str); - if (prec >= 0 && len > prec) - len = prec; + for (len = 0; len < buflen && (prec == -1 || len < prec); ++len) + if (str[len] == 0) + break; } if (width > 0) { if (width > buflen) @@ -413,21 +396,13 @@ * vslp_printer - used in processing a %P format */ static void -vslp_printer __V((void *arg, char *fmt, ...)) +vslp_printer(void *arg, char *fmt, ...) { int n; va_list pvar; struct buffer_info *bi; -#if defined(__STDC__) va_start(pvar, fmt); -#else - void *arg; - char *fmt; - va_start(pvar); - arg = va_arg(pvar, void *); - fmt = va_arg(pvar, char *); -#endif bi = (struct buffer_info *) arg; n = vslprintf(bi->ptr, bi->len, fmt, pvar); @@ -443,11 +418,7 @@ */ void -log_packet(p, len, prefix, level) - u_char *p; - int len; - char *prefix; - int level; +log_packet(u_char *p, int len, char *prefix, int level) { init_pr_log(prefix, level); format_packet(p, len, pr_log, &level); @@ -460,11 +431,7 @@ * calling `printer(arg, format, ...)' to output it. */ static void -format_packet(p, len, printer, arg) - u_char *p; - int len; - printer_func printer; - void *arg; +format_packet(u_char *p, int len, printer_func printer, void *arg) { int i, n; u_short proto; @@ -514,9 +481,7 @@ static int llevel; /* level for logging */ void -init_pr_log(prefix, level) - const char *prefix; - int level; +init_pr_log(const char *prefix, int level) { linep = line; if (prefix != NULL) { @@ -527,7 +492,7 @@ } void -end_pr_log() +end_pr_log(void) { if (linep != line) { *linep = 0; @@ -539,22 +504,14 @@ * pr_log - printer routine for outputting to syslog */ void -pr_log __V((void *arg, char *fmt, ...)) +pr_log(void *arg, char *fmt, ...) { int l, n; va_list pvar; char *p, *eol; char buf[256]; -#if defined(__STDC__) va_start(pvar, fmt); -#else - void *arg; - char *fmt; - va_start(pvar); - arg = va_arg(pvar, void *); - fmt = va_arg(pvar, char *); -#endif n = vslprintf(buf, sizeof(buf), fmt, pvar); va_end(pvar); @@ -598,11 +555,7 @@ * printer. */ void -print_string(p, len, printer, arg) - char *p; - int len; - printer_func printer; - void *arg; +print_string(char *p, int len, printer_func printer, void *arg) { int c; @@ -625,7 +578,7 @@ printer(arg, "\\t"); break; default: - printer(arg, "\\%.3o", c); + printer(arg, "\\%.3o", (unsigned char) c); } } } @@ -636,10 +589,7 @@ * logit - does the hard work for fatal et al. */ static void -logit(level, fmt, args) - int level; - char *fmt; - va_list args; +logit(int level, char *fmt, va_list args) { char buf[1024]; @@ -648,9 +598,7 @@ } static void -log_write(level, buf) - int level; - char *buf; +log_write(int level, char *buf) { syslog(level, "%s", buf); if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { @@ -668,17 +616,11 @@ * fatal - log an error message and die horribly. */ void -fatal __V((char *fmt, ...)) +fatal(char *fmt, ...) { va_list pvar; -#if defined(__STDC__) va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif logit(LOG_ERR, fmt, pvar); va_end(pvar); @@ -690,17 +632,11 @@ * error - log an error message. */ void -error __V((char *fmt, ...)) +error(char *fmt, ...) { va_list pvar; -#if defined(__STDC__) va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif logit(LOG_ERR, fmt, pvar); va_end(pvar); @@ -711,17 +647,11 @@ * warn - log a warning message. */ void -warn __V((char *fmt, ...)) +warn(char *fmt, ...) { va_list pvar; -#if defined(__STDC__) va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif logit(LOG_WARNING, fmt, pvar); va_end(pvar); @@ -731,17 +661,11 @@ * notice - log a notice-level message. */ void -notice __V((char *fmt, ...)) +notice(char *fmt, ...) { va_list pvar; -#if defined(__STDC__) va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif logit(LOG_NOTICE, fmt, pvar); va_end(pvar); @@ -751,17 +675,11 @@ * info - log an informational message. */ void -info __V((char *fmt, ...)) +info(char *fmt, ...) { va_list pvar; -#if defined(__STDC__) va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif logit(LOG_INFO, fmt, pvar); va_end(pvar); @@ -771,17 +689,11 @@ * dbglog - log a debug message. */ void -dbglog __V((char *fmt, ...)) +dbglog(char *fmt, ...) { va_list pvar; -#if defined(__STDC__) va_start(pvar, fmt); -#else - char *fmt; - va_start(pvar); - fmt = va_arg(pvar, char *); -#endif logit(LOG_DEBUG, fmt, pvar); va_end(pvar); @@ -831,7 +743,7 @@ for (done = 0; done < count; ) { nb = read(fd, ptr, count - done); if (nb < 0) { - if (errno == EINTR) + if (errno == EINTR && !got_sigterm) continue; return -1; } @@ -862,8 +774,7 @@ * lock - create a lock file for the named device */ int -lock(dev) - char *dev; +lock(char *dev) { #ifdef LOCKLIB int result; @@ -991,8 +902,7 @@ * between when the parent died and the child rewrote the lockfile). */ int -relock(pid) - int pid; +relock(int pid) { #ifdef LOCKLIB /* XXX is there a way to do this? */ @@ -1027,7 +937,7 @@ * unlock - remove our lockfile */ void -unlock() +unlock(void) { if (lock_file[0]) { #ifdef LOCKLIB diff -Nru ppp-2.4.7/pppdump/bsd-comp.c ppp-2.4.9/pppdump/bsd-comp.c --- ppp-2.4.7/pppdump/bsd-comp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppdump/bsd-comp.c 2021-01-05 00:06:37.000000000 +0100 @@ -124,15 +124,15 @@ #define BSD_OVHD 2 /* BSD compress overhead/packet */ #define BSD_INIT_BITS BSD_MIN_BITS -static void *bsd_decomp_alloc __P((u_char *options, int opt_len)); -static void bsd_free __P((void *state)); -static int bsd_decomp_init __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int mru, int debug)); -static void bsd_incomp __P((void *state, u_char *dmsg, int len)); -static int bsd_decompress __P((void *state, u_char *cmp, int inlen, - u_char *dmp, int *outlen)); -static void bsd_reset __P((void *state)); -static void bsd_comp_stats __P((void *state, struct compstat *stats)); +static void *bsd_decomp_alloc(u_char *options, int opt_len); +static void bsd_free(void *state); +static int bsd_decomp_init(void *state, u_char *options, int opt_len, + int unit, int hdrlen, int mru, int debug); +static void bsd_incomp(void *state, u_char *dmsg, int len); +static int bsd_decompress(void *state, u_char *cmp, int inlen, + u_char *dmp, int *outlen); +static void bsd_reset(void *state); +static void bsd_comp_stats(void *state, struct compstat *stats); /* * Exported procedures. @@ -174,8 +174,7 @@ * clear the dictionary */ static void -bsd_clear(db) - struct bsd_db *db; +bsd_clear(struct bsd_db *db) { db->clear_count++; db->max_ent = FIRST-1; @@ -200,8 +199,7 @@ * must compute the same ratio. */ static int /* 1=output CLEAR */ -bsd_check(db) - struct bsd_db *db; +bsd_check(struct bsd_db *db) { u_int new_ratio; @@ -241,9 +239,7 @@ * Return statistics. */ static void -bsd_comp_stats(state, stats) - void *state; - struct compstat *stats; +bsd_comp_stats(void *state, struct compstat *stats) { struct bsd_db *db = (struct bsd_db *) state; u_int out; @@ -268,8 +264,7 @@ * Reset state, as on a CCP ResetReq. */ static void -bsd_reset(state) - void *state; +bsd_reset(void *state) { struct bsd_db *db = (struct bsd_db *) state; @@ -282,9 +277,7 @@ * Allocate space for a (de) compressor. */ static void * -bsd_alloc(options, opt_len, decomp) - u_char *options; - int opt_len, decomp; +bsd_alloc(u_char *options, int opt_len, int decomp) { int bits; u_int newlen, hsize, hshift, maxmaxcode; @@ -350,8 +343,7 @@ } static void -bsd_free(state) - void *state; +bsd_free(void *state) { struct bsd_db *db = (struct bsd_db *) state; @@ -361,9 +353,7 @@ } static void * -bsd_decomp_alloc(options, opt_len) - u_char *options; - int opt_len; +bsd_decomp_alloc(u_char *options, int opt_len) { return bsd_alloc(options, opt_len, 1); } @@ -372,10 +362,8 @@ * Initialize the database. */ static int -bsd_init(db, options, opt_len, unit, hdrlen, mru, debug, decomp) - struct bsd_db *db; - u_char *options; - int opt_len, unit, hdrlen, mru, debug, decomp; +bsd_init(struct bsd_db *db, u_char *options, int opt_len, int unit, + int hdrlen, int mru, int debug, int decomp) { int i; @@ -409,10 +397,8 @@ } static int -bsd_decomp_init(state, options, opt_len, unit, hdrlen, mru, debug) - void *state; - u_char *options; - int opt_len, unit, hdrlen, mru, debug; +bsd_decomp_init(void *state, u_char *options, int opt_len, + int unit, int hdrlen, int mru, int debug) { return bsd_init((struct bsd_db *) state, options, opt_len, unit, hdrlen, mru, debug, 1); @@ -424,10 +410,7 @@ * incompressible data by pretending to compress the incoming data. */ static void -bsd_incomp(state, dmsg, mlen) - void *state; - u_char *dmsg; - int mlen; +bsd_incomp(void *state, u_char *dmsg, int mlen) { struct bsd_db *db = (struct bsd_db *) state; u_int hshift = db->hshift; @@ -544,10 +527,7 @@ * compression, even though they are detected by inspecting the input. */ static int -bsd_decompress(state, cmsg, inlen, dmp, outlenp) - void *state; - u_char *cmsg, *dmp; - int inlen, *outlenp; +bsd_decompress(void *state, u_char *cmsg, int inlen, u_char *dmp, int *outlenp) { struct bsd_db *db = (struct bsd_db *) state; u_int max_ent = db->max_ent; diff -Nru ppp-2.4.7/pppdump/deflate.c ppp-2.4.9/pppdump/deflate.c --- ppp-2.4.7/pppdump/deflate.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppdump/deflate.c 2021-01-05 00:06:37.000000000 +0100 @@ -65,17 +65,17 @@ #define DEFLATE_OVHD 2 /* Deflate overhead/packet */ -static void *z_alloc __P((void *, u_int items, u_int size)); -static void z_free __P((void *, void *ptr, u_int nb)); -static void *z_decomp_alloc __P((u_char *options, int opt_len)); -static void z_decomp_free __P((void *state)); -static int z_decomp_init __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int mru, int debug)); -static void z_incomp __P((void *state, u_char *dmsg, int len)); -static int z_decompress __P((void *state, u_char *cmp, int inlen, - u_char *dmp, int *outlenp)); -static void z_decomp_reset __P((void *state)); -static void z_comp_stats __P((void *state, struct compstat *stats)); +static void *z_alloc(void *, u_int items, u_int size); +static void z_free(void *, void *ptr, u_int nb); +static void *z_decomp_alloc(u_char *options, int opt_len); +static void z_decomp_free(void *state); +static int z_decomp_init(void *state, u_char *options, int opt_len, + int unit, int hdrlen, int mru, int debug); +static void z_incomp(void *state, u_char *dmsg, int len); +static int z_decompress(void *state, u_char *cmp, int inlen, + u_char *dmp, int *outlenp); +static void z_decomp_reset(void *state); +static void z_comp_stats(void *state, struct compstat *stats); /* * Procedures exported to if_ppp.c. @@ -95,26 +95,19 @@ * Space allocation and freeing routines for use by zlib routines. */ static void * -z_alloc(notused, items, size) - void *notused; - u_int items, size; +z_alloc(void *notused, u_int items, u_int size) { return malloc(items * size); } static void -z_free(notused, ptr, nbytes) - void *notused; - void *ptr; - u_int nbytes; +z_free(void *notused, void *ptr, u_int nbytes) { free(ptr); } static void -z_comp_stats(arg, stats) - void *arg; - struct compstat *stats; +z_comp_stats(void *arg, struct compstat *stats) { struct deflate_state *state = (struct deflate_state *) arg; u_int out; @@ -134,9 +127,7 @@ * Allocate space for a decompressor. */ static void * -z_decomp_alloc(options, opt_len) - u_char *options; - int opt_len; +z_decomp_alloc(u_char *options, int opt_len) { struct deflate_state *state; int w_size; @@ -168,8 +159,7 @@ } static void -z_decomp_free(arg) - void *arg; +z_decomp_free(void *arg) { struct deflate_state *state = (struct deflate_state *) arg; @@ -178,10 +168,8 @@ } static int -z_decomp_init(arg, options, opt_len, unit, hdrlen, mru, debug) - void *arg; - u_char *options; - int opt_len, unit, hdrlen, mru, debug; +z_decomp_init(void *arg, u_char *options, int opt_len, + int unit, int hdrlen, int mru, int debug) { struct deflate_state *state = (struct deflate_state *) arg; @@ -204,8 +192,7 @@ } static void -z_decomp_reset(arg) - void *arg; +z_decomp_reset(void *arg) { struct deflate_state *state = (struct deflate_state *) arg; @@ -230,10 +217,7 @@ * compression, even though they are detected by inspecting the input. */ static int -z_decompress(arg, mi, inlen, mo, outlenp) - void *arg; - u_char *mi, *mo; - int inlen, *outlenp; +z_decompress(void *arg, u_char *mi, int inlen, u_char *mo, int *outlenp) { struct deflate_state *state = (struct deflate_state *) arg; u_char *rptr, *wptr; @@ -302,10 +286,7 @@ * Incompressible data has arrived - add it to the history. */ static void -z_incomp(arg, mi, mlen) - void *arg; - u_char *mi; - int mlen; +z_incomp(void *arg, u_char *mi, int mlen) { struct deflate_state *state = (struct deflate_state *) arg; u_char *rptr; diff -Nru ppp-2.4.7/pppdump/Makefile.linux ppp-2.4.9/pppdump/Makefile.linux --- ppp-2.4.7/pppdump/Makefile.linux 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppdump/Makefile.linux 2021-01-05 00:06:37.000000000 +0100 @@ -1,8 +1,12 @@ +CROSS_COMPILE=@CROSS_COMPILE@ +CC=$(CROSS_COMPILE)@CC@ +COPTS=@CFLAGS@ + DESTDIR = $(INSTROOT)@DESTDIR@ BINDIR = $(DESTDIR)/sbin MANDIR = $(DESTDIR)/share/man/man8 -CFLAGS= -O -I../include/net +CFLAGS = $(COPTS) -I../include/net OBJS = pppdump.o bsd-comp.o deflate.o zlib.o INSTALL= install @@ -10,12 +14,12 @@ all: pppdump pppdump: $(OBJS) - $(CC) -o pppdump $(OBJS) + $(CC) $(LDFLAGS) -o pppdump $(OBJS) clean: rm -f pppdump $(OBJS) *~ install: mkdir -p $(BINDIR) $(MANDIR) - $(INSTALL) -s -c pppdump $(BINDIR) + $(INSTALL) -c pppdump $(BINDIR) $(INSTALL) -c -m 444 pppdump.8 $(MANDIR) diff -Nru ppp-2.4.7/pppdump/ppp-comp.h ppp-2.4.9/pppdump/ppp-comp.h --- ppp-2.4.7/pppdump/ppp-comp.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppdump/ppp-comp.h 2021-01-05 00:06:37.000000000 +0100 @@ -58,21 +58,21 @@ int compress_proto; /* CCP compression protocol number */ /* Allocate space for a decompressor (receive side) */ - void *(*decomp_alloc) __P((u_char *options, int opt_len)); + void *(*decomp_alloc)(u_char *options, int opt_len); /* Free space used by a decompressor */ - void (*decomp_free) __P((void *state)); + void (*decomp_free)(void *state); /* Initialize a decompressor */ - int (*decomp_init) __P((void *state, u_char *options, int opt_len, - int unit, int hdrlen, int mru, int debug)); + int (*decomp_init)(void *state, u_char *options, int opt_len, + int unit, int hdrlen, int mru, int debug); /* Reset a decompressor */ - void (*decomp_reset) __P((void *state)); + void (*decomp_reset)(void *state); /* Decompress a packet. */ - int (*decompress) __P((void *state, u_char *mp, int inlen, - u_char *dmp, int *outlen)); + int (*decompress)(void *state, u_char *mp, int inlen, + u_char *dmp, int *outlen); /* Update state for an incompressible packet received */ - void (*incomp) __P((void *state, u_char *mp, int len)); + void (*incomp)(void *state, u_char *mp, int len); /* Return decompression statistics */ - void (*decomp_stat) __P((void *state, struct compstat *stats)); + void (*decomp_stat)(void *state, struct compstat *stats); }; /* diff -Nru ppp-2.4.7/pppdump/pppdump.8 ppp-2.4.9/pppdump/pppdump.8 --- ppp-2.4.7/pppdump/pppdump.8 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppdump/pppdump.8 2021-01-05 00:06:37.000000000 +0100 @@ -13,6 +13,8 @@ ]] [ .B \-r ] [ +.B \-a +] [ .B \-m \fImru ] [ .I file \fR... @@ -54,6 +56,9 @@ bytes or packets received, and `rcvd' is printed for bytes or packets sent. .TP +.B \-a +Prints absolute times. +.TP .B \-m \fImru Use \fImru\fR as the MRU (maximum receive unit) for both directions of the link when checking for over-length PPP packets (with the \fB\-p\fR diff -Nru ppp-2.4.7/pppdump/pppdump.c ppp-2.4.9/pppdump/pppdump.c --- ppp-2.4.7/pppdump/pppdump.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppdump/pppdump.c 2021-01-05 00:06:37.000000000 +0100 @@ -320,7 +320,7 @@ ++r; ++r; if (endp - r > mru) - printf(" ERROR: length (%d) > MRU (%d)\n", + printf(" ERROR: length (%zd) > MRU (%d)\n", endp - r, mru); if (decompress && fcs == PPP_GOODFCS) { /* See if this is a CCP or compressed packet */ diff -Nru ppp-2.4.7/pppstats/Makefile.linux ppp-2.4.9/pppstats/Makefile.linux --- ppp-2.4.7/pppstats/Makefile.linux 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppstats/Makefile.linux 2021-01-05 00:06:37.000000000 +0100 @@ -1,7 +1,10 @@ # # pppstats makefile -# $Id: Makefile.linux,v 1.9 2006/06/04 05:07:46 paulus Exp $ # +CROSS_COMPILE=@CROSS_COMPILE@ +CC=$(CROSS_COMPILE)@CC@ +COPTS=@CFLAGS@ + DESTDIR = $(INSTROOT)@DESTDIR@ BINDIR = $(DESTDIR)/sbin MANDIR = $(DESTDIR)/share/man/man8 @@ -9,8 +12,6 @@ PPPSTATSRCS = pppstats.c PPPSTATOBJS = pppstats.o -#CC = gcc -COPTS = -O COMPILE_FLAGS = -I../include LIBS = @@ -22,11 +23,11 @@ install: pppstats -mkdir -p $(MANDIR) - $(INSTALL) -s -c pppstats $(BINDIR) + $(INSTALL) -c pppstats $(BINDIR) $(INSTALL) -c -m 444 pppstats.8 $(MANDIR) pppstats: $(PPPSTATSRCS) - $(CC) $(CFLAGS) -o pppstats pppstats.c $(LIBS) + $(CC) $(CFLAGS) $(LDFLAGS) -o pppstats pppstats.c $(LIBS) clean: rm -f pppstats *~ #* core diff -Nru ppp-2.4.7/pppstats/pppstats.8 ppp-2.4.9/pppstats/pppstats.8 --- ppp-2.4.7/pppstats/pppstats.8 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppstats/pppstats.8 2021-01-05 00:06:37.000000000 +0100 @@ -7,6 +7,8 @@ [ .B \-a ] [ +.B \-d +] [ .B \-v ] [ .B \-r @@ -41,6 +43,9 @@ Without this option, the second and subsequent reports show statistics for the time since the last report. .TP +.B \-d +Show data rate (kB/s) instead of bytes. +.TP .B \-c \fIcount Repeat the display .I count diff -Nru ppp-2.4.7/pppstats/pppstats.c ppp-2.4.9/pppstats/pppstats.c --- ppp-2.4.7/pppstats/pppstats.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/pppstats/pppstats.c 2021-01-05 00:06:37.000000000 +0100 @@ -88,7 +88,6 @@ int dflag; /* print data rates, not bytes */ int interval, count; int infinite; -int unit; int s; /* socket or /dev/ppp file descriptor */ int signalled; /* set if alarm goes off "early" */ char *progname; @@ -107,16 +106,16 @@ #define PPP_DRV_NAME "ppp" #endif /* !defined(PPP_DRV_NAME) */ -static void usage __P((void)); -static void catchalarm __P((int)); -static void get_ppp_stats __P((struct ppp_stats *)); -static void get_ppp_cstats __P((struct ppp_comp_stats *)); -static void intpr __P((void)); +static void usage(void); +static void catchalarm(int); +static void get_ppp_stats(struct ppp_stats *); +static void get_ppp_cstats(struct ppp_comp_stats *); +static void intpr(void); -int main __P((int, char *argv[])); +int main(int, char *argv[]); static void -usage() +usage(void) { fprintf(stderr, "Usage: %s [-a|-d] [-v|-r|-z] [-c count] [-w wait] [interface]\n", progname); @@ -128,8 +127,7 @@ * Sets a flag to not wait for the alarm. */ static void -catchalarm(arg) - int arg; +catchalarm(int arg) { signalled = 1; } @@ -137,8 +135,7 @@ #ifndef STREAMS static void -get_ppp_stats(curp) - struct ppp_stats *curp; +get_ppp_stats(struct ppp_stats *curp) { struct ifpppstatsreq req; @@ -150,7 +147,8 @@ #define ifr_name ifr__name #endif - strncpy(req.ifr_name, interface, sizeof(req.ifr_name)); + strncpy(req.ifr_name, interface, IFNAMSIZ); + req.ifr_name[IFNAMSIZ - 1] = 0; if (ioctl(s, SIOCGPPPSTATS, &req) < 0) { fprintf(stderr, "%s: ", progname); if (errno == ENOTTY) @@ -163,8 +161,7 @@ } static void -get_ppp_cstats(csp) - struct ppp_comp_stats *csp; +get_ppp_cstats(struct ppp_comp_stats *csp) { struct ifpppcstatsreq creq; @@ -176,7 +173,8 @@ #define ifr_name ifr__name #endif - strncpy(creq.ifr_name, interface, sizeof(creq.ifr_name)); + strncpy(creq.ifr_name, interface, IFNAMSIZ); + creq.ifr_name[IFNAMSIZ - 1] = 0; if (ioctl(s, SIOCGPPPCSTATS, &creq) < 0) { fprintf(stderr, "%s: ", progname); if (errno == ENOTTY) { @@ -218,9 +216,7 @@ #else /* STREAMS */ int -strioctl(fd, cmd, ptr, ilen, olen) - int fd, cmd, ilen, olen; - char *ptr; +strioctl(int fd, int cmd, char *ptr, int ilen, int olen) { struct strioctl str; @@ -237,8 +233,7 @@ } static void -get_ppp_stats(curp) - struct ppp_stats *curp; +get_ppp_stats(struct ppp_stats *curp) { if (strioctl(s, PPPIO_GETSTAT, curp, 0, sizeof(*curp)) < 0) { fprintf(stderr, "%s: ", progname); @@ -251,8 +246,7 @@ } static void -get_ppp_cstats(csp) - struct ppp_comp_stats *csp; +get_ppp_cstats(struct ppp_comp_stats *csp) { if (strioctl(s, PPPIO_GETCSTAT, csp, 0, sizeof(*csp)) < 0) { fprintf(stderr, "%s: ", progname); @@ -286,7 +280,7 @@ * First line printed is cumulative. */ static void -intpr() +intpr(void) { register int line = 0; sigset_t oldmask, mask; @@ -443,12 +437,11 @@ } int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { int c; #ifdef STREAMS + int unit; char *dev; #endif @@ -506,11 +499,6 @@ if (argc > 0) interface = argv[0]; - if (sscanf(interface, PPP_DRV_NAME "%d", &unit) != 1) { - fprintf(stderr, "%s: invalid interface '%s' specified\n", - progname, interface); - } - #ifndef STREAMS { struct ifreq ifr; @@ -526,7 +514,8 @@ #undef ifr_name #define ifr_name ifr_ifrn.ifrn_name #endif - strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)); + strncpy(ifr.ifr_name, interface, IFNAMSIZ); + ifr.ifr_name[IFNAMSIZ - 1] = 0; if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) { fprintf(stderr, "%s: nonexistent interface '%s' specified\n", progname, interface); @@ -535,6 +524,11 @@ } #else /* STREAMS */ + if (sscanf(interface, PPP_DRV_NAME "%d", &unit) != 1) { + fprintf(stderr, "%s: invalid interface '%s' specified\n", + progname, interface); + } + #ifdef __osf__ dev = "/dev/streams/ppp"; #else diff -Nru ppp-2.4.7/README ppp-2.4.9/README --- ppp-2.4.7/README 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/README 2021-01-05 00:06:37.000000000 +0100 @@ -61,9 +61,74 @@ authenticating itself to you, of course.) -What's new in ppp-2.4.7. +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, diff -Nru ppp-2.4.7/README.eap-tls ppp-2.4.9/README.eap-tls --- ppp-2.4.7/README.eap-tls 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/README.eap-tls 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,229 @@ +EAP-TLS authentication support for PPP +====================================== + +1. Intro + + The Extensible Authentication Protocol (EAP; RFC 3748) is a + security protocol that can be used with PPP. It provides a means + to plug in multiple optional authentication methods. + + Transport Level Security (TLS; RFC 5216) provides for mutual + authentication, integrity-protected ciphersuite negotiation and + key exchange between two endpoints. It also provides for optional + MPPE encryption. + + EAP-TLS (RFC 2716) incapsulates the TLS messages in EAP packets, + allowing TLS mutual authentication to be used as a generic EAP + mechanism. It also provides optional encryption using the MPPE + protocol. + + This patch provide EAP-TLS support to pppd. + This authentication method can be used in both client or server + mode. + +2. Building + + To build pppd with EAP-TLS support, OpenSSL (http://www.openssl.org) + is required. Any version from 0.9.7 should work. + + Configure, compile, and install as usual. + +3. Configuration + + On the client side there are two ways to configure EAP-TLS: + + 1. supply the appropriate 'ca', 'cert' and 'key' command-line parameters + + 2. edit the /etc/ppp/eaptls-client file. + Insert a line for each system with which you use EAP-TLS. + The line is composed of this fields separated by tab: + + - Client name + The name used by the client for authentication, can be * + - Server name + The name of the server, can be * + - Client certificate file + The file containing the certificate chain for the + client in PEM format + - Server certificate file + If you want to specify the certificate that the + server is allowed to use, put the certificate file name. + Else put a dash '-'. + - CA certificate file + The file containing the trusted CA certificates in PEM + format. + - Client private key file + The file containing the client private key in PEM format. + + + On the server side edit the /etc/ppp/eaptls-server file. + Insert a line for each system with which you use EAP-TLS. + The line is composed of this fields separated by tab: + + - Client name + The name used by the client for authentication, can be * + - Server name + The name of the server, can be * + - Client certificate file + If you want to specify the certificate that the + client is allowed to use, put the certificate file name. + Else put a dash '-'. + - Server certificate file + The file containing the certificate chain for the + server in PEM format + - CA certificate file + The file containing the trusted CA certificates in PEM format. + - Client private key file + The file containing the server private key in PEM format. + - addresses + A list of IP addresses the client is allowed to use. + + + OpenSSL engine support is included starting with v0.95 of this patch. + Currently the only engine tested is the 'pkcs11' engine (hardware token + support). To use the 'pksc11' engine: + - Use a special private key fileiname in the /etc/ppp/eaptls-client file: + : + e.g. + pkcs11:123456 + + - The certificate can also be loaded from the 'pkcs11' engine using + a special client certificate filename in the /etc/ppp/eaptls-client file: + : + e.g. + pkcs11:123456 + + - Create an /etc/ppp/openssl.cnf file to load the right OpenSSL engine prior + to starting 'pppd'. A sample openssl.cnf file is + + openssl_conf = openssl_def + + [ openssl_def ] + engines = engine_section + + [ engine_section ] + pkcs11 = pkcs11_section + + [ pkcs11_section ] + engine_id = pkcs11 + dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so + MODULE_PATH = /usr/lib64/libeTPkcs11.so + init = 0 + + - There are two ways to specify a password/PIN for the PKCS11 engine: + - inside the openssl.cnf file using + PIN = your-secret-pin + Note The keyword 'PIN' is case sensitive! + - Using the 'password' in the ppp options file. + From v0.97 of the eap-tls patch the password can also be supplied + using the appropriate 'eaptls_passwd_hook' (see plugins/passprompt.c + for an example). + + +4. Options + + These pppd options are available: + + ca + Use the CA public certificate found in in PEM format + ca-path + Use the directory as the CA public certificate directory + cert + Use the client public certificate found in in PEM format + or in engine:engine_id format + key + Use the client private key found in in PEM format + or in engine:engine_id format + crl + Use the Certificate Revocation List (CRL) file in PEM format. + crl-dir + Use CRL files from directory . It contains CRL files in PEM + format and each file contains a CRL. The files are looked up + by the issuer name hash value. Use the c_rehash utility + to create necessary links. + need-peer-eap + If the peer doesn't ask us to authenticate or doesn't use eap + to authenticate us, disconnect. + 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. + + Note: + password-encrypted certificates can be used as of v0.94 of this + patch. The password for the eap-tls.key file is specified using + the regular + password .... + statement in the ppp options file, or by using the appropriate + plugin which supplies a 'eaptls_passwd_hook' routine. + +5. Connecting + + If you're setting up a pppd server, edit the EAP-TLS configuration file + as written above and then run pppd with the 'auth' option to authenticate + the client. The EAP-TLS method will be used if the other eap methods can't + be used (no secrets). + + If you're setting up a client, edit the configuration file and then run + pppd with 'remotename' option to specify the server name. Add the + 'need-peer-eap' option if you want to be sure the peer ask you to + authenticate (and to use eap) and to disconnect if it doesn't. + +6. Example + + The following example can be used to connect a Linux client with the 'pptp' + package to a Linux server running the 'pptpd' (PoPToP) package. The server + was configured with a certificate with name (CN) 'pptp-server', the client + was configured with a certificate with name (CN) 'pptp-client', both + signed by the same Certificate Authority (CA). + + Server side: + - /etc/pptpd.conf file: + option /etc/ppp/options-pptpd-eaptls + localip 172.16.1.1 + remoteip 172.16.1.10-20 + - /etc/ppp/options-pptpd-eaptls file: + name pptp-server + lock + mtu 1500 + mru 1450 + auth + lcp-echo-failure 3 + lcp-echo-interval 5 + nodeflate + nobsdcomp + nopredictor1 + nopcomp + noaccomp + + require-eap + require-mppe-128 + + crl /home/janjust/ppp/keys/crl.pem + + debug + logfile /tmp/pppd.log + + - /etc/ppp/eaptls-server file: + * pptp-server - /etc/ppp/pptp-server.crt /etc/ppp/ca.crt /etc/ppp/pptp-server.key * + + - On the server, run + pptdp --conf /etc/pptpd.conf + + Client side: + - Run + pppd noauth require-eap require-mppe-128 \ + ipcp-accept-local ipcp-accept-remote noipdefault \ + cert /etc/ppp/keys/pptp-client.crt \ + key /etc/ppp/keys/pptp-client.key \ + ca /etc/ppp/keys/ca.crt \ + name pptp-client remotename pptp-server \ + debug logfile /tmp/pppd.log + pty "pptp pptp-server.example.com --nolaunchpppd" + + Check /var/log/messages and the files /tmp/pppd.log on both sides for debugging info. + +7. Notes + + This is experimental code. + Send suggestions and comments to Jan Just Keijser + diff -Nru ppp-2.4.7/README.pppoe ppp-2.4.9/README.pppoe --- ppp-2.4.7/README.pppoe 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/README.pppoe 2021-01-05 00:06:37.000000000 +0100 @@ -52,7 +52,7 @@ 4. Add the following line to /etc/ppp/options: - plugin rp-pppoe.so + plugin pppoe.so The effect of this line is simply to make "eth0", "eth1", ....,"ethx" all valid device names for pppd (just like ttyS0, diff -Nru ppp-2.4.7/scripts/plog ppp-2.4.9/scripts/plog --- ppp-2.4.7/scripts/plog 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/scripts/plog 2021-01-05 00:06:37.000000000 +0100 @@ -3,5 +3,5 @@ if [ -s /var/log/ppp.log ]; then exec tail "$@" /var/log/ppp.log else - exec tail "$@" /var/log/syslog | grep ' \(pppd\|chat\)\[' + exec grep ' \(pppd\|chat\)\[' /var/log/syslog | tail "$@" fi diff -Nru ppp-2.4.7/scripts/poff ppp-2.4.9/scripts/poff --- ppp-2.4.7/scripts/poff 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/scripts/poff 2021-01-05 00:06:37.000000000 +0100 @@ -91,7 +91,7 @@ fi # There is an argument, so kill the pppd started on that provider. -PID=`ps axw | grep "[ /]pppd call $1" | awk '{print $1}'` +PID=`ps axw | grep "[ /]pppd call $1" | grep -w "$1" | awk '{print $1}'` if test -n "$PID" ; then $KILL -$SIG $PID || { echo "$0: $KILL failed. None ${DONE}." diff -Nru ppp-2.4.7/scripts/secure-card ppp-2.4.9/scripts/secure-card --- ppp-2.4.7/scripts/secure-card 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/scripts/secure-card 2021-01-05 00:06:37.000000000 +0100 @@ -1,4 +1,4 @@ -#!/usr/local/bin/expect -f +#!/usr/bin/expect -f # # This script was written by Jim Isaacson . It is # designed to work as a script to use the SecureCARD(tm) device. This diff -Nru ppp-2.4.7/solaris/ppp_ahdlc.c ppp-2.4.9/solaris/ppp_ahdlc.c --- ppp-2.4.7/solaris/ppp_ahdlc.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/solaris/ppp_ahdlc.c 2021-01-05 00:06:37.000000000 +0100 @@ -109,11 +109,11 @@ MOD_OPEN_DECL(ahdlc_open); MOD_CLOSE_DECL(ahdlc_close); -static int ahdlc_wput __P((queue_t *, mblk_t *)); -static int ahdlc_rput __P((queue_t *, mblk_t *)); -static void ahdlc_encode __P((queue_t *, mblk_t *)); -static void ahdlc_decode __P((queue_t *, mblk_t *)); -static int msg_byte __P((mblk_t *, unsigned int)); +static int ahdlc_wput(queue_t *, mblk_t *); +static int ahdlc_rput(queue_t *, mblk_t *); +static void ahdlc_encode(queue_t *, mblk_t *); +static void ahdlc_decode(queue_t *, mblk_t *); +static int msg_byte(mblk_t *, unsigned int); #if defined(SOL2) /* diff -Nru ppp-2.4.7/solaris/ppp.c ppp-2.4.9/solaris/ppp.c --- ppp-2.4.7/solaris/ppp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/solaris/ppp.c 2021-01-05 00:06:37.000000000 +0100 @@ -31,8 +31,6 @@ * 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. - * - * $Id: ppp.c,v 1.4 2005/06/27 00:59:57 carlsonj Exp $ */ /* @@ -85,12 +83,6 @@ #include /* leave this outside of PRIOQ for htons */ -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif - /* * The IP module may use this SAP value for IP packets. */ @@ -254,45 +246,45 @@ static upperstr_t *ppas = NULL; #ifdef SVR4 -static int pppopen __P((queue_t *, dev_t *, int, int, cred_t *)); -static int pppclose __P((queue_t *, int, cred_t *)); +static int pppopen(queue_t *, dev_t *, int, int, cred_t *); +static int pppclose(queue_t *, int, cred_t *); #else -static int pppopen __P((queue_t *, int, int, int)); -static int pppclose __P((queue_t *, int)); +static int pppopen(queue_t *, int, int, int); +static int pppclose(queue_t *, int); #endif /* SVR4 */ -static int pppurput __P((queue_t *, mblk_t *)); -static int pppuwput __P((queue_t *, mblk_t *)); -static int pppursrv __P((queue_t *)); -static int pppuwsrv __P((queue_t *)); -static int ppplrput __P((queue_t *, mblk_t *)); -static int ppplwput __P((queue_t *, mblk_t *)); -static int ppplrsrv __P((queue_t *)); -static int ppplwsrv __P((queue_t *)); +static int pppurput(queue_t *, mblk_t *); +static int pppuwput(queue_t *, mblk_t *); +static int pppursrv(queue_t *); +static int pppuwsrv(queue_t *); +static int ppplrput(queue_t *, mblk_t *); +static int ppplwput(queue_t *, mblk_t *); +static int ppplrsrv(queue_t *); +static int ppplwsrv(queue_t *); #ifndef NO_DLPI -static void dlpi_request __P((queue_t *, mblk_t *, upperstr_t *)); -static void dlpi_error __P((queue_t *, upperstr_t *, int, int, int)); -static void dlpi_ok __P((queue_t *, int)); +static void dlpi_request(queue_t *, mblk_t *, upperstr_t *); +static void dlpi_error(queue_t *, upperstr_t *, int, int, int); +static void dlpi_ok(queue_t *, int); #endif -static int send_data __P((mblk_t *, upperstr_t *)); -static void new_ppa __P((queue_t *, mblk_t *)); -static void attach_ppa __P((queue_t *, mblk_t *)); +static int send_data(mblk_t *, upperstr_t *); +static void new_ppa(queue_t *, mblk_t *); +static void attach_ppa(queue_t *, mblk_t *); #ifndef NO_DLPI -static void detach_ppa __P((queue_t *, mblk_t *)); +static void detach_ppa(queue_t *, mblk_t *); #endif -static void detach_lower __P((queue_t *, mblk_t *)); -static void debug_dump __P((queue_t *, mblk_t *)); -static upperstr_t *find_dest __P((upperstr_t *, int)); +static void detach_lower(queue_t *, mblk_t *); +static void debug_dump(queue_t *, mblk_t *); +static upperstr_t *find_dest(upperstr_t *, int); #if defined(SOL2) -static upperstr_t *find_promisc __P((upperstr_t *, int)); -static mblk_t *prepend_ether __P((upperstr_t *, mblk_t *, int)); -static mblk_t *prepend_udind __P((upperstr_t *, mblk_t *, int)); -static void promisc_sendup __P((upperstr_t *, mblk_t *, int, int)); +static upperstr_t *find_promisc(upperstr_t *, int); +static mblk_t *prepend_ether(upperstr_t *, mblk_t *, int); +static mblk_t *prepend_udind(upperstr_t *, mblk_t *, int); +static void promisc_sendup(upperstr_t *, mblk_t *, int, int); #endif /* defined(SOL2) */ -static int putctl2 __P((queue_t *, int, int, int)); -static int putctl4 __P((queue_t *, int, int, int)); -static int pass_packet __P((upperstr_t *ppa, mblk_t *mp, int outbound)); +static int putctl2(queue_t *, int, int, int); +static int putctl4(queue_t *, int, int, int); +static int pass_packet(upperstr_t *ppa, mblk_t *mp, int outbound); #ifdef FILTER_PACKETS -static int ip_hard_filter __P((upperstr_t *ppa, mblk_t *mp, int outbound)); +static int ip_hard_filter(upperstr_t *ppa, mblk_t *mp, int outbound); #endif /* FILTER_PACKETS */ #define PPP_ID 0xb1a6 diff -Nru ppp-2.4.7/solaris/ppp_comp.c ppp-2.4.9/solaris/ppp_comp.c --- ppp-2.4.7/solaris/ppp_comp.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/solaris/ppp_comp.c 2021-01-05 00:06:37.000000000 +0100 @@ -74,12 +74,12 @@ MOD_OPEN_DECL(ppp_comp_open); MOD_CLOSE_DECL(ppp_comp_close); -static int ppp_comp_rput __P((queue_t *, mblk_t *)); -static int ppp_comp_rsrv __P((queue_t *)); -static int ppp_comp_wput __P((queue_t *, mblk_t *)); -static int ppp_comp_wsrv __P((queue_t *)); -static void ppp_comp_ccp __P((queue_t *, mblk_t *, int)); -static int msg_byte __P((mblk_t *, unsigned int)); +static int ppp_comp_rput(queue_t *, mblk_t *); +static int ppp_comp_rsrv(queue_t *); +static int ppp_comp_wput(queue_t *, mblk_t *); +static int ppp_comp_wsrv(queue_t *); +static void ppp_comp_ccp(queue_t *, mblk_t *, int); +static int msg_byte(mblk_t *, unsigned int); /* Extract byte i of message mp. */ #define MSG_BYTE(mp, i) ((i) < (mp)->b_wptr - (mp)->b_rptr? (mp)->b_rptr[i]: \ @@ -118,7 +118,7 @@ #ifdef __osf__ -static void ppp_comp_alloc __P((comp_state_t *)); +static void ppp_comp_alloc(comp_state_t *); typedef struct memreq { unsigned char comp_opts[20]; int cmd; diff -Nru ppp-2.4.7/solaris/ppp_mod.c ppp-2.4.9/solaris/ppp_mod.c --- ppp-2.4.7/solaris/ppp_mod.c 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/solaris/ppp_mod.c 2021-01-05 00:06:37.000000000 +0100 @@ -47,16 +47,10 @@ #include #include -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif - -static int ppp_identify __P((dev_info_t *)); -static int ppp_attach __P((dev_info_t *, ddi_attach_cmd_t)); -static int ppp_detach __P((dev_info_t *, ddi_detach_cmd_t)); -static int ppp_devinfo __P((dev_info_t *, ddi_info_cmd_t, void *, void **)); +static int ppp_identify(dev_info_t *); +static int ppp_attach(dev_info_t *, ddi_attach_cmd_t); +static int ppp_detach(dev_info_t *, ddi_detach_cmd_t); +static int ppp_devinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); extern struct streamtab pppinfo; extern krwlock_t ppp_lower_lock; diff -Nru ppp-2.4.7/solaris/ppp_mod.h ppp-2.4.9/solaris/ppp_mod.h --- ppp-2.4.7/solaris/ppp_mod.h 2014-08-09 14:31:39.000000000 +0200 +++ ppp-2.4.9/solaris/ppp_mod.h 2021-01-05 00:06:37.000000000 +0100 @@ -143,10 +143,10 @@ */ #ifdef SVR4 #define MOD_OPEN_DECL(name) \ -static int name __P((queue_t *, dev_t *, int, int, cred_t *)) +static int name(queue_t *, dev_t *, int, int, cred_t *) #define MOD_CLOSE_DECL(name) \ -static int name __P((queue_t *, int, cred_t *)) +static int name(queue_t *, int, cred_t *) #define MOD_OPEN(name) \ static int name(q, devp, flag, sflag, credp) \ @@ -168,10 +168,10 @@ #else /* not SVR4 */ #define MOD_OPEN_DECL(name) \ -static int name __P((queue_t *, int, int, int)) +static int name(queue_t *, int, int, int) #define MOD_CLOSE_DECL(name) \ -static int name __P((queue_t *, int)) +static int name(queue_t *, int) #define MOD_OPEN(name) \ static int name(q, dev, flag, sflag) \ diff -Nru ppp-2.4.7/Submitting-patches.md ppp-2.4.9/Submitting-patches.md --- ppp-2.4.7/Submitting-patches.md 1970-01-01 01:00:00.000000000 +0100 +++ ppp-2.4.9/Submitting-patches.md 2021-01-05 00:06:37.000000000 +0100 @@ -0,0 +1,105 @@ +How to contribute patches to the PPP project. +============================================= + +The PPP project source code is maintained in a Git repository, which +is publicly available at + +git://git.ozlabs.org/~paulus/ppp.git + +and + +https://github.com/paulusmack/ppp.git + +The linux-ppp@vger.kernel.org mailing list is a suitable place to +discuss issues relating to the PPP code and to post patches. + +Although there is a copy of the repository on github.com, the PPP +project is not a "github project", in the sense that the development +of the code does not depend on github infrastructure. In particular, +patch descriptions should be understandable without reference to any +github.com web page. Thus, patches or commits whose description +consists only of something like "Closes #123" will be rejected. See +below for the minimum standards for patch descriptions. + +There are two ways in which patches can be submitted for review: + +1. Post the patch on the linux-ppp@vger.kernel.org mailing list. This + is my preferred way to receive patches, because it provides more + opportunity for other interested people to review the patches. + +2. Create a pull request on github.com. However, please don't make + the mistake of creating a commit with a minimal commit message and + then explaining the rationale for the change in the pull request. + Put the rationale in the commit message. + +Requirements for patch/commit description +----------------------------------------- + +The description on a patch, which becomes the commit message in the +resulting commit, should describe the reason why the change is being +made. If it fixes a bug, it should describe the bug in enough detail +for the reader to understand why and how the change being made fixes +the bug. If it adds a feature, it should describe the feature and how +it might be used and why it would be desirable to have the feature. + +Normally the patch description should be a few paragraphs in length -- +it can be longer for a really subtle bug or complex feature, or +shorter for obvious or trivial changes such as fixing spelling +mistakes. + +The first line of the commit message is the "headline", corresponding +to the subject line of an emailed patch. If the patch is concerned +with one particular area of the package, it is helpful to put that at +the beginning, followed by a colon (':'), for example, "pppd: Fix bug +in vslprintf". The remainder of the headline should be a sentence and +should start with a capital letter. + +Note that as maintainer I will edit the headline or the commit message +if necessary to make it clearer or to fix spelling or grammatical +errors. For a github pull request I may cherry-pick the commits and +modify their commit messages. + +References to information on web sites are permitted provided that the +full URL is given, and that reference to the web site is not essential +for understanding the change being made. For example, you can refer +to a github issue provided that you also put the essential details of +the issue in the commit message, and put the full URL for the issue, +not just the issue number. + +Signoff +------- + +In order to forestall possible (though unlikely) future legal +problems, this project requires a "Signed-off-by" line on all +non-trivial patches, with a real name (not just initials, and no +pseudonyms). Signing off indicates that you certify that your patch +meets the 'Developer's Certificate of Origin' below (taken from the +DCO 1.1 in the Linux kernel source tree). + +Developer's Certificate of Origin +--------------------------------- + +By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +