aboutsummaryrefslogtreecommitdiff
path: root/src/dns/gnunet-helper-dns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dns/gnunet-helper-dns.c')
-rw-r--r--src/dns/gnunet-helper-dns.c82
1 files changed, 41 insertions, 41 deletions
diff --git a/src/dns/gnunet-helper-dns.c b/src/dns/gnunet-helper-dns.c
index bc83da027..8ff6413f8 100644
--- a/src/dns/gnunet-helper-dns.c
+++ b/src/dns/gnunet-helper-dns.c
@@ -23,7 +23,7 @@
23 * @brief helper to install firewall rules to hijack all DNS traffic 23 * @brief helper to install firewall rules to hijack all DNS traffic
24 * and send it to our virtual interface (except for DNS traffic 24 * and send it to our virtual interface (except for DNS traffic
25 * that originates on the specified port). We then 25 * that originates on the specified port). We then
26 * allow interacting with our virtual interface via stdin/stdout. 26 * allow interacting with our virtual interface via stdin/stdout.
27 * @author Philipp Tölke 27 * @author Philipp Tölke
28 * @author Christian Grothoff 28 * @author Christian Grothoff
29 * 29 *
@@ -55,13 +55,13 @@
55 * Naturally, neither of these problems can be helped as this is the 55 * Naturally, neither of these problems can be helped as this is the
56 * fundamental purpose of the binary. Certifying that this code is 56 * fundamental purpose of the binary. Certifying that this code is
57 * "safe" thus only means that it doesn't allow anything else (such 57 * "safe" thus only means that it doesn't allow anything else (such
58 * as local priv. escalation, etc.). 58 * as local priv. escalation, etc.).
59 * 59 *
60 * The following list of people have reviewed this code and considered 60 * The following list of people have reviewed this code and considered
61 * it safe (within specifications) since the last modification (if you 61 * it safe (within specifications) since the last modification (if you
62 * reviewed it, please have your name added to the list): 62 * reviewed it, please have your name added to the list):
63 * 63 *
64 * - Christian Grothoff 64 * - Christian Grothoff
65 */ 65 */
66#include "platform.h" 66#include "platform.h"
67 67
@@ -174,7 +174,7 @@ open_dev_null (int target_fd,
174 if (fd == target_fd) 174 if (fd == target_fd)
175 return; 175 return;
176 if (-1 == dup2 (fd, target_fd)) 176 if (-1 == dup2 (fd, target_fd))
177 { 177 {
178 (void) close (fd); 178 (void) close (fd);
179 abort (); 179 abort ();
180 } 180 }
@@ -184,13 +184,13 @@ open_dev_null (int target_fd,
184 184
185/** 185/**
186 * Run the given command and wait for it to complete. 186 * Run the given command and wait for it to complete.
187 * 187 *
188 * @param file name of the binary to run 188 * @param file name of the binary to run
189 * @param cmd command line arguments (as given to 'execv') 189 * @param cmd command line arguments (as given to 'execv')
190 * @return 0 on success, 1 on any error 190 * @return 0 on success, 1 on any error
191 */ 191 */
192static int 192static int
193fork_and_exec (const char *file, 193fork_and_exec (const char *file,
194 char *const cmd[]) 194 char *const cmd[])
195{ 195{
196 int status; 196 int status;
@@ -200,8 +200,8 @@ fork_and_exec (const char *file,
200 pid = fork (); 200 pid = fork ();
201 if (-1 == pid) 201 if (-1 == pid)
202 { 202 {
203 fprintf (stderr, 203 fprintf (stderr,
204 "fork failed: %s\n", 204 "fork failed: %s\n",
205 strerror (errno)); 205 strerror (errno));
206 return 1; 206 return 1;
207 } 207 }
@@ -210,25 +210,25 @@ fork_and_exec (const char *file,
210 /* we are the child process */ 210 /* we are the child process */
211 /* close stdin/stdout to not cause interference 211 /* close stdin/stdout to not cause interference
212 with the helper's main protocol! */ 212 with the helper's main protocol! */
213 (void) close (0); 213 (void) close (0);
214 open_dev_null (0, O_RDONLY); 214 open_dev_null (0, O_RDONLY);
215 (void) close (1); 215 (void) close (1);
216 open_dev_null (1, O_WRONLY); 216 open_dev_null (1, O_WRONLY);
217 (void) execv (file, cmd); 217 (void) execv (file, cmd);
218 /* can only get here on error */ 218 /* can only get here on error */
219 fprintf (stderr, 219 fprintf (stderr,
220 "exec `%s' failed: %s\n", 220 "exec `%s' failed: %s\n",
221 file, 221 file,
222 strerror (errno)); 222 strerror (errno));
223 _exit (1); 223 _exit (1);
224 } 224 }
225 /* keep running waitpid as long as the only error we get is 'EINTR' */ 225 /* keep running waitpid as long as the only error we get is 'EINTR' */
226 while ( (-1 == (ret = waitpid (pid, &status, 0))) && 226 while ( (-1 == (ret = waitpid (pid, &status, 0))) &&
227 (errno == EINTR) ); 227 (errno == EINTR) );
228 if (-1 == ret) 228 if (-1 == ret)
229 { 229 {
230 fprintf (stderr, 230 fprintf (stderr,
231 "waitpid failed: %s\n", 231 "waitpid failed: %s\n",
232 strerror (errno)); 232 strerror (errno));
233 return 1; 233 return 1;
234 } 234 }
@@ -312,8 +312,8 @@ set_address6 (const char *dev, const char *address, unsigned long prefix_len)
312 sa6.sin6_family = AF_INET6; 312 sa6.sin6_family = AF_INET6;
313 if (1 != inet_pton (AF_INET6, address, sa6.sin6_addr.s6_addr)) 313 if (1 != inet_pton (AF_INET6, address, sa6.sin6_addr.s6_addr))
314 { 314 {
315 fprintf (stderr, 315 fprintf (stderr,
316 "Failed to parse IPv6 address `%s': %s\n", 316 "Failed to parse IPv6 address `%s': %s\n",
317 address, 317 address,
318 strerror (errno)); 318 strerror (errno));
319 exit (1); 319 exit (1);
@@ -321,11 +321,11 @@ set_address6 (const char *dev, const char *address, unsigned long prefix_len)
321 321
322 if (-1 == (fd = socket (PF_INET6, SOCK_DGRAM, 0))) 322 if (-1 == (fd = socket (PF_INET6, SOCK_DGRAM, 0)))
323 { 323 {
324 fprintf (stderr, 324 fprintf (stderr,
325 "Error creating IPv6 socket: %s (ignored)\n", 325 "Error creating IPv6 socket: %s (ignored)\n",
326 strerror (errno)); 326 strerror (errno));
327 /* ignore error, maybe only IPv4 works on this system! */ 327 /* ignore error, maybe only IPv4 works on this system! */
328 return; 328 return;
329 } 329 }
330 330
331 memset (&ifr, 0, sizeof (struct ifreq)); 331 memset (&ifr, 0, sizeof (struct ifreq));
@@ -410,8 +410,8 @@ set_address4 (const char *dev, const char *address, const char *mask)
410 */ 410 */
411 if (1 != inet_pton (AF_INET, address, &addr->sin_addr.s_addr)) 411 if (1 != inet_pton (AF_INET, address, &addr->sin_addr.s_addr))
412 { 412 {
413 fprintf (stderr, 413 fprintf (stderr,
414 "Failed to parse IPv4 address `%s': %s\n", 414 "Failed to parse IPv4 address `%s': %s\n",
415 address, 415 address,
416 strerror (errno)); 416 strerror (errno));
417 exit (1); 417 exit (1);
@@ -420,7 +420,7 @@ set_address4 (const char *dev, const char *address, const char *mask)
420 if (-1 == (fd = socket (PF_INET, SOCK_DGRAM, 0))) 420 if (-1 == (fd = socket (PF_INET, SOCK_DGRAM, 0)))
421 { 421 {
422 fprintf (stderr, 422 fprintf (stderr,
423 "Error creating IPv4 socket: %s\n", 423 "Error creating IPv4 socket: %s\n",
424 strerror (errno)); 424 strerror (errno));
425 exit (1); 425 exit (1);
426 } 426 }
@@ -619,7 +619,7 @@ run (int fd_tun)
619 return; 619 return;
620 } 620 }
621 buftun_size -= written; 621 buftun_size -= written;
622 buftun_read += written; 622 buftun_read += written;
623 } 623 }
624 624
625 if (FD_ISSET (0, &fds_r)) 625 if (FD_ISSET (0, &fds_r))
@@ -749,7 +749,7 @@ main (int argc, char *const*argv)
749 return 254; 749 return 254;
750 } 750 }
751#else 751#else
752 if (0 != seteuid (0)) 752 if (0 != seteuid (0))
753 { 753 {
754 fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno)); 754 fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
755 return 254; 755 return 254;
@@ -763,7 +763,7 @@ main (int argc, char *const*argv)
763 sbin_iptables = "/usr/sbin/iptables"; 763 sbin_iptables = "/usr/sbin/iptables";
764 else 764 else
765 { 765 {
766 fprintf (stderr, 766 fprintf (stderr,
767 "Fatal: executable iptables not found in approved directories: %s\n", 767 "Fatal: executable iptables not found in approved directories: %s\n",
768 strerror (errno)); 768 strerror (errno));
769 return 3; 769 return 3;
@@ -805,7 +805,7 @@ main (int argc, char *const*argv)
805 /* setup pipe to shutdown nicely on SIGINT */ 805 /* setup pipe to shutdown nicely on SIGINT */
806 if (0 != pipe (cpipe)) 806 if (0 != pipe (cpipe))
807 { 807 {
808 fprintf (stderr, 808 fprintf (stderr,
809 "Fatal: could not setup control pipe: %s\n", 809 "Fatal: could not setup control pipe: %s\n",
810 strerror (errno)); 810 strerror (errno));
811 return 6; 811 return 6;
@@ -839,14 +839,14 @@ main (int argc, char *const*argv)
839 } 839 }
840 if ( (SIG_ERR == signal (SIGTERM, &signal_handler)) || 840 if ( (SIG_ERR == signal (SIGTERM, &signal_handler)) ||
841 (SIG_ERR == signal (SIGINT, &signal_handler)) || 841 (SIG_ERR == signal (SIGINT, &signal_handler)) ||
842 (SIG_ERR == signal (SIGHUP, &signal_handler)) ) 842 (SIG_ERR == signal (SIGHUP, &signal_handler)) )
843 { 843 {
844 fprintf (stderr, 844 fprintf (stderr,
845 "Fatal: could not initialize signal handler: %s\n", 845 "Fatal: could not initialize signal handler: %s\n",
846 strerror (errno)); 846 strerror (errno));
847 (void) close (cpipe[0]); 847 (void) close (cpipe[0]);
848 (void) close (cpipe[1]); 848 (void) close (cpipe[1]);
849 return 7; 849 return 7;
850 } 850 }
851 851
852 852
@@ -868,8 +868,8 @@ main (int argc, char *const*argv)
868 return 5; 868 return 5;
869 } 869 }
870 } 870 }
871 871
872 872
873 /* now open virtual interface (first part that requires root) */ 873 /* now open virtual interface (first part that requires root) */
874 if (-1 == (fd_tun = init_tun (dev))) 874 if (-1 == (fd_tun = init_tun (dev)))
875 { 875 {
@@ -907,14 +907,14 @@ main (int argc, char *const*argv)
907 set_address4 (dev, address, mask); 907 set_address4 (dev, address, mask);
908 } 908 }
909 909
910 910
911 /* update routing tables -- next part why we need SUID! */ 911 /* update routing tables -- next part why we need SUID! */
912 /* Forward everything from our EGID (which should only be held 912 /* Forward everything from our EGID (which should only be held
913 by the 'gnunet-service-dns') and with destination 913 by the 'gnunet-service-dns') and with destination
914 to port 53 on UDP, without hijacking */ 914 to port 53 on UDP, without hijacking */
915 r = 8; /* failed to fully setup routing table */ 915 r = 8; /* failed to fully setup routing table */
916 { 916 {
917 char *const mangle_args[] = 917 char *const mangle_args[] =
918 { 918 {
919 "iptables", "-m", "owner", "-t", "mangle", "-I", "OUTPUT", "1", "-p", 919 "iptables", "-m", "owner", "-t", "mangle", "-I", "OUTPUT", "1", "-p",
920 "udp", "--gid-owner", mygid, "--dport", DNS_PORT, "-j", 920 "udp", "--gid-owner", mygid, "--dport", DNS_PORT, "-j",
@@ -922,7 +922,7 @@ main (int argc, char *const*argv)
922 }; 922 };
923 if (0 != fork_and_exec (sbin_iptables, mangle_args)) 923 if (0 != fork_and_exec (sbin_iptables, mangle_args))
924 goto cleanup_rest; 924 goto cleanup_rest;
925 } 925 }
926 /* Mark all of the other DNS traffic using our mark DNS_MARK */ 926 /* Mark all of the other DNS traffic using our mark DNS_MARK */
927 { 927 {
928 char *const mark_args[] = 928 char *const mark_args[] =
@@ -965,7 +965,7 @@ main (int argc, char *const*argv)
965 } 965 }
966#else 966#else
967 /* Note: no 'setuid' here as we must keep our saved UID as root */ 967 /* Note: no 'setuid' here as we must keep our saved UID as root */
968 if (0 != seteuid (uid)) 968 if (0 != seteuid (uid))
969 { 969 {
970 fprintf (stderr, "Failed to seteuid: %s\n", strerror (errno)); 970 fprintf (stderr, "Failed to seteuid: %s\n", strerror (errno));
971 r = 24; 971 r = 24;
@@ -977,7 +977,7 @@ main (int argc, char *const*argv)
977 977
978 /* now forward until we hit a problem */ 978 /* now forward until we hit a problem */
979 run (fd_tun); 979 run (fd_tun);
980 980
981 /* now need to regain privs so we can remove the firewall rules we added! */ 981 /* now need to regain privs so we can remove the firewall rules we added! */
982#ifdef HAVE_SETRESUID 982#ifdef HAVE_SETRESUID
983 if (0 != setresuid (uid, 0, 0)) 983 if (0 != setresuid (uid, 0, 0))
@@ -987,19 +987,19 @@ main (int argc, char *const*argv)
987 goto cleanup_route_4; 987 goto cleanup_route_4;
988 } 988 }
989#else 989#else
990 if (0 != seteuid (0)) 990 if (0 != seteuid (0))
991 { 991 {
992 fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno)); 992 fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
993 r = 40; 993 r = 40;
994 goto cleanup_route_4; 994 goto cleanup_route_4;
995 } 995 }
996#endif 996#endif
997 997
998 /* update routing tables again -- this is why we could not fully drop privs */ 998 /* update routing tables again -- this is why we could not fully drop privs */
999 /* now undo updating of routing tables; normal exit or clean-up-on-error case */ 999 /* now undo updating of routing tables; normal exit or clean-up-on-error case */
1000 cleanup_route_4: 1000 cleanup_route_4:
1001 { 1001 {
1002 char *const route_clean_args[] = 1002 char *const route_clean_args[] =
1003 { 1003 {
1004 "ip", "route", "del", "default", "dev", dev, 1004 "ip", "route", "del", "default", "dev", dev,
1005 "table", DNS_TABLE, NULL 1005 "table", DNS_TABLE, NULL