Merge pull request #101 from vyos/if-renaming-clean
authorPaul Mackerras <paulus@ozlabs.org>
Wed, 30 Dec 2020 09:27:07 +0000 (20:27 +1100)
committerGitHub <noreply@github.com>
Wed, 30 Dec 2020 09:27:07 +0000 (20:27 +1100)
Support for interface renaming by pre-up scripts

110 files changed:
README
README.eap-tls [new file with mode: 0644]
Submitting-patches.md [new file with mode: 0644]
chat/Makefile.linux
chat/chat.c
etc.ppp/eaptls-client [new file with mode: 0644]
etc.ppp/eaptls-server [new file with mode: 0644]
etc.ppp/openssl.cnf [new file with mode: 0644]
include/linux/ppp_defs.h
include/net/if_ppp.h
include/net/ppp-comp.h
include/net/ppp_defs.h
include/net/slcompress.h
include/net/vjcompress.h
linux/Makefile.top
modules/bsd-comp.c
modules/deflate.c
modules/if_ppp.c
modules/ppp.c
modules/ppp_ahdlc.c
modules/ppp_comp.c
modules/ppp_mod.h
pppd/Makefile.linux
pppd/Makefile.sol2
pppd/auth.c
pppd/cbcp.c
pppd/ccp.c
pppd/chap-new.c
pppd/chap_ms.c
pppd/chap_ms.h
pppd/demand.c
pppd/eap-tls.c [new file with mode: 0644]
pppd/eap-tls.h [new file with mode: 0644]
pppd/eap.c
pppd/eap.h
pppd/ecp.c
pppd/eui64.c
pppd/eui64.h
pppd/fsm.c
pppd/fsm.h
pppd/ipcp.c
pppd/ipcp.h
pppd/ipv6cp.c
pppd/ipv6cp.h
pppd/ipxcp.c
pppd/ipxcp.h
pppd/lcp.c
pppd/lcp.h
pppd/magic.c
pppd/magic.h
pppd/main.c
pppd/md4.c
pppd/md4.h
pppd/md5.c
pppd/multilink.c
pppd/options.c
pppd/patchlevel.h
pppd/pathnames.h
pppd/plugins/Makefile.linux
pppd/plugins/passprompt.c
pppd/plugins/passwordfd.c
pppd/plugins/pppoatm/Makefile.linux
pppd/plugins/pppol2tp/Makefile.linux
pppd/plugins/pppol2tp/openl2tp.c
pppd/plugins/pppol2tp/pppol2tp.c
pppd/plugins/radius/Makefile.linux
pppd/plugins/radius/avpair.c
pppd/plugins/radius/buildreq.c
pppd/plugins/radius/clientid.c
pppd/plugins/radius/config.c
pppd/plugins/radius/radius.c
pppd/plugins/radius/radiusclient.h
pppd/plugins/radius/radrealms.c
pppd/plugins/radius/sendserver.c
pppd/plugins/radius/util.c
pppd/plugins/rp-pppoe/Makefile.linux
pppd/plugins/rp-pppoe/common.c
pppd/plugins/rp-pppoe/config.h
pppd/plugins/rp-pppoe/discovery.c
pppd/plugins/rp-pppoe/if.c
pppd/plugins/rp-pppoe/plugin.c
pppd/plugins/rp-pppoe/pppoe-discovery.c
pppd/plugins/rp-pppoe/pppoe.h
pppd/plugins/winbind.c
pppd/pppcrypt.c
pppd/pppcrypt.h
pppd/pppd.8
pppd/pppd.h
pppd/session.c
pppd/sha1.c
pppd/sys-linux.c
pppd/sys-solaris.c
pppd/tty.c
pppd/upap.c
pppd/upap.h
pppd/utils.c
pppdump/Makefile.linux
pppdump/bsd-comp.c
pppdump/deflate.c
pppdump/ppp-comp.h
pppdump/pppdump.8
pppdump/pppdump.c
pppstats/Makefile.linux
pppstats/pppstats.8
pppstats/pppstats.c
solaris/ppp.c
solaris/ppp_ahdlc.c
solaris/ppp_comp.c
solaris/ppp_mod.c
solaris/ppp_mod.h

diff --git a/README b/README
index a21d9f1dac7bfa143a5fcd334d324edbd76b3864..b25d06db325a8abcea3efd8be633e7b6d076e715 100644 (file)
--- a/README
+++ b/README
@@ -61,9 +61,33 @@ use any IP address.  (This only applies where the peer is
 authenticating itself to you, of course.)
 
 
-What's new in ppp-2.4.7.
+What's 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 --git a/README.eap-tls b/README.eap-tls
new file mode 100644 (file)
index 0000000..ab3794e
--- /dev/null
@@ -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:
+          <engine>:<identifier>
+        e.g.
+          pkcs11:123456
+
+      - The certificate can also be loaded from the 'pkcs11' engine using
+        a special client certificate filename in the /etc/ppp/eaptls-client file:
+          <engine>:<identifier>
+        e.g.
+          pkcs11:123456
+
+      - Create an /etc/ppp/openssl.cnf file to load the right OpenSSL engine prior
+        to starting 'pppd'. A sample openssl.cnf file is
+
+        openssl_conf = openssl_def
+
+        [ openssl_def ]
+        engines = engine_section
+
+        [ engine_section ]
+        pkcs11 = pkcs11_section
+
+        [ pkcs11_section ]
+        engine_id = pkcs11
+        dynamic_path = /usr/lib64/openssl/engines/engine_pkcs11.so
+        MODULE_PATH = /usr/lib64/libeTPkcs11.so
+        init = 0
+
+      - There are two ways to specify a password/PIN for the PKCS11 engine:
+          - inside the openssl.cnf file using
+              PIN = your-secret-pin
+            Note The keyword 'PIN' is case sensitive!
+          - Using the 'password' in the ppp options file.
+        From v0.97 of the eap-tls patch the password can also be supplied
+        using the appropriate 'eaptls_passwd_hook' (see plugins/passprompt.c
+        for an example).
+
+
+4. Options
+
+    These pppd options are available:
+
+      ca <ca-file>
+        Use the CA public certificate found in <ca-file> in PEM format
+      ca-path <directory>
+        Use the directory <directory> as the CA public certificate directory
+      cert <cert-file>
+        Use the client public certificate found in <cert-file> in PEM format
+        or in engine:engine_id format
+      key <key-file>
+        Use the client private key found in <key-file> in PEM format
+        or in engine:engine_id format
+      crl <crl-file>
+        Use the Certificate Revocation List (CRL) file <crl-file> in PEM format.
+      crl-dir <dir>
+        Use CRL files from directory <dir>. It contains CRL files in PEM
+        format and each file contains a CRL. The files are looked up 
+        by the issuer name hash value. Use the c_rehash utility 
+        to create necessary links.
+      need-peer-eap
+        If the peer doesn't ask us to authenticate or doesn't use eap
+        to authenticate us, disconnect.
+      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 <janjust@nikhef.nl>
+
diff --git a/Submitting-patches.md b/Submitting-patches.md
new file mode 100644 (file)
index 0000000..6bda0a2
--- /dev/null
@@ -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.
+
index 1065ac51957632606a777711f222887a5f6a98d8..0732ec80dc2736431b1ec9178411ff0bd9e3d100 100644 (file)
@@ -18,7 +18,7 @@ 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
index 710dba9a41c9c0edeb7d916ce1a7171ea80855d5..1639b3e440692f6bbb92da8ab60314d5ad4e15d3 100644 (file)
  *
  */
 
