Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Jan 2001 15:38:32 +0300 (MSK)
From:      Kovirshin.Alexey@orb.ru (cyberwin@mail.ru)
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/24569: [PATCH] New fetures for PPPD 
Message-ID:  <200101231238.PAA03005@orb.ru>

next in thread | raw e-mail | index | archive | help

>Number:         24569
>Category:       bin
>Synopsis:       PATCH for PPPD
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jan 23 04:40:01 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Kovirshin Alexey
>Release:        FreeBSD 4.1-RELEASE i386
>Organization:
>Environment:
FreeBSD orb.ru 4.1-RELEASE FreeBSD 4.1-RELEASE #2: Thu Jan 18 22:36:37 MSK 2001     root@orb.ru:/usr/src/sys/compile/PENTIUM  i386
 



>Description:


    I've modifyed pppd sources and added 3 new options:
    usepeerdns, update-resolv, hide-password
    usepeerdns
        Ask the peer for up to 2 DNS server addresses.  The
        addresses supplied by the peer (if any) are  passed
        to  the  /etc/ppp/ip-up  script  in the environment
        variables DNS1 and DNS2.

    update-resolv
        The /etc/resolv.conf will be updated with  the  DNS
        addresses  supplied by the peer (if any). But envi-
        ronment variables DNS1 and DNS2  are  still  avail-
        able.  This  option is work in conjunction with the
        usepeerdns option only.
    hide-password
        When logging the  contents  of  PAP  packets,  this
        option  causes  pppd to exclude the password string
        from the log.

    Options usepeerdns and hide-password i've taken from pppd-2.3.9,
    but usepeerdns doesn't update resolve.conf automatically(like in 2.3.9)
    so DNS addresses are available from DNS1, DNS2, USEPEERDNS
    environment variables(usefull for /etc/ppp/ip-up(down) scripts).
    Option update-resolv update resolv.conf automatically, but DNS1, DNS2,
    USEPEERDNS environment variables are still available.

    I hope it will be usefull when pppd acts as client.


>How-To-Repeat:
>Fix:

've maked a patch which can be applied 
    to /usr/src/usr.sbin/pppd sources by this way:

    cd /usr/src/usr.sbin/pppd
    patch < pppd-DNSask.patch

Here is the pppd-DNSask.patch

-------------CUT HERE-------------
--- ../pppd.orig/ipcp.c	Sat Aug 28 05:19:03 1999
+++ ipcp.c	Sun Jan 21 04:29:10 2001
@@ -42,7 +42,7 @@
 /* global vars */
 ipcp_options ipcp_wantoptions[NUM_PPP];	/* Options that we want to request */
 ipcp_options ipcp_gotoptions[NUM_PPP];	/* Options that peer ack'd */
-ipcp_options ipcp_allowoptions[NUM_PPP];	/* Options we allow peer to request */
+ipcp_options ipcp_allowoptions[NUM_PPP];/* Options we allow peer to request */
 ipcp_options ipcp_hisoptions[NUM_PPP];	/* Options that we ack'd */
 
 /* local vars */
