Merge branch 'Toastman-RT' into Toastman-RT-N
[tomato.git] / release / src / router / rc / pptpd.c
bloba6cae34af5c20405b1b1a0269927e04ae478b313
1 /*
2 * pptp.c
4 * Copyright (C) 2007 Sebastian Gottschall <gottschall@dd-wrt.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * $Id:
23 #include <rc.h>
24 #include <stdlib.h>
25 #include <bcmnvram.h>
26 #include <shutils.h>
27 #include <utils.h>
28 #include <syslog.h>
29 #include <signal.h>
30 #include <errno.h>
31 #include <sys/stat.h>
33 void get_broadcast(char *ipaddr, char *netmask)
35 int ip2[4], mask2[4];
36 unsigned char ip[4], mask[4];
38 if (!ipaddr || !netmask)
39 return;
41 sscanf(ipaddr, "%d.%d.%d.%d", &ip2[0], &ip2[1], &ip2[2], &ip2[3]);
42 sscanf(netmask, "%d.%d.%d.%d", &mask2[0], &mask2[1], &mask2[2],
43 &mask2[3]);
44 int i = 0;
46 for (i = 0; i < 4; i++) {
47 ip[i] = ip2[i];
48 mask[i] = mask2[i];
49 ip[i] = (ip[i] & mask[i]) | (0xff & ~mask[i]);
52 sprintf(ipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
54 //fprintf(stderr, "get_broadcast return %s\n", value);
57 void write_chap_secret(char *file)
59 FILE *fp;
60 char *nv, *nvp, *b;
61 char *username, *passwd;
62 // char buf[64];
64 fp=fopen(file, "w");
66 if (fp==NULL) return;
68 // nv = nvp = strdup(nvram_safe_get("pptpd_clientlist"));
69 nv = nvp = strdup(nvram_safe_get("pptpd_users"));
71 if(nv) {
72 while ((b = strsep(&nvp, ">")) != NULL) {
73 if((vstrsep(b, "<", &username, &passwd)!=2)) continue;
74 if(strlen(username)==0||strlen(passwd)==0) continue;
75 fprintf(fp, "%s * %s *\n", username, passwd);
77 free(nv);
79 fclose(fp);
82 void start_pptpd(void)
84 int ret = 0, mss = 0, manual_dns = 0;
85 // char *lpTemp;
86 FILE *fp;
88 // int pid = getpid();
89 // _dprintf("start_pptpd: getpid= %d\n", pid);
91 // if(getpid() != 1) {
92 // notify_rc("start_pptpd");
93 // return;
94 // }
96 if (!nvram_match("pptpd_enable", "1")) {
97 return;
99 // cprintf("stop vpn modules\n");
100 // stop_vpn_modules ();
102 // Create directory for use by pptpd daemon and its supporting files
103 mkdir("/tmp/pptpd", 0744);
104 cprintf("open options file\n");
105 // Create options file that will be unique to pptpd to avoid interference
106 // with pppoe and pptp
107 fp = fopen("/tmp/pptpd/options.pptpd", "w");
108 fprintf(fp, "logfile /var/log/pptpd-pppd.log\ndebug\n");
110 if (nvram_match("pptpd_radius", "1"))
111 fprintf(fp, "plugin radius.so\nplugin radattr.so\n"
112 "radius-config-file /tmp/pptpd/radius/radiusclient.conf\n");
114 cprintf("check if wan_wins = zero\n");
115 int nowins = 0;
117 if (nvram_match("wan_wins", "0.0.0.0")) {
118 nvram_set("wan_wins", "");
119 nowins = 1;
121 if (strlen(nvram_safe_get("wan_wins")) == 0)
122 nowins = 1;
124 cprintf("write config\n");
125 fprintf(fp, "lock\n"
126 "name *\n"
127 "proxyarp\n"
128 // "ipcp-accept-local\n"
129 // "ipcp-accept-remote\n"
130 "minunit 4\n" // AB !! - we leave ppp0-ppp3 for WAN and/or other ppp connections (PPTP client, ADSL, etc... perhaps)?
131 "nobsdcomp\n"
132 "lcp-echo-failure 10\n"
133 "lcp-echo-interval 5\n"
134 // "deflate 0\n" "auth\n" "-chap\n" "-mschap\n" "+mschap-v2\n");
135 "refuse-pap\n"
136 "refuse-chap\n"
137 "refuse-mschap\n"
138 "require-mschap-v2\n");
140 // if (nvram_match("pptpd_forcemppe", "none")) {
141 if (nvram_match("pptpd_forcemppe", "0")) {
142 // fprintf(fp, "-mppc\n");
143 fprintf(fp, "nomppe\n");
144 } else {
145 // fprintf(fp, "+mppc\n");
146 /* if (nvram_match("pptpd_forcemppe", "auto")) {
147 fprintf(fp, "+mppe-40\n");
148 fprintf(fp, "+mppe-56\n");
149 fprintf(fp, "+mppe-128\n");
151 else if (nvram_match("pptpd_forcemppe", "+mppe-40")) {
152 fprintf(fp, "+mppe\n");
153 fprintf(fp, "+mppe-40\n");
154 fprintf(fp, "-mppe-56\n");
155 fprintf(fp, "-mppe-128\n");
157 else if (nvram_match("pptpd_forcemppe", "+mppe-128")) {
158 fprintf(fp, "+mppe\n");
159 fprintf(fp, "-mppe-40\n");
160 fprintf(fp, "-mppe-56\n");
161 fprintf(fp, "+mppe-128\n");
163 fprintf(fp, "require-mppe-128\n");
165 fprintf(fp, "nomppe-stateful\n");
166 // }
168 fprintf(fp, "ms-ignore-domain\n"
169 "chap-secrets /tmp/pptpd/chap-secrets\n"
170 "ip-up-script /tmp/pptpd/ip-up\n"
171 "ip-down-script /tmp/pptpd/ip-down\n"
172 "mtu %s\n" "mru %s\n",
173 nvram_get("pptpd_mtu") ? nvram_get("pptpd_mtu") : "1450",
174 nvram_get("pptpd_mru") ? nvram_get("pptpd_mru") : "1450");
175 //WINS Server
176 if (!nowins) {
177 fprintf(fp, "ms-wins %s\n", nvram_safe_get("wan_wins"));
179 if (strlen(nvram_safe_get("pptpd_wins1"))) {
180 fprintf(fp, "ms-wins %s\n", nvram_safe_get("pptpd_wins1"));
182 if (strlen(nvram_safe_get("pptpd_wins2"))) {
183 fprintf(fp, "ms-wins %s\n", nvram_safe_get("pptpd_wins2"));
185 //DNS Server
186 if (strlen(nvram_safe_get("pptpd_dns1"))) {
187 fprintf(fp, "ms-dns %s\n", nvram_safe_get("pptpd_dns1"));
188 manual_dns=1;
190 if (strlen(nvram_safe_get("pptpd_dns2"))) {
191 fprintf(fp, "ms-dns %s\n", nvram_safe_get("pptpd_dns2"));
192 manual_dns=1;
194 if(!manual_dns && !nvram_match("lan_ipaddr", ""))
195 fprintf(fp, "ms-dns %s\n", nvram_safe_get("lan_ipaddr"));
197 fprintf(fp, "%s\n\n", nvram_safe_get("pptpd_custom"));
199 // Following is all crude and need to be revisited once testing confirms
200 // that it does work
201 // Should be enough for testing..
202 /* if (nvram_match("pptpd_radius", "1")) {
203 if (nvram_get("pptpd_radserver") != NULL
204 && nvram_get("pptpd_radpass") != NULL) {
206 fclose(fp);
208 mkdir("/tmp/pptpd/radius", 0744);
210 fp = fopen("/tmp/pptpd/radius/radiusclient.conf", "w");
211 fprintf(fp, "auth_order radius\n"
212 "login_tries 4\n"
213 "login_timeout 60\n"
214 "radius_timeout 10\n"
215 "nologin /etc/nologin\n"
216 "servers /tmp/pptpd/radius/servers\n"
217 "dictionary /etc/dictionary\n"
218 "seqfile /var/run/radius.seq\n"
219 "mapfile /etc/port-id-map\n"
220 "radius_retries 3\n"
221 "authserver %s:%s\n",
222 nvram_get("pptpd_radserver"),
223 nvram_get("pptpd_radport") ?
224 nvram_get("pptpd_radport") : "radius");
226 if (nvram_get("pptpd_radserver") != NULL
227 && nvram_get("pptpd_acctport") != NULL)
228 fprintf(fp, "acctserver %s:%s\n",
229 nvram_get("pptpd_radserver"),
230 nvram_get("pptpd_acctport") ?
231 nvram_get("pptpd_acctport") :
232 "radacct");
233 fclose(fp);
235 fp = fopen("/tmp/pptpd/radius/servers", "w");
236 fprintf(fp, "%s\t%s\n", nvram_get("pptpd_radserver"),
237 nvram_get("pptpd_radpass"));
238 fclose(fp);
240 } else
241 fclose(fp);
242 } else
243 */ fclose(fp);
245 // Create pptpd.conf options file for pptpd daemon
246 fp = fopen("/tmp/pptpd/pptpd.conf", "w");
247 fprintf(fp, "bcrelay %s\n", nvram_safe_get("pptpd_broadcast"));
248 fprintf(fp, "localip %s\n"
249 "remoteip %s\n", nvram_safe_get("lan_ipaddr"),
250 nvram_safe_get("pptpd_remoteip"));
251 fclose(fp);
253 // Create ip-up and ip-down scripts that are unique to pptpd to avoid
254 // interference with pppoe and pptp
256 * adjust for tunneling overhead (mtu - 40 byte IP - 108 byte tunnel
257 * overhead)
259 if (nvram_match("mtu_enable", "1"))
260 mss = atoi(nvram_safe_get("wan_mtu")) - 40 - 108;
261 else
262 mss = 1500 - 40 - 108;
263 char bcast[32];
265 strcpy(bcast, nvram_safe_get("lan_ipaddr"));
266 get_broadcast(bcast, nvram_safe_get("lan_netmask"));
268 fp = fopen("/tmp/pptpd/ip-up", "w");
269 // fprintf(fp, "#!/bin/sh\n" "startservice set_routes\n" // reinitialize
270 fprintf(fp, "#!/bin/sh\n" //"startservice set_routes\n" // reinitialize
271 "echo $PPPD_PID $1 $5 $6 $PEERNAME `date +%%s`>> /tmp/pptp_connected\n"
272 "iptables -I FORWARD -i $1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n"
273 "iptables -I INPUT -i $1 -j ACCEPT\n"
274 "iptables -I FORWARD -i $1 -j ACCEPT\n"
275 "iptables -I FORWARD -o $1 -j ACCEPT\n" // AB!!
276 "iptables -t nat -I PREROUTING -i $1 -p udp -m udp --sport 9 -j DNAT --to-destination %s " // rule for wake on lan over pptp tunnel
277 "%s\n", bcast,
278 nvram_get("pptpd_ipup_script") ? nvram_get("pptpd_ipup_script") : "");
279 fclose(fp);
280 fp = fopen("/tmp/pptpd/ip-down", "w");
281 fprintf(fp, "#!/bin/sh\n" "grep -v $1 /tmp/pptp_connected > /tmp/pptp_connected.new\n"
282 "mv /tmp/pptp_connected.new /tmp/pptp_connected\n"
283 "iptables -D FORWARD -i $1 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu\n"
284 "iptables -D INPUT -i $1 -j ACCEPT\n"
285 "iptables -D FORWARD -i $1 -j ACCEPT\n"
286 "iptables -D FORWARD -o $1 -j ACCEPT\n" // AB!!
287 "iptables -t nat -D PREROUTING -i $1 -p udp -m udp --sport 9 -j DNAT --to-destination %s " // rule for wake on lan over pptp tunnel
288 "%s\n", bcast,
289 nvram_get("pptpd_ipdown_script") ? nvram_get("pptpd_ipdown_script") : "");
290 fclose(fp);
291 chmod("/tmp/pptpd/ip-up", 0744);
292 chmod("/tmp/pptpd/ip-down", 0744);
294 // Exctract chap-secrets from nvram
295 write_chap_secret("/tmp/pptpd/chap-secrets");
297 chmod("/tmp/pptpd/chap-secrets", 0600);
299 // Execute pptpd daemon
300 ret =
301 eval("pptpd", "-c", "/tmp/pptpd/pptpd.conf", "-o",
302 "/tmp/pptpd/options.pptpd",
303 "-C", "6");
305 _dprintf("start_pptpd: ret= %d\n", ret);
306 //dd_syslog(LOG_INFO, "pptpd : pptp daemon successfully started\n");
307 return;
310 void stop_pptpd(void)
312 FILE *fp;
313 int ppppid;
314 char line[128];
316 eval("cp", "/tmp/pptp_connected", "/tmp/pptp_shutdown");
318 fp = fopen("/tmp/pptp_shutdown", "r");
319 if (fp) {
320 while (fgets(line, sizeof(line), fp) != NULL) {
321 if (sscanf(line, "%d %*s %*s %*s %*s %*d", &ppppid) != 1) continue;
322 int n = 10;
323 while ((kill(ppppid, SIGTERM) == 0) && (n > 1)) {
324 sleep(1);
325 n--;
328 fclose(fp);
330 unlink("/tmp/pptp_shutdown");
332 // if (getpid() != 1) {
333 // notify_rc("stop_pptpd");
334 // }
336 killall_tk("pptpd");
337 killall_tk("bcrelay");
338 return;
341 void write_pptpd_dnsmasq_config(FILE* f) {
342 int i;
343 if (nvram_match("pptpd_enable", "1")) {
344 fprintf(f, "interface=");
345 for (i = 4; i <= 9 ; i++) {
346 fprintf(f, "ppp%d%c", i, ((i < 9)? ',' : '\n'));
348 fprintf(f, "no-dhcp-interface=");
349 for (i = 4; i <= 9 ; i++) {
350 fprintf(f, "ppp%d%c", i, ((i < 9)? ',' : '\n'));