Example #1
0
void* connection_thread(void* arg) {
  int sd;
  gnutls_session_t session;
  pp_session_t ppsession;
  int ret;

  sd = (int)(long)arg;

  ret = initialize_tls_session(&session);
  if (ret != GNUTLS_E_SUCCESS) {
    fprintf(stderr, "Error initializing TLS session\n");
    return (void *)(long)ret;
  }
  gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t)(long)sd);

  memset(&ppsession, '\0', sizeof(pp_session_t));
  ppsession.cfg = &cfg;
  gnutls_session_set_ptr(session, &ppsession);

  ret = do_proxy(session);
  if (ret != GNUTLS_E_SUCCESS)
    fprintf(stderr, "- Proxy exited with failure\n");

  close((int)(long)gnutls_transport_get_ptr(session));
  gnutls_deinit(session);

  return 0;
}
Example #2
0
static int gnutls_GetFD(vlc_tls_t *tls)
{
    gnutls_session_t session = tls->sys;
    vlc_tls_t *sock = gnutls_transport_get_ptr(session);

    return vlc_tls_GetFD(sock);
}
Example #3
0
static gint ssl_read(gnutls_session_t ssl, gchar *buf, gint len)
{
	gint r;

	if (gnutls_record_check_pending(ssl) == 0) {
		if (fd_check_io(GPOINTER_TO_INT(gnutls_transport_get_ptr(ssl)), G_IO_IN) < 0)
			return -1;
	}

	while (1) {
		r = gnutls_record_recv(ssl, buf, len);
		if (r > 0)
			return r;

		switch (r) {
		case 0: /* closed connection */
			return -1;

		case GNUTLS_E_REHANDSHAKE:
			do {
				r = gnutls_handshake(ssl);
			} while (r == GNUTLS_E_AGAIN || r == GNUTLS_E_INTERRUPTED);
			break; /* re-receive */
		case GNUTLS_E_AGAIN:
		case GNUTLS_E_INTERRUPTED:
			errno = EAGAIN;
			return -1;

		default:
			return -1;
		}
	}

}
Example #4
0
test_code_t
test_bye (gnutls_session_t session)
{
  int ret;
  char data[20];
  int secs = 6;
#ifndef _WIN32
  int old;

  signal (SIGALRM, got_alarm);
#endif

  sprintf (prio_str, INIT_STR
           ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS ":"
           ALL_KX ":%s", protocol_str, rest);
  _gnutls_priority_set_direct (session, prio_str);

  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);

  ret = do_handshake (session);
  if (ret == TEST_FAILED)
    return ret;

  ret = gnutls_bye (session, GNUTLS_SHUT_WR);
  if (ret < 0)
    return TEST_FAILED;

#ifndef _WIN32
  old = siginterrupt (SIGALRM, 1);
  alarm (secs);
#else
  setsockopt ((int) gnutls_transport_get_ptr (session), SOL_SOCKET,
              SO_RCVTIMEO, (char *) &secs, sizeof (int));
#endif

  do
    {
      ret = gnutls_record_recv (session, data, sizeof (data));
    }
  while (ret > 0);

#ifndef _WIN32
  siginterrupt (SIGALRM, old);
#else
  if (WSAGetLastError () == WSAETIMEDOUT ||
      WSAGetLastError () == WSAECONNABORTED)
    alrm = 1;
#endif
  if (ret == 0)
    return TEST_SUCCEED;

  if (alrm == 0)
    return TEST_UNSURE;

  return TEST_FAILED;
}
Example #5
0
test_code_t
test_bye (gnutls_session session)
{
  int ret;
  char data[20];
  int old, secs = 6;

#ifndef _WIN32
  signal (SIGALRM, got_alarm);
#endif

  ADD_ALL_CIPHERS (session);
  ADD_ALL_COMP (session);
  ADD_ALL_CERTTYPES (session);
  ADD_ALL_PROTOCOLS (session);
  ADD_ALL_MACS (session);
  ADD_ALL_KX (session);
  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred);

  ret = do_handshake (session);
  if (ret == TEST_FAILED)
    return ret;

  ret = gnutls_bye (session, GNUTLS_SHUT_WR);
  if (ret < 0)
    return TEST_FAILED;