@@ -100,6 +100,7 @@
 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));
 
 struct protent ipcp_protent = {
     PPP_IPCP,
@@ -301,7 +302,7 @@
 
 #define LENCIVJ(neg, old)	(neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
 #define LENCIADDR(neg, old)	(neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0)
-
+#define LENCIDNS(neg)		(neg ? (CILEN_ADDR) : 0)
     /*
      * First see if we want to change our options to the old
      * forms because we have received old forms from the peer.
@@ -327,7 +328,9 @@
     }
 
     return (LENCIADDR(go->neg_addr, go->old_addrs) +
-	    LENCIVJ(go->neg_vj, go->old_vj));
+	    LENCIVJ(go->neg_vj, go->old_vj) +
+	    LENCIDNS(go->req_dns1) +
+	    LENCIDNS(go->req_dns2)) ;
 }
 
 
@@ -377,11 +380,28 @@
 	    neg = 0; \
     }
 
+#define ADDCIDNS(opt, neg, addr) \
+    if (neg) { \
+	if (len >= CILEN_ADDR) { \
+	    u_int32_t l; \
+	    PUTCHAR(opt, ucp); \
+	    PUTCHAR(CILEN_ADDR, ucp); \
+	    l = ntohl(addr);\
+	    PUTLONG(l, ucp); \
+	    len -= CILEN_ADDR; \
+	} else \
+	    neg = 0; \
+    }
+
     ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
 	      go->old_addrs, go->ouraddr, go->hisaddr);
 
     ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
 	    go->maxslotindex, go->cflag);
+	    
+    ADDCIDNS(CI_MS_DNS1,go->req_dns1,go->dnsaddr[0]);
+    
+    ADDCIDNS(CI_MS_DNS2,go->req_dns2,go->dnsaddr[1]);
 
     *lenp -= len;
 }
@@ -457,11 +477,30 @@
 	} \
     }
 
+#define ACKCIDNS(opt, neg, addr) \
+    if (neg) { \
+	u_int32_t l; \
+	if ((len -= CILEN_ADDR) < 0) \
+	    goto bad; \
+	GETCHAR(citype, p); \
+	GETCHAR(cilen, p); \
+	if (cilen != CILEN_ADDR || citype != opt) \
+	    goto bad; \
+	GETLONG(l, p); \
+	cilong = htonl(l);\
+	if (addr != cilong) \
+	    goto bad; \
+    }
+
     ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
 	      go->old_addrs, go->ouraddr, go->hisaddr);
 
     ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
 	    go->maxslotindex, go->cflag);
+	    
+    ACKCIDNS(CI_MS_DNS1,go->req_dns1,go->dnsaddr[0]);
+    
+    ACKCIDNS(CI_MS_DNS2,go->req_dns2,go->dnsaddr[1]);
 
     /*
      * If there are any remaining CIs, then this packet is bad.
@@ -494,7 +533,7 @@
     u_char cimaxslotindex, cicflag;
     u_char citype, cilen, *next;
     u_short cishort;
-    u_int32_t ciaddr1, ciaddr2, l;
+    u_int32_t ciaddr1, ciaddr2, l, cidnsaddr;
     ipcp_options no;		/* options we've seen Naks for */
     ipcp_options try;		/* options to request next time */
 
@@ -537,6 +576,19 @@
         code \
     }
 
+#define NAKCIDNS(opt, neg, code) \
+    if (go->neg && \
+	((cilen = p[1]) == CILEN_ADDR) && \
+	len >= cilen && \
+	p[0] == opt) { \
+	len -= cilen; \
+	INCPTR(2, p); \
+	GETLONG(l, p); \
+	cidnsaddr = htonl(l); \
+	no.neg = 1; \
+	code \
+    }
+
     /*
      * Accept the peer's idea of {our,his} address, if different
      * from our idea, only if the accept_{local,remote} flag is set.
@@ -583,6 +635,14 @@
 	    }
 	    );
 
+    NAKCIDNS(CI_MS_DNS1, req_dns1,
+	    try.dnsaddr[0] = cidnsaddr;
+	    );
+
+    NAKCIDNS(CI_MS_DNS2, req_dns2,
+	    try.dnsaddr[1] = cidnsaddr;
+	    );
+
     /*
      * There may be remaining CIs, if the peer is requesting negotiation
      * on an option that we didn't include in our request packet.
@@ -719,12 +779,32 @@
 	try.neg = 0; \
      }
 
+#define REJCIDNS(opt, neg, dnsaddr) \
+    if(go->neg && \
+	((cilen = p[1]) == CILEN_ADDR) && \
+	len >= cilen && \
+	p[0] == opt) { \
+	u_int32_t l; \
+	len -= cilen; \
+	INCPTR(2, p); \
+	GETLONG(l, p); \
+	cilong = htonl(l); \
+	/* Check rejected value. */ \
+	if (cilong != dnsaddr) \
+	    goto bad; \
+	try.neg = 0; \
+    }
+
     REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr,
 	      go->old_addrs, go->ouraddr, go->hisaddr);
 
     REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,
 	    go->maxslotindex, go->cflag);
 
+    REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);
+
+    REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
+
     /*
      * If there are any remaining CIs, then this packet is bad.
      */
@@ -1159,6 +1239,17 @@
     }
     script_setenv("IPLOCAL", ip_ntoa(go->ouraddr));
     script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr));
