Пример #1
0
static void
ssl_openssl_close(PurpleSslConnection *gsc)
{
	PurpleSslOpensslData *openssl_data = PURPLE_SSL_OPENSSL_DATA(gsc);
	int i;

	if (openssl_data == NULL)
		return;

	if (openssl_data->handshake_handler)
		purple_input_remove(openssl_data->handshake_handler);

	if (openssl_data->ssl != NULL) {
		i = SSL_shutdown(openssl_data->ssl);
		if (i == 0)
			SSL_shutdown(openssl_data->ssl);
		SSL_free(openssl_data->ssl);
	}

	if (openssl_data->ssl_ctx != NULL)
		SSL_CTX_free(openssl_data->ssl_ctx);

	g_free(openssl_data);
	gsc->private_data = NULL;
}
Пример #2
0
/*
 * ssl_openssl_handshake_cb
 */
static void
ssl_openssl_handshake_cb(gpointer data, gint source, PurpleInputCondition cond)
{
	PurpleSslConnection *gsc = (PurpleSslConnection *)data;
	PurpleSslOpensslData *openssl_data = PURPLE_SSL_OPENSSL_DATA(gsc);
	int ret, ret2;

	purple_debug_info("openssl", "Connecting to %s\n", gsc->host);

	/*
	 * do the negotiation that sets up the SSL connection between
	 * here and there.
	 */
	ret = SSL_connect(openssl_data->ssl);
	if (ret <= 0) {
		ret2 = SSL_get_error(openssl_data->ssl, ret);

		if (ret2 == SSL_ERROR_WANT_READ || ret2 == SSL_ERROR_WANT_WRITE)
			return;

		purple_debug_error("openssl", "SSL_connect failed: %d\n",
		    ret2);

		if (gsc->error_cb != NULL)
			gsc->error_cb(gsc, PURPLE_SSL_HANDSHAKE_FAILED,
				gsc->connect_cb_data);

		purple_ssl_close(gsc);
		return;
	}

	purple_input_remove(openssl_data->handshake_handler);
	openssl_data->handshake_handler = 0;

	purple_debug_info("openssl", "Connected to %s\n", gsc->host);

	/* SSL connected now */
	gsc->connect_cb(gsc->connect_cb_data, gsc, cond);
}
Пример #3
0
static size_t
ssl_openssl_read(PurpleSslConnection *gsc, void *data, size_t len)
{
	PurpleSslOpensslData *openssl_data = PURPLE_SSL_OPENSSL_DATA(gsc);
	ssize_t s;
	int ret;

	s = SSL_read(openssl_data->ssl, data, len);
	if (s <= 0) {
		ret = SSL_get_error(openssl_data->ssl, s);

		if (ret == SSL_ERROR_WANT_READ || ret == SSL_ERROR_WANT_WRITE) {
			errno = EAGAIN;
			return (-1);
		}

		purple_debug_error("openssl", "receive failed: %d\n", s);
		s = 0;
	}

	return (s);
}
Пример #4
0
static size_t
ssl_openssl_write(PurpleSslConnection *gsc, const void *data, size_t len)
{
	PurpleSslOpensslData *openssl_data = PURPLE_SSL_OPENSSL_DATA(gsc);
	ssize_t s = 0;
	int ret;

	if (openssl_data != NULL)
		s = SSL_write(openssl_data->ssl, data, len);

	if (s <= 0) {
		ret = SSL_get_error(openssl_data->ssl, s);

		if (ret == SSL_ERROR_WANT_READ || ret == SSL_ERROR_WANT_WRITE) {
			errno = EAGAIN;
			return (-1);
		}

		purple_debug_error("openssl", "send failed: %s\n", ERR_error_string(ret, NULL));

		if (ret == SSL_ERROR_ZERO_RETURN) {
			s = 0;
			errno = ECONNRESET;

		} else {
			s = -1;
			/*
			 * TODO: Set errno to something more appropriate.  Or even
			 *       better: allow ssl plugins to keep track of their
			 *       own error message, then add a new ssl_ops function
			 *       that returns the error message.
			 */
			errno = EIO;
		}
	}

	return (s);
}