sharing: Add TLS certificate generation implementation
This copies TLS certificate generation implementation from https://gitlab.gnome.org/chergert/bonsai. No changes were made other than ones required for making it build as part of gnome-control-center's sharing panel. It's currently not suitable to depend on libbonsai, as it will likely see big changes before seeing a release.
This commit is contained in:
parent
0ae59467fb
commit
5eb46ec1b7
3 changed files with 581 additions and 1 deletions
511
panels/sharing/cc-tls-certificate.c
Normal file
511
panels/sharing/cc-tls-certificate.c
Normal file
|
@ -0,0 +1,511 @@
|
|||
/* cc-tls-certificate.c
|
||||
*
|
||||
* Copyright 2018 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <gnutls/x509.h>
|
||||
|
||||
#include "cc-tls-certificate.h"
|
||||
|
||||
#define DEFAULT_KEY_SIZE 4096
|
||||
#define DEFAULT_EXPIRATION (60L*60L*24L*5L*365L)
|
||||
|
||||
static void
|
||||
_gnutls_datum_clear (gnutls_datum_t *datum)
|
||||
{
|
||||
if (datum->data != NULL)
|
||||
gnutls_free (datum->data);
|
||||
}
|
||||
|
||||
static void
|
||||
_gnutls_crt_free (gnutls_x509_crt_t *cert)
|
||||
{
|
||||
if (cert != NULL)
|
||||
gnutls_x509_crt_deinit (*cert);
|
||||
}
|
||||
|
||||
static void
|
||||
_gnutls_privkey_free (gnutls_x509_privkey_t *privkey)
|
||||
{
|
||||
if (privkey != NULL)
|
||||
gnutls_x509_privkey_deinit (*privkey);
|
||||
}
|
||||
|
||||
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC (gnutls_datum_t, _gnutls_datum_clear)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (gnutls_x509_crt_t, _gnutls_crt_free)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC (gnutls_x509_privkey_t, _gnutls_privkey_free)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *public_key_path;
|
||||
gchar *private_key_path;
|
||||
gchar *c;
|
||||
gchar *cn;
|
||||
} GenerateData;
|
||||
|
||||
static void
|
||||
generate_data_free (GenerateData *data)
|
||||
{
|
||||
g_clear_pointer (&data->public_key_path, g_free);
|
||||
g_clear_pointer (&data->private_key_path, g_free);
|
||||
g_clear_pointer (&data->c, g_free);
|
||||
g_clear_pointer (&data->cn, g_free);
|
||||
g_slice_free (GenerateData, data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
make_directory_parent (const gchar *path,
|
||||
GError **error)
|
||||
{
|
||||
g_autofree gchar *dir = NULL;
|
||||
|
||||
g_assert (path != NULL);
|
||||
g_assert (error != NULL);
|
||||
|
||||
dir = g_path_get_dirname (path);
|
||||
|
||||
if (g_mkdir_with_parents (dir, 0750) == -1)
|
||||
{
|
||||
g_set_error_literal (error,
|
||||
G_IO_ERROR,
|
||||
g_io_error_from_errno (errno),
|
||||
g_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
bonsai_tls_certificate_generate_worker (GTask *task,
|
||||
gpointer source_object,
|
||||
gpointer task_data,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
GenerateData *data = task_data;
|
||||
g_autoptr(GTlsCertificate) certificate = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(gnutls_x509_crt_t) certptr = NULL;
|
||||
g_autoptr(gnutls_x509_privkey_t) privkeyptr = NULL;
|
||||
g_auto(gnutls_datum_t) pubkey_data = {0};
|
||||
g_auto(gnutls_datum_t) privkey_data = {0};
|
||||
g_autofree char *dn = NULL;
|
||||
gnutls_x509_privkey_t privkey;
|
||||
gnutls_x509_crt_t cert;
|
||||
guint32 serial = 1;
|
||||
int gtlsret = 0;
|
||||
|
||||
g_assert (G_IS_TASK (task));
|
||||
g_assert (source_object == NULL);
|
||||
g_assert (data != NULL);
|
||||
g_assert (data->public_key_path != NULL);
|
||||
g_assert (data->private_key_path != NULL);
|
||||
g_assert (data->c != NULL);
|
||||
g_assert (data->cn != NULL);
|
||||
|
||||
if (!make_directory_parent (data->public_key_path, &error) ||
|
||||
!make_directory_parent (data->private_key_path, &error))
|
||||
{
|
||||
g_task_return_error (task, g_steal_pointer (&error));
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* From the GnuTLS documentation:
|
||||
*
|
||||
* To be consistent with the X.509/PKIX specifications the provided serial
|
||||
* should be a big-endian positive number (i.e. it's leftmost bit should be
|
||||
* zero).
|
||||
*/
|
||||
serial = GUINT32_TO_BE (serial);
|
||||
|
||||
#define HANDLE_FAILURE(x) \
|
||||
G_STMT_START { \
|
||||
gtlsret = x; \
|
||||
if (gtlsret != GNUTLS_E_SUCCESS) \
|
||||
goto failure; \
|
||||
} G_STMT_END
|
||||
|
||||
HANDLE_FAILURE (gnutls_x509_crt_init (&cert));
|
||||
certptr = &cert;
|
||||
HANDLE_FAILURE (gnutls_x509_crt_set_version (cert, 3));
|
||||
HANDLE_FAILURE (gnutls_x509_crt_set_activation_time (cert, time (NULL)));
|
||||
dn = g_strdup_printf ("C=%s,CN=%s", data->c, data->cn);
|
||||
HANDLE_FAILURE (gnutls_x509_crt_set_dn (cert, dn, NULL));
|
||||
HANDLE_FAILURE (gnutls_x509_crt_set_serial (cert, &serial, sizeof serial));
|
||||
/* 5 years. We'll figure out key rotation in that time... */
|
||||
HANDLE_FAILURE (gnutls_x509_crt_set_expiration_time (cert, time (NULL) + DEFAULT_EXPIRATION));
|
||||
HANDLE_FAILURE (gnutls_x509_privkey_init (&privkey));
|
||||
privkeyptr = &privkey;
|
||||
HANDLE_FAILURE (gnutls_x509_privkey_generate (privkey, GNUTLS_PK_RSA, DEFAULT_KEY_SIZE, 0));
|
||||
HANDLE_FAILURE (gnutls_x509_crt_set_key (cert, privkey));
|
||||
HANDLE_FAILURE (gnutls_x509_crt_sign (cert, cert, privkey));
|
||||
HANDLE_FAILURE (gnutls_x509_crt_export2 (cert, GNUTLS_X509_FMT_PEM, &pubkey_data));
|
||||
if (!g_file_set_contents (data->public_key_path, (char *)pubkey_data.data, pubkey_data.size, &error))
|
||||
goto failure;
|
||||
|
||||
HANDLE_FAILURE (gnutls_x509_privkey_export2 (privkey, GNUTLS_X509_FMT_PEM, &privkey_data));
|
||||
if (!g_file_set_contents (data->private_key_path, (char*)privkey_data.data, privkey_data.size, &error))
|
||||
goto failure;
|
||||
|
||||
#undef HANDLE_FAILURE
|
||||
|
||||
if ((certificate = g_tls_certificate_new_from_files (data->public_key_path, data->private_key_path, &error)))
|
||||
{
|
||||
g_task_return_pointer (task, g_steal_pointer (&certificate), g_object_unref);
|
||||
return;
|
||||
}
|
||||
|
||||
failure:
|
||||
|
||||
if (error != NULL)
|
||||
g_task_return_error (task, g_steal_pointer (&error));
|
||||
else if (gtlsret != 0)
|
||||
g_task_return_new_error (task,
|
||||
G_TLS_ERROR,
|
||||
G_TLS_ERROR_MISC,
|
||||
"GnuTLS Error: %s",
|
||||
gnutls_strerror (gtlsret));
|
||||
else
|
||||
g_task_return_new_error (task,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Failed to generate TLS certificate pair");
|
||||
}
|
||||
|
||||
void
|
||||
bonsai_tls_certificate_new_generate_async (const gchar *public_key_path,
|
||||
const gchar *private_key_path,
|
||||
const gchar *c,
|
||||
const gchar *cn,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(GTask) task = NULL;
|
||||
GenerateData *data;
|
||||
|
||||
g_return_if_fail (public_key_path != NULL);
|
||||
g_return_if_fail (private_key_path != NULL);
|
||||
g_return_if_fail (c != NULL);
|
||||
g_return_if_fail (cn != NULL);
|
||||
g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
task = g_task_new (NULL, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, bonsai_tls_certificate_new_generate_async);
|
||||
|
||||
data = g_slice_new0 (GenerateData);
|
||||
data->public_key_path = g_strdup (public_key_path);
|
||||
data->private_key_path = g_strdup (private_key_path);
|
||||
data->c = g_strdup (c);
|
||||
data->cn = g_strdup (cn);
|
||||
g_task_set_task_data (task, data, (GDestroyNotify)generate_data_free);
|
||||
|
||||
g_task_run_in_thread (task, bonsai_tls_certificate_generate_worker);
|
||||
}
|
||||
|
||||
GTlsCertificate *
|
||||
bonsai_tls_certificate_new_generate_finish (GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (G_IS_TASK (result), NULL);
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
GTlsCertificate *
|
||||
bonsai_tls_certificate_new_generate (const gchar *public_key_path,
|
||||
const gchar *private_key_path,
|
||||
const gchar *c,
|
||||
const gchar *cn,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autoptr(GTask) task = NULL;
|
||||
GenerateData *data;
|
||||
|
||||
g_return_val_if_fail (public_key_path != NULL, NULL);
|
||||
g_return_val_if_fail (private_key_path != NULL, NULL);
|
||||
g_return_val_if_fail (c != NULL, NULL);
|
||||
g_return_val_if_fail (cn != NULL, NULL);
|
||||
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
|
||||
|
||||
task = g_task_new (NULL, cancellable, NULL, NULL);
|
||||
g_task_set_source_tag (task, bonsai_tls_certificate_new_generate);
|
||||
|
||||
data = g_slice_new0 (GenerateData);
|
||||
data->public_key_path = g_strdup (public_key_path);
|
||||
data->private_key_path = g_strdup (private_key_path);
|
||||
data->c = g_strdup (c);
|
||||
data->cn = g_strdup (cn);
|
||||
g_task_set_task_data (task, data, (GDestroyNotify)generate_data_free);
|
||||
|
||||
bonsai_tls_certificate_generate_worker (task, NULL, data, cancellable);
|
||||
|
||||
return g_task_propagate_pointer (task, error);
|
||||
}
|
||||
|
||||
gchar *
|
||||
bonsai_tls_certificate_get_hash (GTlsCertificate *cert)
|
||||
{
|
||||
g_autoptr(GByteArray) bytesarray = NULL;
|
||||
g_autoptr(GChecksum) checksum = NULL;
|
||||
|
||||
g_return_val_if_fail (G_IS_TLS_CERTIFICATE (cert), NULL);
|
||||
|
||||
g_object_get (cert, "certificate", &bytesarray, NULL);
|
||||
|
||||
checksum = g_checksum_new (G_CHECKSUM_SHA256);
|
||||
g_checksum_update (checksum, bytesarray->data, bytesarray->len);
|
||||
|
||||
return g_ascii_strdown (g_checksum_get_string (checksum), -1);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
gchar *public_key_path;
|
||||
gchar *private_key_path;
|
||||
gchar *c;
|
||||
gchar *cn;
|
||||
} NewFromFilesOrGenerate;
|
||||
|
||||
static void
|
||||
new_from_files_or_generate_free (gpointer data)
|
||||
{
|
||||
NewFromFilesOrGenerate *state = data;
|
||||
|
||||
g_clear_pointer (&state->public_key_path, g_free);
|
||||
g_clear_pointer (&state->private_key_path, g_free);
|
||||
g_clear_pointer (&state->c, g_free);
|
||||
g_clear_pointer (&state->cn, g_free);
|
||||
g_free (state);
|
||||
}
|
||||
|
||||
static void
|
||||
bonsai_tls_certificate_new_from_files_or_generate_worker (GTask *task,
|
||||
gpointer source_object,
|
||||
gpointer task_data,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
NewFromFilesOrGenerate *state = task_data;
|
||||
g_autoptr(GTlsCertificate) certificate = NULL;
|
||||
g_autoptr(GError) error = NULL;
|
||||
|
||||
g_assert (G_IS_TASK (task));
|
||||
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
|
||||
g_assert (state != NULL);
|
||||
g_assert (state->public_key_path != NULL);
|
||||
g_assert (state->private_key_path != NULL);
|
||||
|
||||
/* Generate new public/private key for server if we need one.
|
||||
* Ideally, we would generate something signed by a real CA
|
||||
* for the user. But since this is "private cloud" oriented,
|
||||
* we should be fine for now.
|
||||
*/
|
||||
if (!g_file_test (state->public_key_path, G_FILE_TEST_EXISTS) ||
|
||||
!g_file_test (state->private_key_path, G_FILE_TEST_EXISTS))
|
||||
certificate = bonsai_tls_certificate_new_generate (state->public_key_path,
|
||||
state->private_key_path,
|
||||
state->c,
|
||||
state->cn,
|
||||
cancellable,
|
||||
&error);
|
||||
else
|
||||
certificate = g_tls_certificate_new_from_files (state->public_key_path,
|
||||
state->private_key_path,
|
||||
&error);
|
||||
|
||||
if (certificate == NULL)
|
||||
g_task_return_error (task, g_steal_pointer (&error));
|
||||
else
|
||||
g_task_return_pointer (task, g_steal_pointer (&certificate), g_object_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
* bonsai_tls_certificate_new_from_files_or_generate_async:
|
||||
* @public_key_path: the path to the public key file
|
||||
* @private_key_path: the path to the private key file
|
||||
* @cancellable: (nullable): a #GCancellable or %NULL
|
||||
* @callback: a callback to execute upon completion
|
||||
* @user_data: closure data for @callback
|
||||
*
|
||||
* Asynchronously requests that a certificate is loaded, or generate one if it
|
||||
* does not yet exist. The generated certificate is a self-signed certificate.
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
void
|
||||
bonsai_tls_certificate_new_from_files_or_generate_async (const gchar *public_key_path,
|
||||
const gchar *private_key_path,
|
||||
const gchar *c,
|
||||
const gchar *cn,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_autoptr(GTask) task = NULL;
|
||||
NewFromFilesOrGenerate state;
|
||||
|
||||
g_assert (public_key_path != NULL);
|
||||
g_assert (private_key_path != NULL);
|
||||
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
state.public_key_path = g_strdup (public_key_path);
|
||||
state.private_key_path = g_strdup (private_key_path);
|
||||
state.c = g_strdup (c);
|
||||
state.cn = g_strdup (cn);
|
||||
|
||||
task = g_task_new (NULL, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, bonsai_tls_certificate_new_from_files_or_generate_async);
|
||||
g_task_set_task_data (task, g_memdup2 (&state, sizeof state), new_from_files_or_generate_free);
|
||||
g_task_run_in_thread (task, bonsai_tls_certificate_new_from_files_or_generate_worker);
|
||||
}
|
||||
|
||||
/**
|
||||
* bonsai_tls_certificate_new_from_files_or_generate_finish:
|
||||
* @result: a #GAsyncResult provided to callback
|
||||
* @error: a location for a #GError, or %NULL
|
||||
*
|
||||
* Completes a request to
|
||||
* bonsai_tls_certificate_new_from_files_or_generate_async() which will
|
||||
* either load a #GTlsCertificate for the files if they exist, or generate
|
||||
* a new self-signed certificate in their place.
|
||||
*
|
||||
* Returns: (transfer none): a #GTlsCertificate or %NULL and @error is set.
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
GTlsCertificate *
|
||||
bonsai_tls_certificate_new_from_files_or_generate_finish (GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
g_assert (G_IS_TASK (result));
|
||||
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
/**
|
||||
* bonsai_tls_certificate_new_from_files_or_generate:
|
||||
* @public_key_path: the path to the public key
|
||||
* @private_key_path: the path to the private key
|
||||
* @c: the C for the certificate
|
||||
* @cn: the CN for the certificate
|
||||
* @cancellable: (nullable): a #GCancellable or %NULL
|
||||
* @error: the location for the error
|
||||
*
|
||||
* Loads a certificate or generates a new self-signed certificate in
|
||||
* it's place.
|
||||
*
|
||||
* Returns: (transfer full): a #GTlsCertificate or %NULL and @error is set
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
GTlsCertificate *
|
||||
bonsai_tls_certificate_new_from_files_or_generate (const gchar *public_key_path,
|
||||
const gchar *private_key_path,
|
||||
const gchar *c,
|
||||
const gchar *cn,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
GTlsCertificate *ret;
|
||||
|
||||
g_return_val_if_fail (public_key_path != NULL, NULL);
|
||||
g_return_val_if_fail (private_key_path != NULL, NULL);
|
||||
g_return_val_if_fail (c != NULL, NULL);
|
||||
g_return_val_if_fail (cn != NULL, NULL);
|
||||
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
|
||||
|
||||
if (!(ret = g_tls_certificate_new_from_files (public_key_path, private_key_path, NULL)))
|
||||
ret = bonsai_tls_certificate_new_generate (public_key_path,
|
||||
private_key_path,
|
||||
c,
|
||||
cn,
|
||||
cancellable,
|
||||
error);
|
||||
|
||||
return g_steal_pointer (&ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* bonsai_tls_certificate_new_for_user:
|
||||
* @public_key_path: the path to the public key
|
||||
* @private_key_path: the path to the private key
|
||||
*
|
||||
* This is a simplified form to create a new certificate or load a previously
|
||||
* created certificate for the current user.
|
||||
*
|
||||
* Returns: (transfer none): a #GTlsCertificate or %NULL and @error is set.
|
||||
*
|
||||
* Since: 0.2
|
||||
*/
|
||||
GTlsCertificate *
|
||||
bonsai_tls_certificate_new_for_user (GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_autofree gchar *public_key_path = NULL;
|
||||
g_autofree gchar *private_key_path = NULL;
|
||||
|
||||
g_return_val_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable), NULL);
|
||||
|
||||
public_key_path = g_build_filename (g_get_user_config_dir (), "bonsai", "public.key", NULL);
|
||||
private_key_path = g_build_filename (g_get_user_config_dir (), "bonsai", "private.key", NULL);
|
||||
|
||||
return bonsai_tls_certificate_new_from_files_or_generate (public_key_path,
|
||||
private_key_path,
|
||||
"US",
|
||||
"GNOME",
|
||||
cancellable,
|
||||
error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
bonsai_is_tls_hash (const gchar *hash)
|
||||
{
|
||||
guint len = 0;
|
||||
|
||||
if (hash == NULL)
|
||||
return FALSE;
|
||||
|
||||
for (; *hash; hash++)
|
||||
{
|
||||
if (len == 64)
|
||||
return FALSE;
|
||||
|
||||
switch (*hash)
|
||||
{
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
len++;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return len == 64;
|
||||
}
|
||||
|
63
panels/sharing/cc-tls-certificate.h
Normal file
63
panels/sharing/cc-tls-certificate.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
/* cc-tls-certificate.h
|
||||
*
|
||||
* Copyright 2018 Christian Hergert <chergert@redhat.com>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
gboolean bonsai_is_tls_hash (const gchar *hash);
|
||||
GTlsCertificate *bonsai_tls_certificate_new_generate (const gchar *public_key_path,
|
||||
const gchar *private_key_path,
|
||||
const gchar *c,
|
||||
const gchar *cn,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
void bonsai_tls_certificate_new_generate_async (const gchar *public_key_path,
|
||||
const gchar *private_key_path,
|
||||
const gchar *c,
|
||||
const gchar *cn,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GTlsCertificate *bonsai_tls_certificate_new_generate_finish (GAsyncResult *result,
|
||||
GError **error);
|
||||
gchar *bonsai_tls_certificate_get_hash (GTlsCertificate *cert);
|
||||
GTlsCertificate *bonsai_tls_certificate_new_from_files_or_generate (const gchar *public_key_path,
|
||||
const gchar *private_key_path,
|
||||
const gchar *c,
|
||||
const gchar *cn,
|
||||
GCancellable *cancellable,
|
||||
GError **error);
|
||||
void bonsai_tls_certificate_new_from_files_or_generate_async (const gchar *public_key_path,
|
||||
const gchar *private_key_path,
|
||||
const gchar *c,
|
||||
const gchar *cn,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
GTlsCertificate *bonsai_tls_certificate_new_from_files_or_generate_finish (GAsyncResult *result,
|
||||
GError **error);
|
||||
GTlsCertificate *bonsai_tls_certificate_new_for_user (GCancellable *cancellable,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
@ -41,6 +41,7 @@ sources = files(
|
|||
'cc-remote-login.c',
|
||||
'cc-sharing-networks.c',
|
||||
'cc-gnome-remote-desktop.c',
|
||||
'cc-tls-certificate.c',
|
||||
'file-share-properties.c',
|
||||
)
|
||||
|
||||
|
@ -73,12 +74,17 @@ cflags += [
|
|||
]
|
||||
|
||||
libsecret_dep = dependency('libsecret-1')
|
||||
gnutls_dep = dependency('gnutls')
|
||||
|
||||
panels_libs += static_library(
|
||||
cappletname,
|
||||
sources: sources,
|
||||
include_directories: [ top_inc, common_inc ],
|
||||
dependencies: [common_deps, libsecret_dep],
|
||||
dependencies: [
|
||||
common_deps,
|
||||
libsecret_dep,
|
||||
gnutls_dep,
|
||||
],
|
||||
c_args: cflags
|
||||
)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue