vBulletin Search Engine Optimization
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| Greetings, The following patch gives usepeerdns functionality to the version of pppd in OpenBSD. This was cut and pasted from pppd version 2.3.7 (ftp://ftp.samba.org/pub/ppp/old/ppp-2.3.7.tar.gz), the first version of "usepeerdns" that supposedly works correctly, according to the change logs. This is a surgical insertion of only that functionality needed to get the option to work. I have made no other changes to the code. As far as I can tell, in terms of OpenBSD auditing, the new code has the same level of security and safety as any of the other parts of the current pppd. Perhaps someone else can verify this? This patch works for me; your mileage may vary. Use at your own risk. I needed it because I am compelled to connect to my ISP via pptp and wanted to automate all phases of Internet connectivity. If anybody is interested, I can publish the somewhat involved shell script that I run as a cron job every minute to make sure that my pptp/pppd connection stays up, since my OpenBSD box is acting as a firewall/gateway. This patch tested by compilation and use on both 3.6 and 3.7 stable versions of OpenBSD. If this is accepted to be incorporated in anything approaching the mainline (and from a licensing standpoint, there shouldn't be any problem?), please give me credit. Signed-off by: Stephen Biggs <openbsd-tech@yihye-beseder.no-ip.com> -- ipcp.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++- ipcp.h | 2 options.c | 11 +++++ pathnames.h | 1 pppd.8 | 6 ++ 5 files changed, 142 insertions(+), 2 deletions(-) Paste the rest of these following lines into file pppd- usepeerdns.patch. Apply by doing: cd /usr/src patch -p0 < pppd-usepeerdns.patch Then, rebuild pppd: cd usr.sbin/pppd make obj make depend make make install Index: usr.sbin/pppd/ipcp.c ================================================== ================= RCS file: /cvs/src/usr.sbin/pppd/ipcp.c,v retrieving revision 1.11 diff -u -p -d -r1.11 ipcp.c --- usr.sbin/pppd/ipcp.c 18 Jul 2003 22:58:56 -0000 1.11 +++ usr.sbin/pppd/ipcp.c 22 Jun 2005 18:45:37 -0000 @@ -129,6 +129,7 @@ static int ipcp_printpkt(u_char *, int, 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, @@ -300,6 +301,7 @@ ipcp_protrej(unit) /* * ipcp_resetci - Reset our CI. + * Called by fsm_sconfreq, Send Configure Request. */ static void ipcp_resetci(f) @@ -319,6 +321,7 @@ ipcp_resetci(f) /* * ipcp_cilen - Return length of our CI. + * Called by fsm_sconfreq, Send Configure Request. */ static int ipcp_cilen(f) @@ -330,6 +333,7 @@ ipcp_cilen(f) #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 @@ -356,12 +360,15 @@ ipcp_cilen(f) } 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)) ; } /* * ipcp_addci - Add our desired CIs to a packet. + * Called by fsm_sconfreq, Send Configure Request. */ static void ipcp_addci(f, ucp, lenp) @@ -406,12 +413,30 @@ ipcp_addci(f, ucp, lenp) neg = 0; \ } +#define ADDCIDNS(opt, neg) \ + if (neg) { \ + int addrlen = CILEN_ADDR; \ + if (len >= addrlen) { \ + u_int32_t l; \ + PUTCHAR(opt, ucp); \ + PUTCHAR(addrlen, ucp); \ + l = ntohl(0); \ + PUTLONG(l, ucp); \ + len -= addrlen; \ + } 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); + + ADDCIDNS(CI_MS_DNS2, go->req_dns2); + *lenp -= len; } @@ -508,6 +533,7 @@ bad: * ipcp_nakci - Peer has sent a NAK for some of our CIs. * This should not modify any state if the Nak is bad * or if IPCP is in the OPENED state. + * Callback from fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. * * Returns: * 0 - Nak was bad. @@ -523,7 +549,7 @@ ipcp_nakci(f, p, len) 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 */ @@ -566,6 +592,22 @@ ipcp_nakci(f, p, len) code \ } +/* + * Peer returns DNS address in a NAK packet + */ +#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. @@ -612,6 +654,20 @@ ipcp_nakci(f, p, len) } ); + NAKCIDNS(CI_MS_DNS1, req_dns1, + try.dnsaddr[0] = cidnsaddr; + try.req_dns1 = 0; + IPCPDEBUG((LOG_INFO, "primary peer DNS address %s", + ip_ntoa(cidnsaddr))); + ); + + NAKCIDNS(CI_MS_DNS2, req_dns2, + try.dnsaddr[1] = cidnsaddr; + try.req_dns2 = 0; + IPCPDEBUG((LOG_INFO, "secondary peer DNS address %s", + ip_ntoa(cidnsaddr))); + ); + /* * There may be remaining CIs, if the peer is requesting negotiation * on an option that we didn't include in our request packet. @@ -684,6 +740,7 @@ bad: /* * ipcp_rejci - Reject some of our CIs. + * Callback from fsm_rconfnakrej. */ static int ipcp_rejci(f, p, len) @@ -748,12 +805,33 @@ ipcp_rejci(f, p, len) try.neg = 0; \ } +#define REJCIDNS(opt, neg, dnsaddr) \ + if (go->neg && \ + ((cilen = p[1]) == CI_MS_DNS1) && \ + 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. */ @@ -1189,6 +1267,15 @@ ipcp_up(f) script_setenv("IPLOCAL", ip_ntoa(go->ouraddr)); script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr)); + if ((wo->req_dns1 || wo->req_dns2) && (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]) + script_setenv("DNS2", ip_ntoa(go->dnsaddr[1])); + create_resolv(go->dnsaddr[0], go->dnsaddr[1]); + } + /* * Check that the peer is allowed to use the IP address it wants. */ @@ -1281,6 +1368,12 @@ ipcp_up(f) 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]) + syslog(LOG_NOTICE, "secondary DNS address %s", + ip_ntoa(go->dnsaddr[1])); } /* @@ -1384,6 +1477,33 @@ ipcp_script(f, script) argv[6] = ipparam; argv[7] = NULL; run_program(script, argv, 0); +} + +/* + * create_resolv - 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, "nameserver %s\n", ip_ntoa(peerdns1)); + + if (peerdns2) + fprintf(f, "nameserver %s\n", ip_ntoa(peerdns2)); + + if (ferror(f)) + syslog(LOG_ERR, "Write failed to %s: %m", _PATH_RESOLV); + + fclose(f); } /* Index: usr.sbin/pppd/ipcp.h ================================================== ================= RCS file: /cvs/src/usr.sbin/pppd/ipcp.h,v retrieving revision 1.7 diff -u -p -d -r1.7 ipcp.h --- usr.sbin/pppd/ipcp.h 1 Jul 2002 19:31:37 -0000 1.7 +++ usr.sbin/pppd/ipcp.h 22 Jun 2005 18:45:37 -0000 @@ -74,6 +74,8 @@ typedef struct ipcp_options { int neg_vj : 1; /* Van Jacobson Compression? */ int old_vj : 1; /* use old (short) form of VJ option? */ int accept_local : 1; /* accept peer's value for ouraddr */ + int req_dns1 : 1; /* Ask peer to send primary DNS address? */ + int req_dns2 : 1; /* Ask peer to send secondary DNS address? */ int accept_remote : 1; /* accept peer's value for hisaddr */ u_short vj_protocol; /* protocol value to use in VJ option */ u_char maxslotindex, cflag; /* values for RFC1332 VJ compression neg. */ Index: usr.sbin/pppd/options.c ================================================== ================= RCS file: /cvs/src/usr.sbin/pppd/options.c,v retrieving revision 1.19 diff -u -p -d -r1.19 options.c --- usr.sbin/pppd/options.c 4 Apr 2003 20:25:07 -0000 1.19 +++ usr.sbin/pppd/options.c 22 Jun 2005 18:45:41 -0000 @@ -285,6 +285,7 @@ static int setipxcpfails(char **); #ifdef MSLANMAN static int setmslanman(char **); #endif +static int setusepeerdns(char **); static int number_option(char *, u_int32_t *, int); static int int_option(char *, int *); @@ -447,6 +448,7 @@ static struct cmd { #ifdef MSLANMAN {"ms-lanman", 0, setmslanman}, /* Use LanMan psswd when using MS-CHAP */ #endif + {"usepeerdns", 0, setusepeerdns}, /* Ask peer for DNS addrs */ {NULL, 0, NULL} }; @@ -2572,3 +2574,12 @@ setmslanman(argv) return (1); } #endif + +static int +setusepeerdns(argv) + char **argv; +{ + /* Request DNS addresses from the peer */ + ipcp_wantoptions[0].req_dns1 = ipcp_wantoptions[0].req_dns2 = 1; + return (1); +} Index: usr.sbin/pppd/pathnames.h ================================================== ================= RCS file: /cvs/src/usr.sbin/pppd/pathnames.h,v retrieving revision 1.5 diff -u -p -d -r1.5 pathnames.h --- usr.sbin/pppd/pathnames.h 5 Sep 1997 04:32:44 -0000 1.5 +++ usr.sbin/pppd/pathnames.h 22 Jun 2005 18:45:41 -0000 @@ -25,6 +25,7 @@ #define _PATH_CONNERRS "/etc/ppp/connect-errors" #define _PATH_USEROPT ".ppprc" #define _PATH_PEERFILES "/etc/ppp/peers/" +#define _PATH_RESOLV "/etc/ppp/resolv.conf" #ifdef IPX_CHANGE #define _PATH_IPXUP "/etc/ppp/ipx-up" Index: usr.sbin/pppd/pppd.8 ================================================== ================= RCS file: /cvs/src/usr.sbin/pppd/pppd.8,v retrieving revision 1.30 diff -u -p -d -r1.30 pppd.8 --- usr.sbin/pppd/pppd.8 31 Jan 2005 09:50:29 -0000 1.30 +++ usr.sbin/pppd/pppd.8 22 Jun 2005 18:45:46 -0000 @@ -907,6 +907,12 @@ Enforce the use of the hostname (with do as the name of the local system for authentication purposes (overrides the .Cm name option). +.It Cm 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. In addition, pppd will create an +/etc/ppp/resolv.conf file containing one or two nameserver lines with +the address(es) supplied by the peer. .It Cm user Ar name Sets the name used for authenticating the local system to the peer to .Ar name . |