#ifndef _WIN32
  old = siginterrupt (SIGALRM, 1);
  alarm (secs);
#else
  setsockopt (gnutls_transport_get_ptr (session), SOL_SOCKET, SO_RCVTIMEO,
	      (char *) &secs, sizeof (int));
#endif

  do
    {
      ret = gnutls_record_recv (session, data, sizeof (data));
    }
  while (ret > 0);

#ifndef _WIN32
  siginterrupt (SIGALRM, old);
#else
  if (WSAGetLastError () == WSAETIMEDOUT ||
      WSAGetLastError () == WSAECONNABORTED)
    alrm = 1;
#endif
  if (ret == 0)
    return TEST_SUCCEED;

  if (alrm == 0)
    return TEST_UNSURE;

  return TEST_FAILED;
}
static int
g_tls_server_connection_gnutls_retrieve_function (gnutls_session_t             session,
                                                  const gnutls_datum_t        *req_ca_rdn,
                                                  int                          nreqs,
                                                  const gnutls_pk_algorithm_t *pk_algos,
                                                  int                          pk_algos_length,
                                                  gnutls_retr2_st             *st)
{
  g_tls_connection_gnutls_get_certificate (gnutls_transport_get_ptr (session), st);
  return 0;
}
Example #7
0
void
cib_remote_connection_destroy(gpointer user_data)
{
    crm_client_t *client = user_data;
    int csock = 0;

    if (client == NULL) {
        return;
    }

    crm_trace("Cleaning up after client disconnect: %s/%s", crm_str(client->name), client->id);

    num_clients--;
    crm_trace("Num unfree'd clients: %d", num_clients);

    switch (client->kind) {
        case CRM_CLIENT_TCP:
            csock = client->remote->tcp_socket;
            break;
#ifdef HAVE_GNUTLS_GNUTLS_H
        case CRM_CLIENT_TLS:
            if (client->remote->tls_session) {
                void *sock_ptr = gnutls_transport_get_ptr(*client->remote->tls_session);

                csock = GPOINTER_TO_INT(sock_ptr);
                if (client->remote->tls_handshake_complete) {
                    gnutls_bye(*client->remote->tls_session, GNUTLS_SHUT_WR);
                }
                gnutls_deinit(*client->remote->tls_session);
                gnutls_free(client->remote->tls_session);
                client->remote->tls_session = NULL;
            }
            break;
#endif
        default:
            crm_warn("Unexpected client type %d", client->kind);
    }

    if (csock > 0) {
        close(csock);
    }

    crm_client_destroy(client);

    crm_trace("Freed the cib client");

    if (cib_shutdown_flag) {
        cib_shutdown(0);
    }
    return;
}
Example #8
0
static gint ssl_write(gnutls_session_t ssl, const gchar *buf, gint len)
{
	gint ret;

	if (fd_check_io(GPOINTER_TO_INT(gnutls_transport_get_ptr(ssl)), G_IO_OUT) < 0)
		return -1;

	ret = gnutls_record_send(ssl, buf, len);

	switch (ret) {
	case 0:
		return -1;
	case GNUTLS_E_AGAIN:
	case GNUTLS_E_INTERRUPTED:
		return 0;

	default:
		return ret;
	}
}
static int
g_tls_client_connection_gnutls_retrieve_function (gnutls_session_t             session,
						  const gnutls_datum_t        *req_ca_rdn,
						  int                          nreqs,
						  const gnutls_pk_algorithm_t *pk_algos,
						  int                          pk_algos_length,
						  gnutls_retr2_st             *st)
{
  GTlsClientConnectionGnutls *gnutls = gnutls_transport_get_ptr (session);
  GTlsConnectionGnutls *conn = G_TLS_CONNECTION_GNUTLS (gnutls);
  GPtrArray *accepted_cas;
  GByteArray *dn;
  int i;

  gnutls->priv->cert_requested = TRUE;

  accepted_cas = g_ptr_array_new_with_free_func ((GDestroyNotify)g_byte_array_unref);
  for (i = 0; i < nreqs; i++)
    {
      dn = g_byte_array_new ();
      g_byte_array_append (dn, req_ca_rdn[i].data, req_ca_rdn[i].size);
      g_ptr_array_add (accepted_cas, dn);
    }

  if (gnutls->priv->accepted_cas)
    g_ptr_array_unref (gnutls->priv->accepted_cas);
  gnutls->priv->accepted_cas = accepted_cas;
  g_object_notify (G_OBJECT (gnutls), "accepted-cas");

  g_tls_connection_gnutls_get_certificate (conn, st);

  if (st->ncerts == 0)
    {
      g_clear_error (&gnutls->priv->cert_error);
      if (g_tls_connection_gnutls_request_certificate (conn, &gnutls->priv->cert_error))
        g_tls_connection_gnutls_get_certificate (conn, st);
    }

  return 0;
}
Example #10
0
static void
lrmd_remote_client_destroy(gpointer user_data)
{
    crm_client_t *client = user_data;

    if (client == NULL) {
        return;
    }

    crm_notice("Cleaning up after remote client %s disconnected "
               CRM_XS " id=%s",
               (client->name? client->name : ""), client->id);

    ipc_proxy_remove_provider(client);

    /* if this is the last remote connection, stop recurring
     * operations */
    if (crm_hash_table_size(client_connections) == 1) {
        client_disconnect_cleanup(NULL);
    }

    if (client->remote->tls_session) {
        void *sock_ptr;
        int csock;

        sock_ptr = gnutls_transport_get_ptr(*client->remote->tls_session);
        csock = GPOINTER_TO_INT(sock_ptr);

        gnutls_bye(*client->remote->tls_session, GNUTLS_SHUT_RDWR);
        gnutls_deinit(*client->remote->tls_session);
        gnutls_free(client->remote->tls_session);
        close(csock);
    }

    lrmd_client_destroy(client);
    return;
}
void
BIO_get_fd (gnutls_session_t gnutls_state, int *fd)
{
  gnutls_transport_ptr_t tmp = gnutls_transport_get_ptr (gnutls_state);
  *fd = GNUTLS_POINTER_TO_INT (tmp);
}
Example #12
0
/*!
 * \internal
 * \brief Determine if a remote session has data to read
 *
 * \retval 0, timeout occured.
 * \retval positive, data is ready to be read
 * \retval negative, session has ended
 */
