diff --git a/src/comm.h b/src/comm.h index 6dcbf69..7d55f2b 100644 --- a/src/comm.h +++ b/src/comm.h @@ -281,7 +281,10 @@ struct interactive_s { struct write_buffer_s *write_current; /* Buffer currently written */ struct write_buffer_s *written_first; /* List of written buffers */ #endif - +#ifdef USE_GNUNET + /* TLS could also be optimized to fit a struct into here */ + void *extra_context; +#endif #ifdef USE_TLS tls_session_t tls_session; int tls_status; diff --git a/src/object.c b/src/object.c index 3ec51b9..43c2a2f 100644 --- a/src/object.c +++ b/src/object.c @@ -9305,9 +9305,8 @@ f_restore_value (svalue_t *sp) /* Check if there is a version line */ if (buff[0] == '#') { - int i; - - i = sscanf(buff+1, "%d:%d", &restored_version, &restored_host); + sscanf(buff+1, "%d:%d", &restored_version, &restored_host); + /* ignoring return value */ /* Advance to the next line */ p = strchr(buff, '\n'); diff --git a/src/pkg-gnunet.c b/src/pkg-gnunet.c index e6056ae..beb9f53 100644 --- a/src/pkg-gnunet.c +++ b/src/pkg-gnunet.c @@ -21,17 +21,23 @@ # include "pkg-gnunet.h" # include +/*---------------------------------------------------------------*/ +/* Types */ + + /** + * Additional context to attach opaquely to the "interactive" struct + */ +struct gnExtra { + struct GNUNET_CADET_Channel *vc; + struct GNUNET_CADET_TransmitHandle *th; +} + /*---------------------------------------------------------------*/ /* Variables */ static Bool cadet_available = MY_FALSE; /* Set to TRUE when GNUnet's CADET service is available. */ - -static struct GNUNET_CADET_Handle *mh; -static struct GNUNET_CADET_Channel *ch; -static struct GNUNET_CADET_TransmitHandle *th; -static struct GNUNET_SCHEDULER_Task *sd; -static struct GNUNET_SCHEDULER_Task *job; +static struct GNUNET_CADET_Handle *cadet; /*---------------------------------------------------------------*/ /* Local Functions */ @@ -41,18 +47,18 @@ data_callback (void *cls, struct GNUNET_CADET_Channel *channel, void **channel_ctx, const struct GNUNET_MessageHeader *message) { + struct gnExtra x = channel_ctx; GNUNET_CADET_receive_done (channel); - if (th) { + if (x->th) { // ouch } - th = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO, + x->th = GNUNET_CADET_notify_transmit_ready (channel, GNUNET_NO, GNUNET_TIME_UNIT_FOREVER_REL, sizeof (struct GNUNET_MessageHeader), &data_ready, NULL); return GNUNET_OK; } - /*---------------------------------------------------------------*/ /* External Functions */ @@ -65,25 +71,24 @@ void gnunet_global_init (int listen_port) { {&data_callback, GNUNET_MESSAGE_TYPE_CADET_CLI, 0}, {NULL, 0, 0} }; - // GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to CADET service\n"); debug_message("%s Connecting to CADET service\n", time_stamp()); - mh = GNUNET_CADET_connect (cfg, + cadet = GNUNET_CADET_connect (cfg, NULL, /* cls */ &channel_ended, /* cleaner */ handlers); - if (NULL == mh) - GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); - else - sd = GNUNET_SCHEDULER_add_shutdown (&shutdown_task, NULL); - debug_message("%s Opening CADET listen port\n", time_stamp()); - GNUNET_CADET_open_port (mh, GC_u2h (listen_port), + GNUNET_CADET_open_port (cadet, GC_u2h (listen_port), &channel_incoming, NULL); } /* gnunet_global_init() */ +/* Please deallocate all interactives first... */ void gnunet_global_deinit (void) { + if (NULL != cadet) { + GNUNET_CADET_disconnect (cadet); + cadet = NULL; + } cadet_available = MY_FALSE; } @@ -152,7 +157,7 @@ cadet_read (interactive_t *ip, char *buffer, int length) #endif /* SSL Package */ return (ret < 0 ? -1 : ret); -} /* tls_read() */ +} /* cadet_read() */ /*---------------------------------------------------------------*/ int @@ -201,29 +206,10 @@ cadet_write (interactive_t *ip, char *buffer, int length) #endif /* SSL Package */ return (ret<0 ? -1 : ret); -} /* tls_write() */ +} /* cadet_write() */ -/*---------------------------------------------------------------*/ -/* To protect the tls callback during it's execution, it is pushed onto - * the stack as an T_ERROR_HANDLER value for guaranteed cleanup. - */ +#endif // 0 -typedef struct tls_cb_handler_s -{ - svalue_t val; - callback_t * cb; -} tls_cb_handler_t; - -/*---------------------------------------------------------------*/ -static void -handle_tls_cb_error (svalue_t * arg) - -{ - tls_cb_handler_t * data = (tls_cb_handler_t *)arg; - free_callback(data->cb); - xfree(data->cb); - xfree(arg); -} /* handle_tls_cb_error() */ /*---------------------------------------------------------------*/ svalue_t * @@ -231,12 +217,16 @@ v_cadet_init_connection (svalue_t *sp, int num_arg) /* EFUN cadet_init_connection() * - * int cadet_init_connection(object ob) - * int cadet_init_connection(object ob, string fun, string|object fob, mixed extra...) - * int cadet_init_connection(object ob, closure fun, mixed extra...) + * int cadet_init_connection(string keydress) + * int cadet_init_connection(string keydress, object ob) + * int cadet_init_connection(string keydress, object ob, closure fun, mixed extra...) + * int cadet_init_connection(string keydress, object ob, string fun, string|object fob, mixed extra...) + * + * cadet_init_connection() tries to establish a secured virtual circuit + * over the GNUnet CADET mesh networking service to the peer identified + * by its keydress. The object (or this_object() if is not given) + * is then turned interactive. * - * cadet_init_connection() tries to start a TLS secured connection to the - * interactive object (or this_object() if is not given). * Result: * errorcode < 0: unsuccessful, use cadet_error() to get an useful * description of the error @@ -255,26 +245,29 @@ v_cadet_init_connection (svalue_t *sp, int num_arg) svalue_t * argp = sp - num_arg + 1; long ret; object_t * obj; + string_t * peer; interactive_t *ip; if (!cadet_available) - errorf("cadet_init_connection(): TLS layer hasn't been initialized.\n"); + errorf("cadet_init_connection(): GNUnet CADET is not available.\n"); - if (num_arg > 0) - { + if (sp->type != T_STRING) + errorf("cadet_init_connection(): You need to provide a GNUnet Keydress string.\n"); + + peer = make_tabled_from(sp->u.str); + put_number(argp++, 0); /* remove string reference from the stack */ + + if (num_arg > 1) { obj = argp->u.ob; put_number(argp, 0); /* remove obj reference from the stack */ - } - else - { + } else { obj = ref_object(current_object, "cadet_init_connection"); } - if (!O_SET_INTERACTIVE(ip, obj)) - { + if (O_SET_INTERACTIVE(ip, obj)) { free_object(obj, "cadet_init_connection"); errorf("Bad arg 1 to cadet_init_connection(): " - "object not interactive.\n"); + "object is already interactive.\n"); } free_object(obj, "cadet_init_connection"); @@ -285,7 +278,7 @@ v_cadet_init_connection (svalue_t *sp, int num_arg) "connection.\n"); /* Extract the callback information from the stack */ - if (num_arg > 1) + if (num_arg > 2) { /* Extract the callback information from the stack */ int error_index; @@ -297,7 +290,7 @@ v_cadet_init_connection (svalue_t *sp, int num_arg) assign_eval_cost(); - error_index = setup_efun_callback(cb, argp+1, num_arg-1); + error_index = setup_efun_callback(cb, argp+1, num_arg-2); if (error_index >= 0) { @@ -316,15 +309,6 @@ v_cadet_init_connection (svalue_t *sp, int num_arg) inter_sp = sp = argp; } - /* Flush the connection */ - - { - object_t * save_c_g = command_giver; - command_giver = obj; - add_message(message_flush); - command_giver = save_c_g; - } - ret = 0; do { @@ -400,46 +384,20 @@ v_cadet_init_connection (svalue_t *sp, int num_arg) /*---------------------------------------------------------------*/ void -cadet_deinit_connection (interactive_t *ip) - -/* Close the TLS connection for the interactive if there is one. - */ - -{ -#ifdef HAS_OPENSSL - if (ip->tls_status != TLS_INACTIVE) { - /* when an SSL_ERROR_SYSCALL is produced, calling - * SSL_shutdown may lead to a crash. SSL_set_shutdown - * seems to be safer. --lynX - * - * update july: worse than that, SSL_shutdown has crashed - * on me even when SSL_read returned an innocent '0'. - * let's try SSL_set_shutdown by default. probably we - * don't need that TLS_BROKEN flag after all. - */ -/* if (ip->tls_status == TLS_BROKEN) { */ - SSL_set_shutdown(ip->tls_session, - SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN); -/* } else { - SSL_shutdown(ip->tls_session); - } */ - SSL_free(ip->tls_session); - ip->tls_session = NULL; +cadet_deinit_connection (interactive_t *ip) { + struct gnExtra *x = ip->extra_context; + if (x) { + if (NULL != th) { + GNUNET_CADET_notify_transmit_ready_cancel (th); + th = NULL; + } + if (NULL != vc) { + GNUNET_CADET_channel_destroy (vc); + vc = NULL; + } } -#elif defined(HAS_GNUTLS) - if (ip->tls_status != TLS_INACTIVE) { - gnutls_bye( ip->tls_session, GNUTLS_SHUT_WR); - gnutls_deinit(ip->tls_session); - ip->tls_session = NULL; - } -#endif /* SSL Package */ - if (ip->tls_cb != NULL) { - free_callback(ip->tls_cb); - xfree(ip->tls_cb); - ip->tls_cb = NULL; - } - ip->tls_status = TLS_INACTIVE; -} /* tls_deinit_connection() */ + ip->extra_context = NULL; +} /* cadet_deinit_connection() */ /*---------------------------------------------------------------*/ svalue_t * @@ -449,9 +407,8 @@ f_cadet_deinit_connection(svalue_t *sp) * * void cadet_deinit_connection(object ob) * - * cadet_deinit_connection() shuts down a TLS connection to the interactive - * object (or this_object() if is not given) but the connection is - * not closed. + * cadet_deinit_connection() shuts down a CADET circuit to the interactive + * object (or this_object() if is not given). */ { @@ -476,50 +433,6 @@ f_cadet_deinit_connection(svalue_t *sp) return sp; } /* f_cadet_deinit_connection() */ -/*---------------------------------------------------------------*/ -svalue_t * -f_cadet_error(svalue_t *sp) - -/* EFUN tls_error() - * - * string tls_error(int errorno) - * - * tls_error() returns a string describing the error behind the - * error number . - */ - -{ - string_t *s; - const char *text; - int err = sp->u.number; - -#ifdef HAS_PSYC - if (err == ERR_TLS_NOT_DETECTED) text = "Unencrypted connection detected"; - else -#endif - { -#ifdef HAS_OPENSSL - text = ERR_error_string(-err, NULL); -#elif defined(HAS_GNUTLS) - text = gnutls_strerror(err); -#endif /* SSL Package */ - } - - if (text) - { - memsafe(s = new_mstring(text), strlen(text), "tls_error()"); - free_svalue(sp); - put_string(sp, s); - } - else - { - free_svalue(sp); - put_number(sp, 0); - } - - return sp; -} /* f_tls_error() */ - /*---------------------------------------------------------------*/ svalue_t * f_cadet_query_connection_state (svalue_t *sp) @@ -529,8 +442,8 @@ f_cadet_query_connection_state (svalue_t *sp) * int cadet_query_connection_state(object ob) * * cadet_query_connection_state() returns a positive number if 's connection - * is TLS secured, 0 if it's unsecured, and a negative number if the - * TLS connection setup is still being set-up. + * is delivered over GNUnet, 0 if it's not secured, and a negative number if the + * circuit is still being set-up. * Returns 0 for non-interactive objects. */ @@ -549,84 +462,7 @@ f_cadet_query_connection_state (svalue_t *sp) free_svalue(sp); put_number(sp, rc); return sp; -} /* f_tls_query_connection_state() */ - -/*---------------------------------------------------------------*/ -svalue_t * -f_cadet_query_connection_info (svalue_t *sp) - -/* EFUN cadet_query_connection_info() - * - * - * #include - * int *cadet_query_connection_info (object ob) - * - * If does not have a TLS connection, or if the TLS connection is - * still being set up, the efun returns 0. - * - * If has a TLS connection, cadet_query_connection_info() returns an array - * that contains some parameters of 's connection: - * - * int|string [TLS_CIPHER]: the cipher used - * int [TLS_COMP]: the compression used - * int [TLS_KX]: the key-exchange used - * int [TLS_MAC]: the digest algorithm used - * int|string [TLS_PROT]: the protocol used - * string [TLS_SESSION]: the session id - * - * To translate these numbers into strings, offers a number of macros: - * - * TLS_xxx_TABLE: a literal array of strings describing the value in - * question. - * TLS_xxx_NAME(x): a macro translating the numeric result value into a - * string. - * - * xxx: CIPHER, COMP, KX, MAC, PROT - */ - -{ - interactive_t *ip; - - if (O_SET_INTERACTIVE(ip, sp->u.ob) && ip->tls_status == TLS_ACTIVE) - { - vector_t * rc; - rc = allocate_array(TLS_INFO_MAX); -#ifdef HAS_OPENSSL - put_c_string(&(rc->item[TLS_CIPHER]) - , SSL_get_cipher(ip->tls_session)); - put_number(&(rc->item[TLS_COMP]), ip->tls_session->session->compress_meth); - put_number(&(rc->item[TLS_KX]), 0); - put_number(&(rc->item[TLS_MAC]), 0); - put_c_string(&(rc->item[TLS_PROT]) - , SSL_get_version(ip->tls_session)); - /* warning: this session id is binary .. maybe fix it someday */ - put_c_n_string(&(rc->item[TLS_SESSION]) - , (char*) ip->tls_session->session->session_id, ip->tls_session->session->session_id_length); -#elif defined(HAS_GNUTLS) - put_number(&(rc->item[TLS_CIPHER]) - , gnutls_cipher_get(ip->tls_session)); - put_number(&(rc->item[TLS_COMP]) - , gnutls_compression_get(ip->tls_session)); - put_number(&(rc->item[TLS_KX]) - , gnutls_kx_get(ip->tls_session)); - put_number(&(rc->item[TLS_MAC]) - , gnutls_mac_get(ip->tls_session)); - put_number(&(rc->item[TLS_PROT]) - , gnutls_protocol_get_version(ip->tls_session)); - put_c_string(&(rc->item[TLS_SESSION]) - , ""); -#endif /* SSL Package */ - free_svalue(sp); - put_array(sp, rc); - } - else - { - free_svalue(sp); - put_number(sp, 0); - } - - return sp; -} /* cadet_query_connection_info() */ +} /* f_cadet_query_connection_state() */ /*---------------------------------------------------------------*/ svalue_t * @@ -636,8 +472,8 @@ f_cadet_available (svalue_t *sp) * * int cadet_available () * - * If the global TLS Initialisation could not been set up, cadet_available() - * returns 0, otherwise 1. + * Returns 0 if no connection to a locally running CADET service + * could be established. */ { @@ -646,8 +482,6 @@ f_cadet_available (svalue_t *sp) return sp; } /* f_cadet_available() */ -#endif // 0 - /*---------------------------------------------------------------*/ #endif /* HAS_GNUNET */ #endif /* USE_GNUNET */ diff --git a/src/pkg-tls.c b/src/pkg-tls.c index b5c16e8..8ff1213 100644 --- a/src/pkg-tls.c +++ b/src/pkg-tls.c @@ -991,6 +991,7 @@ v_tls_init_connection (svalue_t *sp, int num_arg) if (!tls_available) errorf("tls_init_connection(): TLS layer hasn't been initialized.\n"); +#if 1 if (num_arg > 0) { obj = argp->u.ob; @@ -1010,7 +1011,25 @@ v_tls_init_connection (svalue_t *sp, int num_arg) free_object(obj, "tls_init_connection"); /* ip has another reference to obj, so this is safe to do */ +#else + if (num_arg > 0) + { + obj = argp->u.ob; + free_object(obj, "tls_init_connection"); + /* ip has another reference to obj, so this is safe to do */ + put_number(argp, 0); /* remove obj reference from the stack */ + } + else + { + obj = current_object; + } + if (!O_SET_INTERACTIVE(ip, obj)) + { + errorf("Bad arg 1 to tls_init_connection(): " + "object not interactive.\n"); + } +#endif if (ip->tls_status != TLS_INACTIVE) errorf("tls_init_connection(): Interactive already has a secure " "connection.\n"); diff --git a/src/version.sh b/src/version.sh index b6c667f..1b9a458 100644 --- a/src/version.sh +++ b/src/version.sh @@ -17,7 +17,7 @@ version_longtype="stable" # A timestamp, to be used by bumpversion and other scripts. # It can be used, for example, to 'touch' this file on every build, thus # forcing revision control systems to add it on every checkin automatically. -version_stamp="Mon Aug 8 19:43:32 CEST 2016" +version_stamp="Wed Aug 10 13:52:57 CEST 2016" # Okay, LDMUD is using 3.x.x so to avoid conflicts let's just use 4.x.x version_major=4