]> git.ozlabs.org Git - ppp.git/commitdiff
Merge branch 'pppoatm_wildcard' of https://github.com/sthibaul/ppp
authorPaul Mackerras <paulus@ozlabs.org>
Thu, 31 Dec 2020 04:42:15 +0000 (15:42 +1100)
committerPaul Mackerras <paulus@ozlabs.org>
Thu, 31 Dec 2020 04:42:15 +0000 (15:42 +1100)
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
19 files changed:
chat/Makefile.linux
pppd/Makefile.linux
pppd/chap-new.c
pppd/eap.c
pppd/eap.h
pppd/ipcp.c
pppd/main.c
pppd/options.c
pppd/plugins/pppoatm/pppoatm.c
pppd/plugins/radius/Makefile.linux
pppd/plugins/radius/avpair.c
pppd/plugins/radius/dict.c
pppd/plugins/radius/radiusclient.h
pppd/plugins/rp-pppoe/Makefile.linux
pppd/pppd.h
pppd/sys-linux.c
pppd/sys-solaris.c
pppdump/Makefile.linux
pppstats/Makefile.linux

index 0732ec80dc2736431b1ec9178411ff0bd9e3d100..f082dab78e7b5a33c648004cf292991c9d67a594 100644 (file)
@@ -25,7 +25,7 @@ chat.o:       chat.c
 
 install: chat
        mkdir -p $(BINDIR) $(MANDIR)
-       $(INSTALL) -s -c chat $(BINDIR)
+       $(INSTALL) -c chat $(BINDIR)
        $(INSTALL) -c -m 644 chat.8 $(MANDIR)
 
 clean:
index 44d47ad7f46f35bce09a86998cf4ebaab2ebd15f..a971ff34b33d7506865912f75acbe26d5bb18614 100644 (file)
@@ -112,7 +112,7 @@ CFLAGS      += -DUSE_SRP -DOPENSSL -I/usr/local/ssl/include
 LIBS   += -lsrp -L/usr/local/ssl/lib
 NEEDCRYPTOLIB = y
 TARGETS        += srp-entry
-EXTRAINSTALL = $(INSTALL) -s -c -m 555 srp-entry $(BINDIR)/srp-entry
+EXTRAINSTALL = $(INSTALL) -c -m 555 srp-entry $(BINDIR)/srp-entry
 MANPAGES += srp-entry.8
 EXTRACLEAN += srp-entry.o
 NEEDDES=y
@@ -238,7 +238,7 @@ all: $(TARGETS)
 install: pppd
        mkdir -p $(BINDIR) $(MANDIR)
        $(EXTRAINSTALL)
-       $(INSTALL) -s -c -m 555 pppd $(BINDIR)/pppd
+       $(INSTALL) -c -m 555 pppd $(BINDIR)/pppd
        if chgrp pppusers $(BINDIR)/pppd 2>/dev/null; then \
          chmod o-rx,u+s $(BINDIR)/pppd; fi
        $(INSTALL) -c -m 444 pppd.8 $(MANDIR)
index 0b1bb86e77c0d35a03b6e58629ace81748ec36e5..fab82800a7b33950935c8b13a1be41a0982b45dd 100644 (file)
@@ -59,6 +59,7 @@ int chap_server_timeout_time = 3;
 int chap_max_transmits = 10;
 int chap_rechallenge_time = 0;
 int chap_client_timeout_time = 60;
+int chapms_strip_domain = 0;
 
 /*
  * Command-line options.
@@ -72,6 +73,8 @@ static option_t chap_option_list[] = {
          "Set interval for rechallenge", OPT_PRIO },
        { "chap-timeout", o_int, &chap_client_timeout_time,
          "Set timeout for CHAP (as client)", OPT_PRIO },
+       { "chapms-strip-domain", o_bool, &chapms_strip_domain,
+         "Strip the domain prefix before the Username", 1 },
        { NULL }
 };
 
@@ -355,6 +358,14 @@ chap_handle_response(struct chap_server_state *ss, int id,
                        /* Null terminate and clean remote name. */
                        slprintf(rname, sizeof(rname), "%.*v", len, name);
                        name = rname;
+
+                       /* strip the MS domain name */
+                       if (chapms_strip_domain && strrchr(rname, '\\')) {
+                               char tmp[MAXNAMELEN+1];
+
+                               strcpy(tmp, strrchr(rname, '\\') + 1);
+                               strcpy(rname, tmp);
+                       }
                }
 
                if (chap_verify_hook)
index 92d29ec8bd6c034995f3ebd6a7c737669d80a607..ede5ff0d3a2f09fd7015763bfadfdbda7abc0902 100644 (file)
 #ifdef USE_EAPTLS
 #include "eap-tls.h"
 #endif /* USE_EAPTLS */
+#ifdef CHAPMS
+#include "magic.h"
+#include "chap_ms.h"
+#include "chap-new.h"
+#endif /* CHAPMS */
 
 eap_state eap_states[NUM_PPP];         /* EAP state; one for each unit */
 #ifdef USE_SRP
@@ -687,6 +692,9 @@ eap_figure_next_state(eap_state *esp, int status)
                }
                break;
 
+#ifdef CHAPMS
+       case eapMSCHAPv2Chall:
+#endif
        case eapMD5Chall:
                if (status != 0) {
                        esp->es_server.ea_state = eapBadAuth;
@@ -707,6 +715,162 @@ eap_figure_next_state(eap_state *esp, int status)
 #endif /* USE_EAPTLS */
 }
 
