aboutsummaryrefslogtreecommitdiff
path: root/src/gns/gnunet-gns-proxy.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gns/gnunet-gns-proxy.c')
-rw-r--r--src/gns/gnunet-gns-proxy.c558
1 files changed, 426 insertions, 132 deletions
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c
index 08663a57e..d66f5c658 100644
--- a/src/gns/gnunet-gns-proxy.c
+++ b/src/gns/gnunet-gns-proxy.c
@@ -1,21 +1,19 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012-2014 GNUnet e.V. 3 Copyright (C) 2012-2018 GNUnet e.V.
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software: you can redistribute it and/or modify it
6 it under the terms of the GNU General Public License as published 6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation; either version 3, or (at your 7 by the Free Software Foundation, either version 3 of the License,
8 option) any later version. 8 or (at your option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with GNUnet; see the file COPYING. If not, write to the 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/ 17*/
20/** 18/**
21 * @author Martin Schanzenbach 19 * @author Martin Schanzenbach
@@ -48,6 +46,7 @@
48#include "gns.h" 46#include "gns.h"
49 47
50 48
49
51/** 50/**
52 * Default Socks5 listen port. 51 * Default Socks5 listen port.
53 */ 52 */
@@ -106,7 +105,13 @@
106 * @param fun name of curl_easy-function that gave the error 105 * @param fun name of curl_easy-function that gave the error
107 * @param rc return code from curl 106 * @param rc return code from curl
108 */ 107 */
109#define LOG_CURL_EASY(level,fun,rc) GNUNET_log(level, _("%s failed at %s:%d: `%s'\n"), fun, __FILE__, __LINE__, curl_easy_strerror (rc)) 108#define LOG_CURL_EASY(level,fun,rc) \
109 GNUNET_log (level, \
110 _("%s failed at %s:%d: `%s'\n"), \
111 fun, \
112 __FILE__, \
113 __LINE__, \
114 curl_easy_strerror (rc))
110 115
111 116
112/* *************** Socks protocol definitions (move to TUN?) ****************** */ 117/* *************** Socks protocol definitions (move to TUN?) ****************** */
@@ -626,6 +631,11 @@ struct Socks5Request
626 * Did we suspend MHD processing? 631 * Did we suspend MHD processing?
627 */ 632 */
628 int suspended; 633 int suspended;
634
635 /**
636 * Did we pause CURL processing?
637 */
638 int curl_paused;
629}; 639};
630 640
631 641
@@ -636,7 +646,7 @@ struct Socks5Request
636/** 646/**
637 * The port the proxy is running on (default 7777) 647 * The port the proxy is running on (default 7777)
638 */ 648 */
639static unsigned long long port = GNUNET_GNS_PROXY_PORT; 649static uint16_t port = GNUNET_GNS_PROXY_PORT;
640 650
641/** 651/**
642 * The CA file (pem) to use for the proxy CA 652 * The CA file (pem) to use for the proxy CA
@@ -679,6 +689,11 @@ static CURLM *curl_multi;
679static struct GNUNET_GNS_Handle *gns_handle; 689static struct GNUNET_GNS_Handle *gns_handle;
680 690
681/** 691/**
692 * Disable IPv6.
693 */
694static int disable_v6;
695
696/**
682 * DLL for http/https daemons 697 * DLL for http/https daemons
683 */ 698 */
684static struct MhdHttpList *mhd_httpd_head; 699static struct MhdHttpList *mhd_httpd_head;
@@ -763,21 +778,37 @@ cleanup_s5r (struct Socks5Request *s5r)
763 } 778 }
764 if ( (NULL != s5r->response) && 779 if ( (NULL != s5r->response) &&
765 (curl_failure_response != s5r->response) ) 780 (curl_failure_response != s5r->response) )
781 {
766 MHD_destroy_response (s5r->response); 782 MHD_destroy_response (s5r->response);
783 s5r->response = NULL;
784 }
767 if (NULL != s5r->rtask) 785 if (NULL != s5r->rtask)
786 {
768 GNUNET_SCHEDULER_cancel (s5r->rtask); 787 GNUNET_SCHEDULER_cancel (s5r->rtask);
788 s5r->rtask = NULL;
789 }
769 if (NULL != s5r->timeout_task) 790 if (NULL != s5r->timeout_task)
791 {
770 GNUNET_SCHEDULER_cancel (s5r->timeout_task); 792 GNUNET_SCHEDULER_cancel (s5r->timeout_task);
793 s5r->timeout_task = NULL;
794 }
771 if (NULL != s5r->wtask) 795 if (NULL != s5r->wtask)
796 {
772 GNUNET_SCHEDULER_cancel (s5r->wtask); 797 GNUNET_SCHEDULER_cancel (s5r->wtask);
798 s5r->wtask = NULL;
799 }
773 if (NULL != s5r->gns_lookup) 800 if (NULL != s5r->gns_lookup)
801 {
774 GNUNET_GNS_lookup_with_tld_cancel (s5r->gns_lookup); 802 GNUNET_GNS_lookup_with_tld_cancel (s5r->gns_lookup);
803 s5r->gns_lookup = NULL;
804 }
775 if (NULL != s5r->sock) 805 if (NULL != s5r->sock)
776 { 806 {
777 if (SOCKS5_SOCKET_WITH_MHD <= s5r->state) 807 if (SOCKS5_SOCKET_WITH_MHD <= s5r->state)
778 GNUNET_NETWORK_socket_free_memory_only_ (s5r->sock); 808 GNUNET_NETWORK_socket_free_memory_only_ (s5r->sock);
779 else 809 else
780 GNUNET_NETWORK_socket_close (s5r->sock); 810 GNUNET_NETWORK_socket_close (s5r->sock);
811 s5r->sock = NULL;
781 } 812 }
782 GNUNET_CONTAINER_DLL_remove (s5r_head, 813 GNUNET_CONTAINER_DLL_remove (s5r_head,
783 s5r_tail, 814 s5r_tail,
@@ -823,7 +854,9 @@ mhd_content_cb (void *cls,
823 start the download, the IO buffer is still full 854 start the download, the IO buffer is still full
824 with upload data. */ 855 with upload data. */
825 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 856 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
826 "Pausing MHD download, not yet ready for download\n"); 857 "Pausing MHD download %s%s, not yet ready for download\n",
858 s5r->domain,
859 s5r->url);
827 return 0; /* not yet ready for data download */ 860 return 0; /* not yet ready for data download */
828 } 861 }
829 bytes_to_copy = GNUNET_MIN (max, 862 bytes_to_copy = GNUNET_MIN (max,
@@ -832,12 +865,21 @@ mhd_content_cb (void *cls,
832 (SOCKS5_SOCKET_DOWNLOAD_DONE != s5r->state) ) 865 (SOCKS5_SOCKET_DOWNLOAD_DONE != s5r->state) )
833 { 866 {
834 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 867 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
835 "Pausing MHD download, no data available\n"); 868 "Pausing MHD download %s%s, no data available\n",
869 s5r->domain,
870 s5r->url);
836 if (NULL != s5r->curl) 871 if (NULL != s5r->curl)
837 { 872 {
838 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 873 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
839 "Continuing CURL interaction\n"); 874 "Continuing CURL interaction for %s%s\n",
840 curl_easy_pause (s5r->curl, CURLPAUSE_CONT); 875 s5r->domain,
876 s5r->url);
877 if (GNUNET_YES == s5r->curl_paused)
878 {
879 s5r->curl_paused = GNUNET_NO;
880 curl_easy_pause (s5r->curl,
881 CURLPAUSE_CONT);
882 }
841 curl_download_prepare (); 883 curl_download_prepare ();
842 } 884 }
843 if (GNUNET_NO == s5r->suspended) 885 if (GNUNET_NO == s5r->suspended)
@@ -851,13 +893,17 @@ mhd_content_cb (void *cls,
851 (SOCKS5_SOCKET_DOWNLOAD_DONE == s5r->state) ) 893 (SOCKS5_SOCKET_DOWNLOAD_DONE == s5r->state) )
852 { 894 {
853 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 895 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
854 "Completed MHD download\n"); 896 "Completed MHD download %s%s\n",
897 s5r->domain,
898 s5r->url);
855 return MHD_CONTENT_READER_END_OF_STREAM; 899 return MHD_CONTENT_READER_END_OF_STREAM;
856 } 900 }
857 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 901 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
858 "Writing %llu/%llu bytes\n", 902 "Writing %llu/%llu bytes to %s%s\n",
859 (unsigned long long) bytes_to_copy, 903 (unsigned long long) bytes_to_copy,
860 (unsigned long long) s5r->io_len); 904 (unsigned long long) s5r->io_len,
905 s5r->domain,
906 s5r->url);
861 GNUNET_memcpy (buf, 907 GNUNET_memcpy (buf,
862 s5r->io_buf, 908 s5r->io_buf,
863 bytes_to_copy); 909 bytes_to_copy);
@@ -865,10 +911,14 @@ mhd_content_cb (void *cls,
865 &s5r->io_buf[bytes_to_copy], 911 &s5r->io_buf[bytes_to_copy],
866 s5r->io_len - bytes_to_copy); 912 s5r->io_len - bytes_to_copy);
867 s5r->io_len -= bytes_to_copy; 913 s5r->io_len -= bytes_to_copy;
868 if (NULL != s5r->curl) 914 if ( (NULL != s5r->curl) &&
915 (GNUNET_YES == s5r->curl_paused) )
869 { 916 {
870 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 917 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
871 "Continuing CURL interaction\n"); 918 "Continuing CURL interaction for %s%s\n",
919 s5r->domain,
920 s5r->url);
921 s5r->curl_paused = GNUNET_NO;
872 curl_easy_pause (s5r->curl, 922 curl_easy_pause (s5r->curl,
873 CURLPAUSE_CONT); 923 CURLPAUSE_CONT);
874 } 924 }
@@ -911,8 +961,10 @@ check_ssl_certificate (struct Socks5Request *s5r)
911 tlsinfo->backend); 961 tlsinfo->backend);
912 return GNUNET_SYSERR; 962 return GNUNET_SYSERR;
913 } 963 }
914 chainp = gnutls_certificate_get_peers (tlsinfo->internals, &cert_list_size); 964 chainp = gnutls_certificate_get_peers (tlsinfo->internals,
915 if ( (! chainp) || (0 == cert_list_size) ) 965 &cert_list_size);
966 if ( (! chainp) ||
967 (0 == cert_list_size) )
916 return GNUNET_SYSERR; 968 return GNUNET_SYSERR;
917 969
918 size = sizeof (certdn); 970 size = sizeof (certdn);
@@ -1015,9 +1067,10 @@ check_ssl_certificate (struct Socks5Request *s5r)
1015 name))) 1067 name)))
1016 { 1068 {
1017 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1069 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1018 _("TLS certificate subject name (%s) does not match `%s'\n"), 1070 _("TLS certificate subject name (%s) does not match `%s': %d\n"),
1019 certdn, 1071 certdn,
1020 name); 1072 name,
1073 rc);
1021 gnutls_x509_crt_deinit (x509_cert); 1074 gnutls_x509_crt_deinit (x509_cert);
1022 return GNUNET_SYSERR; 1075 return GNUNET_SYSERR;
1023 } 1076 }
@@ -1075,15 +1128,17 @@ curl_check_hdr (void *buffer,
1075 if (GNUNET_OK != check_ssl_certificate (s5r)) 1128 if (GNUNET_OK != check_ssl_certificate (s5r))
1076 return 0; 1129 return 0;
1077 } 1130 }
1078 1131 ndup = GNUNET_strndup (buffer,
1079 ndup = GNUNET_strndup (buffer, bytes); 1132 bytes);
1080 hdr_type = strtok (ndup, ":"); 1133 hdr_type = strtok (ndup,
1134 ":");
1081 if (NULL == hdr_type) 1135 if (NULL == hdr_type)
1082 { 1136 {
1083 GNUNET_free (ndup); 1137 GNUNET_free (ndup);
1084 return bytes; 1138 return bytes;
1085 } 1139 }
1086 hdr_val = strtok (NULL, ""); 1140 hdr_val = strtok (NULL,
1141 "");
1087 if (NULL == hdr_val) 1142 if (NULL == hdr_val)
1088 { 1143 {
1089 GNUNET_free (ndup); 1144 GNUNET_free (ndup);
@@ -1105,7 +1160,9 @@ curl_check_hdr (void *buffer,
1105 domain_matched = GNUNET_NO; /* make sure we match domain at most once */ 1160 domain_matched = GNUNET_NO; /* make sure we match domain at most once */
1106 for (tok = strtok (hdr_val, ";"); NULL != tok; tok = strtok (NULL, ";")) 1161 for (tok = strtok (hdr_val, ";"); NULL != tok; tok = strtok (NULL, ";"))
1107 { 1162 {
1108 if ( (0 == strncasecmp (tok, " domain", strlen (" domain"))) && 1163 if ( (0 == strncasecmp (tok,
1164 " domain",
1165 strlen (" domain"))) &&
1109 (GNUNET_NO == domain_matched) ) 1166 (GNUNET_NO == domain_matched) )
1110 { 1167 {
1111 domain_matched = GNUNET_YES; 1168 domain_matched = GNUNET_YES;
@@ -1113,7 +1170,8 @@ curl_check_hdr (void *buffer,
1113 if (strlen (cookie_domain) < strlen (s5r->leho)) 1170 if (strlen (cookie_domain) < strlen (s5r->leho))
1114 { 1171 {
1115 delta_cdomain = strlen (s5r->leho) - strlen (cookie_domain); 1172 delta_cdomain = strlen (s5r->leho) - strlen (cookie_domain);
1116 if (0 == strcasecmp (cookie_domain, s5r->leho + delta_cdomain)) 1173 if (0 == strcasecmp (cookie_domain,
1174 s5r->leho + delta_cdomain))
1117 { 1175 {
1118 offset += sprintf (new_cookie_hdr + offset, 1176 offset += sprintf (new_cookie_hdr + offset,
1119 " domain=%s;", 1177 " domain=%s;",
@@ -1121,18 +1179,30 @@ curl_check_hdr (void *buffer,
1121 continue; 1179 continue;
1122 } 1180 }
1123 } 1181 }
1124 else if (0 == strcmp (cookie_domain, s5r->leho)) 1182 else if (0 == strcmp (cookie_domain,
1183 s5r->leho))
1125 { 1184 {
1126 offset += sprintf (new_cookie_hdr + offset, 1185 offset += sprintf (new_cookie_hdr + offset,
1127 " domain=%s;", 1186 " domain=%s;",
1128 s5r->domain); 1187 s5r->domain);
1129 continue; 1188 continue;
1130 } 1189 }
1190 else if ( ('.' == cookie_domain[0]) &&
1191 (0 == strcmp (&cookie_domain[1],
1192 s5r->leho)) )
1193 {
1194 offset += sprintf (new_cookie_hdr + offset,
1195 " domain=.%s;",
1196 s5r->domain);
1197 continue;
1198 }
1131 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1199 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1132 _("Cookie domain `%s' supplied by server is invalid\n"), 1200 _("Cookie domain `%s' supplied by server is invalid\n"),
1133 tok); 1201 tok);
1134 } 1202 }
1135 GNUNET_memcpy (new_cookie_hdr + offset, tok, strlen (tok)); 1203 GNUNET_memcpy (new_cookie_hdr + offset,
1204 tok,
1205 strlen (tok));
1136 offset += strlen (tok); 1206 offset += strlen (tok);
1137 new_cookie_hdr[offset++] = ';'; 1207 new_cookie_hdr[offset++] = ';';
1138 } 1208 }
@@ -1140,7 +1210,14 @@ curl_check_hdr (void *buffer,
1140 } 1210 }
1141 1211
1142 new_location = NULL; 1212 new_location = NULL;
1143 if (0 == strcasecmp (MHD_HTTP_HEADER_LOCATION, hdr_type)) 1213 if (0 == strcasecmp (MHD_HTTP_HEADER_TRANSFER_ENCODING,
1214 hdr_type))
1215 {
1216 /* Ignore transfer encoding, set automatically by MHD if required */
1217 goto cleanup;
1218 }
1219 if (0 == strcasecmp (MHD_HTTP_HEADER_LOCATION,
1220 hdr_type))
1144 { 1221 {
1145 char *leho_host; 1222 char *leho_host;
1146 1223
@@ -1184,6 +1261,7 @@ curl_check_hdr (void *buffer,
1184 s5r->header_tail, 1261 s5r->header_tail,
1185 header); 1262 header);
1186 } 1263 }
1264 cleanup:
1187 GNUNET_free (ndup); 1265 GNUNET_free (ndup);
1188 GNUNET_free_non_null (new_cookie_hdr); 1266 GNUNET_free_non_null (new_cookie_hdr);
1189 GNUNET_free_non_null (new_location); 1267 GNUNET_free_non_null (new_location);
@@ -1227,7 +1305,9 @@ create_mhd_response_from_s5r (struct Socks5Request *s5r)
1227 s5r->domain, 1305 s5r->domain,
1228 s5r->url); 1306 s5r->url);
1229 s5r->response_code = resp_code; 1307 s5r->response_code = resp_code;
1230 s5r->response = MHD_create_response_from_callback ((-1 == content_length) ? MHD_SIZE_UNKNOWN : content_length, 1308 s5r->response = MHD_create_response_from_callback ((-1 == content_length)
1309 ? MHD_SIZE_UNKNOWN
1310 : content_length,
1231 IO_BUFFERSIZE, 1311 IO_BUFFERSIZE,
1232 &mhd_content_cb, 1312 &mhd_content_cb,
1233 s5r, 1313 s5r,
@@ -1269,6 +1349,7 @@ create_mhd_response_from_s5r (struct Socks5Request *s5r)
1269 return GNUNET_OK; 1349 return GNUNET_OK;
1270} 1350}
1271 1351
1352
1272/** 1353/**
1273 * Handle response payload data from cURL. Copies it into our `io_buf` to make 1354 * Handle response payload data from cURL. Copies it into our `io_buf` to make
1274 * it available to MHD. 1355 * it available to MHD.
@@ -1288,6 +1369,12 @@ curl_download_cb (void *ptr,
1288 struct Socks5Request *s5r = ctx; 1369 struct Socks5Request *s5r = ctx;
1289 size_t total = size * nmemb; 1370 size_t total = size * nmemb;
1290 1371
1372 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1373 "Receiving %ux%u bytes for `%s%s' from cURL\n",
1374 (unsigned int) size,
1375 (unsigned int) nmemb,
1376 s5r->domain,
1377 s5r->url);
1291 if (NULL == s5r->response) 1378 if (NULL == s5r->response)
1292 GNUNET_assert (GNUNET_OK == 1379 GNUNET_assert (GNUNET_OK ==
1293 create_mhd_response_from_s5r (s5r)); 1380 create_mhd_response_from_s5r (s5r));
@@ -1302,6 +1389,7 @@ curl_download_cb (void *ptr,
1302 "Pausing CURL download `%s%s', waiting for UPLOAD to finish\n", 1389 "Pausing CURL download `%s%s', waiting for UPLOAD to finish\n",
1303 s5r->domain, 1390 s5r->domain,
1304 s5r->url); 1391 s5r->url);
1392 s5r->curl_paused = GNUNET_YES;
1305 return CURL_WRITEFUNC_PAUSE; /* not yet ready for data download */ 1393 return CURL_WRITEFUNC_PAUSE; /* not yet ready for data download */
1306 } 1394 }
1307 if (sizeof (s5r->io_buf) - s5r->io_len < total) 1395 if (sizeof (s5r->io_buf) - s5r->io_len < total)
@@ -1313,6 +1401,7 @@ curl_download_cb (void *ptr,
1313 (unsigned long long) sizeof (s5r->io_buf), 1401 (unsigned long long) sizeof (s5r->io_buf),
1314 (unsigned long long) s5r->io_len, 1402 (unsigned long long) s5r->io_len,
1315 (unsigned long long) total); 1403 (unsigned long long) total);
1404 s5r->curl_paused = GNUNET_YES;
1316 return CURL_WRITEFUNC_PAUSE; /* not enough space */ 1405 return CURL_WRITEFUNC_PAUSE; /* not enough space */
1317 } 1406 }
1318 GNUNET_memcpy (&s5r->io_buf[s5r->io_len], 1407 GNUNET_memcpy (&s5r->io_buf[s5r->io_len],
@@ -1367,6 +1456,12 @@ curl_upload_cb (void *buf,
1367 (SOCKS5_SOCKET_UPLOAD_DONE == s5r->state) ) 1456 (SOCKS5_SOCKET_UPLOAD_DONE == s5r->state) )
1368 { 1457 {
1369 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED; 1458 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
1459 if (GNUNET_YES == s5r->curl_paused)
1460 {
1461 s5r->curl_paused = GNUNET_NO;
1462 curl_easy_pause (s5r->curl,
1463 CURLPAUSE_CONT);
1464 }
1370 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1465 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1371 "Completed CURL UPLOAD %s%s\n", 1466 "Completed CURL UPLOAD %s%s\n",
1372 s5r->domain, 1467 s5r->domain,
@@ -1381,7 +1476,9 @@ curl_upload_cb (void *buf,
1381 } 1476 }
1382 to_copy = GNUNET_MIN (s5r->io_len, 1477 to_copy = GNUNET_MIN (s5r->io_len,
1383 len); 1478 len);
1384 GNUNET_memcpy (buf, s5r->io_buf, to_copy); 1479 GNUNET_memcpy (buf,
1480 s5r->io_buf,
1481 to_copy);
1385 memmove (s5r->io_buf, 1482 memmove (s5r->io_buf,
1386 &s5r->io_buf[to_copy], 1483 &s5r->io_buf[to_copy],
1387 s5r->io_len - to_copy); 1484 s5r->io_len - to_copy);
@@ -1445,20 +1542,28 @@ curl_download_prepare ()
1445 return; 1542 return;
1446 } 1543 }
1447 to = -1; 1544 to = -1;
1448 GNUNET_break (CURLM_OK == curl_multi_timeout (curl_multi, &to)); 1545 GNUNET_break (CURLM_OK ==
1546 curl_multi_timeout (curl_multi,
1547 &to));
1449 if (-1 == to) 1548 if (-1 == to)
1450 rtime = GNUNET_TIME_UNIT_FOREVER_REL; 1549 rtime = GNUNET_TIME_UNIT_FOREVER_REL;
1451 else 1550 else
1452 rtime = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, to); 1551 rtime = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS,
1552 to);
1453 if (-1 != max) 1553 if (-1 != max)
1454 { 1554 {
1455 grs = GNUNET_NETWORK_fdset_create (); 1555 grs = GNUNET_NETWORK_fdset_create ();
1456 gws = GNUNET_NETWORK_fdset_create (); 1556 gws = GNUNET_NETWORK_fdset_create ();
1457 GNUNET_NETWORK_fdset_copy_native (grs, &rs, max + 1); 1557 GNUNET_NETWORK_fdset_copy_native (grs,
1458 GNUNET_NETWORK_fdset_copy_native (gws, &ws, max + 1); 1558 &rs,
1559 max + 1);
1560 GNUNET_NETWORK_fdset_copy_native (gws,
1561 &ws,
1562 max + 1);
1459 curl_download_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT, 1563 curl_download_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
1460 rtime, 1564 rtime,
1461 grs, gws, 1565 grs,
1566 gws,
1462 &curl_task_download, 1567 &curl_task_download,
1463 curl_multi); 1568 curl_multi);
1464 GNUNET_NETWORK_fdset_destroy (gws); 1569 GNUNET_NETWORK_fdset_destroy (gws);
@@ -1495,6 +1600,9 @@ curl_task_download (void *cls)
1495 running = 0; 1600 running = 0;
1496 mret = curl_multi_perform (curl_multi, 1601 mret = curl_multi_perform (curl_multi,
1497 &running); 1602 &running);
1603 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1604 "Checking CURL multi status: %d\n",
1605 mret);
1498 while (NULL != (msg = curl_multi_info_read (curl_multi, 1606 while (NULL != (msg = curl_multi_info_read (curl_multi,
1499 &msgnum))) 1607 &msgnum)))
1500 { 1608 {
@@ -1527,7 +1635,12 @@ curl_task_download (void *cls)
1527 GNUNET_assert (GNUNET_OK == 1635 GNUNET_assert (GNUNET_OK ==
1528 create_mhd_response_from_s5r (s5r)); 1636 create_mhd_response_from_s5r (s5r));
1529 } 1637 }
1530 s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE; 1638 s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE;
1639 if (GNUNET_YES == s5r->suspended)
1640 {
1641 MHD_resume_connection (s5r->con);
1642 s5r->suspended = GNUNET_NO;
1643 }
1531 run_mhd_now (s5r->hd); 1644 run_mhd_now (s5r->hd);
1532 break; 1645 break;
1533 default: 1646 default:
@@ -1538,6 +1651,11 @@ curl_task_download (void *cls)
1538 curl_easy_strerror (msg->data.result)); 1651 curl_easy_strerror (msg->data.result));
1539 /* FIXME: indicate error somehow? close MHD connection badly as well? */ 1652 /* FIXME: indicate error somehow? close MHD connection badly as well? */
1540 s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE; 1653 s5r->state = SOCKS5_SOCKET_DOWNLOAD_DONE;
1654 if (GNUNET_YES == s5r->suspended)
1655 {
1656 MHD_resume_connection (s5r->con);
1657 s5r->suspended = GNUNET_NO;
1658 }
1541 run_mhd_now (s5r->hd); 1659 run_mhd_now (s5r->hd);
1542 break; 1660 break;
1543 } 1661 }
@@ -1600,13 +1718,10 @@ con_val_iter (void *cls,
1600 struct Socks5Request *s5r = cls; 1718 struct Socks5Request *s5r = cls;
1601 char *hdr; 1719 char *hdr;
1602 1720
1603 if ( (0 == strcasecmp (MHD_HTTP_HEADER_HOST, key)) && 1721 if ( (0 == strcasecmp (MHD_HTTP_HEADER_HOST,
1722 key)) &&
1604 (NULL != s5r->leho) ) 1723 (NULL != s5r->leho) )
1605 value = s5r->leho; 1724 value = s5r->leho;
1606 if (0 == strcasecmp (MHD_HTTP_HEADER_CONTENT_LENGTH, key))
1607 return MHD_YES;
1608 if (0 == strcasecmp (MHD_HTTP_HEADER_ACCEPT_ENCODING, key))
1609 return MHD_YES;
1610 GNUNET_asprintf (&hdr, 1725 GNUNET_asprintf (&hdr,
1611 "%s: %s", 1726 "%s: %s",
1612 key, 1727 key,
@@ -1670,7 +1785,7 @@ create_response (void *cls,
1670 return MHD_NO; 1785 return MHD_NO;
1671 } 1786 }
1672 s5r->con = con; 1787 s5r->con = con;
1673 //Fresh connection. 1788 /* Fresh connection. */
1674 if (SOCKS5_SOCKET_WITH_MHD == s5r->state) 1789 if (SOCKS5_SOCKET_WITH_MHD == s5r->state)
1675 { 1790 {
1676 /* first time here, initialize curl handle */ 1791 /* first time here, initialize curl handle */
@@ -1726,21 +1841,40 @@ create_response (void *cls,
1726 return MHD_queue_response (con, 1841 return MHD_queue_response (con,
1727 MHD_HTTP_INTERNAL_SERVER_ERROR, 1842 MHD_HTTP_INTERNAL_SERVER_ERROR,
1728 curl_failure_response); 1843 curl_failure_response);
1729 curl_easy_setopt (s5r->curl, CURLOPT_HEADERFUNCTION, &curl_check_hdr); 1844 curl_easy_setopt (s5r->curl,
1730 curl_easy_setopt (s5r->curl, CURLOPT_HEADERDATA, s5r); 1845 CURLOPT_HEADERFUNCTION,
1731 curl_easy_setopt (s5r->curl, CURLOPT_FOLLOWLOCATION, 0); 1846 &curl_check_hdr);
1847 curl_easy_setopt (s5r->curl,
1848 CURLOPT_HEADERDATA,
1849 s5r);
1850 curl_easy_setopt (s5r->curl,
1851 CURLOPT_FOLLOWLOCATION,
1852 0);
1732 if (s5r->is_gns) 1853 if (s5r->is_gns)
1733 curl_easy_setopt (s5r->curl, 1854 curl_easy_setopt (s5r->curl,
1734 CURLOPT_IPRESOLVE, 1855 CURLOPT_IPRESOLVE,
1735 CURL_IPRESOLVE_V4); 1856 CURL_IPRESOLVE_V4);
1736 curl_easy_setopt (s5r->curl, CURLOPT_CONNECTTIMEOUT, 600L); 1857 curl_easy_setopt (s5r->curl,
1737 curl_easy_setopt (s5r->curl, CURLOPT_TIMEOUT, 600L); 1858 CURLOPT_CONNECTTIMEOUT,
1738 curl_easy_setopt (s5r->curl, CURLOPT_NOSIGNAL, 1L); 1859 600L);
1739 curl_easy_setopt (s5r->curl, CURLOPT_HTTP_CONTENT_DECODING, 0); 1860 curl_easy_setopt (s5r->curl,
1740 curl_easy_setopt (s5r->curl, CURLOPT_HTTP_TRANSFER_DECODING, 0); 1861 CURLOPT_TIMEOUT,
1741 curl_easy_setopt (s5r->curl, CURLOPT_NOSIGNAL, 1L); 1862 600L);
1742 curl_easy_setopt (s5r->curl, CURLOPT_PRIVATE, s5r); 1863 curl_easy_setopt (s5r->curl,
1743 curl_easy_setopt (s5r->curl, CURLOPT_VERBOSE, 0L); 1864 CURLOPT_NOSIGNAL,
1865 1L);
1866 curl_easy_setopt (s5r->curl,
1867 CURLOPT_HTTP_CONTENT_DECODING,
1868 0);
1869 curl_easy_setopt (s5r->curl,
1870 CURLOPT_NOSIGNAL,
1871 1L);
1872 curl_easy_setopt (s5r->curl,
1873 CURLOPT_PRIVATE,
1874 s5r);
1875 curl_easy_setopt (s5r->curl,
1876 CURLOPT_VERBOSE,
1877 0L);
1744 /** 1878 /**
1745 * Pre-populate cache to resolve Hostname. 1879 * Pre-populate cache to resolve Hostname.
1746 * This is necessary as the DNS name in the CURLOPT_URL is used 1880 * This is necessary as the DNS name in the CURLOPT_URL is used
@@ -1796,37 +1930,131 @@ create_response (void *cls,
1796 MHD_HTTP_METHOD_PUT)) 1930 MHD_HTTP_METHOD_PUT))
1797 { 1931 {
1798 s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED; 1932 s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED;
1799 curl_easy_setopt (s5r->curl, CURLOPT_UPLOAD, 1L); 1933 curl_easy_setopt (s5r->curl,
1800 curl_easy_setopt (s5r->curl, CURLOPT_WRITEFUNCTION, &curl_download_cb); 1934 CURLOPT_UPLOAD,
1801 curl_easy_setopt (s5r->curl, CURLOPT_WRITEDATA, s5r); 1935 1L);
1802 curl_easy_setopt (s5r->curl, CURLOPT_READFUNCTION, &curl_upload_cb); 1936 curl_easy_setopt (s5r->curl,
1803 curl_easy_setopt (s5r->curl, CURLOPT_READDATA, s5r); 1937 CURLOPT_WRITEFUNCTION,
1938 &curl_download_cb);
1939 curl_easy_setopt (s5r->curl,
1940 CURLOPT_WRITEDATA,
1941 s5r);
1942 GNUNET_assert (CURLE_OK ==
1943 curl_easy_setopt (s5r->curl,
1944 CURLOPT_READFUNCTION,
1945 &curl_upload_cb));
1946 curl_easy_setopt (s5r->curl,
1947 CURLOPT_READDATA,
1948 s5r);
1949 {
1950 const char *us;
1951 long upload_size = 0;
1952
1953 us = MHD_lookup_connection_value (con,
1954 MHD_HEADER_KIND,
1955 MHD_HTTP_HEADER_CONTENT_LENGTH);
1956 if ( (1 == sscanf (us,
1957 "%ld",
1958 &upload_size)) &&
1959 (upload_size >= 0) )
1960 {
1961 curl_easy_setopt (s5r->curl,
1962 CURLOPT_INFILESIZE,
1963 upload_size);
1964 }
1965 }
1804 } 1966 }
1805 else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_POST)) 1967 else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_POST))
1806 { 1968 {
1807 s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED; 1969 s5r->state = SOCKS5_SOCKET_UPLOAD_STARTED;
1808 curl_easy_setopt (s5r->curl, CURLOPT_POST, 1L); 1970 curl_easy_setopt (s5r->curl,
1809 curl_easy_setopt (s5r->curl, CURLOPT_WRITEFUNCTION, &curl_download_cb); 1971 CURLOPT_POST,
1810 curl_easy_setopt (s5r->curl, CURLOPT_WRITEDATA, s5r); 1972 1L);
1811 curl_easy_setopt (s5r->curl, CURLOPT_READFUNCTION, &curl_upload_cb); 1973 curl_easy_setopt (s5r->curl,
1812 curl_easy_setopt (s5r->curl, CURLOPT_READDATA, s5r); 1974 CURLOPT_WRITEFUNCTION,
1975 &curl_download_cb);
1976 curl_easy_setopt (s5r->curl,
1977 CURLOPT_WRITEDATA,
1978 s5r);
1979 curl_easy_setopt (s5r->curl,
1980 CURLOPT_READFUNCTION,
1981 &curl_upload_cb);
1982 curl_easy_setopt (s5r->curl,
1983 CURLOPT_READDATA,
1984 s5r);
1985 {
1986 const char *us;
1987 long upload_size;
1988
1989 us = MHD_lookup_connection_value (con,
1990 MHD_HEADER_KIND,
1991 MHD_HTTP_HEADER_CONTENT_LENGTH);
1992 if ( (NULL != us) &&
1993 (1 == sscanf (us,
1994 "%ld",
1995 &upload_size)) &&
1996 (upload_size >= 0) )
1997 {
1998 curl_easy_setopt (s5r->curl,
1999 CURLOPT_INFILESIZE,
2000 upload_size);
2001 } else {
2002 curl_easy_setopt (s5r->curl,
2003 CURLOPT_INFILESIZE,
2004 upload_size);
2005 }
2006 }
1813 } 2007 }
1814 else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_HEAD)) 2008 else if (0 == strcasecmp (meth,
2009 MHD_HTTP_METHOD_HEAD))
1815 { 2010 {
1816 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED; 2011 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
1817 curl_easy_setopt (s5r->curl, CURLOPT_NOBODY, 1L); 2012 curl_easy_setopt (s5r->curl,
2013 CURLOPT_NOBODY,
2014 1L);
1818 } 2015 }
1819 else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_OPTIONS)) 2016 else if (0 == strcasecmp (meth,
2017 MHD_HTTP_METHOD_OPTIONS))
1820 { 2018 {
1821 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED; 2019 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
1822 curl_easy_setopt (s5r->curl, CURLOPT_CUSTOMREQUEST, "OPTIONS"); 2020 curl_easy_setopt (s5r->curl,
2021 CURLOPT_CUSTOMREQUEST,
2022 "OPTIONS");
2023 curl_easy_setopt (s5r->curl,
2024 CURLOPT_WRITEFUNCTION,
2025 &curl_download_cb);
2026 curl_easy_setopt (s5r->curl,
2027 CURLOPT_WRITEDATA,
2028 s5r);
2029
1823 } 2030 }
1824 else if (0 == strcasecmp (meth, MHD_HTTP_METHOD_GET)) 2031 else if (0 == strcasecmp (meth,
2032 MHD_HTTP_METHOD_GET))
1825 { 2033 {
1826 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED; 2034 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
1827 curl_easy_setopt (s5r->curl, CURLOPT_HTTPGET, 1L); 2035 curl_easy_setopt (s5r->curl,
1828 curl_easy_setopt (s5r->curl, CURLOPT_WRITEFUNCTION, &curl_download_cb); 2036 CURLOPT_HTTPGET,
1829 curl_easy_setopt (s5r->curl, CURLOPT_WRITEDATA, s5r); 2037 1L);
2038 curl_easy_setopt (s5r->curl,
2039 CURLOPT_WRITEFUNCTION,
2040 &curl_download_cb);
2041 curl_easy_setopt (s5r->curl,
2042 CURLOPT_WRITEDATA,
2043 s5r);
2044 }
2045 else if (0 == strcasecmp (meth,
2046 MHD_HTTP_METHOD_DELETE))
2047 {
2048 s5r->state = SOCKS5_SOCKET_DOWNLOAD_STARTED;
2049 curl_easy_setopt (s5r->curl,
2050 CURLOPT_CUSTOMREQUEST,
2051 "DELETE");
2052 curl_easy_setopt (s5r->curl,
2053 CURLOPT_WRITEFUNCTION,
2054 &curl_download_cb);
2055 curl_easy_setopt (s5r->curl,
2056 CURLOPT_WRITEDATA,
2057 s5r);
1830 } 2058 }
1831 else 2059 else
1832 { 2060 {
@@ -1840,31 +2068,47 @@ create_response (void *cls,
1840 2068
1841 if (0 == strcasecmp (ver, MHD_HTTP_VERSION_1_0)) 2069 if (0 == strcasecmp (ver, MHD_HTTP_VERSION_1_0))
1842 { 2070 {
1843 curl_easy_setopt (s5r->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); 2071 curl_easy_setopt (s5r->curl,
2072 CURLOPT_HTTP_VERSION,
2073 CURL_HTTP_VERSION_1_0);
1844 } 2074 }
1845 else if (0 == strcasecmp (ver, MHD_HTTP_VERSION_1_1)) 2075 else if (0 == strcasecmp (ver, MHD_HTTP_VERSION_1_1))
1846 { 2076 {
1847 curl_easy_setopt (s5r->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); 2077 curl_easy_setopt (s5r->curl,
2078 CURLOPT_HTTP_VERSION,
2079 CURL_HTTP_VERSION_1_1);
1848 } 2080 }
1849 else 2081 else
1850 { 2082 {
1851 curl_easy_setopt (s5r->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_NONE); 2083 curl_easy_setopt (s5r->curl,
2084 CURLOPT_HTTP_VERSION,
2085 CURL_HTTP_VERSION_NONE);
1852 } 2086 }
1853 2087
1854 if (HTTPS_PORT == s5r->port) 2088 if (HTTPS_PORT == s5r->port)
1855 { 2089 {
1856 curl_easy_setopt (s5r->curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); 2090 curl_easy_setopt (s5r->curl,
2091 CURLOPT_USE_SSL,
2092 CURLUSESSL_ALL);
1857 if (NULL != s5r->dane_data) 2093 if (NULL != s5r->dane_data)
1858 curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYPEER, 0L); 2094 curl_easy_setopt (s5r->curl,
2095 CURLOPT_SSL_VERIFYPEER,
2096 0L);
1859 else 2097 else
1860 curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYPEER, 1L); 2098 curl_easy_setopt (s5r->curl,
2099 CURLOPT_SSL_VERIFYPEER,
2100 1L);
1861 /* Disable cURL checking the hostname, as we will check ourselves 2101 /* Disable cURL checking the hostname, as we will check ourselves
1862 as only we have the domain name or the LEHO or the DANE record */ 2102 as only we have the domain name or the LEHO or the DANE record */
1863 curl_easy_setopt (s5r->curl, CURLOPT_SSL_VERIFYHOST, 0L); 2103 curl_easy_setopt (s5r->curl,
2104 CURLOPT_SSL_VERIFYHOST,
2105 0L);
1864 } 2106 }
1865 else 2107 else
1866 { 2108 {
1867 curl_easy_setopt (s5r->curl, CURLOPT_USE_SSL, CURLUSESSL_NONE); 2109 curl_easy_setopt (s5r->curl,
2110 CURLOPT_USE_SSL,
2111 CURLUSESSL_NONE);
1868 } 2112 }
1869 2113
1870 if (CURLM_OK != 2114 if (CURLM_OK !=
@@ -1892,12 +2136,14 @@ create_response (void *cls,
1892 { 2136 {
1893 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2137 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1894 "Processing %u bytes UPLOAD\n", 2138 "Processing %u bytes UPLOAD\n",
1895 (unsigned int) *upload_data_size); 2139 (unsigned int) *upload_data_size);
1896 2140
1897 /* FIXME: This must be set or a header with Transfer-Encoding: chunked. Else 2141 /* FIXME: This must be set or a header with Transfer-Encoding: chunked. Else
1898 * upload callback is not called! 2142 * upload callback is not called!
1899 */ 2143 */
1900 curl_easy_setopt (s5r->curl, CURLOPT_POSTFIELDSIZE, *upload_data_size); 2144 curl_easy_setopt (s5r->curl,
2145 CURLOPT_POSTFIELDSIZE,
2146 *upload_data_size);
1901 2147
1902 left = GNUNET_MIN (*upload_data_size, 2148 left = GNUNET_MIN (*upload_data_size,
1903 sizeof (s5r->io_buf) - s5r->io_len); 2149 sizeof (s5r->io_buf) - s5r->io_len);
@@ -1907,8 +2153,12 @@ create_response (void *cls,
1907 s5r->io_len += left; 2153 s5r->io_len += left;
1908 *upload_data_size -= left; 2154 *upload_data_size -= left;
1909 GNUNET_assert (NULL != s5r->curl); 2155 GNUNET_assert (NULL != s5r->curl);
1910 curl_easy_pause (s5r->curl, 2156 if (GNUNET_YES == s5r->curl_paused)
1911 CURLPAUSE_CONT); 2157 {
2158 s5r->curl_paused = GNUNET_NO;
2159 curl_easy_pause (s5r->curl,
2160 CURLPAUSE_CONT);
2161 }
1912 return MHD_YES; 2162 return MHD_YES;
1913 } 2163 }
1914 if (SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state) 2164 if (SOCKS5_SOCKET_UPLOAD_STARTED == s5r->state)
@@ -2286,8 +2536,10 @@ load_file (const char* filename,
2286 uint64_t fsize; 2536 uint64_t fsize;
2287 2537
2288 if (GNUNET_OK != 2538 if (GNUNET_OK !=
2289 GNUNET_DISK_file_size (filename, &fsize, 2539 GNUNET_DISK_file_size (filename,
2290 GNUNET_YES, GNUNET_YES)) 2540 &fsize,
2541 GNUNET_YES,
2542 GNUNET_YES))
2291 return NULL; 2543 return NULL;
2292 if (fsize > MAX_PEM_SIZE) 2544 if (fsize > MAX_PEM_SIZE)
2293 return NULL; 2545 return NULL;
@@ -2319,7 +2571,8 @@ load_key_from_file (gnutls_x509_privkey_t key,
2319 gnutls_datum_t key_data; 2571 gnutls_datum_t key_data;
2320 int ret; 2572 int ret;
2321 2573
2322 key_data.data = load_file (keyfile, &key_data.size); 2574 key_data.data = load_file (keyfile,
2575 &key_data.size);
2323 if (NULL == key_data.data) 2576 if (NULL == key_data.data)
2324 return GNUNET_SYSERR; 2577 return GNUNET_SYSERR;
2325 ret = gnutls_x509_privkey_import (key, &key_data, 2578 ret = gnutls_x509_privkey_import (key, &key_data,
@@ -2349,15 +2602,18 @@ load_cert_from_file (gnutls_x509_crt_t crt,
2349 gnutls_datum_t cert_data; 2602 gnutls_datum_t cert_data;
2350 int ret; 2603 int ret;
2351 2604
2352 cert_data.data = load_file (certfile, &cert_data.size); 2605 cert_data.data = load_file (certfile,
2606 &cert_data.size);
2353 if (NULL == cert_data.data) 2607 if (NULL == cert_data.data)
2354 return GNUNET_SYSERR; 2608 return GNUNET_SYSERR;
2355 ret = gnutls_x509_crt_import (crt, &cert_data, 2609 ret = gnutls_x509_crt_import (crt,
2610 &cert_data,
2356 GNUTLS_X509_FMT_PEM); 2611 GNUTLS_X509_FMT_PEM);
2357 if (GNUTLS_E_SUCCESS != ret) 2612 if (GNUTLS_E_SUCCESS != ret)
2358 { 2613 {
2359 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 2614 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2360 _("Unable to import certificate %s\n"), certfile); 2615 _("Unable to import certificate from `%s'\n"),
2616 certfile);
2361 } 2617 }
2362 GNUNET_free_non_null (cert_data.data); 2618 GNUNET_free_non_null (cert_data.data);
2363 return (GNUTLS_E_SUCCESS != ret) ? GNUNET_SYSERR : GNUNET_OK; 2619 return (GNUTLS_E_SUCCESS != ret) ? GNUNET_SYSERR : GNUNET_OK;
@@ -2387,14 +2643,27 @@ generate_gns_certificate (const char *name)
2387 GNUNET_break (GNUTLS_E_SUCCESS == gnutls_x509_crt_init (&request)); 2643 GNUNET_break (GNUTLS_E_SUCCESS == gnutls_x509_crt_init (&request));
2388 GNUNET_break (GNUTLS_E_SUCCESS == gnutls_x509_crt_set_key (request, proxy_ca.key)); 2644 GNUNET_break (GNUTLS_E_SUCCESS == gnutls_x509_crt_set_key (request, proxy_ca.key));
2389 pgc = GNUNET_new (struct ProxyGNSCertificate); 2645 pgc = GNUNET_new (struct ProxyGNSCertificate);
2390 gnutls_x509_crt_set_dn_by_oid (request, GNUTLS_OID_X520_COUNTRY_NAME, 2646 gnutls_x509_crt_set_dn_by_oid (request,
2391 0, "ZZ", 2); 2647 GNUTLS_OID_X520_COUNTRY_NAME,
2392 gnutls_x509_crt_set_dn_by_oid (request, GNUTLS_OID_X520_ORGANIZATION_NAME, 2648 0,
2393 0, "GNU Name System", 4); 2649 "ZZ",
2394 gnutls_x509_crt_set_dn_by_oid (request, GNUTLS_OID_X520_COMMON_NAME, 2650 strlen ("ZZ"));
2395 0, name, strlen (name)); 2651 gnutls_x509_crt_set_dn_by_oid (request,
2396 GNUNET_break (GNUTLS_E_SUCCESS == gnutls_x509_crt_set_version (request, 3)); 2652 GNUTLS_OID_X520_ORGANIZATION_NAME,
2397 gnutls_rnd (GNUTLS_RND_NONCE, &serial, sizeof (serial)); 2653 0,
2654 "GNU Name System",
2655 strlen ("GNU Name System"));
2656 gnutls_x509_crt_set_dn_by_oid (request,
2657 GNUTLS_OID_X520_COMMON_NAME,
2658 0,
2659 name,
2660 strlen (name));
2661 GNUNET_break (GNUTLS_E_SUCCESS ==
2662 gnutls_x509_crt_set_version (request,
2663 3));
2664 gnutls_rnd (GNUTLS_RND_NONCE,
2665 &serial,
2666 sizeof (serial));
2398 gnutls_x509_crt_set_serial (request, 2667 gnutls_x509_crt_set_serial (request,
2399 &serial, 2668 &serial,
2400 sizeof (serial)); 2669 sizeof (serial));
@@ -2408,15 +2677,21 @@ generate_gns_certificate (const char *name)
2408 etime = mktime (tm_data); 2677 etime = mktime (tm_data);
2409 gnutls_x509_crt_set_expiration_time (request, 2678 gnutls_x509_crt_set_expiration_time (request,
2410 etime); 2679 etime);
2411 gnutls_x509_crt_sign (request, 2680 gnutls_x509_crt_sign2 (request,
2412 proxy_ca.cert, 2681 proxy_ca.cert,
2413 proxy_ca.key); 2682 proxy_ca.key,
2683 GNUTLS_DIG_SHA512,
2684 0);
2414 key_buf_size = sizeof (pgc->key); 2685 key_buf_size = sizeof (pgc->key);
2415 cert_buf_size = sizeof (pgc->cert); 2686 cert_buf_size = sizeof (pgc->cert);
2416 gnutls_x509_crt_export (request, GNUTLS_X509_FMT_PEM, 2687 gnutls_x509_crt_export (request,
2417 pgc->cert, &cert_buf_size); 2688 GNUTLS_X509_FMT_PEM,
2418 gnutls_x509_privkey_export (proxy_ca.key, GNUTLS_X509_FMT_PEM, 2689 pgc->cert,
2419 pgc->key, &key_buf_size); 2690 &cert_buf_size);
2691 gnutls_x509_privkey_export (proxy_ca.key,
2692 GNUTLS_X509_FMT_PEM,
2693 pgc->key,
2694 &key_buf_size);
2420 gnutls_x509_crt_deinit (request); 2695 gnutls_x509_crt_deinit (request);
2421 return pgc; 2696 return pgc;
2422} 2697}
@@ -2755,8 +3030,10 @@ handle_gns_result (void *cls,
2755 } 3030 }
2756 if (GNUNET_YES == got_ip) 3031 if (GNUNET_YES == got_ip)
2757 break; 3032 break;
3033 if (GNUNET_YES == disable_v6)
3034 break;
2758 if (GNUNET_OK != 3035 if (GNUNET_OK !=
2759 GNUNET_NETWORK_test_pf (PF_INET)) 3036 GNUNET_NETWORK_test_pf (PF_INET6))
2760 break; 3037 break;
2761 /* FIXME: allow user to disable IPv6 per configuration option... */ 3038 /* FIXME: allow user to disable IPv6 per configuration option... */
2762 got_ip = GNUNET_YES; 3039 got_ip = GNUNET_YES;
@@ -2857,7 +3134,8 @@ do_s5r_read (void *cls)
2857 s5r->rtask = NULL; 3134 s5r->rtask = NULL;
2858 tc = GNUNET_SCHEDULER_get_task_context (); 3135 tc = GNUNET_SCHEDULER_get_task_context ();
2859 if ( (NULL != tc->read_ready) && 3136 if ( (NULL != tc->read_ready) &&
2860 (GNUNET_NETWORK_fdset_isset (tc->read_ready, s5r->sock)) ) 3137 (GNUNET_NETWORK_fdset_isset (tc->read_ready,
3138 s5r->sock)) )
2861 { 3139 {
2862 rlen = GNUNET_NETWORK_socket_recv (s5r->sock, 3140 rlen = GNUNET_NETWORK_socket_recv (s5r->sock,
2863 &s5r->rbuf[s5r->rbuf_len], 3141 &s5r->rbuf[s5r->rbuf_len],
@@ -2983,7 +3261,8 @@ do_s5r_read (void *cls)
2983 s5r->domain = GNUNET_strndup (dom_name, 3261 s5r->domain = GNUNET_strndup (dom_name,
2984 *dom_len); 3262 *dom_len);
2985 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3263 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2986 "Requested connection is to %s:%d\n", 3264 "Requested connection is to http%s://%s:%d\n",
3265 (HTTPS_PORT == s5r->port) ? "s" : "",
2987 s5r->domain, 3266 s5r->domain,
2988 ntohs (*port)); 3267 ntohs (*port));
2989 s5r->state = SOCKS5_RESOLVING; 3268 s5r->state = SOCKS5_RESOLVING;
@@ -3054,17 +3333,22 @@ do_accept (void *cls)
3054 if (lsock == lsock4) 3333 if (lsock == lsock4)
3055 ltask4 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 3334 ltask4 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
3056 lsock, 3335 lsock,
3057 &do_accept, lsock); 3336 &do_accept,
3337 lsock);
3058 else if (lsock == lsock6) 3338 else if (lsock == lsock6)
3059 ltask6 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 3339 ltask6 = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
3060 lsock, 3340 lsock,
3061 &do_accept, lsock); 3341 &do_accept,
3342 lsock);
3062 else 3343 else
3063 GNUNET_assert (0); 3344 GNUNET_assert (0);
3064 s = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL); 3345 s = GNUNET_NETWORK_socket_accept (lsock,
3346 NULL,
3347 NULL);
3065 if (NULL == s) 3348 if (NULL == s)
3066 { 3349 {
3067 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "accept"); 3350 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
3351 "accept");
3068 return; 3352 return;
3069 } 3353 }
3070 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3354 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -3077,7 +3361,8 @@ do_accept (void *cls)
3077 s5r->state = SOCKS5_INIT; 3361 s5r->state = SOCKS5_INIT;
3078 s5r->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 3362 s5r->rtask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
3079 s5r->sock, 3363 s5r->sock,
3080 &do_s5r_read, s5r); 3364 &do_s5r_read,
3365 s5r);
3081} 3366}
3082 3367
3083 3368
@@ -3174,7 +3459,8 @@ bind_v4 ()
3174 if (NULL == ls) 3459 if (NULL == ls)
3175 return NULL; 3460 return NULL;
3176 if (GNUNET_OK != 3461 if (GNUNET_OK !=
3177 GNUNET_NETWORK_socket_bind (ls, (const struct sockaddr *) &sa4, 3462 GNUNET_NETWORK_socket_bind (ls,
3463 (const struct sockaddr *) &sa4,
3178 sizeof (sa4))) 3464 sizeof (sa4)))
3179 { 3465 {
3180 eno = errno; 3466 eno = errno;
@@ -3210,7 +3496,8 @@ bind_v6 ()
3210 if (NULL == ls) 3496 if (NULL == ls)
3211 return NULL; 3497 return NULL;
3212 if (GNUNET_OK != 3498 if (GNUNET_OK !=
3213 GNUNET_NETWORK_socket_bind (ls, (const struct sockaddr *) &sa6, 3499 GNUNET_NETWORK_socket_bind (ls,
3500 (const struct sockaddr *) &sa6,
3214 sizeof (sa6))) 3501 sizeof (sa6)))
3215 { 3502 {
3216 eno = errno; 3503 eno = errno;
@@ -3265,7 +3552,8 @@ run (void *cls,
3265 cafile = cafile_cfg; 3552 cafile = cafile_cfg;
3266 } 3553 }
3267 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3554 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3268 "Using %s as CA\n", cafile); 3555 "Using `%s' as CA\n",
3556 cafile);
3269 3557
3270 gnutls_global_init (); 3558 gnutls_global_init ();
3271 gnutls_x509_crt_init (&proxy_ca.cert); 3559 gnutls_x509_crt_init (&proxy_ca.cert);
@@ -3365,8 +3653,8 @@ run (void *cls,
3365 return; 3653 return;
3366 } 3654 }
3367 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3655 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3368 "Proxy listens on port %llu\n", 3656 "Proxy listens on port %u\n",
3369 port); 3657 (unsigned int) port);
3370 3658
3371 /* start MHD daemon for HTTP */ 3659 /* start MHD daemon for HTTP */
3372 hd = GNUNET_new (struct MhdHttpList); 3660 hd = GNUNET_new (struct MhdHttpList);
@@ -3400,19 +3688,24 @@ run (void *cls,
3400 * @return 0 ok, 1 on error 3688 * @return 0 ok, 1 on error
3401 */ 3689 */
3402int 3690int
3403main (int argc, char *const *argv) 3691main (int argc,
3692 char *const *argv)
3404{ 3693{
3405 struct GNUNET_GETOPT_CommandLineOption options[] = { 3694 struct GNUNET_GETOPT_CommandLineOption options[] = {
3406 GNUNET_GETOPT_option_ulong ('p', 3695 GNUNET_GETOPT_option_uint16 ('p',
3407 "port", 3696 "port",
3408 NULL, 3697 NULL,
3409 gettext_noop ("listen on specified port (default: 7777)"), 3698 gettext_noop ("listen on specified port (default: 7777)"),
3410 &port), 3699 &port),
3411 GNUNET_GETOPT_option_string ('a', 3700 GNUNET_GETOPT_option_string ('a',
3412 "authority", 3701 "authority",
3413 NULL, 3702 NULL,
3414 gettext_noop ("pem file to use as CA"), 3703 gettext_noop ("pem file to use as CA"),
3415 &cafile_opt), 3704 &cafile_opt),
3705 GNUNET_GETOPT_option_flag ('6',
3706 "disable-ivp6",
3707 gettext_noop ("disable use of IPv6"),
3708 &disable_v6),
3416 3709
3417 GNUNET_GETOPT_OPTION_END 3710 GNUNET_GETOPT_OPTION_END
3418 }; 3711 };
@@ -3421,8 +3714,9 @@ main (int argc, char *const *argv)
3421 "</head><body>cURL fail</body></html>"; 3714 "</head><body>cURL fail</body></html>";
3422 int ret; 3715 int ret;
3423 3716
3424 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, 3717 if (GNUNET_OK !=
3425 &argc, &argv)) 3718 GNUNET_STRINGS_get_utf8_args (argc, argv,
3719 &argc, &argv))
3426 return 2; 3720 return 2;
3427 GNUNET_log_setup ("gnunet-gns-proxy", 3721 GNUNET_log_setup ("gnunet-gns-proxy",
3428 "WARNING", 3722 "WARNING",