pali [Mon, 7 Jun 2021 11:11:43 +0000 (13:11 +0200)]
pppd: Set restore_term at correct place (#284)
After successful call to tcsetattr/TCSAFLUSH it is needed to restore
terminal at the end. So set restore_term variable at correct place. Fixes
issue that fatal() call after tcsetattr/TCSAFLUSH does not restore terminal
settings.
pali [Sat, 5 Jun 2021 01:43:24 +0000 (03:43 +0200)]
pppd: Add support for arbitrary baud rates via BOTHER on Linux (#278)
Most Linux architectures and drivers support arbitrary baud rate BOTHER
values via TCGETS2 and TCSETS2 ioctls in struct termios2.
This patch implements support for BOTHER and struct termios2 which allows
pppd to use any baud rate on Linux systems where architecture and drivers
have support for it.
By default standard values are used.
Support for BOTHER is enabled during compilation when header files have
appropriate definitions of TCGETS2 and TCSETS2 ioctls.
Because there is no glibc support for BOTHER and struct termios2 yet, pppd
defines own BOTHER macro and struct termios2.
pppd: Expose the MPPE keys generated through an API (#267)
The lengthy part of this fix is to refactor the handling of MPPE keys
by moving it into mppe.c and thus reducing the clutter in chap_ms.c.
It does so by renaming the mppe_set_keys/2 to the corresponding
mppe_set_chapv1/mppe_set_chapv2 versions and updates callers of these
functions.
Having done so, it conveniently allows the name "mppe_set_keys" to be
re-used for this new purpose which will copy the key material up to
its size and then clear the input parameters (avoids leaving the MPPE
keys on the stack).
Additional functiions added to the MPPE code allow plugins et al. to
access the MPPE keys, clear the keys, and check if they are set. All
plugin and CCP code has been updated to use this API.
This adds pppd.pc into $(INSTROOT)/$(LIBDIR)/pkgconfig. On some distributions
this would be /lib/pkgconfig, or /usr/lib/pkgconfig, but other distributions
may consider specifying --libdir=/usr/lib/x86_x64-linux-gnu/ and the pkgconfig
directory would be under that. Allowing --libdir to be specified at configure
time fixes #223, providing pkgconfig support fixes #19 and allows third party
packages pickup the plugin directory.
Manually cherry picking parts of two commits by @lkundrak from:
https://github.com/NetworkManager/ppp/tree/lr/pkgconfig
Mainly, the difference between the original commit is not to replace DESTDIR
with "prefix". Leave DESTDIR alone, and add needed pkgconfig (pppd.pc.in)
as a part of the linux distribution (previously in pppd/plugin directory).
Eivind Næss [Sun, 14 Mar 2021 23:20:29 +0000 (16:20 -0700)]
pppd: Fix logical error in comparing valid encryption policies (#262)
RFC2548 describes the proper values of the MS-MPPE-Encryption-Policy attribute.
and it can only hold 2 values: 1 (encryption allowed) and 2 (encryption required).
See
https://tools.ietf.org/html/rfc2548, section 2.4.4
The correct comparison should be made with an && and not a ||.
Eivind Næss [Sun, 14 Mar 2021 23:17:41 +0000 (16:17 -0700)]
pppd: EAP-TLS: Verify Subject or CommonName by suffix (#261)
This feature matches closely what OpenVPN and the network-manager-openvpn plugin do for
certificate verification. It allows the end user to configure the certificate to be matched by
its common name (entire string), its subject name, or the suffix of a subject name.
The latter is especially useful if you are trying to match against a random server in a RADIUS
pool. Lastly, it also allows you to turn off the certificate matching altogether.
tls-verify-method can have the following parameter values:
- none
- subject - The entire subject, e.g. /CN=some.server.org
- name - The entire common name, e.g. some.server.org
- suffix - The latter part of a name, e.g. servers.org
Secondly, it also introduces a new parameter 'tls-verify-key-usage' which permits checking
of the 'server' or 'client' side attributes of nsCertType and X509 extended key attributes.
For example, in client mode, it will verify that received certificate has the 'server' side
attributes enabled.
10ne1 [Sun, 14 Mar 2021 23:11:35 +0000 (01:11 +0200)]
pppd: Fix cross-compilation using Clang (#253)
Clang does not have the --print-sysroot option so the shell
snippet silently fails leading to "-I/usr/include/openssl".
Thankfully systems like Gentoo/portage or Yocto/bitbake enable
sysroot poisoning precisely to catch these kinds of bugs.
There is only one user of this non-standard CFLAG include in
pppcrypt.h, so make it consistent with the rest of the sources
(eg. see eap-tls.[h|c] openssl/* includes) and drop the fragile
sysroot hackery.
Signed-off-by: Adrian Ratiu <adrian.ratiu@collabora.com>
pali [Fri, 26 Feb 2021 04:44:19 +0000 (05:44 +0100)]
pppd: defaultroute6 is not frequent option and should not be used (#257)
In pppd.8 manpage, move defaultroute6 option from FREQUENTLY USED OPTIONS
into OPTIONS, and add a warning that this option should not be needed or
used on IPv6 networks. Option defaultroute6 is needed only for broken IPv6
networks. Also add nodefaultroute6 into sample options file.
Pali Rohár [Sat, 16 Jan 2021 21:50:27 +0000 (22:50 +0100)]
pppd: Define request and response rtnetlink IPv6 structures
This simplify understanding of rtnetlink IPv6 API. Also it simplify
code for filling rtnetlink IPv6 address request message and reading
rtnetlink response message as it avoids usage of pointer arithmetic.
Pali Rohár [Sun, 10 Jan 2021 18:46:07 +0000 (19:46 +0100)]
pppd: Set local and remote IPv6 addresses by one call
Currently local IPv6 address is set by SIOCSIFADDR ioctl and remote peer
address is appended by rtnetlink RTM_NEWADDR/NLM_F_REPLACE call. For
RTM_NEWADDR/NLM_F_REPLACE call it is needed to specify both local + remote
addresses as local address is used for matching to which address needs to
be remote peer address appended. When issuing this call kernel first
removes currently configured local address and then inserts a new pair of
local + remote addresses.
Simplify whole setup by just one rtnetlink RTM_NEWADDR/NLM_F_CREATE call by
inserting pair of local + remote addresses atomically. Therefore calling
SIOCSIFADDR ioctl for local IPv6 address is not used or needed anymore.
Pali Rohár [Sun, 10 Jan 2021 18:09:25 +0000 (19:09 +0100)]
pppd: Disable Duplicate Address Detection for IPv6 peer address
IPv6 link-local addresses are negotiated via IPV6CP and therefore are
unique and not duplicate. Doing additional Duplicate Address Detection
is redundant and not needed, so disable it.
pali [Mon, 15 Feb 2021 06:54:01 +0000 (07:54 +0100)]
pppd: Fix compilation with older glibc or kernel headers (#248)
glibc versions prior to 2.24 do not define SOL_NETLINK and linux kernel
versions prior to 4.3 do not define NETLINK_CAP_ACK. So add fallback
definitions for these macros into pppd/sys-linux.c file.
Also extend description why we call SOL_NETLINK/NETLINK_CAP_ACK option.
pali [Tue, 26 Jan 2021 02:58:45 +0000 (03:58 +0100)]
ipv6cp: Fix ipv6cp-use-persistent option when remote address is specified (#246)
Option ipv6cp-use-persistent affects only local interface identifier (local
link-local address). It does not affects remote peer interface identifier
(and remote link-local address) therefore ipv6cp-use-persistent option
should not depend on remote address.
pali [Tue, 26 Jan 2021 02:55:25 +0000 (03:55 +0100)]
pppd: Negotiate IP address when only peer addresses are provided (#236)
This fixes special case when both ppp ends are configured to send only IP
address of other side and do not send its own IP address. Such setup is
correct because both ends can exchange its IP addresses and therefore they
have full information, they known both local and remote address.
This issue can be triggered by calling pppd with arguments:
pali [Tue, 26 Jan 2021 02:53:59 +0000 (03:53 +0100)]
pppd: Fix enforcing peer IP address (#235)
If peer address is specified and ipcp-accept-remote is not set then peer
address is enforced.
But there is bug in pppd which allows peer to not use supplied address when
it reply with empty IPCP ConfReq. In this case pppd thinks that peer
accepted its idea of remote/peer address even it is not truth.
This issue can be reproduced by running pppd with arguments:
Which means that first pppd force usage of address 10.1.0.1 for peer and
second pppd (peer) wants to use only address 10.0.0.1 for itself.
First pppd see this communication
rcvd [IPCP ConfReq id=0x64 <addr 10.0.0.1>]
sent [IPCP ConfNak id=0x64 <addr 10.1.0.1>]
rcvd [IPCP ConfReq id=0x65]
sent [IPCP ConfAck id=0x65]
local IP address 10.0.0.2
remote IP address 10.1.0.1
and thinks that peer (second pppd) accepted its idea of remote/peer
address.
After applying this patch first pppd correctly detects that peer refused
its proposed peer address and therefore close connection.
rcvd [IPCP ConfReq id=0x64 <addr 10.0.0.1>]
sent [IPCP ConfNak id=0x64 <addr 10.1.0.1>]
rcvd [IPCP ConfReq id=0x65]
sent [IPCP ConfAck id=0x65]
Peer refused to agree to his IP address
Connect time 0.0 minutes.
Sent 1024 bytes, received 1018 bytes.
sent [IPCP TermReq id=0x3 "Refused his IP address"]
pali [Tue, 26 Jan 2021 02:52:22 +0000 (03:52 +0100)]
pppd: Fix demand mode with noremoteip option (#232)
When noremoteip is set then initial hisaddr (peer address) is zero. So to
handle setting correct peer address after establishing connection it is
needed to change logic around 'wo->hisaddr != 0' condition. wo->hisaddr
needs to be updated from initial zero address to correct peer address.
Without this patch first pppd receives 10.0.0.1 address from second pppd
even second pppd is configured to not send its IP address.
rcvd [LCP ConfReq id=0x1 <magic 0x7cf29fab>]
sent [LCP ConfReq id=0x1 <magic 0x4550b00c>]
sent [LCP ConfAck id=0x1 <magic 0x7cf29fab>]
rcvd [LCP ConfAck id=0x1 <magic 0x4550b00c>]
sent [LCP EchoReq id=0x0 magic=0x4550b00c]
sent [IPCP ConfReq id=0x1 <addr 0.0.0.0>]
rcvd [LCP EchoReq id=0x0 magic=0x7cf29fab]
sent [LCP EchoRep id=0x0 magic=0x4550b00c]
rcvd [IPCP ConfReq id=0x1]
sent [IPCP ConfNak id=0x1 <addr 0.0.0.0>]
rcvd [LCP EchoRep id=0x0 magic=0x7cf29fab]
rcvd [IPCP ConfNak id=0x1 <addr 10.0.0.2>]
sent [IPCP ConfReq id=0x2 <addr 10.0.0.2>]
rcvd [IPCP ConfReq id=0x2 <addr 10.0.0.1>]
sent [IPCP ConfAck id=0x2 <addr 10.0.0.1>]
rcvd [IPCP ConfAck id=0x2 <addr 10.0.0.2>]
local IP address 10.0.0.2
remote IP address 10.0.0.1
After applying this patch first pppd does not receive remote 10.0.0.1
address anymore which can be seen by the fact that first pppd cannot
determinate remote IP address and defaulting to 10.64.64.64.
rcvd [LCP ConfReq id=0x1 <magic 0x1da305a6>]
sent [LCP ConfReq id=0x1 <magic 0x2d76359>]
sent [LCP ConfAck id=0x1 <magic 0x1da305a6>]
rcvd [LCP ConfAck id=0x1 <magic 0x2d76359>]
sent [LCP EchoReq id=0x0 magic=0x2d76359]
sent [IPCP ConfReq id=0x1 <addr 0.0.0.0>]
rcvd [LCP EchoReq id=0x0 magic=0x1da305a6]
sent [LCP EchoRep id=0x0 magic=0x2d76359]
rcvd [IPCP ConfReq id=0x1]
sent [IPCP ConfNak id=0x1 <addr 0.0.0.0>]
rcvd [LCP EchoRep id=0x0 magic=0x1da305a6]
rcvd [IPCP ConfNak id=0x1 <addr 10.0.0.2>]
sent [IPCP ConfReq id=0x2 <addr 10.0.0.2>]
rcvd [IPCP ConfReq id=0x2]
sent [IPCP ConfAck id=0x2]
rcvd [IPCP ConfAck id=0x2 <addr 10.0.0.2>]
Could not determine remote IP address: defaulting to 10.64.64.64
local IP address 10.0.0.2
remote IP address 10.64.64.64
Pali Rohár [Sat, 9 Jan 2021 13:37:00 +0000 (14:37 +0100)]
ipv6cp: Allow to use demand mode without specifying IPv6 address/identifier
Support is similar as in IPv4, pppd generates random temporary identifier
for LL address and after connection is established then LL address is
changed to the real one.
Richard Purdie [Fri, 8 Jan 2021 01:41:42 +0000 (01:41 +0000)]
pppd/Makefile.linux: Fix reproducibility issue with differing make versions (#234)
We were seeing reproducibility issues where one host would use the internal
logwtmp wrapper, another would use the one in libutil. The issue was that in
some cases the "\#include" was making it to CC, in others, "#include". The
issue seems to be related to shell escaping.
pppd: Refactor eap MSCHAPv2 using chap_find_digest
Remove code duplication from eap.c related to eap MSCHAPv2 (server)
implementation.
The chap_find_digest function - introduced in [1] - exposes the
registered CHAP digests type definitions, providing functions to
generate a challenge and verify a response, among others.
Eivind Næss [Mon, 4 Jan 2021 01:34:34 +0000 (17:34 -0800)]
pppd: Add support for EAP-MSCHAPv2 (client side) (#211)
* Adding EAP-MSCHAPv2 support #175
Implementation based on the RFC: draft-kamath-pppext-eap-mschapv2-02.
Adding support for MSCHAPv2 inside extensible authentication protocol (EAP).
Signed-off-by: Thomas Omerzu <thomas@omerzu.de>
* Removing empty "TODO" in comment section
Signed-off-by: Eivind Naess <eivnaes@yahoo.com>
* Add support for EAP-MSCHAPv2 #138
Rewrote the original patch to use the chap-new.c API for caching request/responses. Also incorporate feedback from @paulusmack for input validation and function signatures.
pali [Sun, 3 Jan 2021 23:01:44 +0000 (00:01 +0100)]
pppd: Fix setting IPv6 peer address (#212)
On Linux IPv6 peer address cannot be set via SIOCSIFDSTADDR ioctl like it
is for IPv4 peer address. Linux kernel does not support SIOCSIFDSTADDR for
AF_INET6 PPP interfaces.
The only way how to set IPv6 peer address on Linux is via kernel netlink
interface which is just a little bit complicated compared to one ioctl
call.
Linux kernel for a long time automatically adds IPv6 peer address from
interface into route table so it is not needed to explicitly set routing
for remote peer address. pppd already does not do it for kernel versions
newer than 2.1.16. So the same check is used also for IPv6 peer route
address.
Prior this patch ppp interface was configured as:
$ ip -6 address show dev ppp0
2: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 state UNKNOWN qlen 3
inet6 fe80::2/128 scope link
valid_lft forever preferred_lft forever
$ ip -6 route show dev ppp0
fe80::1 metric 1 pref medium
fe80::2 proto kernel metric 256 pref medium
And after applying this patch as:
$ ip -6 address show dev ppp0
2: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 state UNKNOWN qlen 3
inet6 fe80::2 peer fe80::1/128 scope link
valid_lft forever preferred_lft forever
$ ip -6 route show dev ppp0
fe80::1 proto kernel metric 256 pref medium
fe80::2 proto kernel metric 256 pref medium
As can be seen IPv6 peer address is now correctly set on the interface and
also kernel correctly fill route table for IPv6 peer address.
Please note that old ifconfig utility cannot show nor change IPv6 peer
address. Peer address is supported only for IPv4 addresses as opposite of
the local addresses where both IPv4 and IPv6 are supported. It is because
old ifconfig utility is also using ioctl interface which cannot handle it.
Therefore for any testing it is really required ip utility or other utility
with netlink interface (and not ioctl interface).
Samuel Thibault [Sat, 2 Jan 2021 03:25:48 +0000 (04:25 +0100)]
pppd: Add replacedefaultroute option (#200)
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.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> Co-authored-by: Chris Boot <bootc@debian.org>
pali [Fri, 1 Jan 2021 08:58:02 +0000 (09:58 +0100)]
pppd: Fix ether_to_eui64() to prefer devnam ether interface (#206)
In case of PPPoE connection, devnam is ethernet interface. So in this case
calculate EUI-64 IPV6CP identifier from the PPPoE ethernet interface
instead from the first ethernet interface in the system.
This would ensure that each PPPoE connection would have unique IPv6 link
local address calculated from the interface MAC address on which is PPPoE
going to be established.
Currently IPv6 link local address is always calculated from the MAC address
of the first ethernet interface and therefore all active PPPoE connections
have by default same (non unique) IPv6 link local address.
These get propagated to the Makefiles in the subdirectories. The
cross-compile prefix is prepended to the CC value, so for example
if you do "./configure --cross_compile=powerpc64le-linux-" then
everything gets compiled and linked using powerpc64le-linux-cc.
Paul Mackerras [Fri, 1 Jan 2021 00:26:48 +0000 (11:26 +1100)]
pppd: Use a run-time test to detect libutil availability on Linux
This tests whether logwtmp is declared in <utmp.h>, and if not we
assume we need to include our own logwtmp implementation. We assume
that if logwtmp is provided by the system then we need -lutil to get
it (as is the case for glibc).
This fixes compilation with musl libc and other libcs that don't
provide logwtmp.
Pali Rohár [Thu, 31 Dec 2020 17:49:27 +0000 (18:49 +0100)]
Make a consistency in pppoe options
Remove 'rp_' prefix from all pppoe options and ensure that pppoe options
have 'pppoe-' prefix. Also change underlines to dashes to be consistent
with other pppd options.
To not break a backward compatibility ensure that old option names still
work via (legacy) aliases.
Now when get_first_ethernet() is implemented for both Linux and Solaris,
implementation of ether_to_eui64() function can use this function
get_first_ethernet() and therefore be system independent.
So change implementation of ether_to_eui64() to use get_first_ethernet()
function and move it from Linux and Solaris files to common ipv6cp.c file
where it is used.
Pali Rohár [Thu, 31 Dec 2020 17:46:01 +0000 (18:46 +0100)]
Rename rp-pppoe.so plugin to pppoe.so
Original out-of-tree rp-pppoe plugin for pppd software is still available
at website https://dianne.skoll.ca/projects/rp-pppoe/ and receives new
releases. The last update is from the June 2020.
Currently it is ambiguous if user is using original out-of-tree rp-pppoe
plugin or in-tree pppd's rp-pppoe plugin. These two plugins are different,
come from different sources but share same name.
Some users want to use original rp-pppoe plugin and not pppd's in-tree
rp-pppoe plugin. Also some distribution want to package both plugins,
pppd's in-tree and original rp-pppoe.
So for this reason and also because all other PPP over <something> plugins
have just pppo prefix, rename in-tree rp-pppoe.so plugin to just pppoe.so.
This will allow to distinguish and make it clear what is the original
rp-pppoe plugin and what is pppd's in-tree pppoe plugin.
When installing pppd create a compatibility symlink from pppoe.so to
rp-pppoe.so so nothing would be broken. This compatibility symlink may be
removed by Linux distribution which do not want to have compatibility with
the old name as before and rather use rp-pppoe.so name for original
rp-pppoe software.
Samuel Thibault [Thu, 31 Dec 2020 05:35:24 +0000 (06:35 +0100)]
pppd: Use a compile test to detect crypt.h (#198)
ppp checks header for existence of crypt.h looking it up in /usr/include.
That's incompatible with non-glibcs or a glibc with multiarch headers
(https://bugs.debian.org/798955). This patch replaces the file existence
test with a compile test.
Reviewed-by: Chris Boot <bootc@debian.org> Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> Co-authored-by: Helmut Grohne <helmut@subdivi.de>
cc -o pppdump pppdump.o deflate.o bsd-comp.o -lz
/usr/bin/ld: deflate.o: in function `z_incomp':
deflate.c:(.text+0x99): undefined reference to `inflateIncomp'
/usr/bin/ld: deflate.o: in function `z_decomp_alloc':
deflate.c:(.text+0x355): undefined reference to `inflateInit2'
collect2: error: ld returned 1 exit status
make[1]: *** [Makefile:38: pppdump] Error 1
The copy of zlib here is not the same as the standard upstream zlib;
this version has some extra functions added.
Samuel Thibault [Thu, 31 Dec 2020 04:30:58 +0000 (05:30 +0100)]
pppd: Make sure that the linkpidfile is always created (#185)
From https://bugs.debian.org/284382
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.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> Co-authored-by: Herbert Xu <herbert@gondor.apana.org.au>
Samuel Thibault [Thu, 31 Dec 2020 04:28:19 +0000 (05:28 +0100)]
pppd: Be sure to close /dev/ppp when reconnecting (#184)
From https://bugs.debian.org/306261
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.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> Co-authored-by: Simon Peter <dn.tlp@gmx.net>
This implements EAP-MSCHAPv2 as specified by
draft-kamath-pppext-eap-mschapv2-02 [1] in server mode (as the client
mode is already proposed by Thomas [2]).
The flow is camparable to MD5-Challenge, with some additional steps for
confirmation:
* Client sends an EAP request
* Server answers with MD5-Challenge
* Client Naks and requests MSCHAPv2
* Server answers with MSCHAPv2-Challenge
* Client answers with MSCHAPv2-Response
* Server answers with MSCHAPv2-{Success/Failure}
* Client possibly confirms MSCHAPv2-{Success/Failure}
I reused as much as possible from pppd/chap-new.c and pppd/chap_ms.c,
but most of the implementation is protected by static functions.
Therefore eap_chapms2_verify_response is an exact copy of
chapms2_verify_response, likewise for eap_chap_verify which is an exact
copy of chap_verify_response. This is not optimal and subject for
improvement.
By using a chap_digest_type struct/object with validator
(verify_response), validation is compatible with other (external)
plugins that have a specific CHAP implementation exposed in the
chap_verify_hook (like radius, windbind, ...).
Changes in eap.h are identical to [2], except for the additional
eapMSCHAPv2Chall server state.
Duncan Sands [Wed, 30 Dec 2020 11:22:50 +0000 (12:22 +0100)]
Fix pppoatm plugin for pppd to accept a wildcard argument for an ATM device
From https://bugs.debian.org/376990
This becomes an issue when using a USB ADSL modem (e.g. Alcatel Speedtouch)
and the USB host controller disconnects the modem, then later re-connects it
with a new USB address and consequently a new ATM device number.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>