#include "gns_proxy_proto.h"
#include "gns.h"
+/** SSL **/
+#include <gnutls/gnutls.h>
+#include <gnutls/x509.h>
+#include <gnutls/abstract.h>
+#include <gnutls/crypto.h>
+#include <time.h>
+
#define GNUNET_GNS_PROXY_PORT 7777
/* MHD/cURL defines */
/* regexp */
#define RE_DOTPLUS "<a href=\"http://(([A-Za-z]+[.])+)([+])"
+#define RE_A_HREF "<a href=\"https?://(([A-Za-z]+[.])+)([+]|zkey)"
#define RE_N_MATCHES 4
/* The usual suspects */
#define HTTPS_PORT 443
+/**
+ * A structure for CA cert/key
+ */
+struct ProxyCA
+{
+ /* The certificate */
+ gnutls_x509_crt_t cert;
+
+ /* The private key */
+ gnutls_x509_privkey_t key;
+};
+
+
+/**
+ * Structure for GNS certificates
+ */
+struct ProxyGNSCertificate
+{
+ /* The certificate as PEM */
+ char cert[10 * 1024];
+
+ /* The private key as PEM */
+ char key[10 * 1024];
+};
+
/**
* A structure for socks requests
/* Length of data in write buffer */
unsigned int wbuf_len;
+
+ /* This handle is scheduled for cleanup? */
+ int cleanup;
+
+ /* Shall we close the client socket on cleanup? */
+ int cleanup_sock;
};
/* Handle to cURL */
CURL *curl;
+ /* Optional header replacements for curl (LEHO) */
+ struct curl_slist *headers;
+
+ /* Optional resolver replacements for curl (LEHO) */
+ struct curl_slist *resolver;
+
/* The URL to fetch */
char url[2048];
/* The hostname (Host header field) */
char host[256];
+ /* The LEgacy HOstname (can be empty) */
+ char leho[256];
+
/* The associated daemon list entry */
- struct MhdHttpList *daemon;
+ struct MhdHttpList *mhd;
};
/* The port the proxy is running on (default 7777) */
-unsigned long port = GNUNET_GNS_PROXY_PORT;
+static unsigned long port = GNUNET_GNS_PROXY_PORT;
+
+/* The CA file (pem) to use for the proxy CA */
+static char* cafile;
/* The listen socket of the proxy */
static struct GNUNET_NETWORK_Handle *lsock;
/* The non SSL httpd daemon handle */
static struct MHD_Daemon *httpd;
-/* The http task ID */
-static GNUNET_SCHEDULER_TaskIdentifier httpd_task;
-
/* The cURL multi handle */
static CURLM *curl_multi;
/* Handle to the regex for dotplus (.+) replacement in HTML */
static regex_t re_dotplus;
+/* The users local GNS zone hash */
+static struct GNUNET_CRYPTO_ShortHashCode local_gns_zone;
+
+/* The CA for SSL certificate generation */
+static struct ProxyCA proxy_ca;
+
/**
* Checks if name is in tld
*
run_mhd (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
- struct MhdHttpList *hd;
+ struct MhdHttpList *hd = cls;
- for (hd=mhd_httpd_head; hd != NULL; hd = hd->next)
+ //for (hd=mhd_httpd_head; hd != NULL; hd = hd->next)
MHD_run (hd->daemon);
}
//GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
// "cURL chunk:\n%s\n", (char*)ctask->buffer);
- run_mhd (NULL, NULL);
+ //run_mhd (NULL, NULL);
+ GNUNET_SCHEDULER_add_now (&run_mhd, ctask->mhd);
return total;
}
{
struct ProxyCurlTask *ctask = cls;
- if (ctask->curl != NULL)
+ if (NULL != ctask->headers)
+ curl_slist_free_all (ctask->headers);
+
+ if (NULL != ctask->curl)
curl_easy_cleanup (ctask->curl);
+ ctask->curl = NULL;
+
GNUNET_free (ctask);
}
-
-
-
/**
* Shorten result callback
*
ctask->pp_finished = GNUNET_YES;
- GNUNET_SCHEDULER_add_now (&run_mhd, NULL);
+ GNUNET_SCHEDULER_add_now (&run_mhd, ctask->mhd);
}
ctask->download_in_progress = GNUNET_NO;
curl_multi_remove_handle (curl_multi, ctask->curl);
curl_easy_cleanup (ctask->curl);
- GNUNET_SCHEDULER_add_now (&run_mhd, NULL);
+ GNUNET_SCHEDULER_add_now (&run_mhd, ctask->mhd);
return MHD_CONTENT_READER_END_OF_STREAM;
}
ctask->download_in_progress = GNUNET_NO;
curl_multi_remove_handle (curl_multi, ctask->curl);
curl_easy_cleanup (ctask->curl);
- GNUNET_SCHEDULER_add_now (&run_mhd, NULL);
+ GNUNET_SCHEDULER_add_now (&run_mhd, ctask->mhd);
return MHD_CONTENT_READER_END_WITH_ERROR;
}
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Skipping next %d bytes in buffer\n", m[0].rm_eo);
- GNUNET_SCHEDULER_add_now (&run_mhd, NULL);
+ GNUNET_SCHEDULER_add_now (&run_mhd, ctask->mhd);
if ( strlen (ctask->pp_buf) <= max )
{
}
memset (ctask->pp_buf, 0, sizeof(ctask->pp_buf));
- memcpy (ctask->pp_buf, hostptr, (m[1].rm_eo-m[1].rm_so));
+
+ /* If .+ extend with authority */
+ if (0 == strcmp (ctask->buffer_ptr+m[1].rm_eo, "+"))
+ {
+ memcpy (ctask->pp_buf, hostptr, (m[1].rm_eo-m[1].rm_so));
+ strcpy ( ctask->pp_buf+strlen(ctask->pp_buf),
+ ctask->authority);
+ }
+ /* If .zkey simply copy the name */
+ else
+ {
+ memcpy (ctask->pp_buf, hostptr, (m[1].rm_eo-m[1].rm_so + strlen (GNUNET_TLD_ZKEY)));
+ }
ctask->is_postprocessing = GNUNET_YES;
ctask->pp_finished = GNUNET_NO;
+
+ GNUNET_GNS_shorten (gns_handle,
+ ctask->pp_buf,
+ &process_shorten,
+ ctask);
//postprocess_name(ctask, NULL);
- ctask->pp_task = GNUNET_SCHEDULER_add_now (&postprocess_name, ctask);
+ //ctask->pp_task = GNUNET_SCHEDULER_add_now (&postprocess_name, ctask);
return 0;
}
ctask->buf_status = BUF_WAIT_FOR_CURL;
ctask->buffer_ptr = ctask->buffer;
curl_easy_pause (ctask->curl, CURLPAUSE_CONT);
- GNUNET_SCHEDULER_add_now (&run_mhd, NULL);
+ GNUNET_SCHEDULER_add_now (&run_mhd, ctask->mhd);
}
}
- GNUNET_SCHEDULER_add_now (&run_mhd, NULL);
+ GNUNET_SCHEDULER_add_now (&run_mhd, ctask->mhd);
return copied;
}
curl_download_prepare();
}
+/**
+ * Process LEHO lookup
+ *
+ * @param cls the ctask
+ * @param rd_count number of records returned
+ * @param rd record data
+ */
+static void
+process_leho_lookup (void *cls,
+ uint32_t rd_count,
+ const struct GNUNET_NAMESTORE_RecordData *rd)
+{
+ struct ProxyCurlTask *ctask = cls;
+ char hosthdr[262]; //256 + "Host: "
+ int i;
+ CURLcode ret;
+ CURLMcode mret;
+ struct hostent *phost;
+ char *ssl_ip;
+ char resolvename[512];
+ char curlurl[512];
+
+ ctask->headers = NULL;
+
+ strcpy (ctask->leho, "");
+
+ for (i=0; i<rd_count; i++)
+ {
+ if (rd[i].record_type != GNUNET_GNS_RECORD_LEHO)
+ continue;
+
+ memcpy (ctask->leho, rd[i].data, rd[i].data_size);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Found LEHO %s for %s\n", ctask->leho, ctask->url);
+ }
+
+ if (0 != strcmp (ctask->leho, ""))
+ {
+ sprintf (hosthdr, "%s%s", "Host: ", ctask->leho);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "New HTTP header value: %s\n", hosthdr);
+ ctask->headers = curl_slist_append (ctask->headers, hosthdr);
+ GNUNET_assert (NULL != ctask->headers);
+ ret = curl_easy_setopt (ctask->curl, CURLOPT_HTTPHEADER, ctask->headers);
+ if (CURLE_OK != ret)
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s failed at %s:%d: `%s'\n",
+ "curl_easy_setopt", __FILE__, __LINE__, curl_easy_strerror(ret));
+ }
+
+ }
+
+ if (ctask->mhd->is_ssl)
+ {
+ phost = (struct hostent*)gethostbyname (ctask->host);
+ ssl_ip = inet_ntoa(*((struct in_addr*)(phost->h_addr)));
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "SSL target server: %s\n", ssl_ip);
+ sprintf (resolvename, "%s:%d:%s", ctask->leho, HTTPS_PORT, ssl_ip);
+ ctask->resolver = curl_slist_append ( ctask->resolver, resolvename);
+ curl_easy_setopt (ctask->curl, CURLOPT_RESOLVE, ctask->resolver);
+ sprintf (curlurl, "https://%s%s", ctask->leho, ctask->url);
+ curl_easy_setopt (ctask->curl, CURLOPT_URL, curlurl);
+ }
+
+ if (CURLM_OK != (mret=curl_multi_add_handle (curl_multi, ctask->curl)))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "%s failed at %s:%d: `%s'\n",
+ "curl_multi_add_handle", __FILE__, __LINE__,
+ curl_multi_strerror (mret));
+ ctask->download_successful = GNUNET_NO;
+ ctask->download_error = GNUNET_YES;
+ return;
+ }
+ GNUNET_CONTAINER_DLL_insert (ctasks_head, ctasks_tail, ctask);
+
+ curl_download_prepare ();
+
+}
+
/**
* Initialize download and trigger curl
*
*
*/
static void
-process_get_authority (void* cls,
+process_get_authority (void *cls,
const char* auth_name)
{
struct ProxyCurlTask *ctask = cls;
"Get authority yielded %s\n", auth_name);
strcpy (ctask->authority, auth_name);
- curl_download_prepare ();
+ GNUNET_GNS_lookup_zone (gns_handle,
+ ctask->host,
+ &local_gns_zone,
+ GNUNET_GNS_RECORD_LEHO,
+ &process_leho_lookup,
+ ctask);
}
/**
void **con_cls)
{
static int dummy;
+ struct MhdHttpList* hd = cls;
const char* page = "<html><head><title>gnoxy</title>"\
"</head><body>cURL fail</body></html>";
struct MHD_Response *response;
char curlurl[512];
int ret = MHD_YES;
- CURLMcode mret;
struct ProxyCurlTask *ctask;
if (0 != strcmp (meth, "GET"))
/* Do cURL */
ctask = GNUNET_malloc (sizeof (struct ProxyCurlTask));
+ ctask->mhd = hd;
ctask->curl = curl_easy_init();
if (curl_multi == NULL)
curl_easy_setopt (ctask->curl, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt (ctask->curl, CURLOPT_MAXREDIRS, 4);
/* no need to abort if the above failed */
- sprintf (curlurl, "http://%s%s", host, url);
+ if (GNUNET_NO == ctask->mhd->is_ssl)
+ sprintf (curlurl, "http://%s%s", host, url);
strcpy (ctask->host, host);
- strcpy (ctask->url, curlurl);
+ strcpy (ctask->url, url);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
"Adding new curl task for %s\n", curlurl);
curl_easy_setopt (ctask->curl, CURLOPT_CONNECTTIMEOUT, 600L);
curl_easy_setopt (ctask->curl, CURLOPT_TIMEOUT, 600L);
- mret = curl_multi_add_handle (curl_multi, ctask->curl);
-
- if (mret != CURLM_OK)
- {
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "%s failed at %s:%d: `%s'\n",
- "curl_multi_add_handle", __FILE__, __LINE__,
- curl_multi_strerror (mret));
- response = MHD_create_response_from_buffer (strlen (page),
- (void*)page,
- MHD_RESPMEM_PERSISTENT);
- ret = MHD_queue_response (con,
- MHD_HTTP_OK,
- response);
- MHD_destroy_response (response);
-
- curl_easy_cleanup (ctask->curl);
- GNUNET_free (ctask);
- return ret;
- }
-
- GNUNET_CONTAINER_DLL_insert (ctasks_head, ctasks_tail, ctask);
-
GNUNET_GNS_get_authority (gns_handle,
ctask->host,
&process_get_authority,
GNUNET_NETWORK_fdset_copy_native (wws, &ws, max + 1);
GNUNET_NETWORK_fdset_copy_native (wes, &es, max + 1);
- if (httpd_task != GNUNET_SCHEDULER_NO_TASK)
+ if (hd->httpd_task != GNUNET_SCHEDULER_NO_TASK)
GNUNET_SCHEDULER_cancel (hd->httpd_task);
hd->httpd_task =
GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_HIGH,
}
+/**
+ * Clean up s5r handles
+ *
+ * @param s5r the handle to destroy
+ */
+static void
+cleanup_s5r (struct Socks5Request *s5r)
+{
+ if (s5r->rtask != GNUNET_SCHEDULER_NO_TASK)
+ GNUNET_SCHEDULER_cancel (s5r->rtask);
+ if (s5r->fwdwtask != GNUNET_SCHEDULER_NO_TASK)
+ GNUNET_SCHEDULER_cancel (s5r->fwdwtask);
+ if (s5r->fwdrtask != GNUNET_SCHEDULER_NO_TASK)
+ GNUNET_SCHEDULER_cancel (s5r->fwdrtask);
+
+ if (NULL != s5r->remote_sock)
+ GNUNET_NETWORK_socket_close (s5r->remote_sock);
+ if ((NULL != s5r->sock) && (s5r->cleanup_sock == GNUNET_YES))
+ GNUNET_NETWORK_socket_close (s5r->sock);
+
+ GNUNET_free(s5r);
+}
+
/**
* Write data to socket
*
{
GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "write");
- //Really!?!?!?
- if (s5r->rtask != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (s5r->rtask);
- if (s5r->fwdwtask != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (s5r->fwdwtask);
- if (s5r->fwdrtask != GNUNET_SCHEDULER_NO_TASK)
- GNUNET_SCHEDULER_cancel (s5r->fwdrtask);
- GNUNET_NETWORK_socket_close (s5r->remote_sock);
- GNUNET_NETWORK_socket_close (s5r->sock);
- GNUNET_free(s5r);
+ s5r->cleanup = GNUNET_YES;
+ s5r->cleanup_sock = GNUNET_YES;
+ cleanup_s5r (s5r);
+
+ return;
+ }
+
+ if (GNUNET_YES == s5r->cleanup)
+ {
+ cleanup_s5r (s5r);
return;
}
return buffer;
}
+/** SSL stuff **/
+
+/**
+ * Load PEM key from file
+ *
+ * @param key where to store the data
+ * @param keyfile path to the PEM file
+ */
+static void
+load_key_from_file (gnutls_x509_privkey_t key, char* keyfile)
+{
+ gnutls_datum_t key_data;
+ int ret;
+
+ key_data.data = (unsigned char*)load_file (keyfile);
+ key_data.size = strlen ((char*)key_data.data);
+
+ ret = gnutls_x509_privkey_import (key, &key_data,
+ GNUTLS_X509_FMT_PEM);
+
+ if (GNUTLS_E_SUCCESS != ret)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unable to import private key %s\n", keyfile);
+ GNUNET_break (0);
+ }
+}
+
+/**
+ * Load cert from file
+ *
+ * @param crt struct to store data in
+ * @param certfile path to pem file
+ */
+static void
+load_cert_from_file (gnutls_x509_crt_t crt, char* certfile)
+{
+ gnutls_datum_t cert_data;
+ int ret;
+
+ cert_data.data = (unsigned char*)load_file (certfile);
+ cert_data.size = strlen ((char*)cert_data.data);
+
+ ret = gnutls_x509_crt_import (crt, &cert_data,
+ GNUTLS_X509_FMT_PEM);
+ if (GNUTLS_E_SUCCESS != ret)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unable to import certificate %s\n", certfile);
+ GNUNET_break (0);
+ }
+
+}
+
+
+/**
+ * Generate new certificate for specific name
+ *
+ * @param name the subject name to generate a cert for
+ * @return a struct holding the PEM data
+ */
+static struct ProxyGNSCertificate *
+generate_gns_certificate (const char *name)
+{
+
+ int ret;
+ unsigned int serial;
+ unsigned int bits;
+ size_t key_buf_size;
+ size_t cert_buf_size;
+ gnutls_x509_crt_t request;
+ gnutls_x509_privkey_t rsa;
+ time_t etime;
+ struct tm *tm_data;
+
+ ret = gnutls_x509_crt_init (&request);
+
+ if (GNUTLS_E_SUCCESS != ret)
+ {
+ GNUNET_break (0);
+ }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Generating key\n");
+ gnutls_x509_privkey_init (&rsa);
+ bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_RSA, GNUTLS_SEC_PARAM_NORMAL);
+ ret = gnutls_x509_privkey_generate (rsa, GNUTLS_PK_RSA, bits, 0);
+
+ if (GNUTLS_E_SUCCESS != ret)
+ {
+ GNUNET_break (0);
+ }
+
+ ret = gnutls_x509_crt_set_key (request, rsa);
+
+ if (GNUTLS_E_SUCCESS != ret)
+ {
+ GNUNET_break (0);
+ }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Generating cert\n");
+
+ struct ProxyGNSCertificate *pgc =
+ GNUNET_malloc (sizeof (struct ProxyGNSCertificate));
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding DNs\n");
+
+ gnutls_x509_crt_set_dn_by_oid (request, GNUTLS_OID_X520_COUNTRY_NAME,
+ 0, "DE", 2);
+
+ gnutls_x509_crt_set_dn_by_oid (request, GNUTLS_OID_X520_ORGANIZATION_NAME,
+ 0, "GNUnet", 6);
+
+ gnutls_x509_crt_set_dn_by_oid (request, GNUTLS_OID_X520_COMMON_NAME,
+ 0, name, strlen (name));
+
+ ret = gnutls_x509_crt_set_version (request, 3);
+
+ ret = gnutls_rnd (GNUTLS_RND_NONCE, &serial, sizeof (serial));
+
+ etime = time (NULL);
+ tm_data = localtime (&etime);
+
+
+ ret = gnutls_x509_crt_set_serial (request,
+ &serial,
+ sizeof (serial));
+
+ ret = gnutls_x509_crt_set_activation_time (request,
+ etime);
+ tm_data->tm_year++;
+ etime = mktime (tm_data);
+
+ if (-1 == etime)
+ {
+ GNUNET_break (0);
+ }
+
+ ret = gnutls_x509_crt_set_expiration_time (request,
+ etime);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Signing...\n");
+
+ ret = gnutls_x509_crt_sign (request, proxy_ca.cert, proxy_ca.key);
+
+ key_buf_size = sizeof (pgc->key);
+ cert_buf_size = sizeof (pgc->cert);
+
+ gnutls_x509_crt_export (request, GNUTLS_X509_FMT_PEM,
+ pgc->cert, &cert_buf_size);
+
+ gnutls_x509_privkey_export (rsa, GNUTLS_X509_FMT_PEM,
+ pgc->key, &key_buf_size);
+
+
+ gnutls_x509_crt_deinit (request);
+ gnutls_x509_privkey_deinit (rsa);
+
+ return pgc;
+
+}
+
+
/**
* Adds a socket to an SSL MHD instance
* It is important the the domain name is
add_handle_to_ssl_mhd (struct GNUNET_NETWORK_Handle *h, char* domain)
{
struct MhdHttpList *hd = NULL;
-
- static char *key_pem;
- static char *cert_pem;
-
- key_pem = load_file ("server.key");
- cert_pem = load_file ("server.pem");
+ struct ProxyGNSCertificate *pgc;
for (hd = mhd_httpd_head; hd != NULL; hd = hd->next)
{
if (NULL == hd)
{
/* Start new MHD */
- /* TODO: create cert, start SSL MHD */
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
- "No previous SSL instance found... starting new one\n");
+ "No previous SSL instance found... starting new one for %s\n",
+ domain);
+
+ pgc = generate_gns_certificate (domain);
+
hd = GNUNET_malloc (sizeof (struct MhdHttpList));
hd->is_ssl = GNUNET_YES;
strcpy (hd->domain, domain);
hd->daemon = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_SSL, http_port++,
NULL, NULL,
- &create_response, NULL,
+ &create_response, hd,
MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 128,
MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16,
MHD_OPTION_NOTIFY_COMPLETED,
NULL, NULL,
- MHD_OPTION_HTTPS_MEM_KEY, key_pem,
- MHD_OPTION_HTTPS_MEM_CERT, cert_pem,
+ MHD_OPTION_HTTPS_MEM_KEY, pgc->key,
+ MHD_OPTION_HTTPS_MEM_CERT, pgc->cert,
MHD_OPTION_END);
hd->httpd_task = GNUNET_SCHEDULER_NO_TASK;
_("Failed to start HTTP server\n"));
s_resp->version = 0x05;
s_resp->reply = 0x01;
+ s5r->cleanup = GNUNET_YES;
+ s5r->cleanup_sock = GNUNET_YES;
s5r->wtask =
GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
s5r->sock,
&do_write, s5r);
- //ERROR!
- //TODO! close socket after the write! schedule task
- //GNUNET_NETWORK_socket_close (s5r->sock);
- //GNUNET_free(s5r);
return;
}
s_resp->reply = 0x00;
s_resp->reserved = 0x00;
s_resp->addr_type = 0x01;
-
+
+ s5r->cleanup = GNUNET_YES;
+ s5r->cleanup_sock = GNUNET_NO;
s5r->wtask =
GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
s5r->sock,
&do_write, s5r);
run_httpds ();
- //GNUNET_free ( s5r );
- //FIXME complete socks resp!
return;
}
else
"Resolve %s error!\n", domain );
s_resp->version = 0x05;
s_resp->reply = 0x01;
+ s5r->cleanup = GNUNET_YES;
+ s5r->cleanup_sock = GNUNET_YES;
s5r->wtask =
GNUNET_SCHEDULER_add_write_net (GNUNET_TIME_UNIT_FOREVER_REL,
s5r->sock,
&do_write, s5r);
- //ERROR!
- //TODO! close socket after the write! schedule task
- //GNUNET_NETWORK_socket_close (s5r->sock);
- //GNUNET_free(s5r);
return;
}
struct MhdHttpList *hd;
struct MhdHttpList *tmp_hd;
+ struct ProxyCurlTask *ctask;
+ struct ProxyCurlTask *ctask_tmp;
if (GNUNET_SCHEDULER_NO_TASK != curl_download_task)
{
{
tmp_hd = hd->next;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Stopping daemon\n");
+
if (GNUNET_SCHEDULER_NO_TASK != hd->httpd_task)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Stopping select task %d\n",
+ hd->httpd_task);
GNUNET_SCHEDULER_cancel (hd->httpd_task);
hd->httpd_task = GNUNET_SCHEDULER_NO_TASK;
}
GNUNET_free (hd);
}
+
+ for (ctask=ctasks_head; ctask != NULL; ctask=ctask_tmp)
+ {
+ ctask_tmp = ctask->next;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Cleaning up cURL task\n");
+
+ if (ctask->curl != NULL)
+ curl_easy_cleanup (ctask->curl);
+ ctask->curl = NULL;
+ if (NULL != ctask->headers)
+ curl_slist_free_all (ctask->headers);
+
+ GNUNET_free (ctask);
+ }
+
+ GNUNET_GNS_disconnect (gns_handle);
}
}
+/**
+ * Loads the users local zone key
+ *
+ * @return GNUNET_YES on success
+ */
+static int
+load_local_zone_key (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ char *keyfile;
+ struct GNUNET_CRYPTO_RsaPrivateKey *key = NULL;
+ struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
+ struct GNUNET_CRYPTO_ShortHashCode *zone = NULL;
+ struct GNUNET_CRYPTO_ShortHashAsciiEncoded zonename;
+
+ if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg, "gns",
+ "ZONEKEY", &keyfile))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unable to load zone key config value!\n");
+ return GNUNET_NO;
+ }
+
+ if (GNUNET_NO == GNUNET_DISK_file_test (keyfile))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unable to load zone key!\n");
+ GNUNET_free(keyfile);
+ return GNUNET_NO;
+ }
+
+ key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
+ GNUNET_CRYPTO_rsa_key_get_public (key, &pkey);
+ GNUNET_CRYPTO_short_hash(&pkey,
+ sizeof(struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
+ &local_gns_zone);
+ zone = &local_gns_zone;
+ GNUNET_CRYPTO_short_hash_to_enc (zone, &zonename);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Using zone: %s!\n", &zonename);
+ GNUNET_CRYPTO_rsa_key_free(key);
+ GNUNET_free(keyfile);
+
+ return GNUNET_YES;
+}
+
+
+
/**
* Main function that will be run
*
struct sockaddr_in sa;
struct MhdHttpList *hd;
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Loading CA\n");
+
+ gnutls_global_init ();
+
+ load_cert_from_file (proxy_ca.cert, cafile);
+ load_key_from_file (proxy_ca.key, cafile);
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "Loading Template\n");
+
compile_regex (&re_dotplus, (char*) RE_DOTPLUS);
gns_handle = GNUNET_GNS_connect (cfg);
+ if (GNUNET_NO == load_local_zone_key (cfg))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Unable to load zone!\n");
+ return;
+ }
+
if (NULL == gns_handle)
{
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
strcpy (hd->domain, "");
httpd = MHD_start_daemon (MHD_USE_DEBUG, http_port++,
NULL, NULL,
- &create_response, NULL,
+ &create_response, hd,
MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 128,
MHD_OPTION_CONNECTION_TIMEOUT, (unsigned int) 16,
MHD_OPTION_NOTIFY_COMPLETED,
{'p', "port", NULL,
gettext_noop ("listen on specified port"), 1,
&GNUNET_GETOPT_set_string, &port},
+ {'a', "authority", NULL,
+ gettext_noop ("pem file to use as CA"), 1,
+ &GNUNET_GETOPT_set_string, &cafile},
GNUNET_GETOPT_OPTION_END
};
int ret;
+ if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
+ return 2;
+
GNUNET_log_setup ("gnunet-gns-proxy", "WARNING", NULL);
ret =
(GNUNET_OK ==