+    
+    if (go->dnsaddr[0] || go->dnsaddr[1]) {
+	script_setenv("USEPEERDNS","1");
+	if (go->dnsaddr[0])
+	    script_setenv("DNS1",ip_ntoa(go->dnsaddr[0]));
+	if (go->dnsaddr[1])
+	    if (go->dnsaddr[1] != go->dnsaddr[0]) /* if addresses are not same */
+		script_setenv("DNS2",ip_ntoa(go->dnsaddr[1]));
+	if (update_resolv)
+	    create_resolv(go->dnsaddr[0], go->dnsaddr[1]);
+    }
 
     /*
      * Check that the peer is allowed to use the IP address it wants.
@@ -1252,6 +1343,11 @@
 
 	syslog(LOG_NOTICE, "local  IP address %s", ip_ntoa(go->ouraddr));
 	syslog(LOG_NOTICE, "remote IP address %s", ip_ntoa(ho->hisaddr));
+	if (go->dnsaddr[0])
+	    syslog(LOG_NOTICE, "primary DNS address %s",ip_ntoa(go->dnsaddr[0]));
+	if (go->dnsaddr[1])
+	    if (go->dnsaddr[1] != go->dnsaddr[0])
+		syslog(LOG_NOTICE, "secondary DNS address %s",ip_ntoa(go->dnsaddr[1]));
     }
 
     /*
@@ -1353,6 +1449,33 @@
     argv[6] = ipparam;
     argv[7] = NULL;
     run_program(script, argv, 0);
+}
+
+/*
+ * create_resolve - create the replacement resolv.conf file
+ */
+static void
+create_resolv(peerdns1, peerdns2)
+    u_int32_t peerdns1, peerdns2;
+{
+    FILE *f;
+    f = fopen(_PATH_RESOLV, "w");
+    if (f == NULL) {
+	syslog(LOG_ERR, "Failed to create %s: %m", _PATH_RESOLV);
+	return;
+    }
+    
+    if (peerdns1)
+	fprintf(f, "\nnameserver %s\n", ip_ntoa(peerdns1));
+
+    if (peerdns2)
+	if (peerdns2 != peerdns1) /* if addresses are not same */
+	    fprintf(f, "nameserver %s\n", ip_ntoa(peerdns2));
+
+    if (ferror(f))
+	syslog(LOG_ERR, "Write failed to %s: %m", _PATH_RESOLV);
+
+    fclose(f);
 }
 
 /*
--- ../pppd.orig/ipcp.h	Sat Aug 28 05:19:03 1999
+++ ipcp.h	Sun Jan 21 04:28:26 2001
@@ -46,6 +46,8 @@
     int neg_addr : 1;		/* Negotiate IP Address? */
     int old_addrs : 1;		/* Use old (IP-Addresses) option? */
     int req_addr : 1;		/* Ask peer to send IP address? */
+    int req_dns1 : 1;		/* Ask peer to send DNS1 address? */
+    int req_dns2 : 1;		/* Ask peer to send DNS2 address? */
     int default_route : 1;	/* Assign default route through interface? */
     int proxy_arp : 1;		/* Make proxy ARP entry for peer? */
     int neg_vj : 1;		/* Van Jacobson Compression? */
--- ../pppd.orig/options.c	Sat Aug 28 05:19:07 1999
+++ options.c	Sun Jan 21 04:28:26 2001
@@ -113,6 +113,8 @@
 int	holdoff = 30;		/* # seconds to pause before reconnecting */
 int	refuse_pap = 0;		/* Set to say we won't do PAP */
 int	refuse_chap = 0;	/* Set to say we won't do CHAP */
+int	hide_password = 0;	/* Hide password in log */
+int	update_resolv = 0;	/* Update resolv.conf */
 
 #ifdef MSLANMAN
 int	ms_lanman = 0;    	/* Nonzero if use LanMan password instead of NT */
@@ -230,6 +232,9 @@
 static int setwinsaddr __P((char **));
 static int showversion __P((char **));
 static int showhelp __P((char **));
+static int usepeerdns __P((char **));
+static int hide_pass __P((char **));
+static int resolv_update __P((char **));
 
 #ifdef PPP_FILTER
 static int setpdebug __P((char **));
@@ -387,6 +392,9 @@
 /* end compat hack */
     {"ms-dns", 1, setdnsaddr},		/* DNS address for the peer's use */
     {"ms-wins", 1, setwinsaddr},	/* Nameserver for SMB over TCP/IP for peer */
+    {"usepeerdns",0, usepeerdns},	/* Ask peer for DNS addrs */
+    {"hide-password",0, hide_pass},	/* Hide password in log */
+    {"update-resolv",0,resolv_update}, /* Update resolv.conf */
     {"noipx",  0, resetipxproto},	/* Disable IPXCP (and IPX) */
     {"-ipx",   0, resetipxproto},	/* Disable IPXCP (and IPX) */
     {"--version", 0, showversion},	/* Show version number */
