diff options
author | Daniel Golle <daniel@makrotopia.org> | 2016-04-18 12:08:38 +0000 |
---|---|---|
committer | Daniel Golle <daniel@makrotopia.org> | 2016-04-18 12:08:38 +0000 |
commit | 85ebcc0bfdaadb37662a77b17cb3cda4d46a92c1 (patch) | |
tree | 008e8a24267aad8ba58154a08dccbd74bef05bb4 /src/dns | |
parent | 7200a570471907816431a57fe914ff5557118ee9 (diff) | |
download | gnunet-85ebcc0bfdaadb37662a77b17cb3cda4d46a92c1.tar.gz gnunet-85ebcc0bfdaadb37662a77b17cb3cda4d46a92c1.zip |
dns: add support for skipping the routing setup
Diffstat (limited to 'src/dns')
-rw-r--r-- | src/dns/gnunet-helper-dns.c | 159 | ||||
-rw-r--r-- | src/dns/gnunet-service-dns.c | 15 |
2 files changed, 99 insertions, 75 deletions
diff --git a/src/dns/gnunet-helper-dns.c b/src/dns/gnunet-helper-dns.c index b36972ac7..2f723d09d 100644 --- a/src/dns/gnunet-helper-dns.c +++ b/src/dns/gnunet-helper-dns.c | |||
@@ -709,6 +709,7 @@ PROCESS_BUFFER: | |||
709 | * 3: IPv6 netmask length in bits ("64") | 709 | * 3: IPv6 netmask length in bits ("64") |
710 | * 4: IPv4 address for the tunnel ("1.2.3.4") | 710 | * 4: IPv4 address for the tunnel ("1.2.3.4") |
711 | * 5: IPv4 netmask ("255.255.0.0") | 711 | * 5: IPv4 netmask ("255.255.0.0") |
712 | * 6: skip sysctl, routing and iptables setup ("0") | ||
712 | * @return 0 on success, otherwise code indicating type of error: | 713 | * @return 0 on success, otherwise code indicating type of error: |
713 | * 1 wrong number of arguments | 714 | * 1 wrong number of arguments |
714 | * 2 invalid arguments (i.e. port number / prefix length wrong) | 715 | * 2 invalid arguments (i.e. port number / prefix length wrong) |
@@ -733,8 +734,9 @@ main (int argc, char *const*argv) | |||
733 | char mygid[32]; | 734 | char mygid[32]; |
734 | int fd_tun; | 735 | int fd_tun; |
735 | uid_t uid; | 736 | uid_t uid; |
737 | int nortsetup = 0; | ||
736 | 738 | ||
737 | if (6 != argc) | 739 | if (7 != argc) |
738 | { | 740 | { |
739 | fprintf (stderr, "Fatal: must supply 6 arguments!\n"); | 741 | fprintf (stderr, "Fatal: must supply 6 arguments!\n"); |
740 | return 1; | 742 | return 1; |
@@ -755,40 +757,45 @@ main (int argc, char *const*argv) | |||
755 | return 254; | 757 | return 254; |
756 | } | 758 | } |
757 | #endif | 759 | #endif |
760 | if (0 == strncmp(argv[6], "1", 2)) | ||
761 | nortsetup = 1; | ||
758 | 762 | ||
759 | /* verify that the binaries were care about are executable */ | 763 | if (0 == nortsetup) |
760 | if (0 == access ("/sbin/iptables", X_OK)) | ||
761 | sbin_iptables = "/sbin/iptables"; | ||
762 | else if (0 == access ("/usr/sbin/iptables", X_OK)) | ||
763 | sbin_iptables = "/usr/sbin/iptables"; | ||
764 | else | ||
765 | { | 764 | { |
766 | fprintf (stderr, | 765 | /* verify that the binaries we care about are executable */ |
767 | "Fatal: executable iptables not found in approved directories: %s\n", | 766 | if (0 == access ("/sbin/iptables", X_OK)) |
768 | strerror (errno)); | 767 | sbin_iptables = "/sbin/iptables"; |
769 | return 3; | 768 | else if (0 == access ("/usr/sbin/iptables", X_OK)) |
770 | } | 769 | sbin_iptables = "/usr/sbin/iptables"; |
771 | if (0 == access ("/sbin/ip", X_OK)) | 770 | else |
772 | sbin_ip = "/sbin/ip"; | 771 | { |
773 | else if (0 == access ("/usr/sbin/ip", X_OK)) | 772 | fprintf (stderr, |
774 | sbin_ip = "/usr/sbin/ip"; | 773 | "Fatal: executable iptables not found in approved directories: %s\n", |
775 | else | 774 | strerror (errno)); |
776 | { | 775 | return 3; |
777 | fprintf (stderr, | 776 | } |
778 | "Fatal: executable ip not found in approved directories: %s\n", | 777 | if (0 == access ("/sbin/ip", X_OK)) |
779 | strerror (errno)); | 778 | sbin_ip = "/sbin/ip"; |
780 | return 4; | 779 | else if (0 == access ("/usr/sbin/ip", X_OK)) |
781 | } | 780 | sbin_ip = "/usr/sbin/ip"; |
782 | if (0 == access ("/sbin/sysctl", X_OK)) | 781 | else |
783 | sbin_sysctl = "/sbin/sysctl"; | 782 | { |
784 | else if (0 == access ("/usr/sbin/sysctl", X_OK)) | 783 | fprintf (stderr, |
785 | sbin_sysctl = "/usr/sbin/sysctl"; | 784 | "Fatal: executable ip not found in approved directories: %s\n", |
786 | else | 785 | strerror (errno)); |
787 | { | 786 | return 4; |
788 | fprintf (stderr, | 787 | } |
789 | "Fatal: executable sysctl not found in approved directories: %s\n", | 788 | if (0 == access ("/sbin/sysctl", X_OK)) |
790 | strerror (errno)); | 789 | sbin_sysctl = "/sbin/sysctl"; |
791 | return 5; | 790 | else if (0 == access ("/usr/sbin/sysctl", X_OK)) |
791 | sbin_sysctl = "/usr/sbin/sysctl"; | ||
792 | else | ||
793 | { | ||
794 | fprintf (stderr, | ||
795 | "Fatal: executable sysctl not found in approved directories: %s\n", | ||
796 | strerror (errno)); | ||
797 | return 5; | ||
798 | } | ||
792 | } | 799 | } |
793 | 800 | ||
794 | /* setup 'mygid' string */ | 801 | /* setup 'mygid' string */ |
@@ -858,6 +865,7 @@ main (int argc, char *const*argv) | |||
858 | dev[IFNAMSIZ - 1] = '\0'; | 865 | dev[IFNAMSIZ - 1] = '\0'; |
859 | 866 | ||
860 | /* Disable rp filtering */ | 867 | /* Disable rp filtering */ |
868 | if (0 == nortsetup) | ||
861 | { | 869 | { |
862 | char *const sysctl_args[] = {"sysctl", "-w", | 870 | char *const sysctl_args[] = {"sysctl", "-w", |
863 | "net.ipv4.conf.all.rp_filter=0", NULL}; | 871 | "net.ipv4.conf.all.rp_filter=0", NULL}; |
@@ -921,46 +929,49 @@ main (int argc, char *const*argv) | |||
921 | /* Forward everything from our EGID (which should only be held | 929 | /* Forward everything from our EGID (which should only be held |
922 | by the 'gnunet-service-dns') and with destination | 930 | by the 'gnunet-service-dns') and with destination |
923 | to port 53 on UDP, without hijacking */ | 931 | to port 53 on UDP, without hijacking */ |
924 | r = 8; /* failed to fully setup routing table */ | 932 | if (0 == nortsetup) |
925 | { | ||
926 | char *const mangle_args[] = | ||
927 | { | ||
928 | "iptables", "-m", "owner", "-t", "mangle", "-I", "OUTPUT", "1", "-p", | ||
929 | "udp", "--gid-owner", mygid, "--dport", DNS_PORT, "-j", | ||
930 | "ACCEPT", NULL | ||
931 | }; | ||
932 | if (0 != fork_and_exec (sbin_iptables, mangle_args)) | ||
933 | goto cleanup_rest; | ||
934 | } | ||
935 | /* Mark all of the other DNS traffic using our mark DNS_MARK */ | ||
936 | { | 933 | { |
937 | char *const mark_args[] = | 934 | r = 8; /* failed to fully setup routing table */ |
938 | { | 935 | { |
939 | "iptables", "-t", "mangle", "-I", "OUTPUT", "2", "-p", | 936 | char *const mangle_args[] = |
940 | "udp", "--dport", DNS_PORT, "-j", "MARK", "--set-mark", DNS_MARK, | 937 | { |
941 | NULL | 938 | "iptables", "-m", "owner", "-t", "mangle", "-I", "OUTPUT", "1", "-p", |
942 | }; | 939 | "udp", "--gid-owner", mygid, "--dport", DNS_PORT, "-j", |
943 | if (0 != fork_and_exec (sbin_iptables, mark_args)) | 940 | "ACCEPT", NULL |
944 | goto cleanup_mangle_1; | 941 | }; |
945 | } | 942 | if (0 != fork_and_exec (sbin_iptables, mangle_args)) |
946 | /* Forward all marked DNS traffic to our DNS_TABLE */ | 943 | goto cleanup_rest; |
947 | { | 944 | } |
948 | char *const forward_args[] = | 945 | /* Mark all of the other DNS traffic using our mark DNS_MARK */ |
949 | { | 946 | { |
950 | "ip", "rule", "add", "fwmark", DNS_MARK, "table", DNS_TABLE, NULL | 947 | char *const mark_args[] = |
951 | }; | 948 | { |
952 | if (0 != fork_and_exec (sbin_ip, forward_args)) | 949 | "iptables", "-t", "mangle", "-I", "OUTPUT", "2", "-p", |
953 | goto cleanup_mark_2; | 950 | "udp", "--dport", DNS_PORT, "-j", "MARK", "--set-mark", DNS_MARK, |
954 | } | 951 | NULL |
955 | /* Finally, add rule in our forwarding table to pass to our virtual interface */ | 952 | }; |
956 | { | 953 | if (0 != fork_and_exec (sbin_iptables, mark_args)) |
957 | char *const route_args[] = | 954 | goto cleanup_mangle_1; |
958 | { | 955 | } |
959 | "ip", "route", "add", "default", "dev", dev, | 956 | /* Forward all marked DNS traffic to our DNS_TABLE */ |
960 | "table", DNS_TABLE, NULL | 957 | { |
961 | }; | 958 | char *const forward_args[] = |
962 | if (0 != fork_and_exec (sbin_ip, route_args)) | 959 | { |
963 | goto cleanup_forward_3; | 960 | "ip", "rule", "add", "fwmark", DNS_MARK, "table", DNS_TABLE, NULL |
961 | }; | ||
962 | if (0 != fork_and_exec (sbin_ip, forward_args)) | ||
963 | goto cleanup_mark_2; | ||
964 | } | ||
965 | /* Finally, add rule in our forwarding table to pass to our virtual interface */ | ||
966 | { | ||
967 | char *const route_args[] = | ||
968 | { | ||
969 | "ip", "route", "add", "default", "dev", dev, | ||
970 | "table", DNS_TABLE, NULL | ||
971 | }; | ||
972 | if (0 != fork_and_exec (sbin_ip, route_args)) | ||
973 | goto cleanup_forward_3; | ||
974 | } | ||
964 | } | 975 | } |
965 | 976 | ||
966 | /* drop privs *except* for the saved UID; this is not perfect, but better | 977 | /* drop privs *except* for the saved UID; this is not perfect, but better |
@@ -1007,6 +1018,7 @@ main (int argc, char *const*argv) | |||
1007 | /* update routing tables again -- this is why we could not fully drop privs */ | 1018 | /* update routing tables again -- this is why we could not fully drop privs */ |
1008 | /* now undo updating of routing tables; normal exit or clean-up-on-error case */ | 1019 | /* now undo updating of routing tables; normal exit or clean-up-on-error case */ |
1009 | cleanup_route_4: | 1020 | cleanup_route_4: |
1021 | if (0 == nortsetup) | ||
1010 | { | 1022 | { |
1011 | char *const route_clean_args[] = | 1023 | char *const route_clean_args[] = |
1012 | { | 1024 | { |
@@ -1017,6 +1029,7 @@ main (int argc, char *const*argv) | |||
1017 | r += 1; | 1029 | r += 1; |
1018 | } | 1030 | } |
1019 | cleanup_forward_3: | 1031 | cleanup_forward_3: |
1032 | if (0 == nortsetup) | ||
1020 | { | 1033 | { |
1021 | char *const forward_clean_args[] = | 1034 | char *const forward_clean_args[] = |
1022 | { | 1035 | { |
@@ -1026,6 +1039,7 @@ main (int argc, char *const*argv) | |||
1026 | r += 2; | 1039 | r += 2; |
1027 | } | 1040 | } |
1028 | cleanup_mark_2: | 1041 | cleanup_mark_2: |
1042 | if (0 == nortsetup) | ||
1029 | { | 1043 | { |
1030 | char *const mark_clean_args[] = | 1044 | char *const mark_clean_args[] = |
1031 | { | 1045 | { |
@@ -1036,6 +1050,7 @@ main (int argc, char *const*argv) | |||
1036 | r += 4; | 1050 | r += 4; |
1037 | } | 1051 | } |
1038 | cleanup_mangle_1: | 1052 | cleanup_mangle_1: |
1053 | if (0 == nortsetup) | ||
1039 | { | 1054 | { |
1040 | char *const mangle_clean_args[] = | 1055 | char *const mangle_clean_args[] = |
1041 | { | 1056 | { |
diff --git a/src/dns/gnunet-service-dns.c b/src/dns/gnunet-service-dns.c index 0f975e82f..972c96f6d 100644 --- a/src/dns/gnunet-service-dns.c +++ b/src/dns/gnunet-service-dns.c | |||
@@ -219,7 +219,7 @@ static struct GNUNET_HELPER_Handle *hijacker; | |||
219 | /** | 219 | /** |
220 | * Command-line arguments we are giving to the hijacker process. | 220 | * Command-line arguments we are giving to the hijacker process. |
221 | */ | 221 | */ |
222 | static char *helper_argv[7]; | 222 | static char *helper_argv[8]; |
223 | 223 | ||
224 | /** | 224 | /** |
225 | * Head of DLL of clients we consult. | 225 | * Head of DLL of clients we consult. |
@@ -284,7 +284,7 @@ cleanup_task (void *cls GNUNET_UNUSED) | |||
284 | GNUNET_HELPER_stop (hijacker, GNUNET_NO); | 284 | GNUNET_HELPER_stop (hijacker, GNUNET_NO); |
285 | hijacker = NULL; | 285 | hijacker = NULL; |
286 | } | 286 | } |
287 | for (i=0;i<7;i++) | 287 | for (i=0;i<8;i++) |
288 | GNUNET_free_non_null (helper_argv[i]); | 288 | GNUNET_free_non_null (helper_argv[i]); |
289 | for (i=0;i<=UINT16_MAX;i++) | 289 | for (i=0;i<=UINT16_MAX;i++) |
290 | cleanup_rr (&requests[i]); | 290 | cleanup_rr (&requests[i]); |
@@ -1040,6 +1040,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
1040 | struct in6_addr dns_exit6; | 1040 | struct in6_addr dns_exit6; |
1041 | char *dns_exit; | 1041 | char *dns_exit; |
1042 | char *binary; | 1042 | char *binary; |
1043 | int nortsetup; | ||
1043 | 1044 | ||
1044 | cfg = cfg_; | 1045 | cfg = cfg_; |
1045 | stats = GNUNET_STATISTICS_create ("dns", cfg); | 1046 | stats = GNUNET_STATISTICS_create ("dns", cfg); |
@@ -1136,7 +1137,15 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
1136 | return; | 1137 | return; |
1137 | } | 1138 | } |
1138 | helper_argv[5] = ipv4mask; | 1139 | helper_argv[5] = ipv4mask; |
1139 | helper_argv[6] = NULL; | 1140 | |
1141 | nortsetup = GNUNET_CONFIGURATION_get_value_yesno (cfg, "dns", | ||
1142 | "SKIP_ROUTING_SETUP"); | ||
1143 | if (GNUNET_YES == nortsetup) | ||
1144 | helper_argv[6] = GNUNET_strdup("1"); | ||
1145 | else | ||
1146 | helper_argv[6] = GNUNET_strdup("0"); | ||
1147 | |||
1148 | helper_argv[7] = NULL; | ||
1140 | hijacker = GNUNET_HELPER_start (GNUNET_NO, | 1149 | hijacker = GNUNET_HELPER_start (GNUNET_NO, |
1141 | "gnunet-helper-dns", | 1150 | "gnunet-helper-dns", |
1142 | helper_argv, | 1151 | helper_argv, |