X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=ssl.c;h=7c7548318ee169ff4fc2aed1f8e3ac114d3e2aed;hb=7d977044b91b7397600510842ff71d9693938a51;hp=2a456579aed878f94d91c619ce88b4c8671e255b;hpb=10b8f77aa8b747467bd0ab3152f37f66e5a3f1df;p=cascardo%2Frnetproxy.git diff --git a/ssl.c b/ssl.c index 2a45657..7c75483 100644 --- a/ssl.c +++ b/ssl.c @@ -19,194 +19,28 @@ */ #include -#include #include #include #include #include "ssl.h" -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - -struct ssl_data -{ - char *server; - gnutls_session_t session; - GString *buffer; - gboolean handshaking; -}; - -static struct ssl_data * -ssl_data_new (char *server) -{ - struct ssl_data *ssl; - int kx_prio[] = {GNUTLS_KX_RSA, 0}; - gnutls_certificate_credentials cred; - gnutls_certificate_allocate_credentials (&cred); - ssl = g_slice_new (struct ssl_data); - ssl->server = g_strdup (server); - gnutls_init (&ssl->session, GNUTLS_CLIENT); - gnutls_set_default_priority (ssl->session); - gnutls_set_default_priority (ssl->session); - gnutls_kx_set_priority (ssl->session, kx_prio); - gnutls_credentials_set (ssl->session, GNUTLS_CRD_CERTIFICATE, cred); - ssl->buffer = g_string_sized_new (4096); - ssl->handshaking = FALSE; - return ssl; -} - static void -ssl_data_destroy (struct ssl_data *ssl) -{ - gnutls_deinit (ssl->session); - g_free (ssl->server); - g_string_free (ssl->buffer, TRUE); - g_slice_free (struct ssl_data, ssl); -} - -static ssize_t -ssl_push (gnutls_transport_ptr_t ptr, const void *buffer, size_t len) -{ - net_hook_t *hook = ptr; - struct ssl_data *ssl = hook->data; - int r; - if (ssl->handshaking == TRUE) - { - g_io_channel_write_chars (hook->conn->iochannel, buffer, len, - &r, NULL); - return r; - } - gnet_conn_write (hook->conn, (void *) buffer, len); - return len; -} - -static ssize_t -ssl_pull (gnutls_transport_ptr_t ptr, void *buffer, size_t len) -{ - net_hook_t *hook = ptr; - struct ssl_data *ssl = hook->data; - int r; - if (ssl->handshaking == TRUE) - { - g_io_channel_read_chars (hook->conn->iochannel, buffer, len, - &r, NULL); - return r; - } - if (len > ssl->buffer->len) - { - r = ssl->buffer->len; - memcpy (buffer, ssl->buffer->str, r); - g_string_truncate (ssl->buffer, 0); - } - else - { - r = len; - memcpy (buffer, ssl->buffer->str, r); - g_string_erase (ssl->buffer, 0, r); - } - if (r == 0) - { - gnutls_transport_set_errno (ssl->session, EAGAIN); - return -1; - } - return r; -} - -static void -ssl_server_connect (net_hook_t *hook) +ssl_connect (net_hook_t *hook) { - struct ssl_data *ssl = hook->data; - int error; - gnutls_transport_set_ptr (ssl->session, (gnutls_transport_ptr_t) hook); - gnutls_transport_set_push_function (ssl->session, ssl_push); - gnutls_transport_set_pull_function (ssl->session, ssl_pull); - ssl->handshaking = TRUE; - if ((error = gnutls_handshake (ssl->session)) < 0) - { - g_message ("%satal error while doing TLS handshaking.\n", - gnutls_error_is_fatal (error) ? "F" : "Nonf"); - g_message ("%s\n", gnutls_strerror (error)); - } - ssl->handshaking = FALSE; } static void -ssl_server_close (net_hook_t *hook) +ssl_close (net_hook_t *hook) { - struct ssl_data *ssl = hook->data; if (hook->peer) { hook->peer->peer = NULL; - gnet_conn_disconnect (hook->peer->conn); - } - gnet_conn_delete (hook->conn); - if (ssl != NULL) - { - gnutls_bye (ssl->session, GNUTLS_SHUT_RDWR); - ssl_data_destroy (ssl); + hc_conn_close (hook->peer->conn); } + hc_conn_close (hook->conn); g_slice_free (net_hook_t, hook); } -static void -ssl_server_write (net_hook_t *hook) -{ -} - -static void -ssl_server_read (net_hook_t *hook, gchar *buffer, size_t len) -{ - struct ssl_data *ssl = hook->data; - int r; - g_string_append_len (ssl->buffer, buffer, len); - do - { - r = gnutls_record_recv (ssl->session, buffer, len); - if (r > 0) - gnet_conn_write (hook->peer->conn, buffer, r); - } while (r > 0); -} - -static void -ssl_server_error (net_hook_t *hook) -{ - g_message ("Error in POP3 client connection."); -} - -static net_hook_t * -ssl_server_hook_new (net_hook_t *client_hook, char *server) -{ - net_hook_t *hook; - hook = g_slice_new (net_hook_t); - hook->conn = gnet_conn_new (server, 995, nethook_event, hook); - hook->peer = client_hook; - hook->server = TRUE; - hook->connect = ssl_server_connect; - hook->close = ssl_server_close; - hook->write = ssl_server_write; - hook->read = ssl_server_read; - hook->data = ssl_data_new (server); - gnet_conn_connect (hook->conn); - gnet_conn_read (hook->conn); - return hook; -} - -static void -ssl_connect (net_hook_t *hook) -{ -} - -static void -ssl_close (net_hook_t *hook) -{ -} - -static void -ssl_write (net_hook_t *hook) -{ -} - static void ssl_read (net_hook_t *hook, gchar *buffer, size_t len) { @@ -220,7 +54,7 @@ ssl_error (net_hook_t *hook) } net_hook_t * -ssl_hook_new (GConn *conn, char *server) +ssl_hook_new (HCConn *conn, char *server, char *port) { net_hook_t *hook; hook = g_slice_new (net_hook_t); @@ -229,11 +63,10 @@ ssl_hook_new (GConn *conn, char *server) hook->server = FALSE; hook->connect = ssl_connect; hook->close = ssl_close; - hook->write = ssl_write; hook->read = ssl_read; hook->data = NULL; - hook->peer = ssl_server_hook_new (hook, server); - gnet_conn_set_callback (hook->conn, nethook_event, hook); + hook->peer = ssl_server_hook_new (hook, server, port); + hc_conn_set_callback (hook->conn, nethook_event, hook); return hook; }