int
crm_remote_ready(crm_remote_t * remote, int timeout /* ms */ )
{
    struct pollfd fds = { 0, };
    int sock = 0;
    int rc = 0;
    time_t start;

#ifdef HAVE_GNUTLS_GNUTLS_H
    if (remote->tls_session) {
        void *sock_ptr = gnutls_transport_get_ptr(*remote->tls_session);

        sock = GPOINTER_TO_INT(sock_ptr);
    } else if (remote->tcp_socket) {
#else
    if (remote->tcp_socket) {
#endif
        sock = remote->tcp_socket;
    } else {
        crm_err("Unsupported connection type");
    }

    if (sock <= 0) {
        crm_trace("No longer connected");
        return -ENOTCONN;
    }

    start = time(NULL);
    errno = 0;
    do {
        fds.fd = sock;
        fds.events = POLLIN;

        /* If we got an EINTR while polling, and we have a
         * specific timeout we are trying to honor, attempt
         * to adjust the timeout to the closest second. */
        if (errno == EINTR && (timeout > 0)) {
            timeout = timeout - ((time(NULL) - start) * 1000);
            if (timeout < 1000) {
                timeout = 1000;
            }
        }

        rc = poll(&fds, 1, timeout);
    } while (rc < 0 && errno == EINTR);

    return rc;
}


/*!
 * \internal
 * \brief Read bytes off non blocking remote connection.
 *
 * \note only use with NON-Blocking sockets. Should only be used after polling socket.
 *       This function will return once max_size is met, the socket read buffer
 *       is empty, or an error is encountered.
 *
 * \retval number of bytes received
 */
static size_t
crm_remote_recv_once(crm_remote_t * remote)
{
    int rc = 0;
    size_t read_len = sizeof(struct crm_remote_header_v0);
    struct crm_remote_header_v0 *header = crm_remote_header(remote);

    if(header) {
        /* Stop at the end of the current message */
        read_len = header->size_total;
    }

    /* automatically grow the buffer when needed */
    if(remote->buffer_size < read_len) {
           remote->buffer_size = 2 * read_len;
        crm_trace("Expanding buffer to %u bytes", remote->buffer_size);

        remote->buffer = realloc_safe(remote->buffer, remote->buffer_size + 1);
        CRM_ASSERT(remote->buffer != NULL);
    }

#ifdef HAVE_GNUTLS_GNUTLS_H
    if (remote->tls_session) {
        rc = gnutls_record_recv(*(remote->tls_session),
                                remote->buffer + remote->buffer_offset,
                                remote->buffer_size - remote->buffer_offset);
        if (rc == GNUTLS_E_INTERRUPTED) {
            rc = -EINTR;
        } else if (rc == GNUTLS_E_AGAIN) {
            rc = -EAGAIN;
        } else if (rc < 0) {
            crm_debug("TLS receive failed: %s (%d)", gnutls_strerror(rc), rc);
            rc = -pcmk_err_generic;
        }
    } else if (remote->tcp_socket) {
#else
    if (remote->tcp_socket) {
#endif
        errno = 0;
        rc = read(remote->tcp_socket,
                  remote->buffer + remote->buffer_offset,
                  remote->buffer_size - remote->buffer_offset);
        if(rc < 0) {
            rc = -errno;
        }

    } else {
        crm_err("Unsupported connection type");
        return -ESOCKTNOSUPPORT;
    }

    /* process any errors. */
    if (rc > 0) {
        remote->buffer_offset += rc;
        /* always null terminate buffer, the +1 to alloc always allows for this. */
        remote->buffer[remote->buffer_offset] = '\0';
        crm_trace("Received %u more bytes, %u total", rc, remote->buffer_offset);

    } else if (rc == -EINTR || rc == -EAGAIN) {
        crm_trace("non-blocking, exiting read: %s (%d)", pcmk_strerror(rc), rc);

    } else if (rc == 0) {
        crm_debug("EOF encoutered after %u bytes", remote->buffer_offset);
        return -ENOTCONN;

    } else {
        crm_debug("Error receiving message after %u bytes: %s (%d)",
                  remote->buffer_offset, pcmk_strerror(rc), rc);
        return -ENOTCONN;
    }

    header = crm_remote_header(remote);
    if(header) {
        if(remote->buffer_offset < header->size_total) {
            crm_trace("Read less than the advertised length: %u < %u bytes",
                      remote->buffer_offset, header->size_total);
        } else {
            crm_trace("Read full message of %u bytes", remote->buffer_offset);
            return remote->buffer_offset;
        }
    }

    return -EAGAIN;
}

/*!
 * \internal
 * \brief Read data off the socket until at least one full message is present or timeout occures.
 * \retval TRUE message read
 * \retval FALSE full message not read
 */

gboolean
crm_remote_recv(crm_remote_t * remote, int total_timeout /*ms */ , int *disconnected)
{
    int rc;
    time_t start = time(NULL);
    int remaining_timeout = 0;

    if (total_timeout == 0) {
        total_timeout = 10000;
    } else if (total_timeout < 0) {
        total_timeout = 60000;
    }
    *disconnected = 0;

    remaining_timeout = total_timeout;
    while ((remaining_timeout > 0) && !(*disconnected)) {

        /* read some more off the tls buffer if we still have time left. */
        crm_trace("waiting to receive remote msg, starting timeout %d, remaining_timeout %d",
                  total_timeout, remaining_timeout);
        rc = crm_remote_ready(remote, remaining_timeout);

        if (rc == 0) {
            crm_err("poll timed out (%d ms) while waiting to receive msg", remaining_timeout);
            return FALSE;

        } else if(rc < 0) {
            crm_debug("poll() failed: %s (%d)", pcmk_strerror(rc), rc);

        } else {
            rc = crm_remote_recv_once(remote);
            if(rc > 0) {
                return TRUE;
            } else if (rc < 0) {
                crm_debug("recv() failed: %s (%d)", pcmk_strerror(rc), rc);
            }
        }

        if(rc == -ENOTCONN) {
            *disconnected = 1;
            return FALSE;
        }

        remaining_timeout = remaining_timeout - ((time(NULL) - start) * 1000);
    }

    return FALSE;
}
gnutls_transport_ptr_t session::get_transport_ptr () const
{
    return gnutls_transport_get_ptr (s);
}
Example #14
0
static void onion_ssl_close(gnutls_session_t s){
	int fd=(long int)gnutls_transport_get_ptr(s);
	gnutls_bye (s, GNUTLS_SHUT_WR);
	gnutls_deinit (s);
	onion_close_socket((void*)(long int)fd);
}
Example #15
0
void
BIO_get_fd (gnutls_session_t gnutls_state, int *fd)
{
  *fd = GNUTLS_POINTER_TO_INT (gnutls_transport_get_ptr (gnutls_state));
}
Example #16
0
static int
tds_verify_certificate(gnutls_session_t session)
{
	unsigned int status;
	int ret;
	TDSSOCKET *tds = (TDSSOCKET *) gnutls_transport_get_ptr(session);

#ifdef ENABLE_DEVELOPING
	unsigned int list_size;
	const gnutls_datum_t *cert_list;
#endif

	if (!tds->login)
		return GNUTLS_E_CERTIFICATE_ERROR;

	ret = gnutls_certificate_verify_peers2(session, &status);
	if (ret < 0) {
		tdsdump_log(TDS_DBG_ERROR, "Error verifying certificate: %s\n", gnutls_strerror(ret));
		return GNUTLS_E_CERTIFICATE_ERROR;
	}

#ifdef ENABLE_DEVELOPING
	cert_list = gnutls_certificate_get_peers(session, &list_size);
	if (cert_list) {
		gnutls_x509_crt_t cert;
		gnutls_datum_t cinfo;
		char buf[8192];
		size_t size;

		gnutls_x509_crt_init(&cert);

		gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER);

		/* This is the preferred way of printing short information about
		 * a certificate. */
		size = sizeof(buf);
		ret = gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_PEM, buf, &size);
		if (ret == 0) {
			FILE *f = fopen("cert.dat", "wb");
			if (f) {
				fwrite(buf, size, 1, f);
				fclose(f);
			}
		}

		ret = gnutls_x509_crt_print(cert, GNUTLS_CRT_PRINT_ONELINE, &cinfo);
		if (ret == 0) {
			tdsdump_log(TDS_DBG_INFO1, "Certificate info: %s\n", cinfo.data);
			gnutls_free(cinfo.data);
		}

		gnutls_x509_crt_deinit(cert);
	}
#endif

	/* Certificate is not trusted */
	if (status != 0) {
		tdsdump_log(TDS_DBG_ERROR, "Certificate status: %u\n", status);
		return GNUTLS_E_CERTIFICATE_ERROR;
	}

	/* check hostname */
	if (tds->login->check_ssl_hostname) {
		const gnutls_datum_t *cert_list;
		unsigned int list_size;
		gnutls_x509_crt_t cert;

		cert_list = gnutls_certificate_get_peers(session, &list_size);
		if (!cert_list) {
			tdsdump_log(TDS_DBG_ERROR, "Error getting TLS session peers\n");
			return GNUTLS_E_CERTIFICATE_ERROR;
		}
		gnutls_x509_crt_init(&cert);
		gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER);
		ret = gnutls_x509_crt_check_hostname(cert, tds_dstr_cstr(&tds->login->server_host_name));
		gnutls_x509_crt_deinit(cert);
		if (!ret) {
			tdsdump_log(TDS_DBG_ERROR, "Certificate hostname does not match\n");
			return GNUTLS_E_CERTIFICATE_ERROR;
		}
	}

	/* notify gnutls to continue handshake normally */
	return 0;
}
Example #17
0
/* This is a send function for the gnutls handshake
 * protocol. Just makes sure that all data have been sent.
 */
