]>
git.ipfire.org Git - ipfire-2.x.git/blob - src/misc-progs/setportfw.c
1 /* SmoothWall helper program - setportfw
3 * This program is distributed under the terms of the GNU General Public
4 * Licence. See the file COPYING for details.
6 * (c) Daniel Goscomb, 2001
7 * Copyright (c) 2002/04/13 Steve Bootes - Added source ip support for aliases
9 * Modifications and improvements by Lawrence Manning.
11 * 10/04/01 Aslak added protocol support
12 * This program reads the list of ports to forward and setups iptables
13 * and rules in ipmasqadm to enable them.
15 * 02/11/03 Darren Critchley modifications to allow it to open multiple
17 * 02/25/03 Darren Critchley modifications to allow port ranges
18 * 04/01/03 Darren Critchley modifications to allow gre protocol
19 * 20/04/03 Robert Kerr Fixed root exploit, validated all variables properly,
20 * tidied up the iptables logic, killed duplicated code,
21 * removed srciptmp (unecessary)
23 * $Id: setportfw.c,v 1.3.2.6 2005/08/24 18:44:19 gespinasse Exp $
30 #include "libsmooth.h"
33 struct keyvalue
*kv
= NULL
;
36 void exithandler(void)
46 FILE *ipfile
= NULL
, *ifacefile
= NULL
;
48 char iface
[STRING_SIZE
];
49 char locip
[STRING_SIZE
];
50 char greenip
[STRING_SIZE
], greenmask
[STRING_SIZE
];
51 char bluedev
[STRING_SIZE
], blueip
[STRING_SIZE
], bluemask
[STRING_SIZE
];
52 char orangedev
[STRING_SIZE
], orangeip
[STRING_SIZE
], orangemask
[STRING_SIZE
];
64 char command
[STRING_SIZE
];
71 /* Read in and verify config */
74 if (!readkeyvalues(kv
, CONFIG_ROOT
"/ethernet/settings"))
76 fprintf(stderr
, "Cannot read ethernet settings\n");
80 if (!findkey(kv
, "GREEN_ADDRESS", greenip
))
82 fprintf(stderr
, "Cannot read GREEN_ADDRESS\n");
86 if (!VALID_IP(greenip
))
88 fprintf(stderr
, "Bad GREEN_ADDRESS: %s\n", greenip
);
92 if (!findkey(kv
, "GREEN_NETMASK", greenmask
))
94 fprintf(stderr
, "Cannot read GREEN_NETMASK\n");
98 if (!VALID_IP(greenmask
))
100 fprintf(stderr
, "Bad GREEN_NETMASK: %s\n", greenmask
);
104 /* Get the BLUE interface details */
105 findkey(kv
, "BLUE_DEV", bluedev
);
110 if (!VALID_DEVICE(bluedev
))
112 fprintf(stderr
, "Bad BLUE_DEV: %s\n", bluedev
);
116 if (!findkey(kv
, "BLUE_ADDRESS", blueip
))
118 fprintf(stderr
, "Cannot read BLUE_ADDRESS\n");
122 if (!VALID_IP(blueip
))
124 fprintf(stderr
, "Bad BLUE_ADDRESS: %s\n", blueip
);
128 if (!findkey(kv
, "BLUE_NETMASK", bluemask
))
130 fprintf(stderr
, "Cannot read BLUE_NETMASK\n");
134 if (!VALID_IP(bluemask
))
136 fprintf(stderr
, "Bad BLUE_NETMASK: %s\n", bluemask
);
142 /* Get the ORANGE interface details */
143 findkey(kv
, "ORANGE_DEV", orangedev
);
145 if (strlen(orangedev
))
148 if (!VALID_DEVICE(orangedev
))
150 fprintf(stderr
, "Bad ORANGE_DEV: %s\n", orangedev
);
154 if (!findkey(kv
, "ORANGE_ADDRESS", orangeip
))
156 fprintf(stderr
, "Cannot read ORANGE_ADDRESS\n");
160 if (!VALID_IP(orangeip
))
162 fprintf(stderr
, "Bad ORANGE_ADDRESS: %s\n", orangeip
);
166 if (!findkey(kv
, "ORANGE_NETMASK", orangemask
))
168 fprintf(stderr
, "Cannot read ORANGE_NETMASK\n");
172 if (!VALID_IP(orangemask
))
174 fprintf(stderr
, "Bad ORANGE_NETMASK: %s\n", orangemask
);
181 if (!(ipfile
= fopen(CONFIG_ROOT
"/red/local-ipaddress", "r")))
183 fprintf(stderr
, "Couldn't open local ip file\n");
186 fgets(locip
, STRING_SIZE
, ipfile
);
187 if (locip
[strlen(locip
) - 1] == '\n')
188 locip
[strlen(locip
) - 1] = '\0';
190 if (!VALID_IP(locip
))
192 fprintf(stderr
, "Bad local IP: %s\n", locip
);
196 if (!(ifacefile
= fopen(CONFIG_ROOT
"/red/iface", "r")))
198 fprintf(stderr
, "Couldn't open iface file\n");
201 fgets(iface
, STRING_SIZE
, ifacefile
);
202 if (iface
[strlen(iface
) - 1] == '\n')
203 iface
[strlen(iface
) - 1] = '\0';
205 if (!VALID_DEVICE(iface
))
207 fprintf(stderr
, "Bad iface: %s\n", iface
);
211 if (!(fwdfile
= fopen(CONFIG_ROOT
"/portfw/config", "r")))
213 fprintf(stderr
, "Couldn't open portfw settings file\n");
217 safe_system("/sbin/iptables -t nat -F PORTFW");
218 safe_system("/sbin/iptables -t mangle -F PORTFWMANGLE");
219 safe_system("/sbin/iptables -F PORTFWACCESS");
221 while (fgets(s
, STRING_SIZE
, fwdfile
) != NULL
)
223 if (s
[strlen(s
) - 1] == '\n')
224 s
[strlen(s
) - 1] = '\0';
225 result
= strtok(s
, ",");
258 result
= strtok(NULL
, ",");
261 if (!(key1
&& key2
&& protocol
&& locport
&& remip
&& remport
&& enabled
265 if (!VALID_PROTOCOL(protocol
))
267 fprintf(stderr
, "Bad protocol: %s\n", protocol
);
270 if (strcmp(protocol
, "gre") == 0)
275 if (strcmp(origip
,"0") && !VALID_IP_AND_MASK(origip
))
277 fprintf(stderr
, "Bad IP: %s\n", origip
);
280 if (!VALID_PORT_RANGE(locport
))
282 fprintf(stderr
, "Bad local port: %s\n", locport
);
285 if (!VALID_IP(remip
))
287 fprintf(stderr
, "Bad remote IP: %s\n", remip
);
290 if (!VALID_PORT_RANGE(remport
))
292 fprintf(stderr
, "Bad remote port: %s\n", remport
);
296 /* check for source ip in config file. If it's there
297 * and it's not 0.0.0.0, use it; else use the
298 * local ip address. (This makes sure we can use old-style
299 * config files without the source ip) */
300 if (!srcip
|| !strcmp(srcip
, "0.0.0.0"))
302 if (strcmp(srcip
,"0") && !VALID_IP(srcip
))
304 fprintf(stderr
, "Bad source IP: %s\n", srcip
);
308 /* This may seem complicated... refer to portfw.pl for an explanation of
309 * the keys and their meaning in certain circumstances */
311 if (strcmp(enabled
, "on") == 0)
314 /* If key2 is a zero, then it is a portfw command, otherwise it is an
315 * external access command */
316 if (strcmp(key2
, "0") == 0)
318 memset(command
, 0, STRING_SIZE
);
319 if (strcmp(protocol
, "gre") == 0)
320 snprintf(command
, STRING_SIZE
- 1, "/sbin/iptables -t nat -A PORTFW -p %s -d %s -j DNAT --to %s", protocol
, srcip
, remip
);
324 /* If locport contains a - we need to change it to a : */
325 if ((ctr
= strchr(locport
, '-')) != NULL
) {*ctr
= ':';}
326 /* If remport contains a : we need to change it to a - */
327 if ((ctr
= strchr(remport
,':')) != NULL
){*ctr
= '-';}
328 snprintf(command
, STRING_SIZE
- 1, "/sbin/iptables -t nat -A PORTFW -p %s -d %s --dport %s -j DNAT --to %s:%s", protocol
, srcip
, locport
, remip
, remport
);
329 safe_system(command
);
330 /* Now if remport contains a - we need to change it to a : */
331 if ((ctr
= strchr(remport
,'-')) != NULL
){*ctr
= ':';}
332 snprintf(command
, STRING_SIZE
- 1, "/sbin/iptables -t mangle -A PORTFWMANGLE -p %s -s %s/%s -d %s --dport %s -j MARK --set-mark 1", protocol
, greenip
, greenmask
, srcip
, locport
);
335 safe_system(command
);
336 snprintf(command
, STRING_SIZE
- 1, "/sbin/iptables -t mangle -A PORTFWMANGLE -p %s -s %s/%s -d %s --dport %s -j MARK --set-mark 2", protocol
, blueip
, bluemask
, srcip
, locport
);
338 if (strlen(orangedev
))
340 safe_system(command
);
341 snprintf(command
, STRING_SIZE
- 1, "/sbin/iptables -t mangle -A PORTFWMANGLE -p %s -s %s/%s -d %s --dport %s -j MARK --set-mark 3", protocol
, orangeip
, orangemask
, srcip
, locport
);
344 safe_system(command
);
347 /* if key2 is not "0" then it's an external access rule, if key2 is "0"
348 * then the portfw rule may contain external access information if origip
349 * is not "0" (the only defined not 0 value seems to be 0.0.0.0 - open
350 * to all; again, check portfw.pl for more details) */
351 if(strcmp(key2
, "0") || strcmp(origip
,"0") )
353 memset(command
, 0, STRING_SIZE
);
354 if (strcmp(protocol
, "gre") == 0)
355 snprintf(command
, STRING_SIZE
- 1, "/sbin/iptables -A PORTFWACCESS -i %s -p %s -s %s -d %s -j ACCEPT", iface
, protocol
, origip
, remip
);
359 /* If remport contains a - we need to change it to a : */
360 if ((ctr
= strchr(remport
,'-')) != NULL
){*ctr
= ':';}
361 snprintf(command
, STRING_SIZE
- 1, "/sbin/iptables -A PORTFWACCESS -i %s -p %s -s %s -d %s --dport %s -j ACCEPT", iface
, protocol
, origip
, remip
, remport
);
363 safe_system(command
);