@@ -1978,6 +1986,31 @@
 {
     ipcp_allowoptions[0].default_route = 0;
     ipcp_wantoptions[0].default_route = 0;
+    return 1;
+}
+
+static int
+usepeerdns(argv)
+    char **argv;
+{
+    ipcp_wantoptions[0].req_dns1 = 1;
+    ipcp_wantoptions[0].req_dns2 = 1;
+    return 1;
+}
+
+static int
+hide_pass(argv)
+    char **argv;
+{
+    hide_password = 1;
+    return 1;
+}
+
+static int
+resolv_update(argv)
+    char **argv;
+{
+    update_resolv = 1;
     return 1;
 }
 
--- ../pppd.orig/pathnames.h	Sat Aug 28 05:19:07 1999
+++ pathnames.h	Sun Jan 21 04:28:26 2001
@@ -25,6 +25,7 @@
 #define _PATH_PEERFILES	"/etc/ppp/peers/"
 #define _PATH_PPPDENY  "/etc/ppp/ppp.deny"
 #define _PATH_PPPSHELLS	"/etc/ppp/ppp.shells"
+#define _PATH_RESOLV	"/etc/resolv.conf"
 
 #ifdef IPX_CHANGE
 #define _PATH_IPXUP	"/etc/ppp/ipx-up"
--- ../pppd.orig/pppd.8	Fri Mar  3 12:11:26 2000
+++ pppd.8	Sun Jan 21 04:28:26 2001
@@ -49,7 +49,7 @@
 .B active-filter \fIfilter-expression
 Specifies a packet filter to be applied to data packets to determine
 which packets are to be regarded as link activity, and therefore reset
-the idle timer, or cause the link to be brought up in demand-dialling
+the idle timer, or cause the link to be brought up in demand-dialing
 mode.  This option is useful in conjunction with the
 \fBidle\fR option if there are packets being sent or received
 regularly over the link (for example, routing information packets)
@@ -459,6 +459,17 @@
 instance of this option specifies the primary WINS address; the second
 instance (if given) specifies the secondary WINS address.
 .TP
+.B usepeerdns
+Ask the peer for up to 2 DNS server addresses.  The addresses supplied
+by the peer (if any) are passed to the /etc/ppp/ip-up script in the
+environment variables DNS1 and DNS2.
+.TP
+.B update-resolv
+The /etc/resolv.conf will be updated with the DNS addresses supplied
+by the peer (if any). But environment variables DNS1 and DNS2 are
+still available. This option is work in conjunction with the
+\fBusepeerdns\fR option only.
+.TP
 .B name \fIname
 Set the name of the local system for authentication purposes to
 \fIname\fR.  This is a privileged option.  With this option, pppd will
@@ -649,6 +660,10 @@
 .B user \fIname
 Sets the name used for authenticating the local system to the peer to
 \fIname\fR.
+.TP
+.B hide-password
+When logging the contents of PAP packets, this option causes pppd to
+exclude the password string from the log.
 .TP
 .B vj-max-slots \fIn
 Sets the number of connection slots to be used by the Van Jacobson
--- ../pppd.orig/pppd.h	Sat Aug 28 05:19:08 1999
+++ pppd.h	Sun Jan 21 04:28:26 2001
@@ -110,6 +110,8 @@
 extern int	holdoff;	/* Dead time before restarting */
 extern int	refuse_pap;	/* Don't wanna auth. ourselves with PAP */
 extern int	refuse_chap;	/* Don't wanna auth. ourselves with CHAP */
+extern int	hide_password;	/* Hide password in log */
+extern int	update_resolv;	/* Update resolv.conf */
 #ifdef PPP_FILTER
 extern struct	bpf_program pass_filter;   /* Filter for pkts to pass */
 extern struct	bpf_program active_filter; /* Filter for link-active pkts */
--- ../pppd.orig/upap.c	Sat Aug 28 05:19:08 1999
+++ upap.c	Sun Jan 21 04:28:26 2001
@@ -591,7 +591,10 @@
 	printer(arg, " user=");
 	print_string(user, ulen, printer, arg);
 	printer(arg, " password=");
-	print_string(pwd, wlen, printer, arg);
+	if (!hide_password)
+	    print_string(pwd, wlen, printer, arg);
+	else
+	    printer(arg, "\"********\"");
 	break;
     case UPAP_AUTHACK:
     case UPAP_AUTHNAK:
-------------CUT HERE-------------

>Release-Note:
>Audit-Trail:
>Unformatted:


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200101231238.PAA03005>