+#if CHAPMS
+static int
+eap_chapms2_verify_response(int id, char *name,
+                           unsigned char *secret, int secret_len,
+                           unsigned char *challenge, unsigned char *response,
+                           char *message, int message_space)
+{
+       unsigned char md[MS_CHAP2_RESPONSE_LEN];
+       char saresponse[MS_AUTH_RESPONSE_LENGTH+1];
+       int challenge_len, response_len;
+
+       challenge_len = *challenge++;   /* skip length, is 16 */
+       response_len = *response++;
+       if (response_len != MS_CHAP2_RESPONSE_LEN)
+               goto bad;       /* not even the right length */
+
+       /* Generate the expected response and our mutual auth. */
+       ChapMS2(challenge, &response[MS_CHAP2_PEER_CHALLENGE], name,
+               (char *)secret, secret_len, md,
+               (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR);
+
+       /* compare MDs and send the appropriate status */
+       /*
+        * Per RFC 2759, success message must be formatted as
+        *     "S=<auth_string> M=<message>"
+        * where
+        *     <auth_string> is the Authenticator Response (mutual auth)
+        *     <message> is a text message
+        *
+        * However, some versions of Windows (win98 tested) do not know
+        * about the M=<message> part (required per RFC 2759) and flag
+        * it as an error (reported incorrectly as an encryption error
+        * to the user).  Since the RFC requires it, and it can be
+        * useful information, we supply it if the peer is a conforming
+        * system.  Luckily (?), win98 sets the Flags field to 0x04
+        * (contrary to RFC requirements) so we can use that to
+        * distinguish between conforming and non-conforming systems.
+        *
+        * Special thanks to Alex Swiridov <say@real.kharkov.ua> for
+        * help debugging this.
+        */
+       if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP],
+                  MS_CHAP2_NTRESP_LEN) == 0) {
+               if (response[MS_CHAP2_FLAGS])
+                       slprintf(message, message_space, "S=%s", saresponse);
+               else
+                       slprintf(message, message_space, "S=%s M=%s",
+                                saresponse, "Access granted");
+               return 1;
+       }
+
+ bad:
+       /*
+        * Failure message must be formatted as
+        *     "E=e R=r C=c V=v M=m"
+        * where
+        *     e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE)
+        *     r = retry (we use 1, ok to retry)
+        *     c = challenge to use for next response, we reuse previous
+        *     v = Change Password version supported, we use 0
+        *     m = text message
+        *
+        * The M=m part is only for MS-CHAPv2.  Neither win2k nor
+        * win98 (others untested) display the message to the user anyway.
+        * They also both ignore the E=e code.
+        *
+        * Note that it's safe to reuse the same challenge as we don't
+        * actually accept another response based on the error message
+        * (and no clients try to resend a response anyway).
+        *
+        * Basically, this whole bit is useless code, even the small
+        * implementation here is only because of overspecification.
+        */
+       slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s",
+                challenge_len, challenge, "Access denied");
+       return 0;
+}
+
+static struct chap_digest_type eap_chapms2_digest = {
+       CHAP_MICROSOFT_V2,      /* code */
+       NULL, /* chapms2_generate_challenge, */
+       eap_chapms2_verify_response,
+       NULL, /* chapms2_make_response, */
+       NULL, /* chapms2_check_success, */
+       NULL, /* chapms_handle_failure, */
+};
+
+/*
+ * eap_chap_verify_response - check whether the peer's response matches
+ * what we think it should be.  Returns 1 if it does (authentication
+ * succeeded), or 0 if it doesn't.
+ */
+static int
+eap_chap_verify_response(char *name, char *ourname, int id,
+                        struct chap_digest_type *digest,
+                        unsigned char *challenge, unsigned char *response,
+                        char *message, int message_space)
+{
+       int ok;
+       unsigned char secret[MAXSECRETLEN];
+       int secret_len;
+
+       /* Get the secret that the peer is supposed to know */
+       if (!get_secret(0, name, ourname, (char *)secret, &secret_len, 1)) {
+               error("No CHAP secret found for authenticating %q", name);
+               return 0;
+       }
+
+       ok = digest->verify_response(id, name, secret, secret_len, challenge,
+                                    response, message, message_space);
+       memset(secret, 0, sizeof(secret));
+
+       return ok;
+}
+
+/*
+ * Format and send an CHAPV2-Success/Failure EAP Request message.
+ */
+static void
+eap_chapms2_send_request(eap_state *esp, u_char id,
+                        u_char opcode, u_char chapid,
+                        char *message, int message_len)
+{
+       u_char *outp;
+       int msglen;
+
+       outp = outpacket_buf;
+
+       MAKEHEADER(outp, PPP_EAP);
+
+       msglen = EAP_HEADERLEN + 5 * sizeof (u_char);
+       msglen += message_len;
+
+       PUTCHAR(EAP_REQUEST, outp);
+       PUTCHAR(id, outp);
+       PUTSHORT(msglen, outp);
+       PUTCHAR(EAPT_MSCHAPV2, outp);
+       PUTCHAR(opcode, outp);
+       PUTCHAR(chapid, outp);
+       /* MS len */
+       PUTSHORT(msglen - 5, outp);
+       BCOPY(message, outp, message_len);
+
+       output(esp->es_unit, outpacket_buf, PPP_HDRLEN + msglen);
+
+       if (opcode == CHAP_SUCCESS) {
+               auth_peer_success(esp->es_unit, PPP_EAP, 0,
+                               esp->es_server.ea_peer, esp->es_server.ea_peerlen);
+       }
+       else {
+               esp->es_server.ea_state = eapBadAuth;
+               auth_peer_fail(esp->es_unit, PPP_EAP);
+       }
+}
+#endif /* CHAPMS */
+
 /*
  * Format an EAP Request message and send it to the peer.  Message
  * type depends on current state.  (Server operation)
@@ -792,6 +956,30 @@ eap_send_request(eap_state *esp)
                INCPTR(esp->es_server.ea_namelen, outp);
                break;
 
+#ifdef CHAPMS
+       case eapMSCHAPv2Chall:
+               challen = 0x10;
+               esp->es_challen = challen;
+               esp->es_challenge[0] = challen;
+               random_bytes(&esp->es_challenge[1], challen);
+
+               PUTCHAR(EAPT_MSCHAPV2, outp);
+               PUTCHAR(CHAP_CHALLENGE, outp);
+               PUTCHAR(esp->es_server.ea_id, outp);
+               /* MS len */
+               PUTSHORT(5 + challen +
+                               esp->es_server.ea_namelen,
+                               outp);
+               /* challen + challenge */
+               BCOPY(esp->es_challenge, outp, challen+1);
+               INCPTR(challen+1, outp);
+               BCOPY(esp->es_server.ea_name,
+                               outp,
+                               esp->es_server.ea_namelen);
+               INCPTR(esp->es_server.ea_namelen, outp);
+               break;
+#endif /* CHAPMS */
+
 #ifdef USE_EAPTLS
        case eapTlsStart:
                PUTCHAR(EAPT_TLS, outp);