-#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 <stdio.h>
 #include <ctype.h>
 #include <time.h>
@@ -102,6 +94,7 @@ static const char rcsid[] = "$Id: chat.c,v 1.30 2004/01/17 05:47:55 carlsonj Exp
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <syslog.h>
+#include <stdarg.h>
 
 #ifndef TERMIO
 #undef TERMIOS
@@ -121,20 +114,6 @@ static const char rcsid[] = "$Id: chat.c,v 1.30 2004/01/17 05:47:55 carlsonj Exp
 #define SIGTYPE void
 #endif
 
-#undef __P
-#undef __V
-
-#ifdef __STDC__
-#include <stdarg.h>
-#define __V(x) x
-#define __P(x) x
-#else
-#include <varargs.h>
-#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 clear_report_next = 0;
 
 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 @@ size_t c;
     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 @@ size_t len;
  *     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 @@ main(argc, argv)
  *  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 @@ char *chat_file;
 /*
  *     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 @@ char line[1024];
 /*
  * 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 @@ int signo;
        msgf("alarm");
 }
 
-void unalarm()
+void unalarm(void)
 {
     int flags;
 
@@ -572,25 +529,22 @@ void unalarm()
        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 @@ void init()
     alarmed = 0;
 }
 
-void set_tty_parameters()
+void set_tty_parameters(void)
 {
 #if defined(get_term_param)
     term_parms t;
@@ -626,15 +580,14 @@ void set_tty_parameters()
 #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 @@ int status;
 /*
  *     '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 @@ int sending;  /* set to 1 when sending (putting) this string. */
  * 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 @@ char *expect_strtok (s, term)
  * Process the expect string
  */
 
