aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gns/gnunet-dns2gns.c1
-rw-r--r--src/gns/gnunet-gns-proxy.c1279
2 files changed, 546 insertions, 734 deletions
diff --git a/src/gns/gnunet-dns2gns.c b/src/gns/gnunet-dns2gns.c
index 70c791de4..8bbf22c46 100644
--- a/src/gns/gnunet-dns2gns.c
+++ b/src/gns/gnunet-dns2gns.c
@@ -166,7 +166,6 @@ static struct GNUNET_IDENTITY_Handle *identity;
166static struct GNUNET_IDENTITY_Operation *id_op; 166static struct GNUNET_IDENTITY_Operation *id_op;
167 167
168 168
169
170/** 169/**
171 * Task run on shutdown. Cleans up everything. 170 * Task run on shutdown. Cleans up everything.
172 * 171 *
diff --git a/src/gns/gnunet-gns-proxy.c b/src/gns/gnunet-gns-proxy.c
index 7ccd14470..90c2256d6 100644
--- a/src/gns/gnunet-gns-proxy.c
+++ b/src/gns/gnunet-gns-proxy.c
@@ -33,37 +33,39 @@
33#include <regex.h> 33#include <regex.h>
34#include "gnunet_util_lib.h" 34#include "gnunet_util_lib.h"
35#include "gnunet_gns_service.h" 35#include "gnunet_gns_service.h"
36#include "gnunet_identity_service.h"
36#include "gns_proxy_proto.h" 37#include "gns_proxy_proto.h"
37#include "gns.h" 38#include "gns.h"
38 39
39#define HAVE_MHD_NO_LISTEN_SOCKET (MHD_VERSION >= 0x00091401)
40 40
41#define GNUNET_GNS_PROXY_PORT 7777 41#define GNUNET_GNS_PROXY_PORT 7777
42
42#define MHD_MAX_CONNECTIONS 300 43#define MHD_MAX_CONNECTIONS 300
44
43#define MAX_HTTP_URI_LENGTH 2048 45#define MAX_HTTP_URI_LENGTH 2048
46
44#define POSTBUFFERSIZE 4096 47#define POSTBUFFERSIZE 4096
45 48
46/* MHD/cURL defines */ 49#define HTTP_PORT 80
50
51#define HTTPS_PORT 443
52
53/**
54 * Log curl error.
55 *
56 * @param level log level
57 * @param fun name of curl_easy-function that gave the error
58 * @param rc return code from curl
59 */
60#define LOG_CURL_EASY(level,fun,rc) GNUNET_log(level, _("%s failed at %s:%d: `%s'\n"), fun, __FILE__, __LINE__, curl_easy_strerror (rc))
61
62
47enum BufferStatus 63enum BufferStatus
48 { 64 {
49 BUF_WAIT_FOR_CURL, 65 BUF_WAIT_FOR_CURL,
50 BUF_WAIT_FOR_MHD, 66 BUF_WAIT_FOR_MHD
51 BUF_WAIT_FOR_PP
52 }; 67 };
53 68
54#define HTML_HDR_CONTENT "Content-Type: text/html"
55
56/* buffer padding for proper RE matching */
57#define CURL_BUF_PADDING 1000
58
59/* regexp */
60//#define RE_DOTPLUS "<a href=\"http://(([A-Za-z]+[.])+)([+])"
61#define RE_A_HREF "href=\"https?://(([A-Za-z0-9]+[.])+)([+]|[a-z]+)"
62#define RE_N_MATCHES 4
63
64/* The usual suspects */
65#define HTTP_PORT 80
66#define HTTPS_PORT 443
67 69
68 70
69/** 71/**
@@ -71,10 +73,14 @@ enum BufferStatus
71 */ 73 */
72struct ProxyCA 74struct ProxyCA
73{ 75{
74 /* The certificate */ 76 /**
77 * The certificate
78 */
75 gnutls_x509_crt_t cert; 79 gnutls_x509_crt_t cert;
76 80
77 /* The private key */ 81 /**
82 * The private key
83 */
78 gnutls_x509_privkey_t key; 84 gnutls_x509_privkey_t key;
79}; 85};
80 86
@@ -98,58 +104,91 @@ struct ProxyGNSCertificate
98 */ 104 */
99struct Socks5Request 105struct Socks5Request
100{ 106{
101 /* The client socket */ 107 /**
108 * The client socket
109 */
102 struct GNUNET_NETWORK_Handle *sock; 110 struct GNUNET_NETWORK_Handle *sock;
103 111
104 /* The server socket */ 112 /**
113 * The server socket
114 */
105 struct GNUNET_NETWORK_Handle *remote_sock; 115 struct GNUNET_NETWORK_Handle *remote_sock;
106 116
107 /* The socks state */ 117 /**
118 * The socks state
119 */
108 int state; 120 int state;
109 121
110 /* Client socket read task */ 122 /**
123 * Client socket read task
124 */
111 GNUNET_SCHEDULER_TaskIdentifier rtask; 125 GNUNET_SCHEDULER_TaskIdentifier rtask;
112 126
113 /* Server socket read task */ 127 /**
128 * Server socket read task
129 */
114 GNUNET_SCHEDULER_TaskIdentifier fwdrtask; 130 GNUNET_SCHEDULER_TaskIdentifier fwdrtask;
115 131
116 /* Client socket write task */ 132 /**
133 * Client socket write task
134 */
117 GNUNET_SCHEDULER_TaskIdentifier wtask; 135 GNUNET_SCHEDULER_TaskIdentifier wtask;
118 136
119 /* Server socket write task */ 137 /**
138 * Server socket write task
139 */
120 GNUNET_SCHEDULER_TaskIdentifier fwdwtask; 140 GNUNET_SCHEDULER_TaskIdentifier fwdwtask;
121 141
122 /* Read buffer */ 142 /**
143 * Read buffer
144 */
123 char rbuf[2048]; 145 char rbuf[2048];
124 146
125 /* Write buffer */ 147 /**
148 * Write buffer
149 */
126 char wbuf[2048]; 150 char wbuf[2048];
127 151
128 /* Length of data in read buffer */ 152 /**
153 * Length of data in read buffer
154 */
129 unsigned int rbuf_len; 155 unsigned int rbuf_len;
130 156
131 /* Length of data in write buffer */ 157 /**
158 * Length of data in write buffer
159 */
132 unsigned int wbuf_len; 160 unsigned int wbuf_len;
133 161
134 /* This handle is scheduled for cleanup? */ 162 /**
163 * This handle is scheduled for cleanup?
164 */
135 int cleanup; 165 int cleanup;
136 166
137 /* Shall we close the client socket on cleanup? */ 167 /**
168 * Shall we close the client socket on cleanup?
169 */
138 int cleanup_sock; 170 int cleanup_sock;
139}; 171};
140 172
173
141/** 174/**
142 * DLL for Network Handles 175 * DLL for Network Handles
143 */ 176 */
144struct NetworkHandleList 177struct NetworkHandleList
145{ 178{
146 /*DLL*/ 179 /**
180 * DLL
181 */
147 struct NetworkHandleList *next; 182 struct NetworkHandleList *next;
148 183
149 /*DLL*/ 184 /**
185 * DLL
186 */
150 struct NetworkHandleList *prev; 187 struct NetworkHandleList *prev;
151 188
152 /* The handle */ 189 /**
190 * The handle
191 */
153 struct GNUNET_NETWORK_Handle *h; 192 struct GNUNET_NETWORK_Handle *h;
154}; 193};
155 194
@@ -158,31 +197,49 @@ struct NetworkHandleList
158 */ 197 */
159struct MhdHttpList 198struct MhdHttpList
160{ 199{
161 /* DLL for httpds */ 200 /**
201 * DLL for httpds
202 */
162 struct MhdHttpList *prev; 203 struct MhdHttpList *prev;
163 204
164 /* DLL for httpds */ 205 /**
206 * DLL for httpds
207 */
165 struct MhdHttpList *next; 208 struct MhdHttpList *next;
166 209
167 /* is this an ssl daemon? */ 210 /**
211 * is this an ssl daemon?
212 */
168 int is_ssl; 213 int is_ssl;
169 214
170 /* the domain name to server (only important for SSL) */ 215 /**
216 * the domain name to server (only important for SSL)
217 */
171 char domain[256]; 218 char domain[256];
172 219
173 /* The daemon handle */ 220 /**
221 * The daemon handle
222 */
174 struct MHD_Daemon *daemon; 223 struct MHD_Daemon *daemon;
175 224
176 /* Optional proxy certificate used */ 225 /**
226 * Optional proxy certificate used
227 */
177 struct ProxyGNSCertificate *proxy_cert; 228 struct ProxyGNSCertificate *proxy_cert;
178 229
179 /* The task ID */ 230 /**
231 * The task ID
232 */
180 GNUNET_SCHEDULER_TaskIdentifier httpd_task; 233 GNUNET_SCHEDULER_TaskIdentifier httpd_task;
181 234
182 /* Handles associated with this daemon */ 235 /**
236 * Handles associated with this daemon
237 */
183 struct NetworkHandleList *socket_handles_head; 238 struct NetworkHandleList *socket_handles_head;
184 239
185 /* Handles associated with this daemon */ 240 /**
241 * Handles associated with this daemon
242 */
186 struct NetworkHandleList *socket_handles_tail; 243 struct NetworkHandleList *socket_handles_tail;
187}; 244};
188 245
@@ -191,69 +248,93 @@ struct MhdHttpList
191 */ 248 */
192struct ProxyCurlTask 249struct ProxyCurlTask
193{ 250{
194 /* DLL for tasks */ 251 /**
252 * DLL for tasks
253 */
195 struct ProxyCurlTask *prev; 254 struct ProxyCurlTask *prev;
196 255
197 /* DLL for tasks */ 256 /**
257 * DLL for tasks
258 */
198 struct ProxyCurlTask *next; 259 struct ProxyCurlTask *next;
199 260
200 /* Handle to cURL */ 261 /**
262 * Handle to cURL
263 */
201 CURL *curl; 264 CURL *curl;
202 265
203 /* Optional header replacements for curl (LEHO) */ 266 /**
267 * Optional header replacements for curl (LEHO)
268 */
204 struct curl_slist *headers; 269 struct curl_slist *headers;
205 270
206 /* Optional resolver replacements for curl (LEHO) */ 271 /**
272 * Optional resolver replacements for curl (LEHO)
273 */
207 struct curl_slist *resolver; 274 struct curl_slist *resolver;
208 275
209 /* curl response code */ 276 /**
277 * curl response code
278 */
210 long curl_response_code; 279 long curl_response_code;
211 280
212 /* The URL to fetch */ 281 /**
282 * The URL to fetch
283 */
213 char url[MAX_HTTP_URI_LENGTH]; 284 char url[MAX_HTTP_URI_LENGTH];
214 285
215 /* The cURL write buffer / MHD read buffer */ 286 /**
216 char buffer[CURL_MAX_WRITE_SIZE + CURL_BUF_PADDING]; 287 * The cURL write buffer / MHD read buffer
288 */
289 char buffer[CURL_MAX_WRITE_SIZE];
217 290
218 /* Read pos of the data in the buffer */ 291 /**
292 * Read pos of the data in the buffer
293 */
219 char *buffer_read_ptr; 294 char *buffer_read_ptr;
220 295
221 /* Write pos in the buffer */ 296 /**
297 * Write pos in the buffer
298 */
222 char *buffer_write_ptr; 299 char *buffer_write_ptr;
223 300
224 /* connection */ 301 /**
302 * connection
303 */
225 struct MHD_Connection *connection; 304 struct MHD_Connection *connection;
226 305
227 /*put*/ 306 /**
307 * put
308 */
228 size_t put_read_offset; 309 size_t put_read_offset;
229 size_t put_read_size; 310 size_t put_read_size;
230 311
231 /*post*/ 312 /**
313 *post
314 */
232 struct MHD_PostProcessor *post_handler; 315 struct MHD_PostProcessor *post_handler;
233 316
234 /* post data */ 317 /* post data */
235 struct ProxyUploadData *upload_data_head; 318 struct ProxyUploadData *upload_data_head;
236 struct ProxyUploadData *upload_data_tail; 319 struct ProxyUploadData *upload_data_tail;
237 320
238 /* the type of POST encoding */ 321 /**
322 * the type of POST encoding
323 */
239 char* post_type; 324 char* post_type;
240 325
241 struct curl_httppost *httppost; 326 struct curl_httppost *httppost;
242 327
243 struct curl_httppost *httppost_last; 328 struct curl_httppost *httppost_last;
244 329
245 /* Number of bytes in buffer */ 330 /**
331 * Number of bytes in buffer
332 */
246 unsigned int bytes_in_buffer; 333 unsigned int bytes_in_buffer;
247 334
248 /* PP task */ 335 /* PP task */
249 GNUNET_SCHEDULER_TaskIdentifier pp_task; 336 GNUNET_SCHEDULER_TaskIdentifier pp_task;
250 337
251 /* PP match list */
252 struct ProxyREMatch *pp_match_head;
253
254 /* PP match list */
255 struct ProxyREMatch *pp_match_tail;
256
257 /* The associated daemon list entry */ 338 /* The associated daemon list entry */
258 struct MhdHttpList *mhd; 339 struct MhdHttpList *mhd;
259 340
@@ -275,97 +356,76 @@ struct ProxyCurlTask
275 /* The LEgacy HOstname (can be empty) */ 356 /* The LEgacy HOstname (can be empty) */
276 char leho[256]; 357 char leho[256];
277 358
278 /* The port */ 359 /**
360 * The port
361 */
279 uint16_t port; 362 uint16_t port;
280 363
281 /* The buffer status (BUF_WAIT_FOR_CURL or BUF_WAIT_FOR_MHD) */ 364 /**
365 * The buffer status (BUF_WAIT_FOR_CURL or BUF_WAIT_FOR_MHD)
366 */
282 enum BufferStatus buf_status; 367 enum BufferStatus buf_status;
283 368
284 /* connection status */ 369 /**
370 * connection status
371 */
285 int ready_to_queue; 372 int ready_to_queue;
286 373
287 /* is curl running? */ 374 /**
375 * is curl running?
376 */
288 int curl_running; 377 int curl_running;
289 378
290 /* are we done */ 379 /**
380 * are we done
381 */
291 int fin; 382 int fin;
292 383
293 /* Already accepted */ 384 /**
385 * Already accepted
386 */
294 int accepted; 387 int accepted;
295 388
296 /* Indicates wheather the download is in progress */ 389 /**
390 * Indicates wheather the download is in progress
391 */
297 int download_in_progress; 392 int download_in_progress;
298 393
299 /* Indicates wheather the download was successful */ 394 /**
395 * Indicates wheather the download was successful
396 */
300 int download_is_finished; 397 int download_is_finished;
301 398
302 /* Indicates wheather the download failed */ 399 /**
400 * Indicates wheather the download failed
401 */
303 int download_error; 402 int download_error;
304 403
305 /* Indicates wheather we need to parse HTML */
306 int parse_content;
307
308 /* Indicates wheather we are postprocessing the HTML right now */
309 int is_postprocessing;
310
311 /* Indicates wheather postprocessing has finished */
312 int pp_finished;
313
314 int post_done; 404 int post_done;
315 405
316 int is_httppost; 406 int is_httppost;
317 407
318}; 408};
319 409
320/**
321 * Struct for RE matches in postprocessing of HTML
322 */
323struct ProxyREMatch
324{
325 /* DLL */
326 struct ProxyREMatch *next;
327
328 /* DLL */
329 struct ProxyREMatch *prev;
330
331 /* start of match in buffer */
332 char* start;
333
334 /* end of match in buffer */
335 char* end;
336
337 /* associated proxycurltask */
338 struct ProxyCurlTask *ctask;
339
340 /* hostname found */
341 char hostname[255];
342
343 /* PP result */
344 char result[255];
345
346 /* shorten task */
347 struct GNUNET_GNS_ShortenRequest *shorten_task;
348
349 /* are we done */
350 int done;
351
352 /* is SSL */
353 int is_ssl;
354
355};
356 410
357/** 411/**
358 * Struct for set-cookies 412 * Struct for set-cookies
359 */ 413 */
360struct ProxySetCookieHeader 414struct ProxySetCookieHeader
361{ 415{
362 /* DLL */ 416 /**
417 * DLL
418 */
363 struct ProxySetCookieHeader *next; 419 struct ProxySetCookieHeader *next;
364 420
365 /* DLL */ 421 /**
422 * DLL
423 */
366 struct ProxySetCookieHeader *prev; 424 struct ProxySetCookieHeader *prev;
367 425
368 /* the cookie */ 426 /**
427 * the cookie
428 */
369 char *cookie; 429 char *cookie;
370}; 430};
371 431
@@ -374,10 +434,14 @@ struct ProxySetCookieHeader
374 */ 434 */
375struct ProxyUploadData 435struct ProxyUploadData
376{ 436{
377 /* DLL */ 437 /**
438 * DLL
439 */
378 struct ProxyUploadData *next; 440 struct ProxyUploadData *next;
379 441
380 /* DLL */ 442 /**
443 * DLL
444 */
381 struct ProxyUploadData *prev; 445 struct ProxyUploadData *prev;
382 446
383 char *key; 447 char *key;
@@ -388,78 +452,137 @@ struct ProxyUploadData
388 452
389 size_t content_length; 453 size_t content_length;
390 454
391 /* value */ 455 /**
456 * value
457 */
392 char *value; 458 char *value;
393 459
394 /* to copy */ 460 /**
461 * to copy
462 */
395 size_t bytes_left; 463 size_t bytes_left;
396 464
397 /* size */ 465 /**
466 * size
467 */
398 size_t total_bytes; 468 size_t total_bytes;
399}; 469};
400 470
401 471
402/* The port the proxy is running on (default 7777) */ 472/**
473 * The port the proxy is running on (default 7777)
474 */
403static unsigned long port = GNUNET_GNS_PROXY_PORT; 475static unsigned long port = GNUNET_GNS_PROXY_PORT;
404 476
405/* The CA file (pem) to use for the proxy CA */ 477/**
478 * The CA file (pem) to use for the proxy CA
479 */
406static char* cafile_opt; 480static char* cafile_opt;
407 481
408/* The listen socket of the proxy */ 482/**
483 * The listen socket of the proxy
484 */
409static struct GNUNET_NETWORK_Handle *lsock; 485static struct GNUNET_NETWORK_Handle *lsock;
410 486
411/* The listen task ID */ 487/**
488 * The listen task ID
489 */
412static GNUNET_SCHEDULER_TaskIdentifier ltask; 490static GNUNET_SCHEDULER_TaskIdentifier ltask;
413 491
414/* The cURL download task */ 492/**
493 * The cURL download task
494 */
415static GNUNET_SCHEDULER_TaskIdentifier curl_download_task; 495static GNUNET_SCHEDULER_TaskIdentifier curl_download_task;
416 496
417/* The non SSL httpd daemon handle */ 497/**
498 * The non SSL httpd daemon handle
499 */
418static struct MHD_Daemon *httpd; 500static struct MHD_Daemon *httpd;
419 501
420/* Number of current mhd connections */ 502/**
503 * Number of current mhd connections
504 */
421static unsigned int total_mhd_connections; 505static unsigned int total_mhd_connections;
422 506
423/* The cURL multi handle */ 507/**
508 * The cURL multi handle
509 */
424static CURLM *curl_multi; 510static CURLM *curl_multi;
425 511
426/* Handle to the GNS service */ 512/**
513 * Handle to the GNS service
514 */
427static struct GNUNET_GNS_Handle *gns_handle; 515static struct GNUNET_GNS_Handle *gns_handle;
428 516
429/* DLL for ProxyCurlTasks */ 517/**
518 * DLL for ProxyCurlTasks
519 */
430static struct ProxyCurlTask *ctasks_head; 520static struct ProxyCurlTask *ctasks_head;
431 521
432/* DLL for ProxyCurlTasks */ 522/**
523 * DLL for ProxyCurlTasks
524 */
433static struct ProxyCurlTask *ctasks_tail; 525static struct ProxyCurlTask *ctasks_tail;
434 526
435/* DLL for http daemons */ 527/**
528 * DLL for http daemons
529 */
436static struct MhdHttpList *mhd_httpd_head; 530static struct MhdHttpList *mhd_httpd_head;
437 531
438/* DLL for http daemons */ 532/**
533 * DLL for http daemons
534 */
439static struct MhdHttpList *mhd_httpd_tail; 535static struct MhdHttpList *mhd_httpd_tail;
440 536
441/* Handle to the regex for dotplus (.+) replacement in HTML */ 537/**
442static regex_t re_dotplus; 538 * The users local GNS master zone
443 539 */
444/* The users local GNS zone hash */ 540static struct GNUNET_CRYPTO_EccPublicSignKey local_gns_zone;
445static struct GNUNET_CRYPTO_ShortHashCode *local_gns_zone;
446 541
447/* The users local private zone */ 542/**
448static struct GNUNET_CRYPTO_ShortHashCode *local_private_zone; 543 * The users local shorten zone
544 */
545static struct GNUNET_CRYPTO_EccPrivateKey local_shorten_zone;
449 546
450/* The users local shorten zone */ 547/**
451static struct GNUNET_CRYPTO_ShortHashCode *local_shorten_zone; 548 * Is shortening enabled?
549 */
550static int do_shorten;
452 551
453/* The CA for SSL certificate generation */ 552/**
553 * The CA for SSL certificate generation
554 */
454static struct ProxyCA proxy_ca; 555static struct ProxyCA proxy_ca;
455 556
456/* UNIX domain socket for mhd */ 557/**
457#if !HAVE_MHD_NO_LISTEN_SOCKET 558 * UNIX domain socket for mhd
559 */
458static struct GNUNET_NETWORK_Handle *mhd_unix_socket; 560static struct GNUNET_NETWORK_Handle *mhd_unix_socket;
459#endif
460 561
461/* Shorten zone private key */ 562/**
462static struct GNUNET_CRYPTO_EccPrivateKey *shorten_zonekey; 563 * Shorten zone private key
564 */
565static struct GNUNET_CRYPTO_EccPrivateKey shorten_zonekey;
566
567/**
568 * Response we return on cURL failures.
569 */
570static struct MHD_Response *curl_failure_response;
571
572/**
573 * Connection to identity service.
574 */
575static struct GNUNET_IDENTITY_Handle *identity;
576
577/**
578 * Request for our ego.
579 */
580static struct GNUNET_IDENTITY_Operation *id_op;
581
582/**
583 * Our configuration.
584 */
585static const struct GNUNET_CONFIGURATION_Handle *cfg;
463 586
464 587
465/** 588/**
@@ -467,7 +590,7 @@ static struct GNUNET_CRYPTO_EccPrivateKey *shorten_zonekey;
467 * 590 *
468 * @param name the name to check 591 * @param name the name to check
469 * @param tld the TLD to check for (must NOT begin with ".") 592 * @param tld the TLD to check for (must NOT begin with ".")
470 * @return GNUNET_YES or GNUNET_NO 593 * @return #GNUNET_YES or #GNUNET_NO
471 */ 594 */
472static int 595static int
473is_tld (const char* name, const char* tld) 596is_tld (const char* name, const char* tld)
@@ -515,7 +638,7 @@ con_post_data_iter (void *cls,
515 /* new part */ 638 /* new part */
516 if (0 == off) 639 if (0 == off)
517 { 640 {
518 pdata = GNUNET_malloc (sizeof (struct ProxyUploadData)); 641 pdata = GNUNET_new (struct ProxyUploadData);
519 pdata->key = GNUNET_strdup (key); 642 pdata->key = GNUNET_strdup (key);
520 643
521 if (NULL != filename) 644 if (NULL != filename)
@@ -566,7 +689,7 @@ con_post_data_iter (void *cls,
566 return MHD_NO; 689 return MHD_NO;
567 } 690 }
568 /* a key */ 691 /* a key */
569 pdata = GNUNET_malloc (sizeof (struct ProxyUploadData)); 692 pdata = GNUNET_new (struct ProxyUploadData);
570 pdata->value = GNUNET_malloc (strlen (enc) + 3); 693 pdata->value = GNUNET_malloc (strlen (enc) + 3);
571 if (NULL != ctask->upload_data_head) 694 if (NULL != ctask->upload_data_head)
572 { 695 {
@@ -596,7 +719,7 @@ con_post_data_iter (void *cls,
596 GNUNET_break (0); 719 GNUNET_break (0);
597 return MHD_NO; 720 return MHD_NO;
598 } 721 }
599 pdata = GNUNET_malloc (sizeof (struct ProxyUploadData)); 722 pdata = GNUNET_new (struct ProxyUploadData);
600 pdata->value = GNUNET_malloc (strlen (enc) + 1); 723 pdata->value = GNUNET_malloc (strlen (enc) + 1);
601 memcpy (pdata->value, enc, strlen (enc)); 724 memcpy (pdata->value, enc, strlen (enc));
602 pdata->bytes_left = strlen (pdata->value); 725 pdata->bytes_left = strlen (pdata->value);
@@ -621,7 +744,7 @@ con_post_data_iter (void *cls,
621 * @param kind value kind 744 * @param kind value kind
622 * @param key field key 745 * @param key field key
623 * @param value field value 746 * @param value field value
624 * @return MHD_NO when Host found 747 * @return #MHD_NO when Host found
625 */ 748 */
626static int 749static int
627con_val_iter (void *cls, 750con_val_iter (void *cls,
@@ -721,9 +844,7 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls)
721{ 844{
722 size_t bytes = size * nmemb; 845 size_t bytes = size * nmemb;
723 struct ProxyCurlTask *ctask = cls; 846 struct ProxyCurlTask *ctask = cls;
724 int html_mime_len = strlen (HTML_HDR_CONTENT);
725 int cookie_hdr_len = strlen (MHD_HTTP_HEADER_SET_COOKIE); 847 int cookie_hdr_len = strlen (MHD_HTTP_HEADER_SET_COOKIE);
726 char hdr_mime[html_mime_len+1];
727 char hdr_generic[bytes+1]; 848 char hdr_generic[bytes+1];
728 char new_cookie_hdr[bytes+strlen (ctask->leho)+1]; 849 char new_cookie_hdr[bytes+strlen (ctask->leho)+1];
729 char new_location[MAX_HTTP_URI_LENGTH+500]; 850 char new_location[MAX_HTTP_URI_LENGTH+500];
@@ -773,20 +894,6 @@ curl_check_hdr (void *buffer, size_t size, size_t nmemb, void *cls)
773 } 894 }
774 ctask->ready_to_queue = GNUNET_YES; 895 ctask->ready_to_queue = GNUNET_YES;
775 } 896 }
776
777 if (html_mime_len <= bytes)
778 {
779 memcpy (hdr_mime, buffer, html_mime_len);
780 hdr_mime[html_mime_len] = '\0';
781
782 if (0 == strcmp (hdr_mime, HTML_HDR_CONTENT))
783 {
784 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
785 "Got HTML HTTP response header\n");
786 ctask->parse_content = GNUNET_YES;
787 }
788 }
789
790 if (cookie_hdr_len > bytes) 897 if (cookie_hdr_len > bytes)
791 return bytes; 898 return bytes;
792 899
@@ -993,7 +1100,6 @@ mhd_content_free (void *cls,
993 struct ProxyCurlTask *ctask = cls; 1100 struct ProxyCurlTask *ctask = cls;
994 struct ProxyUploadData *pdata; 1101 struct ProxyUploadData *pdata;
995 1102
996 GNUNET_assert (NULL == ctask->pp_match_head);
997 if (NULL != ctask->headers) 1103 if (NULL != ctask->headers)
998 curl_slist_free_all (ctask->headers); 1104 curl_slist_free_all (ctask->headers);
999 1105
@@ -1040,7 +1146,6 @@ mhd_content_cb (void *cls,
1040 size_t max) 1146 size_t max)
1041{ 1147{
1042 struct ProxyCurlTask *ctask = cls; 1148 struct ProxyCurlTask *ctask = cls;
1043 struct ProxyREMatch *re_match;
1044 ssize_t copied = 0; 1149 ssize_t copied = 0;
1045 size_t bytes_to_copy = ctask->buffer_write_ptr - ctask->buffer_read_ptr; 1150 size_t bytes_to_copy = ctask->buffer_write_ptr - ctask->buffer_read_ptr;
1046 1151
@@ -1077,68 +1182,6 @@ mhd_content_cb (void *cls,
1077 return 0; 1182 return 0;
1078 1183
1079 copied = 0; 1184 copied = 0;
1080 for (re_match = ctask->pp_match_head; NULL != re_match; re_match = ctask->pp_match_head)
1081 {
1082 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1083 "MHD: Processing PP %s\n",
1084 re_match->hostname);
1085 bytes_to_copy = re_match->start - ctask->buffer_read_ptr;
1086 if (bytes_to_copy+copied > max)
1087 {
1088 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1089 "MHD: buffer in response too small for %u. Using available space (%d). (%s)\n",
1090 (unsigned int) bytes_to_copy,
1091 max,
1092 ctask->url);
1093 memcpy (buf+copied, ctask->buffer_read_ptr, max-copied);
1094 ctask->buffer_read_ptr += max-copied;
1095 copied = max;
1096 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1097 "MHD: copied %d bytes\n", (int) copied);
1098 return copied;
1099 }
1100
1101 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1102 "MHD: copying %u bytes to mhd response at offset %d\n",
1103 (unsigned int) bytes_to_copy, ctask->buffer_read_ptr);
1104 memcpy (buf+copied, ctask->buffer_read_ptr, bytes_to_copy);
1105 copied += bytes_to_copy;
1106
1107 if (GNUNET_NO == re_match->done)
1108 {
1109 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1110 "MHD: Waiting for PP of %s\n", re_match->hostname);
1111 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1112 "MHD: copied %d bytes\n", (int) copied);
1113 ctask->buffer_read_ptr += bytes_to_copy;
1114 return copied;
1115 }
1116
1117 if (strlen (re_match->result) > (max - copied))
1118 {
1119 //FIXME partially copy domain here
1120 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1121 "MHD: buffer in response too small for %s! (%s)\n",
1122 re_match->result,
1123 ctask->url);
1124 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1125 "MHD: copied %d bytes\n", (int) copied);
1126 ctask->buffer_read_ptr += bytes_to_copy;
1127 return copied;
1128 }
1129
1130 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1131 "MHD: Adding PP result %s to buffer\n",
1132 re_match->result);
1133 memcpy (buf + copied, re_match->result, strlen (re_match->result));
1134 copied += strlen (re_match->result);
1135 ctask->buffer_read_ptr = re_match->end;
1136 GNUNET_CONTAINER_DLL_remove (ctask->pp_match_head,
1137 ctask->pp_match_tail,
1138 re_match);
1139 GNUNET_free (re_match);
1140 }
1141
1142 bytes_to_copy = ctask->buffer_write_ptr - ctask->buffer_read_ptr; 1185 bytes_to_copy = ctask->buffer_write_ptr - ctask->buffer_read_ptr;
1143 1186
1144 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1174,134 +1217,6 @@ mhd_content_cb (void *cls,
1174 1217
1175 1218
1176/** 1219/**
1177 * Shorten result callback
1178 *
1179 * @param cls the proxycurltask
1180 * @param short_name the shortened name (NULL on error)
1181 */
1182static void
1183process_shorten (void* cls, const char* short_name)
1184{
1185 struct ProxyREMatch *re_match = cls;
1186 char result[sizeof (re_match->result)];
1187
1188 if (NULL == short_name)
1189 {
1190 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1191 "PP: Unable to shorten %s\n",
1192 re_match->hostname);
1193 GNUNET_CONTAINER_DLL_remove (re_match->ctask->pp_match_head,
1194 re_match->ctask->pp_match_tail,
1195 re_match);
1196 GNUNET_free (re_match);
1197 return;
1198 }
1199
1200 if (0 == strcmp (short_name, re_match->ctask->leho))
1201 strcpy (result, re_match->ctask->host);
1202 else
1203 strcpy (result, short_name);
1204
1205 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1206 "PP: Shorten %s -> %s\n",
1207 re_match->hostname,
1208 result);
1209
1210 if (re_match->is_ssl)
1211 sprintf (re_match->result, "href=\"https://%s", result);
1212 else
1213 sprintf (re_match->result, "href=\"http://%s", result);
1214
1215 re_match->done = GNUNET_YES;
1216 run_mhd_now (re_match->ctask->mhd);
1217}
1218
1219
1220/**
1221 * Postprocess data in buffer. From read ptr to write ptr
1222 *
1223 * @param cls the curlproxytask
1224 * @param tc task context
1225 */
1226static void
1227postprocess_buffer (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1228{
1229 struct ProxyCurlTask *ctask = cls;
1230 struct ProxyREMatch *re_match;
1231 char* re_ptr = ctask->buffer_read_ptr;
1232 char re_hostname[255];
1233 regmatch_t m[RE_N_MATCHES];
1234
1235 ctask->pp_task = GNUNET_SCHEDULER_NO_TASK;
1236
1237 if (GNUNET_YES != ctask->parse_content)
1238 {
1239 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1240 "PP: Not parsing content\n");
1241 ctask->buf_status = BUF_WAIT_FOR_MHD;
1242 run_mhd_now (ctask->mhd);
1243 return;
1244 }
1245
1246 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1247 "PP: We need to parse the HTML\n");
1248
1249 /* 0 means match found */
1250 while (0 == regexec (&re_dotplus, re_ptr, RE_N_MATCHES, m, 0))
1251 {
1252 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1253 "PP: regex match\n");
1254
1255 GNUNET_assert (m[1].rm_so != -1);
1256
1257 memset (re_hostname, 0, sizeof (re_hostname));
1258 memcpy (re_hostname, re_ptr+m[1].rm_so, (m[3].rm_eo-m[1].rm_so));
1259
1260
1261 re_match = GNUNET_malloc (sizeof (struct ProxyREMatch));
1262 re_match->start = re_ptr + m[0].rm_so;
1263 re_match->end = re_ptr + m[3].rm_eo;
1264 re_match->done = GNUNET_NO;
1265 re_match->ctask = ctask;
1266
1267 if ('s' == *(re_ptr+m[1].rm_so-strlen("://")-1)) //FIXME strcmp
1268 re_match->is_ssl = GNUNET_YES;
1269 else
1270 re_match->is_ssl = GNUNET_NO;
1271
1272 strcpy (re_match->hostname, re_hostname);
1273 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1274 "PP: Got hostname %s\n", re_hostname);
1275 re_ptr += m[3].rm_eo;
1276
1277 if (GNUNET_YES == is_tld (re_match->hostname, GNUNET_GNS_TLD_PLUS))
1278 {
1279 re_match->hostname[strlen(re_match->hostname)-1] = '\0';
1280 strcpy (re_match->hostname+strlen(re_match->hostname),
1281 ctask->authority);
1282 }
1283
1284 re_match->shorten_task = GNUNET_GNS_shorten_zone (gns_handle,
1285 re_match->hostname,
1286 local_private_zone,
1287 local_shorten_zone,
1288 local_gns_zone,
1289 &process_shorten,
1290 re_match); //FIXME cancel appropriately
1291
1292 GNUNET_CONTAINER_DLL_insert_tail (ctask->pp_match_head,
1293 ctask->pp_match_tail,
1294 re_match);
1295 }
1296
1297 ctask->buf_status = BUF_WAIT_FOR_MHD;
1298 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1299 "PP: No more matches\n");
1300 run_mhd_now (ctask->mhd);
1301}
1302
1303
1304/**
1305 * Handle data from cURL 1220 * Handle data from cURL
1306 * 1221 *
1307 * @param ptr pointer to the data 1222 * @param ptr pointer to the data
@@ -1316,41 +1231,31 @@ curl_download_cb (void *ptr, size_t size, size_t nmemb, void* ctx)
1316 const char *cbuf = ptr; 1231 const char *cbuf = ptr;
1317 size_t total = size * nmemb; 1232 size_t total = size * nmemb;
1318 struct ProxyCurlTask *ctask = ctx; 1233 struct ProxyCurlTask *ctask = ctx;
1319 size_t buf_space = sizeof (ctask->buffer) - 1234 size_t buf_space = sizeof (ctask->buffer) - (ctask->buffer_write_ptr - ctask->buffer);
1320 (ctask->buffer_write_ptr-ctask->buffer);
1321 1235
1322 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1236 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1323 "CURL: Got %d. %d free in buffer\n", 1237 "CURL: Got %d. %d free in buffer\n",
1324 total, buf_space); 1238 (int) total,
1325 1239 (int) buf_space);
1326 if (BUF_WAIT_FOR_CURL != ctask->buf_status) 1240 if (0 == buf_space)
1327 return CURL_WRITEFUNC_PAUSE;
1328
1329 if (total > (buf_space - CURL_BUF_PADDING))
1330 { 1241 {
1331 if (ctask->buf_status == BUF_WAIT_FOR_CURL) 1242 ctask->buf_status = BUF_WAIT_FOR_MHD;
1332 { 1243 run_mhd_now (ctask->mhd);
1333 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1334 "CURL: Buffer full starting postprocessing\n");
1335 ctask->buf_status = BUF_WAIT_FOR_PP;
1336 ctask->pp_task = GNUNET_SCHEDULER_add_now (&postprocess_buffer,
1337 ctask);
1338 return CURL_WRITEFUNC_PAUSE;
1339 }
1340
1341 /* we should not get called in that case */
1342 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1343 "CURL: called out of context and no space in buffer!\n");
1344 return CURL_WRITEFUNC_PAUSE; 1244 return CURL_WRITEFUNC_PAUSE;
1345 } 1245 }
1346 1246 if (total > buf_space)
1247 total = buf_space;
1347 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1248 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1348 "CURL: Copying %d bytes to buffer (%s)\n", total, ctask->url); 1249 "CURL: Copying %d bytes to buffer (%s)\n",
1250 total, ctask->url);
1349 memcpy (ctask->buffer_write_ptr, cbuf, total); 1251 memcpy (ctask->buffer_write_ptr, cbuf, total);
1350 ctask->bytes_in_buffer += total; 1252 ctask->bytes_in_buffer += total;
1351 ctask->buffer_write_ptr += total; 1253 ctask->buffer_write_ptr += total;
1352 ctask->buffer_write_ptr[0] = '\0'; 1254 if (ctask->bytes_in_buffer > 0)
1353 1255 {
1256 ctask->buf_status = BUF_WAIT_FOR_MHD;
1257 run_mhd_now (ctask->mhd);
1258 }
1354 return total; 1259 return total;
1355} 1260}
1356 1261
@@ -1576,7 +1481,6 @@ curl_task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1576 1481
1577 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1482 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1578 "Running curl tasks: %d\n", running); 1483 "Running curl tasks: %d\n", running);
1579
1580 for (ctask = ctasks_head; NULL != ctask; ctask = ctask->next) 1484 for (ctask = ctasks_head; NULL != ctask; ctask = ctask->next)
1581 { 1485 {
1582 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1486 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -1584,12 +1488,6 @@ curl_task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1584 num_ctasks++; 1488 num_ctasks++;
1585 } 1489 }
1586 1490
1587 if (num_ctasks != running)
1588 {
1589 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1590 "%d ctasks, %d curl running\n", num_ctasks, running);
1591 }
1592
1593 do 1491 do
1594 { 1492 {
1595 1493
@@ -1661,10 +1559,9 @@ curl_task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1661 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1559 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1662 "CURL: Completed ctask!\n"); 1560 "CURL: Completed ctask!\n");
1663 if (GNUNET_SCHEDULER_NO_TASK == ctask->pp_task) 1561 if (GNUNET_SCHEDULER_NO_TASK == ctask->pp_task)
1664 { 1562 {
1665 ctask->buf_status = BUF_WAIT_FOR_PP; 1563 ctask->buf_status = BUF_WAIT_FOR_MHD;
1666 ctask->pp_task = GNUNET_SCHEDULER_add_now (&postprocess_buffer, 1564 run_mhd_now (ctask->mhd);
1667 ctask);
1668 } 1565 }
1669 1566
1670 ctask->ready_to_queue = MHD_YES; 1567 ctask->ready_to_queue = MHD_YES;
@@ -1700,14 +1597,7 @@ curl_task_download (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1700 num_ctasks=0; 1597 num_ctasks=0;
1701 for (ctask=ctasks_head; NULL != ctask; ctask = ctask->next) 1598 for (ctask=ctasks_head; NULL != ctask; ctask = ctask->next)
1702 num_ctasks++; 1599 num_ctasks++;
1703 1600 GNUNET_assert (num_ctasks == running);
1704 if (num_ctasks != running)
1705 {
1706 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1707 "CURL: %d tasks, %d running\n", num_ctasks, running);
1708 }
1709
1710 GNUNET_assert ( num_ctasks == running );
1711 1601
1712 } while (mret == CURLM_CALL_MULTI_PERFORM); 1602 } while (mret == CURLM_CALL_MULTI_PERFORM);
1713 1603
@@ -1767,13 +1657,8 @@ process_leho_lookup (void *cls,
1767 "New HTTP header value: %s\n", hosthdr); 1657 "New HTTP header value: %s\n", hosthdr);
1768 ctask->headers = curl_slist_append (ctask->headers, hosthdr); 1658 ctask->headers = curl_slist_append (ctask->headers, hosthdr);
1769 GNUNET_assert (NULL != ctask->headers); 1659 GNUNET_assert (NULL != ctask->headers);
1770 ret = curl_easy_setopt (ctask->curl, CURLOPT_HTTPHEADER, ctask->headers); 1660 if (CURLE_OK != (ret = curl_easy_setopt (ctask->curl, CURLOPT_HTTPHEADER, ctask->headers)))
1771 if (CURLE_OK != ret) 1661 LOG_CURL_EASY(GNUNET_ERROR_TYPE_WARNING,"curl_easy_setopt",ret);
1772 {
1773 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s failed at %s:%d: `%s'\n",
1774 "curl_easy_setopt", __FILE__, __LINE__, curl_easy_strerror(ret));
1775 }
1776
1777 } 1662 }
1778 1663
1779 if (ctask->mhd->is_ssl) 1664 if (ctask->mhd->is_ssl)
@@ -1789,14 +1674,17 @@ process_leho_lookup (void *cls,
1789 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1674 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1790 "Curl resolve: %s\n", resolvename); 1675 "Curl resolve: %s\n", resolvename);
1791 ctask->resolver = curl_slist_append ( ctask->resolver, resolvename); 1676 ctask->resolver = curl_slist_append ( ctask->resolver, resolvename);
1792 curl_easy_setopt (ctask->curl, CURLOPT_RESOLVE, ctask->resolver); 1677 if (CURLE_OK != (ret = curl_easy_setopt (ctask->curl, CURLOPT_RESOLVE, ctask->resolver)))
1678 LOG_CURL_EASY(GNUNET_ERROR_TYPE_WARNING,"curl_easy_setopt",ret);
1793 sprintf (curlurl, "https://%s:%d%s", ctask->leho, ctask->port, ctask->url); 1679 sprintf (curlurl, "https://%s:%d%s", ctask->leho, ctask->port, ctask->url);
1794 curl_easy_setopt (ctask->curl, CURLOPT_URL, curlurl); 1680 if (CURLE_OK != (ret = curl_easy_setopt (ctask->curl, CURLOPT_URL, curlurl)))
1681 LOG_CURL_EASY(GNUNET_ERROR_TYPE_WARNING,"curl_easy_setopt",ret);
1795 } 1682 }
1796 else 1683 else
1797 { 1684 {
1798 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1685 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1799 "gethostbyname failed for %s!\n", ctask->host); 1686 "gethostbyname failed for %s!\n",
1687 ctask->host);
1800 ctask->download_is_finished = GNUNET_YES; 1688 ctask->download_is_finished = GNUNET_YES;
1801 ctask->download_error = GNUNET_YES; 1689 ctask->download_error = GNUNET_YES;
1802 return; 1690 return;
@@ -1816,7 +1704,6 @@ process_leho_lookup (void *cls,
1816 GNUNET_CONTAINER_DLL_insert (ctasks_head, ctasks_tail, ctask); 1704 GNUNET_CONTAINER_DLL_insert (ctasks_head, ctasks_tail, ctask);
1817 1705
1818 curl_download_prepare (); 1706 curl_download_prepare ();
1819
1820} 1707}
1821 1708
1822 1709
@@ -1825,7 +1712,6 @@ process_leho_lookup (void *cls,
1825 * 1712 *
1826 * @param cls the proxycurltask 1713 * @param cls the proxycurltask
1827 * @param auth_name the name of the authority (site of origin) of ctask->host 1714 * @param auth_name the name of the authority (site of origin) of ctask->host
1828 *
1829 */ 1715 */
1830static void 1716static void
1831process_get_authority (void *cls, 1717process_get_authority (void *cls,
@@ -1846,23 +1732,24 @@ process_get_authority (void *cls,
1846 strcpy (ctask->authority, auth_name); 1732 strcpy (ctask->authority, auth_name);
1847 } 1733 }
1848 1734
1849 GNUNET_GNS_lookup_zone (gns_handle, 1735 GNUNET_GNS_lookup (gns_handle,
1850 ctask->host, 1736 ctask->host,
1851 local_gns_zone, 1737 &local_gns_zone,
1852 GNUNET_NAMESTORE_TYPE_LEHO, 1738 GNUNET_NAMESTORE_TYPE_LEHO,
1853 GNUNET_YES, //Only cached for performance 1739 GNUNET_YES /* Only cached for performance */,
1854 shorten_zonekey, 1740 &shorten_zonekey,
1855 &process_leho_lookup, 1741 &process_leho_lookup,
1856 ctask); 1742 ctask);
1857} 1743}
1858 1744
1859 1745
1860static void* 1746static void*
1861mhd_log_callback (void* cls, const char* url) 1747mhd_log_callback (void* cls,
1748 const char* url)
1862{ 1749{
1863 struct ProxyCurlTask *ctask; 1750 struct ProxyCurlTask *ctask;
1864 1751
1865 ctask = GNUNET_malloc (sizeof (struct ProxyCurlTask)); 1752 ctask = GNUNET_new (struct ProxyCurlTask);
1866 strcpy (ctask->url, url); 1753 strcpy (ctask->url, url);
1867 return ctask; 1754 return ctask;
1868} 1755}
@@ -1884,11 +1771,11 @@ mhd_log_callback (void* cls, const char* url)
1884 * data *will* be made available incrementally in 1771 * data *will* be made available incrementally in
1885 * upload_data) 1772 * upload_data)
1886 * @param upload_data_size set initially to the size of the 1773 * @param upload_data_size set initially to the size of the
1887 * upload_data provided; the method must update this 1774 * @a upload_data provided; the method must update this
1888 * value to the number of bytes NOT processed; 1775 * value to the number of bytes NOT processed;
1889 * @param con_cls pointer to location where we store the 'struct Request' 1776 * @param con_cls pointer to location where we store the 'struct Request'
1890 * @return MHD_YES if the connection was handled successfully, 1777 * @return #MHD_YES if the connection was handled successfully,
1891 * MHD_NO if the socket must be closed due to a serious 1778 * #MHD_NO if the socket must be closed due to a serious
1892 * error while handling the request 1779 * error while handling the request
1893 */ 1780 */
1894static int 1781static int
@@ -1901,10 +1788,7 @@ create_response (void *cls,
1901 size_t *upload_data_size, 1788 size_t *upload_data_size,
1902 void **con_cls) 1789 void **con_cls)
1903{ 1790{
1904 struct MhdHttpList* hd = cls; 1791 struct MhdHttpList* hd = cls;
1905 const char* page = "<html><head><title>gnunet-gns-proxy</title>"
1906 "</head><body>cURL fail</body></html>";
1907
1908 char curlurl[MAX_HTTP_URI_LENGTH]; // buffer overflow! 1792 char curlurl[MAX_HTTP_URI_LENGTH]; // buffer overflow!
1909 int ret = MHD_YES; 1793 int ret = MHD_YES;
1910 int i; 1794 int i;
@@ -1935,13 +1819,9 @@ create_response (void *cls,
1935 ctask->curl_running = GNUNET_NO; 1819 ctask->curl_running = GNUNET_NO;
1936 if (NULL == ctask->curl) 1820 if (NULL == ctask->curl)
1937 { 1821 {
1938 ctask->response = MHD_create_response_from_buffer (strlen (page),
1939 (void*)page,
1940 MHD_RESPMEM_PERSISTENT);
1941 ret = MHD_queue_response (con, 1822 ret = MHD_queue_response (con,
1942 MHD_HTTP_OK, 1823 MHD_HTTP_OK,
1943 ctask->response); 1824 curl_failure_response);
1944 MHD_destroy_response (ctask->response);
1945 GNUNET_free (ctask); 1825 GNUNET_free (ctask);
1946 return ret; 1826 return ret;
1947 } 1827 }
@@ -2004,9 +1884,9 @@ create_response (void *cls,
2004 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1884 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2005 "Setting up POST processor\n"); 1885 "Setting up POST processor\n");
2006 ctask->post_handler = MHD_create_post_processor (con, 1886 ctask->post_handler = MHD_create_post_processor (con,
2007 POSTBUFFERSIZE, 1887 POSTBUFFERSIZE,
2008 &con_post_data_iter, 1888 &con_post_data_iter,
2009 ctask); 1889 ctask);
2010 ctask->headers = curl_slist_append (ctask->headers, 1890 ctask->headers = curl_slist_append (ctask->headers,
2011 "Transfer-Encoding: chunked"); 1891 "Transfer-Encoding: chunked");
2012 return MHD_YES; 1892 return MHD_YES;
@@ -2124,7 +2004,7 @@ create_response (void *cls,
2124 return MHD_YES; 2004 return MHD_YES;
2125 } 2005 }
2126 2006
2127 fin_post = GNUNET_malloc (sizeof (struct ProxyUploadData)); 2007 fin_post = GNUNET_new (struct ProxyUploadData);
2128 GNUNET_CONTAINER_DLL_insert_tail (ctask->upload_data_head, 2008 GNUNET_CONTAINER_DLL_insert_tail (ctask->upload_data_head,
2129 ctask->upload_data_tail, 2009 ctask->upload_data_tail,
2130 fin_post); 2010 fin_post);
@@ -2162,9 +2042,6 @@ run_httpds ()
2162} 2042}
2163 2043
2164 2044
2165#define UNSIGNED_MHD_LONG_LONG unsigned MHD_LONG_LONG
2166
2167
2168/** 2045/**
2169 * schedule mhd 2046 * schedule mhd
2170 * 2047 *
@@ -2181,7 +2058,7 @@ run_httpd (struct MhdHttpList *hd)
2181 struct GNUNET_NETWORK_FDSet *wes; 2058 struct GNUNET_NETWORK_FDSet *wes;
2182 int max; 2059 int max;
2183 int haveto; 2060 int haveto;
2184 UNSIGNED_MHD_LONG_LONG timeout; 2061 MHD_UNSIGNED_LONG_LONG timeout;
2185 struct GNUNET_TIME_Relative tv; 2062 struct GNUNET_TIME_Relative tv;
2186 2063
2187 FD_ZERO (&rs); 2064 FD_ZERO (&rs);
@@ -2505,7 +2382,7 @@ load_key_from_file (gnutls_x509_privkey_t key, const char* keyfile)
2505 * 2382 *
2506 * @param crt struct to store data in 2383 * @param crt struct to store data in
2507 * @param certfile path to pem file 2384 * @param certfile path to pem file
2508 * @return GNUNET_OK on success 2385 * @return #GNUNET_OK on success
2509 */ 2386 */
2510static int 2387static int
2511load_cert_from_file (gnutls_x509_crt_t crt, char* certfile) 2388load_cert_from_file (gnutls_x509_crt_t crt, char* certfile)
@@ -2556,7 +2433,7 @@ generate_gns_certificate (const char *name)
2556 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Generating cert\n"); 2433 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Generating cert\n");
2557 2434
2558 struct ProxyGNSCertificate *pgc = 2435 struct ProxyGNSCertificate *pgc =
2559 GNUNET_malloc (sizeof (struct ProxyGNSCertificate)); 2436 GNUNET_new (struct ProxyGNSCertificate);
2560 2437
2561 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding DNs\n"); 2438 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding DNs\n");
2562 2439
@@ -2571,8 +2448,7 @@ generate_gns_certificate (const char *name)
2571 ret = gnutls_rnd (GNUTLS_RND_NONCE, &serial, sizeof (serial)); 2448 ret = gnutls_rnd (GNUTLS_RND_NONCE, &serial, sizeof (serial));
2572 2449
2573 etime = time (NULL); 2450 etime = time (NULL);
2574 tm_data = localtime (&etime); 2451 tm_data = localtime (&etime);
2575
2576 2452
2577 ret = gnutls_x509_crt_set_serial (request, 2453 ret = gnutls_x509_crt_set_serial (request,
2578 &serial, 2454 &serial,
@@ -2648,7 +2524,7 @@ accept_cb (void* cls, const struct sockaddr *addr, socklen_t addrlen)
2648 * 2524 *
2649 * @param h the handle to add to a daemon 2525 * @param h the handle to add to a daemon
2650 * @param domain the domain the ssl daemon has to serve 2526 * @param domain the domain the ssl daemon has to serve
2651 * @return MHD_YES on success 2527 * @return #MHD_YES on success
2652 */ 2528 */
2653static int 2529static int
2654add_handle_to_ssl_mhd (struct GNUNET_NETWORK_Handle *h, const char* domain) 2530add_handle_to_ssl_mhd (struct GNUNET_NETWORK_Handle *h, const char* domain)
@@ -2665,7 +2541,7 @@ add_handle_to_ssl_mhd (struct GNUNET_NETWORK_Handle *h, const char* domain)
2665 { 2541 {
2666 pgc = generate_gns_certificate (domain); 2542 pgc = generate_gns_certificate (domain);
2667 2543
2668 hd = GNUNET_malloc (sizeof (struct MhdHttpList)); 2544 hd = GNUNET_new (struct MhdHttpList);
2669 hd->is_ssl = GNUNET_YES; 2545 hd->is_ssl = GNUNET_YES;
2670 strcpy (hd->domain, domain); 2546 strcpy (hd->domain, domain);
2671 hd->proxy_cert = pgc; 2547 hd->proxy_cert = pgc;
@@ -2674,7 +2550,6 @@ add_handle_to_ssl_mhd (struct GNUNET_NETWORK_Handle *h, const char* domain)
2674 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2550 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2675 "No previous SSL instance found... starting new one for %s\n", 2551 "No previous SSL instance found... starting new one for %s\n",
2676 domain); 2552 domain);
2677#if HAVE_MHD_NO_LISTEN_SOCKET
2678 hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SSL | MHD_USE_NO_LISTEN_SOCKET, 2553 hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SSL | MHD_USE_NO_LISTEN_SOCKET,
2679 0, 2554 0,
2680 &accept_cb, NULL, 2555 &accept_cb, NULL,
@@ -2688,29 +2563,13 @@ add_handle_to_ssl_mhd (struct GNUNET_NETWORK_Handle *h, const char* domain)
2688 MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback, 2563 MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback,
2689 NULL, 2564 NULL,
2690 MHD_OPTION_END); 2565 MHD_OPTION_END);
2691#else
2692 hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SSL,
2693 4444 /* dummy port */,
2694 &accept_cb, NULL,
2695 &create_response, hd,
2696 MHD_OPTION_LISTEN_SOCKET, GNUNET_NETWORK_get_fd (mhd_unix_socket),
2697 MHD_OPTION_CONNECTION_LIMIT,
2698 MHD_MAX_CONNECTIONS,
2699 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16,
2700 MHD_OPTION_NOTIFY_COMPLETED, NULL, NULL,
2701 MHD_OPTION_HTTPS_MEM_KEY, pgc->key,
2702 MHD_OPTION_HTTPS_MEM_CERT, pgc->cert,
2703 MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback,
2704 NULL,
2705 MHD_OPTION_END);
2706#endif
2707 GNUNET_assert (hd->daemon != NULL); 2566 GNUNET_assert (hd->daemon != NULL);
2708 hd->httpd_task = GNUNET_SCHEDULER_NO_TASK; 2567 hd->httpd_task = GNUNET_SCHEDULER_NO_TASK;
2709 2568
2710 GNUNET_CONTAINER_DLL_insert (mhd_httpd_head, mhd_httpd_tail, hd); 2569 GNUNET_CONTAINER_DLL_insert (mhd_httpd_head, mhd_httpd_tail, hd);
2711 } 2570 }
2712 2571
2713 nh = GNUNET_malloc (sizeof (struct NetworkHandleList)); 2572 nh = GNUNET_new (struct NetworkHandleList);
2714 nh->h = h; 2573 nh->h = h;
2715 2574
2716 GNUNET_CONTAINER_DLL_insert (hd->socket_handles_head, 2575 GNUNET_CONTAINER_DLL_insert (hd->socket_handles_head,
@@ -2841,7 +2700,7 @@ do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2841 { 2700 {
2842 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2701 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2843 "Requested connection is HTTP\n"); 2702 "Requested connection is HTTP\n");
2844 nh = GNUNET_malloc (sizeof (struct NetworkHandleList)); 2703 nh = GNUNET_new (struct NetworkHandleList);
2845 nh->h = s5r->sock; 2704 nh->h = s5r->sock;
2846 2705
2847 GNUNET_CONTAINER_DLL_insert (mhd_httpd_head->socket_handles_head, 2706 GNUNET_CONTAINER_DLL_insert (mhd_httpd_head->socket_handles_head,
@@ -3006,7 +2865,8 @@ do_read (void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3006 * @param tc the scheduler context 2865 * @param tc the scheduler context
3007 */ 2866 */
3008static void 2867static void
3009do_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 2868do_accept (void *cls,
2869 const struct GNUNET_SCHEDULER_TaskContext *tc)
3010{ 2870{
3011 struct GNUNET_NETWORK_Handle *s; 2871 struct GNUNET_NETWORK_Handle *s;
3012 struct Socks5Request *s5r; 2872 struct Socks5Request *s5r;
@@ -3014,23 +2874,18 @@ do_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
3014 ltask = GNUNET_SCHEDULER_NO_TASK; 2874 ltask = GNUNET_SCHEDULER_NO_TASK;
3015 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 2875 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
3016 return; 2876 return;
3017
3018 ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 2877 ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
3019 lsock, 2878 lsock,
3020 &do_accept, NULL); 2879 &do_accept, NULL);
3021
3022 s = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL); 2880 s = GNUNET_NETWORK_socket_accept (lsock, NULL, NULL);
3023
3024 if (NULL == s) 2881 if (NULL == s)
3025 { 2882 {
3026 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "accept"); 2883 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "accept");
3027 return; 2884 return;
3028 } 2885 }
3029
3030 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2886 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3031 "Got an inbound connection, waiting for data\n"); 2887 "Got an inbound connection, waiting for data\n");
3032 2888 s5r = GNUNET_new (struct Socks5Request);
3033 s5r = GNUNET_malloc (sizeof (struct Socks5Request));
3034 s5r->sock = s; 2889 s5r->sock = s;
3035 s5r->state = SOCKS5_INIT; 2890 s5r->state = SOCKS5_INIT;
3036 s5r->wtask = GNUNET_SCHEDULER_NO_TASK; 2891 s5r->wtask = GNUNET_SCHEDULER_NO_TASK;
@@ -3062,13 +2917,6 @@ do_shutdown (void *cls,
3062 2917
3063 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 2918 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3064 "Shutting down...\n"); 2919 "Shutting down...\n");
3065 if (NULL != local_gns_zone)
3066 GNUNET_free (local_gns_zone);
3067 if (NULL != local_private_zone)
3068 GNUNET_free (local_private_zone);
3069 if (NULL != local_shorten_zone)
3070 GNUNET_free (local_shorten_zone);
3071
3072 if (GNUNET_SCHEDULER_NO_TASK != curl_download_task) 2920 if (GNUNET_SCHEDULER_NO_TASK != curl_download_task)
3073 { 2921 {
3074 GNUNET_SCHEDULER_cancel (curl_download_task); 2922 GNUNET_SCHEDULER_cancel (curl_download_task);
@@ -3148,221 +2996,38 @@ do_shutdown (void *cls,
3148 } 2996 }
3149 GNUNET_free (ctask); 2997 GNUNET_free (ctask);
3150 } 2998 }
3151 curl_multi_cleanup (curl_multi); 2999 if (NULL != lsock)
3152 GNUNET_GNS_disconnect (gns_handle);
3153 gnutls_global_deinit ();
3154}
3155
3156
3157/**
3158 * Compiles a regex for us
3159 *
3160 * @param re ptr to re struct
3161 * @param rt the expression to compile
3162 * @return 0 on success
3163 */
3164static int
3165compile_regex (regex_t *re, const char* rt)
3166{
3167 int status;
3168 char err[1024];
3169
3170 status = regcomp (re, rt, REG_EXTENDED|REG_NEWLINE);
3171 if (status)
3172 { 3000 {
3173 regerror (status, re, err, 1024); 3001 GNUNET_NETWORK_socket_close (lsock);
3174 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3002 lsock = NULL;
3175 "Regex error compiling '%s': %s\n", rt, err);
3176 return 1;
3177 } 3003 }
3178 return 0; 3004 if (NULL != id_op)
3179}
3180
3181
3182/**
3183 * Loads the users local zone key
3184 *
3185 * @return GNUNET_YES on success
3186 */
3187static int
3188load_local_zone_key (const struct GNUNET_CONFIGURATION_Handle *cfg)
3189{
3190 char *keyfile;
3191 struct GNUNET_CRYPTO_EccPrivateKey *key;
3192 struct GNUNET_CRYPTO_EccPublicSignKey pkey;
3193 struct GNUNET_CRYPTO_ShortHashCode *zone;
3194 struct GNUNET_CRYPTO_ShortHashAsciiEncoded zonename;
3195
3196 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
3197 "ZONEKEY", &keyfile))
3198 {
3199 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3200 "Unable to load zone key config value!\n");
3201 return GNUNET_NO;
3202 }
3203
3204 if (GNUNET_NO == GNUNET_DISK_file_test (keyfile))
3205 {
3206 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3207 "Unable to load zone key %s!\n", keyfile);
3208 GNUNET_free(keyfile);
3209 return GNUNET_NO;
3210 }
3211
3212 key = GNUNET_CRYPTO_ecc_key_create_from_file (keyfile);
3213 GNUNET_CRYPTO_ecc_key_get_public_for_signature (key, &pkey);
3214 local_gns_zone = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_ShortHashCode));
3215 GNUNET_CRYPTO_short_hash (&pkey,
3216 sizeof (struct GNUNET_CRYPTO_EccPublicSignKey),
3217 local_gns_zone);
3218 zone = local_gns_zone;
3219 GNUNET_CRYPTO_short_hash_to_enc (zone, &zonename);
3220 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3221 "Using zone: %s!\n", &zonename);
3222 GNUNET_free(key);
3223 GNUNET_free(keyfile);
3224 keyfile = NULL;
3225
3226 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
3227 "PRIVATE_ZONEKEY", &keyfile))
3228 {
3229 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3230 "Unable to load private zone key config value!\n");
3231 }
3232
3233 if ((NULL != keyfile) && (GNUNET_NO == GNUNET_DISK_file_test (keyfile)))
3234 {
3235 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3236 "Unable to load private zone key %s!\n", keyfile);
3237 GNUNET_free(keyfile);
3238 }
3239 else
3240 {
3241 key = GNUNET_CRYPTO_ecc_key_create_from_file (keyfile);
3242 GNUNET_CRYPTO_ecc_key_get_public_for_signature (key, &pkey);
3243 local_private_zone = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_ShortHashCode));
3244 GNUNET_CRYPTO_short_hash (&pkey,
3245 sizeof (struct GNUNET_CRYPTO_EccPublicSignKey),
3246 local_private_zone);
3247 GNUNET_CRYPTO_short_hash_to_enc (zone, &zonename);
3248 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3249 "Using private zone: %s!\n", &zonename);
3250 GNUNET_free(key);
3251 GNUNET_free(keyfile);
3252 }
3253 keyfile = NULL;
3254
3255 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
3256 "SHORTEN_ZONEKEY", &keyfile))
3257 { 3005 {
3258 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3006 GNUNET_IDENTITY_cancel (id_op);
3259 "Unable to load shorten zone key config value!\n"); 3007 id_op = NULL;
3260 }
3261
3262 if ((NULL != keyfile) && (GNUNET_NO == GNUNET_DISK_file_test (keyfile)))
3263 {
3264 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3265 "Unable to load shorten zone key %s!\n", keyfile);
3266 GNUNET_free(keyfile);
3267 } 3008 }
3268 else 3009 if (NULL != identity)
3269 { 3010 {
3270 key = GNUNET_CRYPTO_ecc_key_create_from_file (keyfile); 3011 GNUNET_IDENTITY_disconnect (identity);
3271 GNUNET_CRYPTO_ecc_key_get_public_for_signature (key, &pkey); 3012 identity = NULL;
3272 local_shorten_zone = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_ShortHashCode));
3273 GNUNET_CRYPTO_short_hash (&pkey,
3274 sizeof(struct GNUNET_CRYPTO_EccPublicSignKey),
3275 local_shorten_zone);
3276 GNUNET_CRYPTO_short_hash_to_enc (zone, &zonename);
3277 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3278 "Using shorten zone: %s!\n", &zonename);
3279 GNUNET_free(key);
3280 GNUNET_free(keyfile);
3281 } 3013 }
3282 3014 curl_multi_cleanup (curl_multi);
3283 return GNUNET_YES; 3015 GNUNET_GNS_disconnect (gns_handle);
3016 gnutls_global_deinit ();
3284} 3017}
3285 3018
3286 3019
3287/** 3020/**
3288 * Main function that will be run 3021 * Continue initialization after we have our zone information.
3289 *
3290 * @param cls closure
3291 * @param args remaining command-line arguments
3292 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
3293 * @param cfg configuration
3294 */ 3022 */
3295static void 3023static void
3296run (void *cls, char *const *args, const char *cfgfile, 3024run_cont ()
3297 const struct GNUNET_CONFIGURATION_Handle *cfg)
3298{ 3025{
3299 struct sockaddr_in sa;
3300 struct MhdHttpList *hd; 3026 struct MhdHttpList *hd;
3301 char* cafile_cfg = NULL;
3302 char* cafile;
3303#if !HAVE_MHD_NO_LISTEN_SOCKET
3304 size_t len; 3027 size_t len;
3028 struct sockaddr_in sa;
3305 char* proxy_sockfile; 3029 char* proxy_sockfile;
3306 struct sockaddr_un mhd_unix_sock_addr; 3030 struct sockaddr_un mhd_unix_sock_addr;
3307#endif
3308
3309 if (NULL == (curl_multi = curl_multi_init ()))
3310 {
3311 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3312 "Failed to create cURL multo handle!\n");
3313 return;
3314 }
3315
3316 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
3317 "Loading CA\n");
3318 cafile = cafile_opt;
3319 if (NULL == cafile)
3320 {
3321 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns-proxy",
3322 "PROXY_CACERT",
3323 &cafile_cfg))
3324 {
3325 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3326 "Unable to load proxy CA config value!\n");
3327 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3328 "No proxy CA provided!\n");
3329 return;
3330 }
3331 cafile = cafile_cfg;
3332 }
3333 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3334 "Using %s as CA\n", cafile);
3335
3336 gnutls_global_init ();
3337 gnutls_x509_crt_init (&proxy_ca.cert);
3338 gnutls_x509_privkey_init (&proxy_ca.key);
3339
3340 if ( (GNUNET_OK != load_cert_from_file (proxy_ca.cert, cafile)) ||
3341 (GNUNET_OK != load_key_from_file (proxy_ca.key, cafile)) )
3342 {
3343 // FIXME: release resources...
3344 return;
3345 }
3346
3347 GNUNET_free_non_null (cafile_cfg);
3348
3349 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3350 "Loading Template\n");
3351
3352 compile_regex (&re_dotplus, (char*) RE_A_HREF);
3353
3354 if (NULL == (gns_handle = GNUNET_GNS_connect (cfg)))
3355 {
3356 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3357 "Unable to connect to GNS!\n");
3358 return;
3359 }
3360 if (GNUNET_NO == load_local_zone_key (cfg))
3361 {
3362 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3363 "Unable to load zone!\n");
3364 return;
3365 }
3366 3031
3367 memset (&sa, 0, sizeof (sa)); 3032 memset (&sa, 0, sizeof (sa));
3368 sa.sin_family = AF_INET; 3033 sa.sin_family = AF_INET;
@@ -3374,25 +3039,24 @@ run (void *cls, char *const *args, const char *cfgfile,
3374 lsock = GNUNET_NETWORK_socket_create (AF_INET, 3039 lsock = GNUNET_NETWORK_socket_create (AF_INET,
3375 SOCK_STREAM, 3040 SOCK_STREAM,
3376 0); 3041 0);
3377 3042 if (NULL == lsock)
3378 if ((NULL == lsock) ||
3379 (GNUNET_OK !=
3380 GNUNET_NETWORK_socket_bind (lsock, (const struct sockaddr *) &sa,
3381 sizeof (sa), 0)))
3382 { 3043 {
3383 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3044 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "socket");
3384 "Failed to create listen socket bound to `%s'", 3045 GNUNET_SCHEDULER_shutdown ();
3385 GNUNET_a2s ((const struct sockaddr *) &sa, sizeof (sa))); 3046 return;
3386 if (NULL != lsock) 3047 }
3387 GNUNET_NETWORK_socket_close (lsock); 3048 if (GNUNET_OK !=
3049 GNUNET_NETWORK_socket_bind (lsock, (const struct sockaddr *) &sa,
3050 sizeof (sa), 0))
3051 {
3052 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
3053 GNUNET_SCHEDULER_shutdown ();
3388 return; 3054 return;
3389 } 3055 }
3390 3056
3391 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (lsock, 5)) 3057 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (lsock, 5))
3392 { 3058 {
3393 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3059 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen");
3394 "Failed to listen on socket bound to `%s'",
3395 GNUNET_a2s ((const struct sockaddr *) &sa, sizeof (sa)));
3396 return; 3060 return;
3397 } 3061 }
3398 ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, 3062 ltask = GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL,
@@ -3402,19 +3066,19 @@ run (void *cls, char *const *args, const char *cfgfile,
3402 { 3066 {
3403 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3067 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3404 "cURL global init failed!\n"); 3068 "cURL global init failed!\n");
3069 GNUNET_SCHEDULER_shutdown ();
3405 return; 3070 return;
3406 } 3071 }
3407 3072
3408 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3073 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3409 "Proxy listens on port %u\n", 3074 "Proxy listens on port %u\n",
3410 port); 3075 port);
3411#if ! HAVE_MHD_NO_LISTEN_SOCKET
3412 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns-proxy", 3076 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns-proxy",
3413 "PROXY_UNIXPATH", 3077 "PROXY_UNIXPATH",
3414 &proxy_sockfile)) 3078 &proxy_sockfile))
3415 { 3079 {
3416 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3080 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, "gns-proxy", "PROXY_UNIXPATH");
3417 "Specify PROXY_UNIXPATH in gns-proxy config section!\n"); 3081 GNUNET_SCHEDULER_shutdown ();
3418 return; 3082 return;
3419 } 3083 }
3420 if (NULL == (mhd_unix_socket = GNUNET_NETWORK_socket_create (AF_UNIX, 3084 if (NULL == (mhd_unix_socket = GNUNET_NETWORK_socket_create (AF_UNIX,
@@ -3422,7 +3086,8 @@ run (void *cls, char *const *args, const char *cfgfile,
3422 0))) 3086 0)))
3423 { 3087 {
3424 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3088 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3425 "Unable to create unix domain socket!\n"); 3089 "Unable to create UNIX domain socket!\n");
3090 GNUNET_SCHEDULER_shutdown ();
3426 return; 3091 return;
3427 } 3092 }
3428 3093
@@ -3440,28 +3105,26 @@ run (void *cls, char *const *args, const char *cfgfile,
3440 GNUNET_free (proxy_sockfile); 3105 GNUNET_free (proxy_sockfile);
3441 3106
3442 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (mhd_unix_socket, 3107 if (GNUNET_OK != GNUNET_NETWORK_socket_bind (mhd_unix_socket,
3443 (struct sockaddr*)&mhd_unix_sock_addr, 3108 (struct sockaddr *) &mhd_unix_sock_addr,
3444 len, 0)) 3109 len, 0))
3445 { 3110 {
3446 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3111 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "bind");
3447 "Unable to bind unix domain socket!\n"); 3112 GNUNET_SCHEDULER_shutdown ();
3448 return; 3113 return;
3449 } 3114 }
3450 3115
3451 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (mhd_unix_socket, 3116 if (GNUNET_OK != GNUNET_NETWORK_socket_listen (mhd_unix_socket,
3452 1)) 3117 1))
3453 { 3118 {
3454 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 3119 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "listen");
3455 "Unable to listen on unix domain socket!\n"); 3120 GNUNET_SCHEDULER_shutdown ();
3456 return; 3121 return;
3457 } 3122 }
3458#endif
3459 3123
3460 hd = GNUNET_malloc (sizeof (struct MhdHttpList)); 3124 hd = GNUNET_new (struct MhdHttpList);
3461 hd->is_ssl = GNUNET_NO; 3125 hd->is_ssl = GNUNET_NO;
3462 strcpy (hd->domain, ""); 3126 strcpy (hd->domain, "");
3463 3127
3464#if HAVE_MHD_NO_LISTEN_SOCKET
3465 httpd = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET, 3128 httpd = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET,
3466 0, 3129 0,
3467 &accept_cb, NULL, 3130 &accept_cb, NULL,
@@ -3472,24 +3135,166 @@ run (void *cls, char *const *args, const char *cfgfile,
3472 NULL, NULL, 3135 NULL, NULL,
3473 MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback, NULL, 3136 MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback, NULL,
3474 MHD_OPTION_END); 3137 MHD_OPTION_END);
3475#else 3138 if (NULL == httpd)
3476 httpd = MHD_start_daemon (MHD_USE_DEBUG, 3139 {
3477 4444 /* Dummy port */, 3140
3478 &accept_cb, NULL, 3141 GNUNET_SCHEDULER_shutdown ();
3479 &create_response, hd, 3142 return;
3480 MHD_OPTION_LISTEN_SOCKET, GNUNET_NETWORK_get_fd (mhd_unix_socket), 3143 }
3481 MHD_OPTION_CONNECTION_LIMIT, MHD_MAX_CONNECTIONS,
3482 MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16,
3483 MHD_OPTION_NOTIFY_COMPLETED,
3484 NULL, NULL,
3485 MHD_OPTION_URI_LOG_CALLBACK, &mhd_log_callback, NULL,
3486 MHD_OPTION_END);
3487#endif
3488 GNUNET_break (httpd != NULL);
3489 hd->daemon = httpd; 3144 hd->daemon = httpd;
3490 hd->httpd_task = GNUNET_SCHEDULER_NO_TASK; 3145 hd->httpd_task = GNUNET_SCHEDULER_NO_TASK;
3491 GNUNET_CONTAINER_DLL_insert (mhd_httpd_head, mhd_httpd_tail, hd); 3146 GNUNET_CONTAINER_DLL_insert (mhd_httpd_head, mhd_httpd_tail, hd);
3492 run_httpds (); 3147 run_httpds ();
3148}
3149
3150
3151/**
3152 * Method called to inform about the egos of the shorten zone of this peer.
3153 *
3154 * When used with #GNUNET_IDENTITY_create or #GNUNET_IDENTITY_get,
3155 * this function is only called ONCE, and 'NULL' being passed in
3156 * @a ego does indicate an error (i.e. name is taken or no default
3157 * value is known). If @a ego is non-NULL and if '*ctx'
3158 * is set in those callbacks, the value WILL be passed to a subsequent
3159 * call to the identity callback of #GNUNET_IDENTITY_connect (if
3160 * that one was not NULL).
3161 *
3162 * @param cls closure, NULL
3163 * @param ego ego handle
3164 * @param ctx context for application to store data for this ego
3165 * (during the lifetime of this process, initially NULL)
3166 * @param name name assigned by the user for this ego,
3167 * NULL if the user just deleted the ego and it
3168 * must thus no longer be used
3169 */
3170static void
3171identity_shorten_cb (void *cls,
3172 struct GNUNET_IDENTITY_Ego *ego,
3173 void **ctx,
3174 const char *name)
3175{
3176 id_op = NULL;
3177 if (NULL == ego)
3178 {
3179 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
3180 _("No ego configured for `shorten-zone`\n"));
3181 }
3182 else
3183 {
3184 local_shorten_zone = *GNUNET_IDENTITY_ego_get_private_key (ego);
3185 do_shorten = GNUNET_YES;
3186 }
3187 run_cont ();
3188}
3189
3190
3191/**
3192 * Method called to inform about the egos of the master zone of this peer.
3193 *
3194 * When used with #GNUNET_IDENTITY_create or #GNUNET_IDENTITY_get,
3195 * this function is only called ONCE, and 'NULL' being passed in
3196 * @a ego does indicate an error (i.e. name is taken or no default
3197 * value is known). If @a ego is non-NULL and if '*ctx'
3198 * is set in those callbacks, the value WILL be passed to a subsequent
3199 * call to the identity callback of #GNUNET_IDENTITY_connect (if
3200 * that one was not NULL).
3201 *
3202 * @param cls closure, NULL
3203 * @param ego ego handle
3204 * @param ctx context for application to store data for this ego
3205 * (during the lifetime of this process, initially NULL)
3206 * @param name name assigned by the user for this ego,
3207 * NULL if the user just deleted the ego and it
3208 * must thus no longer be used
3209 */
3210static void
3211identity_master_cb (void *cls,
3212 struct GNUNET_IDENTITY_Ego *ego,
3213 void **ctx,
3214 const char *name)
3215{
3216 id_op = NULL;
3217 if (NULL == ego)
3218 {
3219 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3220 _("No ego configured for `master-zone`\n"));
3221 GNUNET_SCHEDULER_shutdown ();
3222 return;
3223 }
3224 GNUNET_IDENTITY_ego_get_public_key (ego,
3225 &local_gns_zone);
3226 id_op = GNUNET_IDENTITY_get (identity,
3227 "shorten-zone",
3228 &identity_shorten_cb,
3229 NULL);
3230}
3231
3232
3233/**
3234 * Main function that will be run
3235 *
3236 * @param cls closure
3237 * @param args remaining command-line arguments
3238 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
3239 * @param c configuration
3240 */
3241static void
3242run (void *cls, char *const *args, const char *cfgfile,
3243 const struct GNUNET_CONFIGURATION_Handle *c)
3244{
3245 char* cafile_cfg = NULL;
3246 char* cafile;
3247
3248 cfg = c;
3249 if (NULL == (curl_multi = curl_multi_init ()))
3250 {
3251 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3252 "Failed to create cURL multi handle!\n");
3253 return;
3254 }
3255 cafile = cafile_opt;
3256 if (NULL == cafile)
3257 {
3258 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns-proxy",
3259 "PROXY_CACERT",
3260 &cafile_cfg))
3261 {
3262 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
3263 "gns-proxy",
3264 "PROXY_CACERT");
3265 return;
3266 }
3267 cafile = cafile_cfg;
3268 }
3269 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3270 "Using %s as CA\n", cafile);
3271
3272 gnutls_global_init ();
3273 gnutls_x509_crt_init (&proxy_ca.cert);
3274 gnutls_x509_privkey_init (&proxy_ca.key);
3275
3276 if ( (GNUNET_OK != load_cert_from_file (proxy_ca.cert, cafile)) ||
3277 (GNUNET_OK != load_key_from_file (proxy_ca.key, cafile)) )
3278 {
3279 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3280 _("Failed to load SSL/TLS key and certificate from `%s'\n"),
3281 cafile);
3282 // FIXME: release resources...
3283 return;
3284 }
3285 GNUNET_free_non_null (cafile_cfg);
3286 if (NULL == (gns_handle = GNUNET_GNS_connect (cfg)))
3287 {
3288 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
3289 "Unable to connect to GNS!\n");
3290 return;
3291 }
3292 identity = GNUNET_IDENTITY_connect (cfg,
3293 NULL, NULL);
3294 id_op = GNUNET_IDENTITY_get (identity,
3295 "master-zone",
3296 &identity_master_cb,
3297 NULL);
3493 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, 3298 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
3494 &do_shutdown, NULL); 3299 &do_shutdown, NULL);
3495} 3300}
@@ -3514,17 +3319,25 @@ main (int argc, char *const *argv)
3514 &GNUNET_GETOPT_set_string, &cafile_opt}, 3319 &GNUNET_GETOPT_set_string, &cafile_opt},
3515 GNUNET_GETOPT_OPTION_END 3320 GNUNET_GETOPT_OPTION_END
3516 }; 3321 };
3322 static const char* page =
3323 "<html><head><title>gnunet-gns-proxy</title>"
3324 "</head><body>cURL fail</body></html>";
3517 int ret; 3325 int ret;
3518 3326
3519 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv)) 3327 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
3520 return 2; 3328 return 2;
3521 GNUNET_log_setup ("gnunet-gns-proxy", "WARNING", NULL); 3329 GNUNET_log_setup ("gnunet-gns-proxy", "WARNING", NULL);
3330 curl_failure_response = MHD_create_response_from_buffer (strlen (page),
3331 (void*)page,
3332 MHD_RESPMEM_PERSISTENT);
3333
3522 ret = 3334 ret =
3523 (GNUNET_OK == 3335 (GNUNET_OK ==
3524 GNUNET_PROGRAM_run (argc, argv, "gnunet-gns-proxy", 3336 GNUNET_PROGRAM_run (argc, argv, "gnunet-gns-proxy",
3525 _("GNUnet GNS proxy"), 3337 _("GNUnet GNS proxy"),
3526 options, 3338 options,
3527 &run, NULL)) ? 0 : 1; 3339 &run, NULL)) ? 0 : 1;
3340 MHD_destroy_response (curl_failure_response);
3528 GNUNET_free_non_null ((char *) argv); 3341 GNUNET_free_non_null ((char *) argv);
3529 return ret; 3342 return ret;
3530} 3343}