@@ -2018,6 +2206,12 @@ eap_response(eap_state *esp, u_char *inp, int id, int len)
        struct eaptls_session *ets;
        u_char flags;
 #endif /* USE_EAPTLS */
+#ifdef CHAPMS
+       u_char opcode;
+       int (*chap_verifier)(char *, char *, int, struct chap_digest_type *,
+               unsigned char *, unsigned char *, char *, int);
+       char response_message[256];
+#endif /* CHAPMS */
 
        /*
         * Ignore responses if we're not open
@@ -2160,6 +2354,13 @@ eap_response(eap_state *esp, u_char *inp, int id, int len)
                        break;
 #endif /* USE_EAPTLS */
 
+#ifdef CHAPMS
+               case EAPT_MSCHAPV2:
+                       info("EAP: peer proposes MSCHAPv2");
+                       esp->es_server.ea_state = eapMSCHAPv2Chall;
+                       break;
+#endif /* CHAPMS */
+
                default:
                        dbglog("EAP: peer requesting unknown Type %d", vallen);
                        switch (esp->es_server.ea_state) {
@@ -2241,6 +2442,103 @@ eap_response(eap_state *esp, u_char *inp, int id, int len)
                        TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
                break;
 
+#ifdef CHAPMS
+       case EAPT_MSCHAPV2:
+               if (len < 1) {
+                       error("EAP: received MSCHAPv2 with no data");
+                       eap_figure_next_state(esp, 1);
+                       break;
+               }
+               GETCHAR(opcode, inp);
+               len--;
+
+               switch (opcode) {
+               case CHAP_RESPONSE:
+                       if (esp->es_server.ea_state != eapMSCHAPv2Chall) {
+                               error("EAP: unexpected MSCHAPv2-Response");
+                               eap_figure_next_state(esp, 1);
+                               break;
+                       }
+                       /* skip MS ID + len */
+                       INCPTR(3, inp);
+                       GETCHAR(vallen, inp);
+                       len -= 4;
+
+                       if (vallen != MS_CHAP2_RESPONSE_LEN || vallen > len) {
+                               error("EAP: Invalid MSCHAPv2-Response "
+                                               "length %d", vallen);
+                               eap_figure_next_state(esp, 1);
+                               break;
+                       }
+
+                       /* Not so likely to happen. */
+                       if (len - vallen >= sizeof (rhostname)) {
+                               dbglog("EAP: trimming really long peer name down");
+                               BCOPY(inp + vallen, rhostname, sizeof (rhostname) - 1);
+                               rhostname[sizeof (rhostname) - 1] = '\0';
+                       } else {
+                               BCOPY(inp + vallen, rhostname, len - vallen);
+                               rhostname[len - vallen] = '\0';
+                       }
+
+                       /* In case the remote doesn't give us his name. */
+                       if (explicit_remote ||
+                                       (remote_name[0] != '\0' && vallen == len))
+                               strlcpy(rhostname, remote_name, sizeof (rhostname));
+
+                       if (chap_verify_hook)
+                               chap_verifier = chap_verify_hook;
+                       else
+                               chap_verifier = eap_chap_verify_response;
+
+                       esp->es_server.ea_id += 1;
+                       if ((*chap_verifier)(rhostname,
+                                               esp->es_server.ea_name,
+                                               id,
+                                               &eap_chapms2_digest,
+                                               esp->es_challenge,
+                                               inp - 1,
+                                               response_message,
+                                               sizeof(response_message)))
+                       {
+                               info("EAP: MSCHAPv2 success for peer %q",
+                                               rhostname);
+                               esp->es_server.ea_type = EAPT_MSCHAPV2;
+                               eap_chapms2_send_request(esp,
+                                               esp->es_server.ea_id,
+                                               CHAP_SUCCESS,
+                                               esp->es_server.ea_id,
+                                               response_message,
+                                               strlen(response_message));
+                               eap_figure_next_state(esp, 0);
+                               if (esp->es_rechallenge != 0)
+                                       TIMEOUT(eap_rechallenge, esp, esp->es_rechallenge);
+                       }
+                       else {
+                               warn("EAP: MSCHAPv2 failure for peer %q",
+                                               rhostname);
+                               eap_chapms2_send_request(esp,
+                                               esp->es_server.ea_id,
+                                               CHAP_FAILURE,
+                                               esp->es_server.ea_id,
+                                               response_message,
+                                               strlen(response_message));
+                       }
+                       break;
+               case CHAP_SUCCESS:
+                       info("EAP: MSCHAPv2 success confirmed");
+                       break;
+               case CHAP_FAILURE:
+                       info("EAP: MSCHAPv2 failure confirmed");
+                       break;
+               default:
+                       error("EAP: Unhandled MSCHAPv2 opcode %d", opcode);
+                       eap_send_nak(esp, id, EAPT_SRP);
+               }
+
+               break;
+#endif /* CHAPMS */
+
 #ifdef USE_SRP
        case EAPT_SRP:
                if (len < 1) {
@@ -2499,7 +2797,9 @@ static char *eap_typenames[] = {
        "OTP", "Generic-Token", NULL, NULL,
        "RSA", "DSS", "KEA", "KEA-Validate",
        "TLS", "Defender", "Windows 2000", "Arcot",
-       "Cisco", "Nokia", "SRP"
+       "Cisco", "Nokia", "SRP", NULL,
+       "TTLS", "RAS", "AKA", "3COM", "PEAP",
+       "MSCHAPv2"
 };
 
 static int
@@ -2512,6 +2812,9 @@ eap_printpkt(u_char *inp, int inlen,
 #ifdef USE_EAPTLS
        u_char flags;
 #endif /* USE_EAPTLS */
+#ifdef CHAPMS
+       u_char opcode;
+#endif /* CHAPMS */
 
        if (inlen < EAP_HEADERLEN)
                return (0);
@@ -2576,6 +2879,61 @@ eap_printpkt(u_char *inp, int inlen,
                        }
                        break;
 
+#ifdef CHAPMS
+               case EAPT_MSCHAPV2:
+                       if (len <= 0)
+                               break;
+                       GETCHAR(opcode, inp);
+                       len--;
+                       switch (opcode) {
+                       case CHAP_CHALLENGE:
+                               INCPTR(3, inp);
+                               len -= 3;
+                               GETCHAR(vallen, inp);
+                               len--;
+                               if (vallen > len)
+                                       goto truncated;
+                               len -= vallen;
+                               printer(arg, " Challenge <");
+                               for (; vallen > 0; --vallen) {
+                                       u_char val;
+                                       GETCHAR(val, inp);
+                                       printer(arg, "%.2x", val);
+                               }
+                               printer(arg, ">");
+                               if (len > 0) {
+                                       printer(arg, ", <Name ");
+                                       print_string((char *)inp, len, printer, arg);
+                                       printer(arg, ">");
+                                       INCPTR(len, inp);
+                                       len = 0;
+                               } else {
+                                       printer(arg, ", <No name>");
+                               }
+                               break;
+                       case CHAP_SUCCESS:
+                               INCPTR(3, inp);
+                               len -= 3;
+                               printer(arg, " Success <Message ");
+                               print_string((char *)inp, len, printer, arg);
+                               printer(arg, ">");
+                               break;
+                       case CHAP_FAILURE:
+                               INCPTR(3, inp);
+                               len -= 3;
+                               printer(arg, " Failure <Message ");
+                               print_string((char *)inp, len, printer, arg);
+                               printer(arg, ">");
+                               break;
+                       default:
+                               INCPTR(3, inp);
+                               len -= 3;
+                               printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
+                               break;
+                       }
+                       break;
+#endif /* CHAPMS */
+
 #ifdef USE_EAPTLS
                case EAPT_TLS:
                        if (len < 1)
@@ -2761,6 +3119,51 @@ eap_printpkt(u_char *inp, int inlen,
                        }
                        break;
 
+#ifdef CHAPMS
+               case EAPT_MSCHAPV2:
+                       if (len <= 0)
+                               break;
+                       GETCHAR(opcode, inp);
+                       len--;
+                       switch (opcode) {
+                       case CHAP_RESPONSE:
+                               INCPTR(3, inp);
+                               len -= 3;
+                               GETCHAR(vallen, inp);
+                               len--;
+                               if (vallen > len)
+                                       goto truncated;
+                               len -= vallen;
+                               printer(arg, " Response <");
+                               for (; vallen > 0; --vallen) {
+                                       u_char val;
+                                       GETCHAR(val, inp);
+                                       printer(arg, "%.2x", val);
+                               }
+                               printer(arg, ">");
+                               if (len > 0) {
+                                       printer(arg, ", <Name ");
+                                       print_string((char *)inp, len, printer, arg);
+                                       printer(arg, ">");
+                                       INCPTR(len, inp);
+                                       len = 0;
+                               } else {
+                                       printer(arg, ", <No name>");
+                               }
+                               break;
+                       case CHAP_SUCCESS:
+                               printer(arg, " Success");
+                               break;
+                       case CHAP_FAILURE:
+                               printer(arg, " Failure");
+                               break;
+                       default:
+                               printer(arg, " opcode=0x%x <%.*B>", opcode, len, inp);
+                               break;
+                       }
+                       break;
+#endif /* CHAPMS */
+
                case EAPT_SRP:
                        if (len < 1)
                                goto truncated;
index 56bef136d75590a7f9b6073d9ab93c7adb2f2c98..f72fe61bcbfe1c3d30379a42817d67e6b6530130 100644 (file)
@@ -59,6 +59,18 @@ extern "C" {
 #define        EAPT_NOKIACARD          18      /* Nokia IP smart card */
 #define        EAPT_SRP                19      /* Secure Remote Password */
 /* 20 is deprecated */
+#define        EAPT_TTLS               21      /* EAP Tunneled TLS Authentication Protocol RFC5281 */
+#define        EAPT_RAS                22      /* Remote Access Service */
+#define        EAPT_AKA                23      /* EAP method for 3rd Generation Authentication and Key Agreement RFC4187 */
+#define        EAPT_3COM               24      /* EAP-3Com Wireless */
+#define        EAPT_PEAP               25      /* Protected EAP */
+#define        EAPT_MSCHAPV2           26      /* EAP-MSCHAPv2 RFC-draft-kamath-pppext-eap-mschapv2-02 */
+
+/* OpCodes for MSCHAPv2 */
+#define CHAP_CHALLENGE         1
+#define CHAP_RESPONSE          2
+#define CHAP_SUCCESS           3
+#define CHAP_FAILURE           4
 
 /* EAP SRP-SHA1 Subtypes */
 #define        EAPSRP_CHALLENGE        1       /* Request 1 - Challenge */
@@ -98,6 +110,7 @@ enum eap_state_code {
        eapSRP2,        /* Sent EAP SRP-SHA1 Subtype 2 */
        eapSRP3,        /* Sent EAP SRP-SHA1 Subtype 3 */
        eapMD5Chall,    /* Sent MD5-Challenge */
+       eapMSCHAPv2Chall,       /* Sent MSCHAPv2-Challenge */
        eapOpen,        /* Completed authentication */
        eapSRP4,        /* Sent EAP SRP-SHA1 Subtype 4 */
        eapBadAuth      /* Failed authentication */
@@ -107,7 +120,7 @@ enum eap_state_code {
        "Initial", "Pending", "Closed", "Listen", "Identify", \
        "TlsStart", "TlsRecv", "TlsSendAck", "TlsSend", "TlsRecvAck", "TlsRecvClient",\
        "TlsSendAlert", "TlsRecvAlertAck" , "TlsRecvSuccess", "TlsRecvFailure", \
-       "SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth"
+       "SRP1", "SRP2", "SRP3", "MD5Chall", "MSCHAPv2Chall", "Open", "SRP4", "BadAuth"
 
 #ifdef USE_EAPTLS
 #define        eap_client_active(esp)  ((esp)->es_client.ea_state != eapInitial &&\
index 7357ac8ea546323f3ba178db99f0e77639beef3f..f8942a9645592ad7961b2555f8c8fd0393f23c1d 100644 (file)
@@ -1922,7 +1922,7 @@ ipcp_up(fsm *f)
      */
     if (ipcp_script_state == s_down && ipcp_script_pid == 0) {
        ipcp_script_state = s_up;
-       ipcp_script(_PATH_IPUP, 0);
+       ipcp_script(path_ipup, 0);
     }
 }
 
@@ -1971,7 +1971,7 @@ ipcp_down(fsm *f)
     /* Execute the ip-down script */
     if (ipcp_script_state == s_up && ipcp_script_pid == 0) {
        ipcp_script_state = s_down;
-       ipcp_script(_PATH_IPDOWN, 0);
+       ipcp_script(path_ipdown, 0);
     }
 }
 
@@ -2020,13 +2020,13 @@ ipcp_script_done(void *arg)
     case s_up:
        if (ipcp_fsm[0].state != OPENED) {
            ipcp_script_state = s_down;
-           ipcp_script(_PATH_IPDOWN, 0);
+           ipcp_script(path_ipdown, 0);
        }
        break;
     case s_down:
        if (ipcp_fsm[0].state == OPENED) {
            ipcp_script_state = s_up;
-           ipcp_script(_PATH_IPUP, 0);
+           ipcp_script(path_ipup, 0);
        }
        break;
     }
index 099c0505a4217ff942e75ffe3fb419996a0e7b57..aaaa5c8f8f7bcb8ba91733c2eb35ed7c97a66230 100644 (file)
@@ -293,6 +293,9 @@ main(int argc, char *argv[])
     struct protent *protp;
     char numbuf[16];
 
+    strlcpy(path_ipup, _PATH_IPUP, sizeof(path_ipup));
+    strlcpy(path_ipdown, _PATH_IPDOWN, sizeof(path_ipdown));
+
     link_stats_valid = 0;
     new_phase(PHASE_INITIALIZE);
 
@@ -763,8 +766,7 @@ detach(void)
        /* update pid files if they have been written already */
        if (pidfilename[0])
            create_pidfile(pid);
-       if (linkpidfile[0])
-           create_linkpidfile(pid);
+       create_linkpidfile(pid);
        exit(0);                /* parent dies */
     }
     setsid();
index c45f7cc552cbe1eba97b374b6fcd5e86259210dc..108e2b8c1197968f770bb3bb40bc560f9a53c19a 100644 (file)
@@ -115,6 +115,8 @@ char        linkname[MAXPATHLEN];   /* logical name for link */
 bool   tune_kernel;            /* may alter kernel settings */
 int    connect_delay = 1000;   /* wait this many ms after connect script */
 int    req_unit = -1;          /* requested interface unit */
+char   path_ipup[MAXPATHLEN];  /* pathname of ip-up script */
+char   path_ipdown[MAXPATHLEN];/* pathname of ip-down script */
 char   req_ifname[MAXIFNAMELEN];       /* requested interface name */
 bool   multilink = 0;          /* Enable multilink operation */
 char   *bundle_name = NULL;    /* bundle name for multilink */
@@ -315,6 +317,13 @@ option_t general_options[] = {
       "Metric to use for the default route (Linux only; -1 for default behavior)",
       OPT_PRIV|OPT_LLIMIT|OPT_INITONLY, NULL, 0, -1 },
 
+    { "ip-up-script", o_string, path_ipup,
+      "Set pathname of ip-up script",
+      OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+    { "ip-down-script", o_string, path_ipdown,
+      "Set pathname of ip-down script",
+      OPT_PRIV|OPT_STATIC, NULL, MAXPATHLEN },
+
 #ifdef HAVE_MULTILINK
     { "multilink", o_bool, &multilink,
       "Enable multilink operation", OPT_PRIO | 1 },
index cef5ff75dfd5471cce92a274982994e69e2c256a..5a3ecd61b6a2c278781ad94151c6e92458b4f77b 100644 (file)
@@ -70,18 +70,20 @@ static int setdevname_pppoatm(const char *cp, const char **argv, int doit)
 {
        struct sockaddr_atmpvc addr;
        extern struct stat devstat;
+
        if (device_got_set)
                return 0;
-       //info("PPPoATM setdevname_pppoatm: '%s'", cp);
+
        memset(&addr, 0, sizeof addr);
        if (text2atm(cp, (struct sockaddr *) &addr, sizeof(addr),
            T2A_PVC | T2A_NAME | T2A_WILDCARD) < 0) {
-               if(doit)
-                   info("atm does not recognize: %s", cp);
+               if (doit)
+                       info("cannot parse the ATM address: %s", cp);
                return 0;
-           }
-       if (!doit) return 1;
-       //if (!dev_set_ok()) return -1;
+       }
+       if (!doit)
+               return 1;
+
        memcpy(&pvcaddr, &addr, sizeof pvcaddr);
        strlcpy(devnam, cp, sizeof devnam);
        devstat.st_mode = S_IFSOCK;
@@ -93,7 +95,6 @@ static int setdevname_pppoatm(const char *cp, const char **argv, int doit)
                lcp_allowoptions[0].neg_asyncmap = 0;
                lcp_wantoptions[0].neg_pcompression = 0;
        }
-       info("PPPoATM setdevname_pppoatm - SUCCESS:%s", cp);
        device_got_set = 1;
        return 1;
 }
@@ -108,6 +109,7 @@ static void no_device_given_pppoatm(void)
 static void set_line_discipline_pppoatm(int fd)
 {
        struct atm_backend_ppp be;
+
        be.backend_num = ATM_BACKEND_PPP;
        if (!llc_encaps)
                be.encaps = PPPOATM_ENCAPS_VC;
@@ -115,6 +117,7 @@ static void set_line_discipline_pppoatm(int fd)
                be.encaps = PPPOATM_ENCAPS_LLC;
        else
                be.encaps = PPPOATM_ENCAPS_AUTODETECT;
+
        if (ioctl(fd, ATM_SETBACKEND, &be) < 0)
                fatal("ioctl(ATM_SETBACKEND): %m");
 }
@@ -168,7 +171,7 @@ static void disconnect_pppoatm(void)
 
 void plugin_init(void)
 {
-#if defined(__linux__)
+#ifdef linux
        extern int new_style_driver;    /* From sys-linux.c */
        if (!ppp_available() && !new_style_driver)
                fatal("Kernel doesn't support ppp_generic - "
@@ -176,9 +179,9 @@ void plugin_init(void)
 #else
        fatal("No PPPoATM support on this OS");
 #endif
-       info("PPPoATM plugin_init");
        add_options(pppoa_options);
 }
+
 struct channel pppoa_channel = {
     options: pppoa_options,
     process_extra_options: NULL,
index e7022636906d8219d75165fda6ffccda695c9fe0..ddfa9b544194b023f2d748d139f494ad9cee0cff 100644 (file)
@@ -36,9 +36,9 @@ all: $(PLUGIN)
 
 install: all
        $(INSTALL) -d -m 755 $(LIBDIR)
-       $(INSTALL) -s -c -m 755 radius.so $(LIBDIR)
-       $(INSTALL) -s -c -m 755 radattr.so $(LIBDIR)
-       $(INSTALL) -s -c -m 755 radrealms.so $(LIBDIR)
+       $(INSTALL) -c -m 755 radius.so $(LIBDIR)
+       $(INSTALL) -c -m 755 radattr.so $(LIBDIR)
+       $(INSTALL) -c -m 755 radrealms.so $(LIBDIR)
        $(INSTALL) -c -m 444 pppd-radius.8 $(MANDIR)
        $(INSTALL) -c -m 444 pppd-radattr.8 $(MANDIR)
 
index ebc1895c0a6900d79e8d799e596e1169dcaad8e4..b97a7cf3632fbf4dcdccf51e724abe68c59ac897 100644 (file)
@@ -222,6 +222,9 @@ VALUE_PAIR *rc_avpair_gen (AUTH_HDR *auth)
                        {
 
                            case PW_TYPE_STRING:
+                           case PW_TYPE_IFID:
+                           case PW_TYPE_IPV6ADDR:
+                           case PW_TYPE_IPV6PREFIX:
                                memcpy (pair->strvalue, (char *) ptr, (size_t) attrlen);
                                pair->strvalue[attrlen] = '\0';
                                pair->lvalue = attrlen;
@@ -692,9 +695,10 @@ int rc_avpair_parse (char *buffer, VALUE_PAIR **first_pair)
 int rc_avpair_tostr (VALUE_PAIR *pair, char *name, int ln, char *value, int lv)
 {
        DICT_VALUE     *dval;
-       char            buffer[32];
+       char            buffer[INET6_ADDRSTRLEN + 4]; // for a prefix: addr + '/' + prefixlen
        struct in_addr  inad;
        unsigned char         *ptr;
+       char            *str;
 
        *name = *value = '\0';
 
@@ -753,6 +757,26 @@ int rc_avpair_tostr (VALUE_PAIR *pair, char *name, int ln, char *value, int lv)
                strncpy(value, buffer, lv-1);
                break;
 
+           case PW_TYPE_IFID:
+               ptr = pair->strvalue;
+               snprintf(buffer, sizeof (buffer), "%x:%x:%x:%x",
+                        (ptr[0] << 8) + ptr[1], (ptr[2] << 8) + ptr[3],
+                        (ptr[4] << 8) + ptr[5], (ptr[6] << 8) + ptr[7]);
+               strncpy(value, buffer, lv-1);
+               break;
+
+           case PW_TYPE_IPV6ADDR:
+               inet_ntop(AF_INET6, pair->strvalue, buffer, sizeof (buffer));
+               strncpy(value, buffer, lv-1);
+               break;
+
+           case PW_TYPE_IPV6PREFIX:
+               inet_ntop(AF_INET6, pair->strvalue + 2, buffer, sizeof (buffer));
+               str = buffer + strlen(buffer);
+               snprintf(str, sizeof (buffer) - (str - buffer), "/%d", *(pair->strvalue + 1));
+               strncpy(value, buffer, lv-1);
+               break;
+
            default:
                error("rc_avpair_tostr: unknown attribute type %d", pair->type);
                return (-1);
index 72b3e708cb20718c897d3d3bc1cfd377a15c6071..3b2add2ae4e7cbc7fe84b67b83a3722d4b8e6f73 100644 (file)
@@ -158,6 +158,18 @@ int rc_read_dictionary (char *filename)
                        {
                                type = PW_TYPE_DATE;
                        }
+                       else if (strcmp (typestr, "ifid") == 0)
+                       {
+                               type = PW_TYPE_IFID;
+                       }
+                       else if (strcmp (typestr, "ipv6addr") == 0)
+                       {
+                               type = PW_TYPE_IPV6ADDR;
+                       }
+                       else if (strcmp (typestr, "ipv6prefix") == 0)
+                       {
+                               type = PW_TYPE_IPV6PREFIX;
+                       }
                        else
                        {
                                error("rc_read_dictionary: invalid type on line %d of dictionary %s",
index c3a8e7abb21332e1eb97a7f7b498bb77cddd24be..17f64259d222364f5d12a39da4e65baddcc22451 100644 (file)
@@ -77,6 +77,17 @@ typedef struct pw_auth_hdr
 #define PW_TYPE_INTEGER                        1
 #define PW_TYPE_IPADDR                 2
 #define PW_TYPE_DATE                   3
+#define PW_TYPE_ABINARY                        4
+#define PW_TYPE_OCTETS                 5
+#define PW_TYPE_IFID                   6
+#define PW_TYPE_IPV6ADDR               7
+#define PW_TYPE_IPV6PREFIX             8
+#define PW_TYPE_BYTE                   9
+#define PW_TYPE_SHORT                  10
+#define PW_TYPE_ETHERNET               11
+#define PW_TYPE_SIGNED                 12
+#define PW_TYPE_COMBO_IP               13
+#define PW_TYPE_TLV                    14
 
 /* standard RADIUS codes */
 
index 749ccc2c931cc8406189fe90ae7d53219db4ed99..2c93f4a34b7fb02a8a27d3228b4dae38779faa16 100644 (file)
@@ -43,9 +43,9 @@ rp-pppoe.so: plugin.o discovery.o if.o common.o
 
 install: all
        $(INSTALL) -d -m 755 $(LIBDIR)
-       $(INSTALL) -s -c -m 4550 rp-pppoe.so $(LIBDIR)
+       $(INSTALL) -c -m 4550 rp-pppoe.so $(LIBDIR)
        $(INSTALL) -d -m 755 $(BINDIR)
-       $(INSTALL) -s -c -m 555 pppoe-discovery $(BINDIR)
+       $(INSTALL) -c -m 555 pppoe-discovery $(BINDIR)
 
 clean:
        rm -f *.o *.so pppoe-discovery
index b5f3ad2a5d5f725943606b6b8ff47969ef15e0d5..32b914ef6c2a4b022726c3e52ab9bfb5cf94fa4a 100644 (file)
@@ -325,6 +325,8 @@ extern bool tune_kernel;    /* May alter kernel settings as necessary */
 extern int     connect_delay;  /* Time to delay after connect script */
 extern int     max_data_rate;  /* max bytes/sec through charshunt */
 extern int     req_unit;       /* interface unit number to use */
+extern char    path_ipup[MAXPATHLEN]; /* pathname of ip-up script */
+extern char    path_ipdown[MAXPATHLEN]; /* pathname of ip-down script */
 extern char    req_ifname[MAXIFNAMELEN]; /* interface name to use */
 extern bool    multilink;      /* enable multilink operation */
 extern bool    noendpoint;     /* don't send or accept endpt. discrim. */
index 6e1423808458c32f61e57293fdfcd486fffaeb29..587242bb1ed7a2cb0107061a2109e17ccdde1dd1 100644 (file)
@@ -467,6 +467,13 @@ int generic_establish_ppp (int fd)
     if (new_style_driver) {
        int flags;
 
+       /* If a ppp_fd is already open, close it first */
+       if (ppp_fd >= 0) {
+           close(ppp_fd);
+           remove_fd(ppp_fd);
+           ppp_fd = -1;
+       }
+
        /* Open an instance of /dev/ppp and connect the channel to it */
        if (ioctl(fd, PPPIOCGCHAN, &chindex) == -1) {
            error("Couldn't get channel number: %m");
@@ -2087,7 +2094,7 @@ get_if_hwaddr(u_char *addr, char *name)
 
        sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
        if (sock_fd < 0)
-               return 0;
+               return -1;
        memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
        strlcpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
        ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
@@ -2101,10 +2108,43 @@ get_if_hwaddr(u_char *addr, char *name)
  * get_first_ethernet - return the name of the first ethernet-style
  * interface on this system.
  */
+static char first_ether_name[IF_NAMESIZE];
 char *
 get_first_ethernet(void)
 {
-       return "eth0";
+       struct if_nameindex *if_ni, *i;
+       struct ifreq ifreq;
+       int ret, sock_fd;
+
+       sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
+       if (sock_fd < 0)
+               return NULL;
+
+       if_ni = if_nameindex();
+       if (!if_ni) {
+               close(sock_fd);
+               return NULL;
+       }
+
+       first_ether_name[0] = 0;
+
+       for (i = if_ni; !(i->if_index == 0 && i->if_name == NULL); i++) {
+               memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
+               strlcpy(ifreq.ifr_name, i->if_name, sizeof(ifreq.ifr_name));
+               ret = ioctl(sock_fd, SIOCGIFHWADDR, &ifreq);
+               if (ret >= 0 && ifreq.ifr_hwaddr.sa_family == ARPHRD_ETHER) {
+                       strlcpy(first_ether_name, i->if_name, sizeof(first_ether_name));
+                       break;
+               }
+       }
+
+       if_freenameindex(if_ni);
+       close(sock_fd);
+
+       if (!first_ether_name[0])
+               return NULL;
+
+       return first_ether_name;
 }
 
 /********************************************************************
index d96d23c26d6c587b2e7f44986bc6db4a339af85c..6e925f9fc4623edc295babf77054dc1f162587ef 100644 (file)
@@ -1508,7 +1508,7 @@ netif_set_mtu(int unit, int mtu)
 
     memset(&ifr, 0, sizeof(ifr));
     strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
-    ifr.ifr_metric = link_mtu;
+    ifr.ifr_metric = mtu;
     if (ioctl(ipfd, SIOCSIFMTU, &ifr) < 0) {
        error("Couldn't set IP MTU (%s): %m", ifr.ifr_name);
     }
@@ -1520,7 +1520,7 @@ netif_set_mtu(int unit, int mtu)
 
     memset(&lifr, 0, sizeof(lifr));
     strlcpy(lifr.lifr_name, ifname, sizeof(lifr.lifr_name));
-    lifr.lifr_mtu = link_mtu;
+    lifr.lifr_mtu = mtu;
     if (ioctl(fd, SIOCSLIFMTU, &lifr) < 0) {
        close(fd);
        error("Couldn't set IPv6 MTU (%s): %m", ifr.ifr_name);
index cdf7ac4341fb4859d105970bf53ff208cd06f7cd..b61bc9dda31896508ccd217e2b5c3a09212cfd18 100644 (file)
@@ -2,20 +2,44 @@ DESTDIR = $(INSTROOT)@DESTDIR@
 BINDIR = $(DESTDIR)/sbin
 MANDIR = $(DESTDIR)/share/man/man8
 
+DO_DEFLATE=y
+DO_BSD_COMPRESS=y
+HAVE_ZLIB=n
+
 CFLAGS= -O -I../include/net
-OBJS = pppdump.o bsd-comp.o deflate.o zlib.o
+OBJS = pppdump.o
+LIBS =
+
+ifdef DO_DEFLATE
+CFLAGS += -DDO_DEFLATE=1
+OBJS += deflate.o
+ifdef HAVE_ZLIB
+LIBS += -lz
+else
+OBJS += zlib.o
+endif
+else
+CFLAGS += -DDO_DEFLATE=0
+endif
+
+ifdef DO_BSD_COMPRESS
+CFLAGS += -DDO_BSD_COMPRESS=1
+OBJS += bsd-comp.o
+else
+CFLAGS += -DDO_BSD_COMPRESS=0
+endif
 
 INSTALL= install
 
 all:   pppdump
 
 pppdump: $(OBJS)
-       $(CC) $(LDFLAGS) -o pppdump $(OBJS)
+       $(CC) $(LDFLAGS) -o pppdump $(OBJS) $(LIBS)
 
 clean:
        rm -f pppdump $(OBJS) *~
 
 install:
        mkdir -p $(BINDIR) $(MANDIR)
-       $(INSTALL) -s -c pppdump $(BINDIR)
+       $(INSTALL) -c pppdump $(BINDIR)
        $(INSTALL) -c -m 444 pppdump.8 $(MANDIR)
index 71afbe67eff4916bfd70bb4ba9bf01b8d1c3d374..181937089753cf02dc64d50a10906d092b9ca3e9 100644 (file)
@@ -22,7 +22,7 @@ all: pppstats
 
 install: pppstats
        -mkdir -p $(MANDIR)
-       $(INSTALL) -s -c pppstats $(BINDIR)
+       $(INSTALL) -c pppstats $(BINDIR)
        $(INSTALL) -c -m 444 pppstats.8 $(MANDIR)
 
 pppstats: $(PPPSTATSRCS)