-void chat_expect (s)
-char *s;
+void chat_expect (char *s)
 {
     char *expect;
     char *reply;
@@ -1012,8 +962,7 @@ char *s;
  * the data.
  */
 
-char *character(c)
-int c;
+char *character(int c)
 {
     static char string[10];
     char *meta;
@@ -1034,8 +983,7 @@ int c;
 /*
  *  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 @@ register char *s;
        fatal(1, "Failed");
 }
 
-int get_char()
+int get_char(void)
 {
     int status;
     char c;
@@ -1250,8 +1198,7 @@ int get_char()
     }
 }
 
-int put_char(c)
-int c;
+int put_char(int c)
 {
     int status;
     char ch = c;
@@ -1278,8 +1225,7 @@ int c;
     }
 }
 
-int write_char (c)
-int c;
+int write_char(int c)
 {
     if (alarmed || put_char(c) < 0) {
        alarm(0);
@@ -1296,8 +1242,7 @@ int c;
     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 @@ register char *s;
  *     When called with -1, a '\n' character is generated when
  *     the cursor is not at the beginning of a line.
  */
-void echo_stderr(n)
-int n;
+void echo_stderr(int n)
 {
     static int need_lf;
     char *s;
@@ -1379,8 +1323,7 @@ int n;
 /*
  *     '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 @@ register char *string;
 
 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 @@ usleep( usec )                             /* returns 0 if ok, else -1 */
 }
 #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 @@ pack_array (array, end)
 #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 --git a/etc.ppp/eaptls-client b/etc.ppp/eaptls-client
new file mode 100644 (file)
index 0000000..7782f0e
--- /dev/null
@@ -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 --git a/etc.ppp/eaptls-server b/etc.ppp/eaptls-server
new file mode 100644 (file)
index 0000000..fa53cbd
--- /dev/null
@@ -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 --git a/etc.ppp/openssl.cnf b/etc.ppp/openssl.cnf
new file mode 100644 (file)
index 0000000..dd32f30
--- /dev/null
@@ -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
+
index 314339e96e317b94fba7f7b2511cf95d7bc522ab..ef4232b462151d2e106aadfa604e5ba5e8342461 100644 (file)
@@ -184,12 +184,4 @@ struct ppp_idle {
     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_ */
index bfec6064efe2f58786876124ff0108e0d139cc1d..d08605e3cbd9d34e8c5ff1a0403202d4e3d4b9f9 100644 (file)
@@ -150,7 +150,7 @@ struct ifpppcstatsreq {
 #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_ */
index 088c73e95145e79a4921d3904fa4a63acc669312..b09ef710fc39533a4fa8673d14ea33ed205dc68e 100644 (file)
@@ -59,36 +59,36 @@ struct compressor {
        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 */
 
index b06eda5aae3ab1a24a567e855e86d3bb97d1abc8..a5112b3513f2ec2aba19c4fb6f4d62deed029dd6 100644 (file)
@@ -183,12 +183,4 @@ struct ppp_idle {
     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_ */
index d887dfc2c9e44f9b299cb1d46b16e9598800f959..3712a1ae8c1d25e0b84c2d59ae7dfb2fd49cd6f8 100644 (file)
@@ -137,12 +137,12 @@ struct slcompress {
 /* 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_ */
index 03a33bf79c9b3f975c941d869d0a6f9ab4a69df7..ba1ee1f7030a9aba6646e3c28d01bba21f1c9455 100644 (file)
@@ -130,15 +130,15 @@ struct vjcompress {
 /* 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_ */
index f63d45e58a78ab2e275c8dbffbac8469126ed8a4..894f8f32c9e4bd4284ad614382f6b5f2b29a959a 100644 (file)
@@ -26,7 +26,7 @@ install-progs:
        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 @@ $(ETCDIR)/pap-secrets:
        $(INSTALL) -c -m 600 etc.ppp/pap-secrets $@
 $(ETCDIR)/chap-secrets:
        $(INSTALL) -c -m 600 etc.ppp/chap-secrets $@
+$(ETCDIR)/eaptls-server:
+       $(INSTALL) -c -m 600 etc.ppp/eaptls-server $@
+$(ETCDIR)/eaptls-client:
+       $(INSTALL) -c -m 600 etc.ppp/eaptls-client $@
 
 $(BINDIR):
        $(INSTALL) -d -m 755 $@
index 9d2b12ef047e2c047983e83bd19f77dcfe054a99..fb52aa29e2fb1411af430c2688f7337b416c5d0a 100644 (file)
@@ -148,19 +148,19 @@ struct bsd_db {
 #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.
index c896846db6718a43d513daffd2f8f9fb6ce9f2ec..27023261edbf7ca0130a33c7e3b50892b1b66d49 100644 (file)
@@ -80,25 +80,25 @@ struct deflate_state {
 
 #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.
index 85962d67df9f37e599770b5073be8ecd0d4510a7..e150923306400646794e96cd0752a7858e79bb62 100644 (file)
 
 #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 int ppp_nalloc;            /* Number of elements of ifs and states */
 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 @@ static struct ether_header snit_ehdr = {{0}, {0}, ETHERTYPE_IP};
 #endif
 
 #ifndef __osf__
-static void ppp_if_detach __P((struct ifnet *));
+static void ppp_if_detach(struct ifnet *);
 
 /*
  * Detach all the interfaces before unloading.
index ad345db6ee7261479aa34fc204fa8d67b9b55493..f5fb71f1aa4696d07da7ea025d7cd6afa433c568 100644 (file)
@@ -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 $
  */
 
 /*
 
 #include <netinet/in.h>        /* 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 *minor_devs = NULL;
 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
index 184b535657d199a605bde2c30bac3fe8692bd079..68e090785782c888a3395e3a90274015b26d8cec 100644 (file)
@@ -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 @@ typedef unsigned int            uintpointer_t;
 
 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)
 /*
index 97d13ebd3bf608b624718e60ed23566f191588e3..9e204d9d0cdf7da1457044c213fe4ab8999b7fdf 100644 (file)
@@ -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 $
  */
 
 /*
 
 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 @@ int ppp_comp_count;         /* number of module instances in use */
 
 #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;
index f0af008861ef0f1972a126ee71e65b09cef1bf4b..792c4d4fc5b5feb129dac73df19447d50e785670 100644 (file)
@@ -143,10 +143,10 @@ typedef int minor_t;
  */
 #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 @@ static int name(q, flag, credp)   \
 
 #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)   \
index a74c914fd3acf84dbcaac360e6f5cabd3582f802..44d47ad7f46f35bce09a86998cf4ebaab2ebd15f 100644 (file)
@@ -33,12 +33,12 @@ 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 +60,11 @@ HAVE_MULTILINK=y
 # 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
@@ -76,6 +81,9 @@ PLUGIN=y
 # Use libutil
 USE_LIBUTIL=y
 
+# Enable EAP-TLS authentication (requires MPPE support, libssl and libcrypto)
+USE_EAPTLS=y
+
 MAXOCTETS=y
 
 INCLUDE_DIRS= -I../include
@@ -94,13 +102,15 @@ CFLAGS   += -DMSLANMAN=1
 endif
 ifdef MPPE
 CFLAGS   += -DMPPE=1
+HEADERS  += mppe.h
 endif
 endif
 
 # EAP SRP-SHA1
 ifdef USE_SRP
 CFLAGS += -DUSE_SRP -DOPENSSL -I/usr/local/ssl/include
-LIBS   += -lsrp -L/usr/local/ssl/lib -lcrypto
+LIBS   += -lsrp -L/usr/local/ssl/lib
+NEEDCRYPTOLIB = y
 TARGETS        += srp-entry
 EXTRAINSTALL = $(INSTALL) -s -c -m 555 srp-entry $(BINDIR)/srp-entry
 MANPAGES += srp-entry.8
@@ -115,12 +125,22 @@ HEADERS += sha1.h
 PPPDOBJS += sha1.o
 endif
 
+# EAP-TLS
+ifdef USE_EAPTLS
+CFLAGS += -DUSE_EAPTLS=1
+LIBS += -lssl
+NEEDCRYPTOLIB = y
+PPPDSRC += eap-tls.c
+HEADERS += eap-tls.h
+PPPDOBJS += eap-tls.o
+endif
+
 ifdef HAS_SHADOW
 CFLAGS   += -DHAS_SHADOW
 #LIBS     += -lshadow $(LIBS)
 endif
 
-ifneq ($(wildcard /usr/include/crypt.h),)
+ifneq ($(wildcard $(shell $(CC) --print-sysroot)/usr/include/crypt.h),)
 CFLAGS  += -DHAVE_CRYPT_H=1
 LIBS   += -lcrypt
 endif
@@ -132,7 +152,8 @@ endif
 
 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 +161,10 @@ PPPDOBJS += pppcrypt.o
 HEADERS += pppcrypt.h
 endif
 
+ifdef NEEDCRYPTOLIB
+LIBS     += -lcrypto
+endif
+
 # For "Pluggable Authentication Modules", see ftp.redhat.com:/pub/pam/.
 ifdef USE_PAM
 CFLAGS   += -DUSE_PAM
@@ -170,9 +195,14 @@ LIBS     += -llock
 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
 
@@ -214,7 +244,7 @@ install: pppd
        $(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)
index 45b6b6269bd2a096a433bf284b7eac67b2d88cc7..809cb4b3519fcd4af10e67601300dd707af84921 100644 (file)
@@ -39,6 +39,14 @@ OBJS += ipv6cp.o eui64.o
 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
index 4271af687102dc62e3c2e3b47d3fc8ab1d70d0f8..ffa0e14afb097e775e18cc0257f0e56d7256d9a9 100644 (file)
@@ -78,6 +78,7 @@
 #include <pwd.h>
 #include <grp.h>
 #include <string.h>
+#include <strings.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
 #endif
 #include <time.h>
 
+#ifdef SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
 #include "pppd.h"
 #include "fsm.h"
 #include "lcp.h"
 #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 int passwd_from_file;
 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_remote = 0; /* User specified explicit remote name */
 bool explicit_user = 0;                /* Set if "user" option supplied */
 bool explicit_passwd = 0;      /* Set if "password" option supplied */
 char remote_name[MAXNAMELEN];  /* Peer's name for authentication */
+#ifdef USE_EAPTLS
+char *cacert_file  = NULL;     /* CA certificate file (pem format) */
+char *ca_path      = NULL;     /* directory with CA certificates */
+char *cert_file    = NULL;     /* client certificate file (pem format) */
+char *privkey_file = NULL;     /* client private key file (pem format) */
+char *crl_dir      = NULL;     /* directory containing CRL files */
+char *crl_file     = NULL;     /* Certificate Revocation List (CRL) file (pem format) */
+char *max_tls_version = NULL;  /* Maximum TLS protocol version (default=1.2) */
+bool need_peer_eap = 0;                        /* Require peer to authenticate us */
+#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 @@ option_t auth_options[] = {
       "Set telephone number(s) which are allowed to connect",
       OPT_PRIV | OPT_A2LIST },
 
+#ifdef USE_EAPTLS
+    { "ca", o_string, &cacert_file,   "EAP-TLS CA certificate in PEM format" },
+    { "capath", o_string, &ca_path,   "EAP-TLS CA certificate directory" },
+    { "cert", o_string, &cert_file,   "EAP-TLS client certificate in PEM format" },
+    { "key", o_string, &privkey_file, "EAP-TLS client private key in PEM format" },
+    { "crl-dir", o_string, &crl_dir,  "Use CRLs in directory" },
+    { "crl", o_string, &crl_file,     "Use specific CRL file" },
+    { "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 @@ option_t auth_options[] = {
  * 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 @@ setupapfile(argv)
     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 @@ setupapfile(argv)
        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 @@ setupapfile(argv)
        || 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 @@ setupapfile(argv)
        explicit_passwd = 1;
     }
 
+    free(fname);
     return (1);
 }
 
@@ -472,8 +522,7 @@ setupapfile(argv)
  * 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 @@ privgroup(argv)
  * 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_noauth_addr(argv)
  * 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 @@ set_permitted_number(argv)
  * 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 @@ void start_link(unit)
  * 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 @@ link_terminated(unit)
  * 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 @@ void upper_layers_down(int unit)
  * 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 @@ link_established(unit)
        }
     }
 
+#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 @@ link_established(unit)
  * Proceed to the network phase.
  */
 static void
-network_phase(unit)
-    int unit;
+network_phase(int unit)
 {
     lcp_options *go = &lcp_gotoptions[unit];
 
@@ -848,8 +908,7 @@ network_phase(unit)
 }
 
 void
-start_networks(unit)
-    int unit;
+start_networks(int unit)
 {
     int i;
     struct protent *protp;
@@ -889,8 +948,7 @@ start_networks(unit)
 }
 
 void
-continue_networks(unit)
-    int unit;
+continue_networks(int unit)
 {
     int i;
     struct protent *protp;
@@ -915,8 +973,7 @@ continue_networks(unit)
  * 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 @@ auth_peer_fail(unit, protocol)
  * 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 @@ auth_peer_success(unit, protocol, prot_flavor, name, namelen)
  * 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 @@ auth_withpeer_fail(unit, protocol)
  * 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 @@ auth_withpeer_success(unit, protocol, prot_flavor)
  * 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 @@ np_up(unit, proto)
        /*
         * 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_up(unit, proto)
  * 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_down(unit, proto)
  * 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 @@ np_finished(unit, proto)
 
 #ifdef MAXOCTETS
 static void
-check_maxoctets(arg)
-    void *arg;
+check_maxoctets(void *arg)
 {
     unsigned int used;
 
@@ -1176,8 +1232,7 @@ check_maxoctets(arg)
  * 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 @@ check_idle(arg)
  * 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 @@ connect_time_expired(arg)
  * 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 @@ auth_check_options()
                                    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 @@ auth_check_options()
  * 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 @@ auth_reset(unit)
     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 @@ auth_reset(unit)
            !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 @@ auth_reset(unit)
  * 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 @@ check_passwd(unit, auser, userlen, apasswd, passwdlen, msg)
  * and return 1.
  */
 static int
-null_login(unit)
-    int unit;
+null_login(int unit)
 {
     char *filename;
     FILE *f;
@@ -1541,8 +1607,7 @@ null_login(unit)
  * 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 @@ get_pap_passwd(passwd)
  * 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 @@ have_pap_secret(lacks_ipp)
  * 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 @@ have_chap_secret(client, server, need_ip, lacks_ipp)
  * 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 @@ have_srp_secret(client, server, need_ip, lacks_ipp)
  * (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 @@ get_secret(unit, client, server, secret, secret_len, am_server)
  * (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 @@ get_srp_secret(unit, client, server, secret, am_server)
  * 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 @@ set_allowed_addrs(unit, addrs, opts)
  * 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 @@ auth_ip_addr(unit, addr)
 }
 
 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 @@ ip_addr_check(addr, addrs)
  * 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 @@ bad_ip_adrs(addr)
  * 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 @@ some_ip_ok(addrs)
  * Returns 1 if authorized, 0 otherwise.
  */
 int
-auth_number()
+auth_number(void)
 {
     struct wordlist *wp = permitted_numbers;
     int l;
@@ -2083,9 +2123,7 @@ auth_number()
  * 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 @@ check_access(f, filename)
  * 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 @@ scan_authfile(f, client, server, secret, addrs, opts, filename, flags)
  * 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 @@ wordlist_count(wp)
  * 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 @@ free_wordlist(wp)
  * 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 @@ auth_script_done(arg)
  * 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(script)
 
     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
index 7f2f7877cbbf4011a007441c3545d4dd2520e8dd..e3566336982709115b1b121e56f3f5526401598c 100644 (file)
@@ -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 <stdio.h>
 #include <string.h>
 #include <sys/types.h>
 #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 @@ static option_t cbcp_option_list[] = {
 /*
  * 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 @@ cbcp_state cbcp[NUM_PPP];
 
 /* 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 @@ setcbcp(argv)
 
 /* init state */
 static void
-cbcp_init(iface)
-    int iface;
+cbcp_init(int iface)
 {
     cbcp_state *us;
 
@@ -130,8 +125,7 @@ cbcp_init(iface)
 
 /* lower layer is up */
 static void
-cbcp_lowerup(iface)
-    int iface;
+cbcp_lowerup(int iface)
 {
     cbcp_state *us = &cbcp[iface];
 
@@ -143,18 +137,14 @@ cbcp_lowerup(iface)
 }
 
 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 @@ char *cbcp_optionnames[] = {
 
 /* 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 @@ cbcp_printpkt(p, plen, printer, arg)
 
 /* 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 @@ cbcp_recvreq(us, pckt, pcktlen)
 }
 
 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 @@ cbcp_resp(us)
 }
 
 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 @@ cbcp_send(us, code, buf, len)
 }
 
 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 @@ cbcp_recvack(us, pckt, len)
 
 /* ok peer will do callback */
 static void
-cbcp_up(us)
-    cbcp_state *us;
+cbcp_up(cbcp_state *us)
 {
     persist = 0;
     status = EXIT_CALLBACK;
index 7d7922afcfc0b2d4178319dc903dc3c19427c1c3..052c4c61081bdc74489ea282e8e0df46ed1891fc 100644 (file)
@@ -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 @@ static const char rcsid[] = RCSID;
 /*
  * 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 @@ static option_t ccp_option_list[] = {
 /*
  * 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 @@ ccp_options ccp_hisoptions[NUM_PPP];      /* what we agreed to do */
 /*
  * 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 @@ static int all_rejected[NUM_PPP];   /* we rejected all peer's options */
  * Option parsing.
  */
 static int
-setbsdcomp(argv)
-    char **argv;
+setbsdcomp(char **argv)
 {
     int rbits, abits;
     char *str, *endp;
@@ -297,8 +295,7 @@ setbsdcomp(argv)
 }
 
 static int
-setdeflate(argv)
-    char **argv;
+setdeflate(char **argv)
 {
     int rbits, abits;
     char *str, *endp;
@@ -348,8 +345,7 @@ setdeflate(argv)
  * 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_init(unit)
  * 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_open(unit)
  * 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_close(unit, reason)
  * 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_lowerup(unit)
  * 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_lowerdown(unit)
  * 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 @@ ccp_input(unit, p, len)
  * 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_extcode(f, code, id, p, len)
  * 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_protrej(unit)
  * 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 @@ ccp_resetci(f)
     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 @@ ccp_resetci(f)
            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,8 +670,7 @@ ccp_resetci(f)
  * 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];
 
@@ -687,10 +686,7 @@ ccp_cilen(f)
  * 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];
@@ -806,10 +802,7 @@ ccp_addci(f, p, lenp)
  * 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;
@@ -895,11 +888,7 @@ ccp_ackci(f, p, len)
  * 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 */
@@ -985,10 +974,7 @@ ccp_nakci(f, p, len, treat_as_reject)
  * 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 */
@@ -1067,11 +1053,7 @@ ccp_rejci(f, p, len)
  * 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;
@@ -1358,8 +1340,7 @@ ccp_reqci(f, p, lenp, dont_nak)
  * 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];
 
@@ -1423,8 +1404,7 @@ method_name(opt, opt2)
  * 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];
@@ -1457,8 +1437,7 @@ ccp_up(f)
  * 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);
@@ -1487,11 +1466,8 @@ static char *ccp_codenames[] = {
 };
 
 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;
@@ -1620,10 +1596,7 @@ ccp_printpkt(p, plen, printer, arg)
  * 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;
 
@@ -1664,8 +1637,7 @@ ccp_datainput(unit, pkt, len)
  * Timeout waiting for reset-ack.
  */
 static void
-ccp_rack_timeout(arg)
-    void *arg;
+ccp_rack_timeout(void *arg)
 {
     fsm *f = arg;
 
index 2714bff6478589412aeed098f77262e89a91349c..0b1bb86e77c0d35a03b6e58629ace81748ec36e5 100644 (file)
@@ -55,20 +55,23 @@ int (*chap_verify_hook)(char *name, char *ourname, int id,
 /*
  * 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;
 
 /*
  * 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 },
        { NULL }
 };
 
@@ -114,7 +117,8 @@ static struct chap_server_state {
 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 +133,7 @@ static void chap_handle_status(struct chap_client_state *cs, int code, int id,
 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;
@@ -171,7 +175,7 @@ chap_lowerup(int unit)
        cs->flags |= LOWERUP;
        ss->flags |= LOWERUP;
        if (ss->flags & AUTH_STARTED)
-               chap_timeout(ss);
+               chap_server_timeout(ss);
 }
 
 static void
@@ -180,9 +184,11 @@ chap_lowerdown(int unit)
        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 +220,7 @@ chap_auth_peer(int unit, char *our_name, int digest_code)
        ss->id = (unsigned char)(drand48() * 256);
        ss->flags |= AUTH_STARTED;
        if (ss->flags & LOWERUP)
-               chap_timeout(ss);
+               chap_server_timeout(ss);
 }
 
 /*
@@ -240,16 +246,17 @@ chap_auth_with_peer(int unit, char *our_name, int digest_code)
 
        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 +275,19 @@ chap_timeout(void *arg)
        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 +346,7 @@ chap_handle_response(struct chap_server_state *ss, int id,
 
                if (ss->flags & TIMEOUT_PENDING) {
                        ss->flags &= ~TIMEOUT_PENDING;
-                       UNTIMEOUT(chap_timeout, ss);
+                       UNTIMEOUT(chap_server_timeout, ss);
                }
 
                if (explicit_remote) {
@@ -392,7 +411,7 @@ chap_handle_response(struct chap_server_state *ss, int id,
                                                  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 +514,9 @@ chap_handle_status(struct chap_client_state *cs, int code, int id,
                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 +584,7 @@ chap_protrej(int unit)
 
        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 +606,7 @@ static char *chap_code_names[] = {
 
 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;
index c2bd00f9c6f7ec0e3e3a5dd6b00c4153b6c41d25..e6b84f203fc3fc2f62ca2a471b17e11d8422e975 100644 (file)
 #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 @@ chapms2_check_success(int id, unsigned char *msg, int len)
        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.");
index 040d80adbeab088477df6239746979e7b937e622..005eb63bc6dfb38987d977d78e50f5b9535402e0 100644 (file)
@@ -87,16 +87,16 @@ extern void set_mppe_enc_types(int, int);
 #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],
index 5e57658ea831908e98e7554e23329e51e14918a1..289c9f8fdd57959588e65835d16cc3adf7950c6a 100644 (file)
@@ -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 {
 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_conf()
  * 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 @@ demand_block()
  * with an error.
  */
 void
-demand_discard()
+demand_discard(void)
 {
     struct packet *pkt, *nextpkt;
     int i;
@@ -160,7 +159,7 @@ demand_discard()
  * 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 @@ static u_short fcstab[256] = {
  * 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 @@ loop_chars(p, n)
  * 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 @@ loop_frame(frame, len)
  * 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 @@ demand_rexmit(proto)
  * 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 --git a/pppd/eap-tls.c b/pppd/eap-tls.c
new file mode 100644 (file)
index 0000000..5740f30
--- /dev/null
@@ -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 <string.h>
+#include <strings.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <openssl/conf.h>
+#include <openssl/engine.h>
+#include <openssl/hmac.h>
+#include <openssl/err.h>
+#include <openssl/ui.h>
+#include <openssl/x509v3.h>
+
+#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 --git a/pppd/eap-tls.h b/pppd/eap-tls.h
new file mode 100644 (file)
index 0000000..cdbc9e4
--- /dev/null
@@ -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 <openssl/ssl.h>
+#include <openssl/bio.h>
+
+#define EAP_TLS_FLAGS_LI        128    /* length included flag */
+#define EAP_TLS_FLAGS_MF        64     /* more fragments flag */
+#define EAP_TLS_FLAGS_START     32     /* start flag */
+
+#define EAP_TLS_MAX_LEN         65536  /* max eap tls packet size */
+
+struct eaptls_session
+{
+    u_char *data;               /* buffered data */
+    int datalen;                /* buffered data len */
+    int offset;                 /* from where to send */
+    int tlslen;                 /* total length of tls data */
+    bool frag;                  /* packet is fragmented */
+    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
index 6ea6c1f8bff6423c4038edb9e47763e111ea0724..92d29ec8bd6c034995f3ebd6a7c737669d80a607 100644 (file)
  * 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 $"
+/*
+ * Modification by Beniamino Galvani, Mar 2005
+ * Implemented EAP-TLS authentication
+ */
 
 /*
  * TODO:
@@ -76,7 +79,9 @@
 #define        SHA_DIGESTSIZE 20
 #endif
 
-static const char rcsid[] = RCSID;
+#ifdef USE_EAPTLS
+#include "eap-tls.h"
+#endif /* USE_EAPTLS */
 
 eap_state eap_states[NUM_PPP];         /* EAP state; one for each unit */
 #ifdef USE_SRP
@@ -111,13 +116,13 @@ static option_t eap_option_list[] = {
 /*
  * 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 +144,7 @@ struct protent eap_protent = {
        NULL                    /* say whether to bring up link for this pkt */
 };
 
+#ifdef USE_SRP
 /*
  * A well-known 2048 bit modulus.
  */
@@ -176,16 +182,16 @@ static const u_char wkmodulus[] = {
        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 +203,7 @@ enum eap_state_code esc;
  * 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 +214,9 @@ int unit;
        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 */
 }
 
 /*
@@ -216,8 +224,7 @@ int unit;
  * Request messages.
  */
 static void
-eap_client_timeout(arg)
-void *arg;
+eap_client_timeout(void *arg)
 {
        eap_state *esp = (eap_state *) arg;
 
@@ -236,9 +243,7 @@ void *arg;
  * 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 +267,7 @@ char *localname;
  * (Server operation)
  */
 static void
-eap_send_failure(esp)
-eap_state *esp;
+eap_send_failure(eap_state *esp)
 {
        u_char *outp;
 
@@ -287,8 +291,7 @@ eap_state *esp;
  * (Server operation)
  */
 static void
-eap_send_success(esp)
-eap_state *esp;
+eap_send_success(eap_state *esp)
 {
        u_char *outp;
 
@@ -342,11 +345,7 @@ struct b64state {
 };
 
 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 +367,7 @@ u_char *outp;
 }
 
 static int
-b64flush(bs, outp)
-struct b64state *bs;
-u_char *outp;
+b64flush(struct b64state *bs, u_char *outp)
 {
        int outlen = 0;
 
@@ -390,11 +387,7 @@ u_char *outp;
 }
 
 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 +415,7 @@ u_char *outp;
  * 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 +427,16 @@ int status;
        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 +561,81 @@ int status;
                        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;
@@ -630,6 +701,10 @@ int status;
        }
        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 */
 }
 
 /*
@@ -637,8 +712,7 @@ int status;
  * 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 +792,30 @@ eap_state *esp;
                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);
@@ -871,9 +969,7 @@ eap_state *esp;
  * 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 +997,59 @@ char *localname;
  * 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 +1060,7 @@ void *arg;
  * 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 +1076,7 @@ void *arg;
 }
 
 static void
-srp_lwrechallenge(arg)
-void *arg;
+srp_lwrechallenge(void *arg)
 {
        eap_state *esp = (eap_state *)arg;
 
@@ -960,8 +1099,7 @@ void *arg;
  * thing.
  */
 static void
-eap_lowerup(unit)
-int unit;
+eap_lowerup(int unit)
 {
        eap_state *esp = &eap_states[unit];
 
@@ -984,8 +1122,7 @@ int unit;
  * 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 +1156,7 @@ int unit;
  * failure.
  */
 static void
-eap_protrej(unit)
-int unit;
+eap_protrej(int unit)
 {
        eap_state *esp = &eap_states[unit];
 
@@ -1039,12 +1175,8 @@ int unit;
  * 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 +1202,8 @@ int lenstr;
  * 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 +1234,8 @@ int namelen;
  * 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 +1262,7 @@ int lenstr;
  * 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 +1286,77 @@ u_char *str;
 }
 #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_send_nak(esp, id, type)
-eap_state *esp;
-u_char id;
-u_char type;
+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(eap_state *esp, u_char id, u_char type)
 {
        u_char *outp;
        int msglen;
@@ -1192,7 +1378,7 @@ u_char type;
 
 #ifdef USE_SRP
 static char *
-name_of_pn_file()
+name_of_pn_file(void)
 {
        char *user, *path, *file;
        struct passwd *pw;
@@ -1218,8 +1404,7 @@ name_of_pn_file()
 }
 
 static int
-open_pn_file(modebits)
-mode_t modebits;
+open_pn_file(mode_t modebits)
 {
        char *path;
        int fd, err;
@@ -1234,7 +1419,7 @@ mode_t modebits;
 }
 
 static void
-remove_pn_file()
+remove_pn_file(void)
 {
        char *path;
 
@@ -1245,10 +1430,7 @@ remove_pn_file()
 }
 
 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;
@@ -1307,11 +1489,7 @@ int len, id;
  * 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 +1498,11 @@ int len;
        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;
@@ -1329,6 +1512,12 @@ int len;
        int fd;
 #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
@@ -1385,7 +1574,7 @@ int len;
                        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 +1610,7 @@ int len;
                }
 
                /* 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 +1645,96 @@ int len;
                    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(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_TLS);
+                       esp->es_client.ea_using_eaptls = 0;
+                       break;
+               }
+
+               break;
+#endif /* USE_EAPTLS */
+
 #ifdef USE_SRP
        case EAPT_SRP:
                if (len < 1) {
@@ -1717,11 +1996,7 @@ client_failure:
  * 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 +2010,21 @@ int len;
        struct t_num A;
        SHA1_CTX ctxt;
        u_char dig[SHA_DIGESTSIZE];
+       SHA1_CTX ctxt;
+       u_char dig[SHA_DIGESTSIZE];
 #endif /* USE_SRP */
 
+#ifdef USE_EAPTLS
+       struct eaptls_session *ets;
+       u_char flags;
+#endif /* USE_EAPTLS */
+
+       /*
+        * 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 +2064,64 @@ int len;
                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 +2153,13 @@ int len;
                        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) {
@@ -1847,7 +2200,7 @@ int len;
                }
 
                /* 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';
@@ -2012,19 +2365,29 @@ int len;
  * 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 +2405,14 @@ int len;
  * 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 +2438,7 @@ int len;
  * 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;
@@ -2141,15 +2503,15 @@ static char *eap_typenames[] = {
 };
 
 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 */
 
        if (inlen < EAP_HEADERLEN)
                return (0);
@@ -2214,6 +2576,24 @@ void *arg;
                        }
                        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 +2705,25 @@ void *arg;
                        }
                        break;
 
+#ifdef USE_EAPTLS
+               case EAPT_TLS:
+                       if (len < 1)
+                               break;
+                       GETCHAR(flags, inp);
+                       len--;
+
+                        if(flags == 0 && len == 0){
+                                printer(arg, " Ack");
+                                break;
+                        }
+
+                       printer(arg, flags & EAP_TLS_FLAGS_LI ? " L":" -");
+                       printer(arg, flags & EAP_TLS_FLAGS_MF ? "M":"-");
+                       printer(arg, flags & EAP_TLS_FLAGS_START ? "S":"- ");
+
+                       break;
+#endif /* USE_EAPTLS */
+
                case EAPT_NAK:
                        if (len <= 0) {
                                printer(arg, " <missing hint>");
index 199d1849b8261093ebd0f54a1b100081f27d2f3f..56bef136d75590a7f9b6073d9ab93c7adb2f2c98 100644 (file)
@@ -84,6 +84,16 @@ enum eap_state_code {
        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 @@ enum eap_state_code {
 
 #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 @@ struct eap_auth {
        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,14 +164,19 @@ typedef struct eap_state {
  * 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;
 
index e5754e5516f3730fa6b83ea678b89747412434d6..1ecd7be0d79e64007085e51763bee6b3c3f7fa6d 100644 (file)
  * 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 <string.h>
 
 #include "pppd.h"
@@ -79,20 +75,20 @@ static option_t ecp_option_list[] = {
 /*
  * 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 @@ static fsm_callbacks ecp_callbacks = {
  * ecp_init - initialize ECP.
  */
 static void
-ecp_init(unit)
-    int unit;
+ecp_init(int unit)
 {
     fsm *f = &ecp_fsm[unit];
 
@@ -162,11 +157,8 @@ ecp_init(unit)
 
 
 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;
 }
index d025eff4c1e2742d8dbf86ee205dc53ff059ab6c..98caf9447408d6ea4741d49f3c4e065852373bf6 100644 (file)
  * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  *
- * $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];
 
index 0f6b6fd46647aa05ab2b6b6e35fd823bc77ef91a..c48d689eda7b0dcf40df2e0bd83c7199d66705b0 100644 (file)
@@ -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 @@ typedef union
                                } 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__ */
 
index e9bd34f0e8f48fd0da69e4ffea3349691975f435..96d20e86e98db3160de9eda59033d578d8c4b6fe 100644 (file)
@@ -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.
 #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 @@ int peer_mru[NUM_PPP];
  * Initialize fsm state.
  */
 void
-fsm_init(f)
-    fsm *f;
+fsm_init(fsm *f)
 {
     f->state = INITIAL;
     f->flags = 0;
@@ -95,8 +91,7 @@ fsm_init(f)
  * 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 @@ fsm_lowerup(f)
  * 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_lowerdown(f)
  * 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 @@ fsm_open(f)
  * 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 @@ terminate_layer(f, nextstate)
  * 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_close(f, reason)
  * fsm_timeout - Timeout expired.
  */
 static void
-fsm_timeout(arg)
-    void *arg;
+fsm_timeout(void *arg)
 {
     fsm *f = (fsm *) arg;
 
@@ -331,10 +319,7 @@ fsm_timeout(arg)
  * 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_input(f, inpacket, l)
  * 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;
 
@@ -481,11 +462,7 @@ fsm_rconfreq(f, id, inp, len)
  * 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_rconfack(f, id, inp, len)
  * 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_rconfnakrej(f, code, id, inp, len)
  * 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_rtermreq(f, id, p, len)
  * 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_rtermack(f)
  * 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 @@ fsm_rcoderej(f, inp, len)
  * 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_protreject(f)
  * 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 @@ fsm_sconfreq(f, retransmit)
  * 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;
index 87a78d38e8b2b48b1dfcf9c67d819bfc752d1253..75a36d52fe94e9172a0578ef5491a06e2fb26344 100644 (file)
@@ -85,34 +85,26 @@ typedef struct fsm {
 
 
 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 @@ typedef struct fsm_callbacks {
 /*
  * 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);
 
 
 /*
index 48d7095f58ad3fa517a9763d7e566c76e2e3ced5..7357ac8ea546323f3ba178db99f0e77639beef3f 100644 (file)
@@ -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:
  */
@@ -62,7 +60,6 @@
 #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 */
@@ -76,13 +73,13 @@ bool        disable_defaultip = 0;  /* Don't use hostname for default IP adrs */
 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;
@@ -101,16 +98,16 @@ static char netmask_str[20];               /* string form of netmask value */
 /*
  * 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 */
 
@@ -135,12 +132,12 @@ static fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */
 /*
  * 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,
@@ -176,10 +173,10 @@ static option_t ipcp_option_list[] = {
     { "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 },
@@ -238,19 +235,19 @@ static option_t ipcp_option_list[] = {
 /*
  * 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,
@@ -272,9 +269,9 @@ struct protent ipcp_protent = {
     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);
+static void ipcp_script (char *, int); /* Run an up/down script */
+static void ipcp_script_done (void *);
 
 /*
  * Lengths of configuration options.
@@ -303,8 +300,7 @@ static pid_t ipcp_script_pid;
  * 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];
 
@@ -320,8 +316,7 @@ u_int32_t ipaddr;
  * setvjslots - set maximum number of connection slots for VJ compression
  */
 static int
-setvjslots(argv)
-    char **argv;
+setvjslots(char **argv)
 {
     int value;
 
@@ -341,8 +336,7 @@ setvjslots(argv)
  * setdnsaddr - set the dns address(es)
  */
 static int
-setdnsaddr(argv)
-    char **argv;
+setdnsaddr(char **argv)
 {
     u_int32_t dns;
     struct hostent *hp;
@@ -377,8 +371,7 @@ setdnsaddr(argv)
  * 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;
@@ -414,10 +407,7 @@ setwinsaddr(argv)
  * 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;
@@ -481,10 +471,7 @@ setipaddr(arg, argv, doit)
 }
 
 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];
 
@@ -499,8 +486,7 @@ printipaddr(opt, printer, arg)
  * 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;
@@ -527,9 +513,7 @@ setnetmask(argv)
 }
 
 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;
@@ -564,8 +548,7 @@ parse_dotted_ip(p, vp)
  * 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];
@@ -616,8 +599,7 @@ ipcp_init(unit)
  * 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;
@@ -628,9 +610,7 @@ ipcp_open(unit)
  * 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);
 }
@@ -640,8 +620,7 @@ ipcp_close(unit, reason)
  * ipcp_lowerup - The lower layer is up.
  */
 static void
-ipcp_lowerup(unit)
-    int unit;
+ipcp_lowerup(int unit)
 {
     fsm_lowerup(&ipcp_fsm[unit]);
 }
@@ -651,8 +630,7 @@ ipcp_lowerup(unit)
  * ipcp_lowerdown - The lower layer is down.
  */
 static void
-ipcp_lowerdown(unit)
-    int unit;
+ipcp_lowerdown(int unit)
 {
     fsm_lowerdown(&ipcp_fsm[unit]);
 }
@@ -662,10 +640,7 @@ ipcp_lowerdown(unit)
  * 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);
 }
@@ -677,8 +652,7 @@ ipcp_input(unit, p, len)
  * 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]);
 }
@@ -689,8 +663,7 @@ ipcp_protrej(unit)
  * 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];
@@ -722,8 +695,7 @@ ipcp_resetci(f)
  * 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];
@@ -766,10 +738,7 @@ ipcp_cilen(f)
  * 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;
@@ -873,10 +842,7 @@ ipcp_addci(f, ucp, lenp)
  *     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;
@@ -1017,11 +983,7 @@ bad:
  *     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;
@@ -1266,10 +1228,7 @@ bad:
  * 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;
@@ -1417,11 +1376,7 @@ bad:
  * 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];
@@ -1706,7 +1661,7 @@ endswitch:
  * and assign appropriate defaults.
  */
 static void
-ip_check_options()
+ip_check_options(void)
 {
     struct hostent *hp;
     u_int32_t local;
@@ -1738,8 +1693,7 @@ ip_check_options()
  * 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];
 
@@ -1782,8 +1736,7 @@ ip_demand_conf(u)
  * 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];
@@ -1981,8 +1934,7 @@ ipcp_up(f)
  * 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
@@ -2029,10 +1981,7 @@ ipcp_down(f)
  * 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)
 {
     if (proxy_arp_set[unit]) {
        cifproxyarp(unit, hisaddr);
@@ -2050,8 +1999,7 @@ ipcp_clear_addrs(unit, ouraddr, hisaddr)
  * 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;
@@ -2065,8 +2013,7 @@ ipcp_finished(f)
  * has finished.
  */
 static void
-ipcp_script_done(arg)
-    void *arg;
+ipcp_script_done(void *arg)
 {
     ipcp_script_pid = 0;
     switch (ipcp_script_state) {
@@ -2091,9 +2038,7 @@ ipcp_script_done(arg)
  * 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];
@@ -2121,8 +2066,7 @@ ipcp_script(script, wait)
  * 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;
 
@@ -2153,11 +2097,8 @@ static char *ipcp_codenames[] = {
 };
 
 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;
@@ -2297,9 +2238,7 @@ ipcp_printpkt(p, plen, printer, arg)
 #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;
index 6cf14c990578260634440ff441ca443d422d76a7..dc6665cf0cd7c731151704d36a768fdbf2546e06 100644 (file)
@@ -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 $
  */
 
 /*
@@ -91,6 +89,6 @@ extern ipcp_options ipcp_gotoptions[];
 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;
index 356ff84ead4103cb846c31c6e806786b166a33e5..dec6cfea7568f75e808077f937633ea730f87ed7 100644 (file)
  * 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: 
  *
 #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 @@ ipv6cp_options ipv6cp_hisoptions[NUM_PPP];        /* Options that we ack'd */
 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 @@ struct notifier *ipv6_down_notifier = NULL;
 /*
  * 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 @@ static fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */
 /*
  * 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 @@ 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 },
+
+    { "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 @@ static option_t ipv6cp_option_list[] = {
 /*
  * 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 @@ struct protent ipv6cp_protent = {
     ipv6cp_close,
     ipv6cp_printpkt,
     NULL,
-    0,
+    1,
     "IPV6CP",
     "IPV6",
     ipv6cp_option_list,
@@ -301,9 +308,9 @@ struct protent ipv6cp_protent = {
     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 @@ static pid_t ipv6cp_script_pid;
  * 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 @@ setifaceid(argv)
 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 @@ printifaceid(opt, printer, arg)
  * 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 @@ llv6_ntoa(ifaceid)
  * 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 @@ ipv6cp_init(unit)
     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 @@ ipv6cp_init(unit)
     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_init(unit)
  * 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_open(unit)
  * 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_close(unit, reason)
  * 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_lowerup(unit)
  * 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_lowerdown(unit)
  * 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 @@ ipv6cp_input(unit, p, len)
  * 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_protrej(unit)
  * 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 @@ ipv6cp_resetci(f)
     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_resetci(f)
  * 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_cilen(f)
  * 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 @@ ipv6cp_addci(f, ucp, lenp)
  *     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 @@ bad:
  *     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 @@ bad:
  * 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 @@ bad:
  * 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 @@ ipv6cp_reqci(f, inp, len, reject_if_disagree)
                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)) {
                    
@@ -1079,7 +1060,7 @@ endswitch:
  * and assign appropriate defaults.
  */
 static void
-ipv6_check_options()
+ipv6_check_options(void)
 {
     ipv6cp_options *wo = &ipv6cp_wantoptions[0];
 
@@ -1137,8 +1118,7 @@ ipv6_check_options()
  * 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 +1132,9 @@ ipv6_demand_conf(u)
 #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 +1150,7 @@ ipv6_demand_conf(u)
  * 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 +1213,10 @@ ipv6cp_up(f)
                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 +1238,11 @@ ipv6cp_up(f)
        }
        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 +1272,7 @@ ipv6cp_up(f)
  * 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 +1321,7 @@ ipv6cp_down(f)
  * 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 +1331,7 @@ ipv6cp_clear_addrs(unit, ourid, hisid)
  * 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 +1342,7 @@ ipv6cp_finished(f)
  * 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 +1367,7 @@ ipv6cp_script_done(arg)
  * 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 +1398,8 @@ static char *ipv6cp_codenames[] = {
 };
 
 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 +1502,7 @@ ipv6cp_printpkt(p, plen, printer, arg)
 #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;
 
index 2f4c06ddc1892c2c27f26a519f5e78efc82fc219..19bc01362f8b9a69d032ffb1be15cac89abca4e7 100644 (file)
  * 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 $
  */
 
 /*
 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 */
index aaff10f76200fd65799edb2e45c0a506c2147933..d39b14c4848106ca26840fa58dc6b1f2c63f387a 100644 (file)
@@ -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 @@ ipxcp_options ipxcp_hisoptions[NUM_PPP];    /* Options that we ack'd */
 /*
  * 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 @@ static fsm_callbacks ipxcp_callbacks = { /* IPXCP callback routines */
 /*
  * 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 @@ static option_t ipxcp_option_list[] = {
  * 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 @@ struct protent ipxcp_protent = {
 
 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 char *ipx_ntoa __P((u_int32_t));
  */
 
 static short int
-to_external(internal)
-short int internal;
+to_external(short int internal)
 {
     short int  external;
 
@@ -248,8 +244,7 @@ short int internal;
  */
 
 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 @@ u_int32_t ipxaddr;
 
 
 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 @@ u_char *src, *dst;
 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 @@ setipxnode(argv)
     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 @@ setipxnode(argv)
 }
 
 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 @@ printipxnode(opt, printer, arg)
 }
 
 static int
-setipxname (argv)
-    char **argv;
+setipxname (char **argv)
 {
     u_char *dest = ipxcp_wantoptions[0].name;
     char *src  = *argv;
@@ -377,8 +366,7 @@ setipxname (argv)
  * ipxcp_init - Initialize IPXCP.
  */
 static void
-ipxcp_init(unit)
-    int unit;
+ipxcp_init(int unit)
 {
     fsm *f = &ipxcp_fsm[unit];
 
@@ -414,8 +402,7 @@ ipxcp_init(unit)
  */
 
 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 @@ u_char *src, *dst;
  */
 
 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 @@ u_char *src, *dst;
  */
 
 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 @@ u_char *node;
  */
 
 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 @@ u_char *node;
  * 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_open(unit)
  * 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_close(unit, reason)
  * 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_lowerup(unit)
  * 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_lowerdown(unit)
  * 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 @@ ipxcp_input(unit, p, len)
  * 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_protrej(unit)
  * 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 @@ ipxcp_resetci(f)
  */
 
 static int
-ipxcp_cilen(f)
-    fsm *f;
+ipxcp_cilen(fsm *f)
 {
     int len;
 
@@ -607,10 +580,7 @@ ipxcp_cilen(f)
  * 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 @@ ipxcp_addci(f, ucp, lenp)
  *     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 @@ ipxcp_ackci(f, p, len)
  */
 
 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 @@ bad:
  * 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 @@ ipxcp_rejci(f, p, len)
  * 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 */
@@ -1290,8 +1246,7 @@ endswitch:
  */
 
 static void
-ipxcp_up(f)
-    fsm *f;
+ipxcp_up(fsm *f)
 {
     int unit = f->unit;
 
@@ -1369,8 +1324,7 @@ ipxcp_up(f)
  */
 
 static void
-ipxcp_down(f)
-    fsm *f;
+ipxcp_down(fsm *f)
 {
     IPXCPDEBUG(("ipxcp: down"));
 
@@ -1389,8 +1343,7 @@ ipxcp_down(f)
  * 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 @@ ipxcp_finished(f)
  * 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 char *ipxcp_codenames[] = {
 };
 
 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;
index 396b6bba7df12115df7a5b47323acd9011cf933f..8a69232a8b06f658d3e90566391ee4fc8e007567 100644 (file)
@@ -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 $
  */
 
 /*
index 8ed2778bfb672084181a0b27834dfcfdbb875abb..ac5d5ce6488416afefde82633d969c7bc352a502 100644 (file)
  * 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 <stdio.h>
 #include <string.h>
 #include <stdlib.h>
@@ -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 @@ static const char rcsid[] = RCSID;
 /* 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 @@ 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,
@@ -202,31 +197,31 @@ static u_char nak_buffer[PPP_MRU];        /* where we construct a nak packet */
 /*
  * 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