ssize_t
_gnutls_handshake_io_send_int (gnutls_session_t session,
                               content_type_t type,
                               gnutls_handshake_description_t htype,
                               const void *iptr, size_t n)
{
    size_t left;
    ssize_t ret = 0;
    const opaque *ptr;
    ssize_t retval = 0;

    ptr = iptr;

    if (session->internals.handshake_send_buffer.length > 0 && ptr == NULL
            && n == 0)
    {
        /* resuming previously interrupted write
         */
        gnutls_assert ();
        ret =
            _gnutls_buffer_get (&session->internals.handshake_send_buffer,
                                &ptr, &n);
        if (ret < 0)
        {
            gnutls_assert ();
            return retval;
        }

        type = session->internals.handshake_send_buffer_type;
        htype = session->internals.handshake_send_buffer_htype;

    }
    else if (session->internals.handshake_send_buffer.length > 0)
    {
        gnutls_assert ();
        return GNUTLS_E_INTERNAL_ERROR;
    }
#ifdef WRITE_DEBUG
    else
    {
        size_t sum = 0, x, j;

        _gnutls_write_log ("HWRITE: will write %d bytes to %d.\n", n,
                           gnutls_transport_get_ptr (session));
        for (x = 0; x < ((n) / 16) + 1; x++)
        {
            if (sum > n)
                break;

            _gnutls_write_log ("%.4x - ", x);
            for (j = 0; j < 16; j++)
            {
                if (sum < n)
                {
                    _gnutls_write_log ("%.2x ", ((unsigned char *) ptr)[sum++]);
                }
                else
                    break;
            }
            _gnutls_write_log ("\n");
        }
        _gnutls_write_log ("\n");
    }
#endif

    if (n == 0)
    {   /* if we have no data to send */
        gnutls_assert ();
        return 0;
    }
    else if (ptr == NULL)
    {
        gnutls_assert ();
        return GNUTLS_E_INTERNAL_ERROR;
    }


    left = n;
    while (left > 0)
    {
        ret = _gnutls_send_int (session, type, htype, &ptr[n - left], left);

        if (ret <= 0)
        {
            if (ret == 0)
            {
                gnutls_assert ();
                ret = GNUTLS_E_INTERNAL_ERROR;
            }

            if (left > 0
                    && (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN))
            {
                gnutls_assert ();

                retval =
                    _gnutls_buffer_insert (&session->internals.
                                           handshake_send_buffer,
                                           &ptr[n - left], left);
                if (retval < 0)
                {
                    gnutls_assert ();
                    return retval;
                }

                session->internals.handshake_send_buffer_prev_size += n - left;

                session->internals.handshake_send_buffer_type = type;
                session->internals.handshake_send_buffer_htype = htype;

            }
            else
            {
                session->internals.handshake_send_buffer_prev_size = 0;
                session->internals.handshake_send_buffer.length = 0;
            }

            gnutls_assert ();
            return ret;
        }
        left -= ret;
    }

    retval = n + session->internals.handshake_send_buffer_prev_size;

    session->internals.handshake_send_buffer.length = 0;
    session->internals.handshake_send_buffer_prev_size = 0;

    return retval;

}