Hi gerhard and tech,

You wrote the following in 2015 and I was wondering if it was worth
upstreaming it:

The PPPoE kernel module gets a new option auto for the authproto
in addition to pap and chap in client mode.

In this case the authentication protocol sent by the server in the
LCP configure request is used.

by gerhard@

Index: sbin/ifconfig/ifconfig.8
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.8,v
retrieving revision 1.390
diff -u -p -r1.390 ifconfig.8
--- sbin/ifconfig/ifconfig.8    27 Feb 2023 14:53:38 -0000      1.390
+++ sbin/ifconfig/ifconfig.8    10 Mar 2023 19:56:33 -0000
@@ -1693,6 +1693,7 @@ interface acting as a client.
 The protocol name can be either
 .Ql chap ,
 .Ql pap ,
+.Ql auto ,
 or
 .Ql none .
 In the latter case, authentication will be turned off.
Index: sbin/ifconfig/ifconfig.c
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.461
diff -u -p -r1.461 ifconfig.c
--- sbin/ifconfig/ifconfig.c    18 Jan 2023 21:57:10 -0000      1.461
+++ sbin/ifconfig/ifconfig.c    10 Mar 2023 19:56:33 -0000
@@ -5481,6 +5481,8 @@ setspppproto(const char *val, int d)
                spa.proto = PPP_PAP;
        else if (strcmp(val, "chap") == 0)
                spa.proto = PPP_CHAP;
+       else if (d == 0 && strcmp(val, "auto") == 0)
+               spa.proto = PPP_AUTOAUTH;
        else if (strcmp(val, "none") == 0)
                spa.proto = 0;
        else
@@ -5588,6 +5590,9 @@ sppp_printproto(const char *name, struct
                break;
        case PPP_CHAP:
                printf("chap ");
+               break;
+       case PPP_AUTOAUTH:
+               printf("auto ");
                break;
        default:
                printf("0x%04x ", auth->proto);
Index: sys/net/if_sppp.h
===================================================================
RCS file: /cvs/src/sys/net/if_sppp.h,v
retrieving revision 1.30
diff -u -p -r1.30 if_sppp.h
--- sys/net/if_sppp.h   17 Nov 2021 18:00:24 -0000      1.30
+++ sys/net/if_sppp.h   10 Mar 2023 19:56:33 -0000
@@ -40,6 +40,8 @@
 #ifndef _NET_IF_SPPP_H_
 #define _NET_IF_SPPP_H_
 
+#define PPP_AUTOAUTH           0xffee  /* automatic auth protocol selection */
+
 #define AUTHFLAG_NOCALLOUT     1 /* don't require authentication on callouts */
 #define AUTHFLAG_NORECHALLENGE 2 /* don't re-challenge CHAP */
 
@@ -185,6 +187,7 @@ struct sppp {
        struct sipcp ipv6cp;            /* IPV6CP params */
        struct sauth myauth;            /* auth params, i'm peer */
        struct sauth hisauth;           /* auth params, i'm authenticator */
+       u_short peerproto;              /* auth protocol requested by peer */
        u_char chap_challenge[AUTHCHALEN]; /* random challenge used by CHAP */
 
        /*
Index: sys/net/if_spppsubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_spppsubr.c,v
retrieving revision 1.191
diff -u -p -r1.191 if_spppsubr.c
--- sys/net/if_spppsubr.c       2 Jan 2022 22:36:03 -0000       1.191
+++ sys/net/if_spppsubr.c       10 Mar 2023 19:57:55 -0000
@@ -1894,11 +1894,16 @@ sppp_lcp_RCR(struct sppp *sp, struct lcp
 
                case LCP_OPT_AUTH_PROTO:
                        authproto = (p[2] << 8) + p[3];
-                       if (sp->myauth.proto != authproto) {
+                       if (sp->myauth.proto == PPP_AUTOAUTH) {
+                               if (debug)
+                                       addlog("[peer wants %s] ",
+                                              sppp_proto_name(authproto));
+                               sp->peerproto = authproto;
+                       } else if (sp->myauth.proto != authproto) {
                                /* not agreed, nak */
                                if (debug)
                                        addlog("[mine %s != his %s] ",
-                                              
sppp_proto_name(sp->hisauth.proto),
+                                              
sppp_proto_name(sp->myauth.proto),
                                               sppp_proto_name(authproto));
                                p[2] = sp->myauth.proto >> 8;
                                p[3] = sp->myauth.proto;
@@ -3409,7 +3414,8 @@ sppp_chap_input(struct sppp *sp, struct 
                }
                x = splnet();
                sp->pp_flags &= ~PP_NEEDAUTH;
-               if (sp->myauth.proto == PPP_CHAP &&
+               if ((sp->myauth.proto == PPP_CHAP ||
+                   sp->myauth.proto == PPP_AUTOAUTH) &&
                    (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) &&
                    (sp->lcp.protos & (1 << IDX_CHAP)) == 0) {
                        /*
@@ -3558,7 +3564,8 @@ sppp_chap_init(struct sppp *sp)
 void
 sppp_chap_open(struct sppp *sp)
 {
-       if (sp->myauth.proto == PPP_CHAP &&
+       if ((sp->myauth.proto == PPP_CHAP ||
+           (sp->myauth.proto == PPP_AUTOAUTH && sp->peerproto == PPP_CHAP)) &&
            (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) != 0) {
                /* we are authenticator for CHAP, start it */
                chap.scr(sp);
@@ -3814,7 +3821,8 @@ sppp_pap_input(struct sppp *sp, struct m
                }
                x = splnet();
                sp->pp_flags &= ~PP_NEEDAUTH;
-               if (sp->myauth.proto == PPP_PAP &&
+               if ((sp->myauth.proto == PPP_PAP ||
+                   sp->myauth.proto == PPP_AUTOAUTH) &&
                    (sp->lcp.opts & (1 << LCP_OPT_AUTH_PROTO)) &&
                    (sp->lcp.protos & (1 << IDX_PAP)) == 0) {
                        /*
@@ -3879,7 +3887,8 @@ sppp_pap_open(struct sppp *sp)
                sp->rst_counter[IDX_PAP] = sp->lcp.max_configure;
                sppp_cp_change_state(&pap, sp, STATE_REQ_SENT);
        }
-       if (sp->myauth.proto == PPP_PAP) {
+       if (sp->myauth.proto == PPP_PAP ||
+           (sp->myauth.proto == PPP_AUTOAUTH && sp->peerproto == PPP_PAP)) {
                /* we are peer, send a request, and start a timer */
                pap.scr(sp);
                timeout_add_sec(&sp->pap_my_to_ch, sp->lcp.timeout);
@@ -4643,7 +4652,7 @@ sppp_set_params(struct sppp *sp, struct 
                }
 
                if (spa->proto != 0 && spa->proto != PPP_PAP &&
-                   spa->proto != PPP_CHAP) {
+                   spa->proto != PPP_CHAP && spa->proto != PPP_AUTOAUTH) {
                        free(spa, M_DEVBUF, sizeof(*spa));
                        return EINVAL;
                }
@@ -4853,6 +4862,7 @@ sppp_proto_name(u_short proto)
        case PPP_IPV6CP: return "ipv6cp";
        case PPP_PAP:   return "pap";
        case PPP_CHAP:  return "chap";
+       case PPP_AUTOAUTH: return "auto";
        }
        snprintf(buf, sizeof buf, "0x%x", (unsigned)proto);
        return buf;

Reply via email to