GList * cockpit_template_expand (GBytes *input, CockpitTemplateFunc func, gpointer user_data) { GList *output = NULL; const gchar *data; const gchar *end; const gchar *before; const gchar *after; GBytes *bytes; gchar *name; g_return_val_if_fail (func != NULL, NULL); data = g_bytes_get_data (input, NULL); end = data + g_bytes_get_size (input); for (;;) { name = find_variable (data, end, &before, &after); if (name == NULL) break; if (before != data) { g_assert (before > data); bytes = g_bytes_new_with_free_func (data, before - data, (GDestroyNotify)g_bytes_unref, g_bytes_ref (input)); output = g_list_prepend (output, bytes); } bytes = (func) (name, user_data); g_free (name); if (!bytes) { g_assert (after > before); bytes = g_bytes_new_with_free_func (before, after - before, (GDestroyNotify)g_bytes_unref, g_bytes_ref (input)); } output = g_list_prepend (output, bytes); g_assert (after <= end); data = after; } if (data != end) { g_assert (end > data); bytes = g_bytes_new_with_free_func (data, end - data, (GDestroyNotify)g_bytes_unref, g_bytes_ref (input)); output = g_list_prepend (output, bytes); } return g_list_reverse (output); }
static GBytes * expand_variables (const gchar *variable, gpointer user_data) { ExpandInfo *expand = user_data; CockpitPackage *package; gchar *val; package = g_hash_table_lookup (expand->listing, variable); if (package) { if (package->checksum) { return g_bytes_new_with_free_func (package->checksum, strlen (package->checksum), cockpit_package_unref, cockpit_package_ref (package)); } else if (expand->host) { val = g_strdup_printf ("%s@%s", package->name, expand->host); return g_bytes_new_take (val, strlen (val)); } else { return g_bytes_new_with_free_func (package->name, strlen (package->name), cockpit_package_unref, cockpit_package_ref (package)); } } else { return g_bytes_new (variable, strlen (variable)); } }
static void test_autoslist (void) { char data[1] = {0}; gboolean freed1 = FALSE; gboolean freed2 = FALSE; gboolean freed3 = FALSE; GBytes *b1 = g_bytes_new_with_free_func (data, sizeof(data), mark_freed, &freed1); GBytes *b2 = g_bytes_new_with_free_func (data, sizeof(data), mark_freed, &freed2); GBytes *b3 = g_bytes_new_with_free_func (data, sizeof(data), mark_freed, &freed3); { g_autoslist(GBytes) l = NULL; l = g_slist_prepend (l, b1); l = g_slist_prepend (l, b3); } /* Only assert if autoptr works */ #ifdef __GNUC__ g_assert (freed1); g_assert (freed3); #endif g_assert (!freed2); g_bytes_unref (b2); g_assert (freed2); }
static gboolean rsa_subject_public_key_from_attributes (GckAttributes *attrs, GNode *info_asn) { const GckAttribute *modulus; const GckAttribute *exponent; GNode *key_asn; GNode *params_asn; GBytes *key; GBytes *usg; modulus = gck_attributes_find (attrs, CKA_MODULUS); exponent = gck_attributes_find (attrs, CKA_PUBLIC_EXPONENT); if (modulus == NULL || gck_attribute_is_invalid (modulus) || exponent == NULL || gck_attribute_is_invalid (exponent)) return FALSE; key_asn = egg_asn1x_create (pk_asn1_tab, "RSAPublicKey"); g_return_val_if_fail (key_asn, FALSE); params_asn = egg_asn1x_create (pk_asn1_tab, "RSAParameters"); g_return_val_if_fail (params_asn, FALSE); usg = g_bytes_new_with_free_func (modulus->value, modulus->length, gck_attributes_unref, gck_attributes_ref (attrs)); egg_asn1x_set_integer_as_usg (egg_asn1x_node (key_asn, "modulus", NULL), usg); g_bytes_unref (usg); usg = g_bytes_new_with_free_func (exponent->value, exponent->length, gck_attributes_unref, gck_attributes_ref (attrs)); egg_asn1x_set_integer_as_usg (egg_asn1x_node (key_asn, "publicExponent", NULL), usg); g_bytes_unref (usg); key = egg_asn1x_encode (key_asn, NULL); egg_asn1x_destroy (key_asn); egg_asn1x_set_null (params_asn); egg_asn1x_set_bits_as_raw (egg_asn1x_node (info_asn, "subjectPublicKey", NULL), key, g_bytes_get_size (key) * 8); egg_asn1x_set_oid_as_quark (egg_asn1x_node (info_asn, "algorithm", "algorithm", NULL), GCR_OID_PKIX1_RSA); egg_asn1x_set_any_from (egg_asn1x_node (info_asn, "algorithm", "parameters", NULL), params_asn); egg_asn1x_destroy (params_asn); g_bytes_unref (key); return TRUE; }
static GkmDataResult load_encrypted_key (GBytes *data, const gchar *dekinfo, const gchar *password, gssize n_password, gcry_sexp_t *skey) { guchar *decrypted = NULL; gsize n_decrypted = 0; GBytes *bytes; GkmDataResult ret; gint length; /* Decrypt, this will result in garble if invalid password */ decrypted = egg_openssl_decrypt_block (dekinfo, password, n_password, data, &n_decrypted); if (!decrypted) return FALSE; /* Unpad the DER data */ length = egg_asn1x_element_length (decrypted, n_decrypted); if (length > 0) n_decrypted = length; bytes = g_bytes_new_with_free_func (decrypted, n_decrypted, egg_secure_free, decrypted); /* Try to parse */ ret = gkm_data_der_read_private_key (bytes, skey); g_bytes_unref (bytes); if (ret != GKM_DATA_UNRECOGNIZED) return ret; return GKM_DATA_LOCKED; }
/** * gdk_texture_new_for_surface: * @surface: a cairo image surface * * Creates a new texture object representing the surface. * @surface must be an image surface with format CAIRO_FORMAT_ARGB32. * * Returns: a new #GdkTexture */ GdkTexture * gdk_texture_new_for_surface (cairo_surface_t *surface) { GdkTexture *texture; GBytes *bytes; g_return_val_if_fail (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE, NULL); g_return_val_if_fail (cairo_image_surface_get_width (surface) > 0, NULL); g_return_val_if_fail (cairo_image_surface_get_height (surface) > 0, NULL); bytes = g_bytes_new_with_free_func (cairo_image_surface_get_data (surface), cairo_image_surface_get_height (surface) * cairo_image_surface_get_stride (surface), (GDestroyNotify) cairo_surface_destroy, cairo_surface_reference (surface)); texture = gdk_memory_texture_new (cairo_image_surface_get_width (surface), cairo_image_surface_get_height (surface), GDK_MEMORY_CAIRO_FORMAT_ARGB32, bytes, cairo_image_surface_get_stride (surface)); g_bytes_unref (bytes); return texture; }
static GBytes * read_output_edid (MetaMonitorManagerKms *manager_kms, MetaOutput *output) { MetaOutputKms *output_kms = output->driver_private; drmModePropertyBlobPtr edid_blob = NULL; if (output_kms->edid_blob_id == 0) return NULL; edid_blob = drmModeGetPropertyBlob (manager_kms->fd, output_kms->edid_blob_id); if (!edid_blob) { meta_warning ("Failed to read EDID of output %s: %s\n", output->name, strerror(errno)); return NULL; } if (edid_blob->length > 0) return g_bytes_new_with_free_func (edid_blob->data, edid_blob->length, (GDestroyNotify)drmModeFreePropertyBlob, edid_blob); else { drmModeFreePropertyBlob (edid_blob); return NULL; } }
static GNode * cert_subject_public_key_from_attributes (GckAttributes *attributes) { const GckAttribute *attr; GBytes *bytes; GNode *cert; GNode *asn; attr = gck_attributes_find (attributes, CKA_VALUE); if (attr == NULL || gck_attribute_is_invalid (attr)) { _gcr_debug ("no value attribute for certificate"); return NULL; } bytes = g_bytes_new_with_free_func (attr->value, attr->length, gck_attributes_unref, gck_attributes_ref (attributes)); cert = egg_asn1x_create_and_decode (pkix_asn1_tab, "Certificate", bytes); g_bytes_unref (bytes); if (cert == NULL) { _gcr_debug ("couldn't parse certificate value"); return NULL; } asn = egg_asn1x_node (cert, "tbsCertificate", "subjectPublicKeyInfo", NULL); g_return_val_if_fail (asn != NULL, NULL); /* Remove the subject public key out of the certificate */ g_node_unlink (asn); egg_asn1x_destroy (cert); return asn; }
/** * gdk_texture_new_for_pixbuf: * @pixbuf: a #GdkPixbuf * * Creates a new texture object representing the GdkPixbuf. * * Returns: a new #GdkTexture */ GdkTexture * gdk_texture_new_for_pixbuf (GdkPixbuf *pixbuf) { GdkTexture *texture; GBytes *bytes; g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); bytes = g_bytes_new_with_free_func (gdk_pixbuf_get_pixels (pixbuf), gdk_pixbuf_get_height (pixbuf) * gdk_pixbuf_get_rowstride (pixbuf), g_object_unref, g_object_ref (pixbuf)); texture = gdk_memory_texture_new (gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), gdk_pixbuf_get_has_alpha (pixbuf) ? GDK_MEMORY_GDK_PIXBUF_ALPHA : GDK_MEMORY_GDK_PIXBUF_OPAQUE, bytes, gdk_pixbuf_get_rowstride (pixbuf)); g_bytes_unref (bytes); return texture; }
/** * soup_buffer_get_as_bytes: * @buffer: a #SoupBuffer * * Creates a #GBytes pointing to the same memory as @buffer. The * #GBytes will hold a reference on @buffer to ensure that it is not * freed while the #GBytes is still valid. * * Returns: (transfer full): a new #GBytes which has the same content * as the #SoupBuffer. * * Since: 2.40 */ GBytes * soup_buffer_get_as_bytes (SoupBuffer *buffer) { SoupBuffer *copy; copy = soup_buffer_copy (buffer); return g_bytes_new_with_free_func (copy->data, copy->length, (GDestroyNotify)soup_buffer_free, copy); }
/** * g_mapped_file_get_bytes: * @file: a #GMappedFile * * Creates a new #GBytes which references the data mapped from @file. * The mapped contents of the file must not be modified after creating this * bytes object, because a #GBytes should be immutable. * * Returns: (transfer full): A newly allocated #GBytes referencing data * from @file * * Since: 2.34 **/ GBytes * g_mapped_file_get_bytes (GMappedFile *file) { g_return_val_if_fail (file != NULL, NULL); return g_bytes_new_with_free_func (file->contents, file->length, (GDestroyNotify) g_mapped_file_unref, g_mapped_file_ref (file)); }
/** * g_bytes_new_from_bytes: * @bytes: a #GBytes * @offset: offset which subsection starts at * @length: length of subsection * * Creates a #GBytes which is a subsection of another #GBytes. The @offset + * @length may not be longer than the size of @bytes. * * A reference to @bytes will be held by the newly created #GBytes until * the byte data is no longer needed. * * Returns: (transfer full): a new #GBytes * * Since: 2.32 */ GBytes * g_bytes_new_from_bytes (GBytes *bytes, gsize offset, gsize length) { g_return_val_if_fail (bytes != NULL, NULL); g_return_val_if_fail (offset <= bytes->size, NULL); g_return_val_if_fail (offset + length <= bytes->size, NULL); return g_bytes_new_with_free_func ((gchar *)bytes->data + offset, length, (GDestroyNotify)g_bytes_unref, g_bytes_ref (bytes)); }
static void g_tls_client_connection_gnutls_finish_handshake (GTlsConnectionGnutls *conn, GError **inout_error) { GTlsClientConnectionGnutls *gnutls = G_TLS_CLIENT_CONNECTION_GNUTLS (conn); int resumed; g_assert (inout_error != NULL); if (g_error_matches (*inout_error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS) && gnutls->priv->cert_requested) { g_clear_error (inout_error); if (gnutls->priv->cert_error) { *inout_error = gnutls->priv->cert_error; gnutls->priv->cert_error = NULL; } else { g_set_error_literal (inout_error, G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED, _("Server required TLS certificate")); } } resumed = gnutls_session_is_resumed (g_tls_connection_gnutls_get_session (conn)); if (*inout_error || !resumed) { /* Clear session data since the server did not accept what we provided. */ gnutls->priv->session_data_override = FALSE; g_clear_pointer (&gnutls->priv->session_data, g_bytes_unref); if (gnutls->priv->session_id) g_tls_backend_gnutls_remove_session (GNUTLS_CLIENT, gnutls->priv->session_id); } if (!*inout_error && !resumed) { gnutls_datum_t session_datum; if (gnutls_session_get_data2 (g_tls_connection_gnutls_get_session (conn), &session_datum) == 0) { gnutls->priv->session_data = g_bytes_new_with_free_func (session_datum.data, session_datum.size, (GDestroyNotify)gnutls_free, session_datum.data); g_tls_backend_gnutls_store_session (GNUTLS_CLIENT, gnutls->priv->session_id, gnutls->priv->session_data); } } }
static JsonObject * read_control_message (int fd) { JsonObject *options = NULL; GBytes *payload = NULL; GBytes *bytes = NULL; gchar *channel = NULL; guchar *data = NULL; gssize length = 0; length = cockpit_frame_read (fd, &data); if (length < 0) { g_message ("couldn't read askpass authorize message: %s", g_strerror (errno)); length = 0; } else if (length > 0) { /* This could have a password, so clear it when freeing */ bytes = g_bytes_new_with_free_func (data, length, byte_array_clear_and_free, g_byte_array_new_take (data, length)); payload = cockpit_transport_parse_frame (bytes, &channel); data = NULL; } if (payload == NULL) { if (length > 0) g_message ("askpass did not receive valid message"); } else if (channel != NULL) { g_message ("askpass did not receive a control message"); } else if (!cockpit_transport_parse_command (payload, NULL, NULL, &options)) { g_message ("askpass did not receive a valid control message"); } g_free (channel); if (bytes) g_bytes_unref (bytes); if (payload) g_bytes_unref (payload); free (data); return options; }
/** * cockpit_auth_start_session: * @self: a CockpitAuth * @creds: credentials for the session * * Start a local session process for the given credentials. It may be * that one is hanging around from prior authentication, in which case * that one is used. * * If launching the session fails, then the pipe will be created in a * failed state, and will close shortly. A CockpitPipe is always returned. * * Returns: (transfer full): the new pipe */ CockpitPipe * cockpit_auth_start_session (CockpitAuth *self, CockpitCreds *creds) { CockpitPipe *pipe; CockpitPipe *auth_pipe = NULL; const gchar *password; GBytes *bytes; g_return_val_if_fail (creds != NULL, NULL); pipe = pop_session_process (self, creds); if (pipe == NULL) { password = cockpit_creds_get_password (creds); if (password == NULL) { bytes = NULL; } else { bytes = g_bytes_new_with_free_func (password, strlen (password), cockpit_creds_unref, creds); } pipe = spawn_session_process (cockpit_creds_get_user (creds), bytes, cockpit_creds_get_rhost (creds), &auth_pipe); if (auth_pipe) { /* * Any failure will come from the pipe exit code, but the session * needs our password (if we have one) so let it get sent. */ g_signal_connect (auth_pipe, "close", G_CALLBACK (g_object_unref), NULL); } } if (!pipe) { pipe = g_object_new (COCKPIT_TYPE_PIPE, "problem", "internal-error", NULL); } return pipe; }
static gboolean on_transport_control (CockpitTransport *transport, const char *command, guint channel, JsonObject *options, GBytes *message, gpointer user_data) { CockpitPolkitAgent *self = COCKPIT_POLKIT_AGENT (user_data); ReauthorizeCaller *caller; const gchar *response; const gchar *cookie; GBytes *bytes; if (!g_str_equal (command, "authorize")) return FALSE; if (!cockpit_json_get_string (options, "cookie", NULL, &cookie) || !cockpit_json_get_string (options, "response", NULL, &response) || !cookie || !response) { g_warning ("got an invalid authorize command from cockpit-ws"); cockpit_transport_close (transport, "protocol-error"); return TRUE; } caller = g_hash_table_lookup (self->callers, cookie); if (!caller) { g_debug ("received authorize response for caller that has gone away"); return TRUE; } g_debug ("got \"authorize\" response from cockpit-ws, will send to helper: %s", response); bytes = g_bytes_new_with_free_func (response, strlen (response), (GDestroyNotify)json_object_unref, json_object_ref (options)); cockpit_pipe_write (caller->helper, bytes); g_bytes_unref (bytes); bytes = g_bytes_new_static ("\n", 1); cockpit_pipe_write (caller->helper, bytes); g_bytes_unref (bytes); return TRUE; }
GBytes * cockpit_auth_parse_authorization (GHashTable *headers, gchar **type) { gchar *line; gchar *next; gchar *contents; gsize length; gpointer key; gsize i; /* Avoid copying as it can contain passwords */ if (!g_hash_table_lookup_extended (headers, "Authorization", &key, (gpointer *)&line)) return NULL; g_hash_table_steal (headers, "Authorization"); g_free (key); line = str_skip (line, ' '); next = strchr (line, ' '); if (!next) { g_free (line); return NULL; } contents = str_skip (next, ' '); if (g_base64_decode_inplace (contents, &length) == NULL) { g_free (line); return NULL; } /* Null terminate for convenience, but null count not included in GBytes */ contents[length] = '\0'; if (type) { *type = g_strndup (line, next - line); for (i = 0; (*type)[i] != '\0'; i++) (*type)[i] = g_ascii_tolower ((*type)[i]); } /* Avoid copying by using the line directly */ return g_bytes_new_with_free_func (contents, length, clear_free_authorization, line); }
static void test_http_callback( SoupServer* server, SoupMessage* msg, const char* path, GHashTable* query, SoupClientContext* context, gpointer data) { char* uri = soup_uri_to_string(soup_message_get_uri (msg), FALSE); MMS_VERBOSE("%s %s HTTP/1.%d", msg->method, uri, soup_message_get_http_version(msg)); g_free(uri); if (msg->method == SOUP_METHOD_CONNECT) { soup_message_set_status(msg, SOUP_STATUS_NOT_IMPLEMENTED); } else { TestHttp* http = data; if (msg->request_body->length) { SoupBuffer* request = soup_message_body_flatten(msg->request_body); if (http->req_bytes) g_bytes_unref(http->req_bytes); http->req_bytes = g_bytes_new_with_free_func(request->data, request->length, (GDestroyNotify)soup_buffer_free, request); } soup_message_set_status(msg, http->resp_status); soup_message_headers_set_content_type(msg->response_headers, http->resp_content_type ? http->resp_content_type : "text/plain", NULL); soup_message_headers_append(msg->response_headers, "Accept-Ranges", "bytes"); soup_message_headers_append(msg->response_headers, "Connection", "close"); if (http->resp_file) { soup_message_headers_set_content_length(msg->response_headers, g_mapped_file_get_length(http->resp_file)); soup_message_body_append(msg->response_body, SOUP_MEMORY_TEMPORARY, g_mapped_file_get_contents(http->resp_file), g_mapped_file_get_length(http->resp_file)); } else { soup_message_headers_set_content_length(msg->response_headers, 0); } } soup_message_body_complete(msg->request_body); }
static gboolean dsa_subject_public_key_from_private (GNode *key_asn, const GckAttribute *ap, const GckAttribute *aq, const GckAttribute *ag, const GckAttribute *ax) { gcry_mpi_t mp, mq, mg, mx, my; size_t n_buffer; gcry_error_t gcry; unsigned char *buffer; gcry = gcry_mpi_scan (&mp, GCRYMPI_FMT_USG, ap->value, ap->length, NULL); g_return_val_if_fail (gcry == 0, FALSE); gcry = gcry_mpi_scan (&mq, GCRYMPI_FMT_USG, aq->value, aq->length, NULL); g_return_val_if_fail (gcry == 0, FALSE); gcry = gcry_mpi_scan (&mg, GCRYMPI_FMT_USG, ag->value, ag->length, NULL); g_return_val_if_fail (gcry == 0, FALSE); gcry = gcry_mpi_scan (&mx, GCRYMPI_FMT_USG, ax->value, ax->length, NULL); g_return_val_if_fail (gcry == 0, FALSE); /* Calculate the public part from the private */ my = gcry_mpi_snew (gcry_mpi_get_nbits (mx)); g_return_val_if_fail (my, FALSE); gcry_mpi_powm (my, mg, mx, mp); gcry = gcry_mpi_aprint (GCRYMPI_FMT_STD, &buffer, &n_buffer, my); g_return_val_if_fail (gcry == 0, FALSE); egg_asn1x_take_integer_as_raw (key_asn, g_bytes_new_with_free_func (buffer, n_buffer, gcry_free, buffer)); gcry_mpi_release (mp); gcry_mpi_release (mq); gcry_mpi_release (mg); gcry_mpi_release (mx); gcry_mpi_release (my); return TRUE; }
/** * g_bytes_new_static: (skip) * @data: (transfer full) (array length=size) (element-type guint8): the data to be used for the bytes * @size: the size of @data * * Creates a new #GBytes from static data. * * @data must be static (ie: never modified or freed). * * Returns: (transfer full): a new #GBytes * * Since: 2.32 */ GBytes * g_bytes_new_static (gconstpointer data, gsize size) { return g_bytes_new_with_free_func (data, size, NULL, NULL); }
/** * g_bytes_new_take: * @data: (transfer full) (array length=size) (element-type guint8): the data to be used for the bytes * @size: the size of @data * * Creates a new #GBytes from @data. * * After this call, @data belongs to the bytes and may no longer be * modified by the caller. g_free() will be called on @data when the * bytes is no longer in use. Because of this @data must have been created by * a call to g_malloc(), g_malloc0() or g_realloc() or by one of the many * functions that wrap these calls (such as g_new(), g_strdup(), etc). * * For creating #GBytes with memory from other allocators, see * g_bytes_new_with_free_func(). * * Returns: (transfer full): a new #GBytes * * Since: 2.32 */ GBytes * g_bytes_new_take (gpointer data, gsize size) { return g_bytes_new_with_free_func (data, size, g_free, data); }
static gboolean process_socket_authorize (CockpitWebService *self, CockpitSocket *socket, const gchar *channel, JsonObject *options, GBytes *payload) { const gchar *response = NULL; gboolean ret = FALSE; GBytes *bytes = NULL; char *password = NULL; char *user = NULL; char *type = NULL; gpointer data; gsize length; if (!cockpit_json_get_string (options, "response", NULL, &response)) { g_warning ("%s: received invalid \"response\" field in authorize command", socket->id); goto out; } ret = TRUE; if (response) { if (!cockpit_authorize_type (response, &type) || !g_str_equal (type, "basic")) goto out; password = cockpit_authorize_parse_basic (response, &user); if (password && !user) { cockpit_memory_clear (password, -1); free (password); password = NULL; } } else { send_socket_hints (self, "credential", cockpit_creds_get_password (self->creds) ? "password" : "none"); if (self->credential_requests) send_socket_hints (self, "credential", "request"); goto out; } if (password == NULL) { send_socket_hints (self, "credential", "none"); self->credential_requests = 0; bytes = NULL; } else { send_socket_hints (self, "credential", "password"); bytes = g_bytes_new_with_free_func (password, strlen (password), clear_and_free_string, password); password = NULL; } cockpit_creds_set_user (self->creds, user); cockpit_creds_set_password (self->creds, bytes); /* Clear out the payload memory */ data = (gpointer)g_bytes_get_data (payload, &length); cockpit_memory_clear (data, length); out: free (type); free (user); if (bytes) g_bytes_unref (bytes); return ret; }
static void dspy_introspection_model_init_introspect_cb (GObject *object, GAsyncResult *result, gpointer user_data) { GDBusConnection *bus = (GDBusConnection *)object; DspyIntrospectionModel *self; g_autoptr(Introspect) state = user_data; g_autoptr(GVariant) reply = NULL; g_autoptr(GError) error = NULL; GCancellable *cancellable; gint *n_active; g_assert (G_IS_DBUS_CONNECTION (bus)); g_assert (G_IS_ASYNC_RESULT (result)); g_assert (state != NULL); g_assert (G_IS_TASK (state->task)); g_assert (state->path != NULL); self = g_task_get_source_object (state->task); n_active = g_task_get_task_data (state->task); cancellable = g_task_get_cancellable (state->task); g_assert (self != NULL); g_assert (DSPY_IS_INTROSPECTION_MODEL (self)); g_assert (n_active != NULL); g_assert (*n_active > 0); if ((reply = g_dbus_connection_call_finish (bus, result, &error))) { g_autoptr(GBytes) bytes = NULL; const gchar *str = NULL; /* Get the XML contents, and wrap it in a new GBytes that will * reference the original GVariant to avoid a copy as this might * contain a large amount of text. */ g_variant_get (reply, "(&s)", &str); if (str[0] != 0) { bytes = g_bytes_new_with_free_func (str, strlen (str), (GDestroyNotify) g_variant_unref, g_variant_ref (reply)); parse_xml_async (self, bytes, cancellable, dspy_introspection_model_init_parse_cb, g_steal_pointer (&state)); return; } } else { DspyConnection *connection = dspy_name_get_connection (self->name); dspy_connection_add_error (connection, error); } if (--(*n_active) == 0) g_task_return_boolean (state->task, TRUE); }
BOSNode *file_type_archive_alloc(load_images_state_t state, file_t *file) {/*{{{*/ GError *error_pointer = NULL; GBytes *data = buffered_file_as_bytes(file, NULL, &error_pointer); if(!data) { g_printerr("Failed to load archive %s: %s\n", file->display_name, error_pointer ? error_pointer->message : "Unknown error"); g_clear_error(&error_pointer); file_free(file); return FALSE_POINTER; } struct archive *archive = file_type_archive_gen_archive(data); if(!archive) { buffered_file_unref(file); file_free(file); return FALSE_POINTER; } GtkFileFilterInfo file_filter_info; file_filter_info.contains = GTK_FILE_FILTER_FILENAME | GTK_FILE_FILTER_DISPLAY_NAME; BOSNode *first_node = FALSE_POINTER; struct archive_entry *entry; while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) { const gchar *entry_name = archive_entry_pathname(entry); #if ARCHIVE_VERSION_NUMBER < 3003002 // Affected by libarchive bug #869 if(archive_entry_size(entry) == 0) { const char *archive_format = archive_format_name(archive); if(strncmp("ZIP", archive_format, 3) == 0) { g_printerr("Failed to load archive %s: This ZIP file is affected by libarchive bug #869, which was fixed in v3.3.2. Skipping file.\n", file->display_name); archive_read_free(archive); buffered_file_unref(file); file_free(file); return FALSE_POINTER; } } #endif // Prepare a new file_t for this entry gchar *sub_name = g_strdup_printf("%s#%s", file->display_name, entry_name); file_t *new_file = image_loader_duplicate_file(file, g_strdup(sub_name), g_strdup(sub_name), sub_name); if(new_file->file_data) { g_bytes_unref(new_file->file_data); new_file->file_data = NULL; } size_t delegate_struct_alloc_size = sizeof(file_loader_delegate_archive_t) + strlen(entry_name) + 2; file_loader_delegate_archive_t *new_file_data = g_malloc(delegate_struct_alloc_size); new_file_data->source_archive = image_loader_duplicate_file(file, NULL, NULL, NULL); new_file_data->entry_name = (char *)(new_file_data) + sizeof(file_loader_delegate_archive_t) + 1; memcpy(new_file_data->entry_name, entry_name, strlen(entry_name) + 1); new_file->file_data = g_bytes_new_with_free_func(new_file_data, delegate_struct_alloc_size, (GDestroyNotify)file_type_archive_data_free, new_file_data); new_file->file_flags |= FILE_FLAGS_MEMORY_IMAGE; new_file->file_data_loader = file_type_archive_data_loader; // Find an appropriate handler for this file gchar *name_lowerc = g_utf8_strdown(entry_name, -1); file_filter_info.filename = file_filter_info.display_name = name_lowerc; // Check if one of the file type handlers can handle this file BOSNode *node = load_images_handle_parameter_find_handler(entry_name, state, new_file, &file_filter_info); if(node == NULL) { // No handler found. We could fall back to using a default. Free new_file instead. file_free(new_file); } else if(node == FALSE_POINTER) { // File type is known, but loading failed; new_file has already been free()d node = NULL; } else if(first_node == FALSE_POINTER) { first_node = node; } g_free(name_lowerc); archive_read_data_skip(archive); } archive_read_free(archive); buffered_file_unref(file); file_free(file); return first_node; }/*}}}*/
static gboolean dsa_subject_public_key_from_attributes (GckAttributes *attrs, gulong klass, GNode *info_asn) { const GckAttribute *value, *g, *q, *p; GNode *key_asn, *params_asn; GBytes *key; p = gck_attributes_find (attrs, CKA_PRIME); q = gck_attributes_find (attrs, CKA_SUBPRIME); g = gck_attributes_find (attrs, CKA_BASE); value = gck_attributes_find (attrs, CKA_VALUE); if (p == NULL || gck_attribute_is_invalid (p) || q == NULL || gck_attribute_is_invalid (q) || g == NULL || gck_attribute_is_invalid (g) || value == NULL || gck_attribute_is_invalid (value)) return FALSE; key_asn = egg_asn1x_create (pk_asn1_tab, "DSAPublicPart"); g_return_val_if_fail (key_asn, FALSE); params_asn = egg_asn1x_create (pk_asn1_tab, "DSAParameters"); g_return_val_if_fail (params_asn, FALSE); egg_asn1x_take_integer_as_usg (egg_asn1x_node (params_asn, "p", NULL), g_bytes_new_with_free_func (p->value, p->length, gck_attributes_unref, gck_attributes_ref (attrs))); egg_asn1x_take_integer_as_usg (egg_asn1x_node (params_asn, "q", NULL), g_bytes_new_with_free_func (q->value, q->length, gck_attributes_unref, gck_attributes_ref (attrs))); egg_asn1x_take_integer_as_usg (egg_asn1x_node (params_asn, "g", NULL), g_bytes_new_with_free_func (g->value, g->length, gck_attributes_unref, gck_attributes_ref (attrs))); /* Are these attributes for a public or private key? */ if (klass == CKO_PRIVATE_KEY) { /* We need to calculate the public from the private key */ if (!dsa_subject_public_key_from_private (key_asn, p, q, g, value)) g_return_val_if_reached (FALSE); } else if (klass == CKO_PUBLIC_KEY) { egg_asn1x_take_integer_as_usg (key_asn, g_bytes_new_with_free_func (value->value, value->length, gck_attributes_unref, gck_attributes_ref (attrs))); } else { g_assert_not_reached (); } key = egg_asn1x_encode (key_asn, NULL); egg_asn1x_destroy (key_asn); egg_asn1x_set_bits_as_raw (egg_asn1x_node (info_asn, "subjectPublicKey", NULL), key, g_bytes_get_size (key) * 8); egg_asn1x_set_any_from (egg_asn1x_node (info_asn, "algorithm", "parameters", NULL), params_asn); egg_asn1x_set_oid_as_quark (egg_asn1x_node (info_asn, "algorithm", "algorithm", NULL), GCR_OID_PKIX1_DSA); g_bytes_unref (key); egg_asn1x_destroy (params_asn); return TRUE; }
GBytes *buffered_file_as_bytes(file_t *file, GInputStream *data, GError **error_pointer) { g_rec_mutex_lock(&file_buffer_table_mutex); if(!file_buffer_table) { file_buffer_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); } struct buffered_file *buffer = g_hash_table_lookup(file_buffer_table, file->file_name); if(!buffer) { GBytes *data_bytes = NULL; if((file->file_flags & FILE_FLAGS_MEMORY_IMAGE)) { if(file->file_data_loader) { data_bytes = file->file_data_loader(file, error_pointer); } else { data_bytes = g_bytes_ref(file->file_data); } if(!data_bytes) { g_rec_mutex_unlock(&file_buffer_table_mutex); return NULL; } } else { #ifdef HAS_MMAP // If this is a local file, try to mmap() it first instead of loading it completely GFile *input_file = gfile_for_commandline_arg(file->file_name); char *input_file_abspath = g_file_get_path(input_file); if(input_file_abspath) { GFileInfo *file_info = g_file_query_info(input_file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, error_pointer); if(!file_info) { g_object_unref(input_file); g_rec_mutex_unlock(&file_buffer_table_mutex); return NULL; } goffset input_file_size = g_file_info_get_size(file_info); g_object_unref(file_info); int fd = open(input_file_abspath, O_RDONLY); g_free(input_file_abspath); if(fd < 0) { g_object_unref(input_file); g_rec_mutex_unlock(&file_buffer_table_mutex); *error_pointer = g_error_new(g_quark_from_static_string("pqiv-filebuffer-error"), 1, "Opening the file failed with errno=%d: %s", errno, strerror(errno)); return NULL; } void *input_file_data = mmap(NULL, input_file_size, PROT_READ, MAP_SHARED, fd, 0); if(input_file_data != MAP_FAILED) { struct buffered_file_mmap_info *mmap_info = g_slice_new(struct buffered_file_mmap_info); mmap_info->ptr = input_file_data; mmap_info->fd = fd; mmap_info->size = input_file_size; data_bytes = g_bytes_new_with_free_func(input_file_data, input_file_size, (GDestroyNotify)buffered_file_mmap_free_helper, mmap_info); } else { close(fd); } } g_object_unref(input_file); #endif if(data_bytes) { // mmap() above worked } else if(!data) { data = image_loader_stream_file(file, error_pointer); if(!data) { g_rec_mutex_unlock(&file_buffer_table_mutex); return NULL; } data_bytes = g_input_stream_read_completely(data, image_loader_cancellable, error_pointer); g_object_unref(data); } else { data_bytes = g_input_stream_read_completely(data, image_loader_cancellable, error_pointer); } if(!data_bytes) { g_rec_mutex_unlock(&file_buffer_table_mutex); return NULL; } }
GBytes * gkm_data_der_write_private_pkcs8_crypted (gcry_sexp_t skey, const gchar *password, gsize n_password) { gcry_error_t gcry; gcry_cipher_hd_t cih; GNode *asn = NULL; GBytes *key, *data; guchar *raw; gsize n_raw, n_key; gsize block = 0; /* Encode the key in normal pkcs8 fashion */ key = gkm_data_der_write_private_pkcs8_plain (skey); if (key == NULL) return NULL; asn = egg_asn1x_create (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo"); g_return_val_if_fail (asn, NULL); /* Create a and write out a cipher used for encryption */ cih = prepare_and_encode_pkcs8_cipher (asn, password, n_password, &block); g_return_val_if_fail (cih, NULL); n_key = g_bytes_get_size (key); /* Pad the block of data */ if(block > 1) { gsize n_pad = block - (n_key % block); if (n_pad == 0) n_pad = block; raw = egg_secure_alloc (n_key + n_pad); memcpy (raw, g_bytes_get_data (key, NULL), n_key); memset (raw + n_key, (int)n_pad, n_pad); n_raw = n_key + n_pad; /* No padding, probably stream cipher */ } else { raw = egg_secure_alloc (n_key); memcpy (raw, g_bytes_get_data (key, NULL), n_key); n_raw = n_key; } g_bytes_unref (key); gcry = gcry_cipher_encrypt (cih, raw, n_raw, NULL, 0); g_return_val_if_fail (gcry == 0, NULL); gcry_cipher_close (cih); key = g_bytes_new_with_free_func (raw, n_raw, egg_secure_free, raw); egg_asn1x_set_string_as_bytes (egg_asn1x_node (asn, "encryptedData", NULL), key); g_bytes_unref (key); data = egg_asn1x_encode (asn, NULL); if (data == NULL) g_warning ("couldn't encode encrypted pkcs8 key: %s", egg_asn1x_message (asn)); egg_asn1x_destroy (asn); return data; }
/** * g_resource_lookup_data: * @resource: A #GResource * @path: A pathname inside the resource * @lookup_flags: A #GResourceLookupFlags * @error: return location for a #GError, or %NULL * * Looks for a file at the specified @path in the resource and * returns a #GBytes that lets you directly access the data in * memory. * * The data is always followed by a zero byte, so you * can safely use the data as a C string. However, that byte * is not included in the size of the GBytes. * * For uncompressed resource files this is a pointer directly into * the resource bundle, which is typically in some readonly data section * in the program binary. For compressed files we allocate memory on * the heap and automatically uncompress the data. * * @lookup_flags controls the behaviour of the lookup. * * Returns: (transfer full): #GBytes or %NULL on error. * Free the returned object with g_bytes_unref() * * Since: 2.32 **/ GBytes * g_resource_lookup_data (GResource *resource, const gchar *path, GResourceLookupFlags lookup_flags, GError **error) { const void *data; guint32 flags; gsize data_size; gsize size; if (!do_lookup (resource, path, lookup_flags, &size, &flags, &data, &data_size, error)) return NULL; if (flags & G_RESOURCE_FLAGS_COMPRESSED) { char *uncompressed, *d; const char *s; GConverterResult res; gsize d_size, s_size; gsize bytes_read, bytes_written; GZlibDecompressor *decompressor = g_zlib_decompressor_new (G_ZLIB_COMPRESSOR_FORMAT_ZLIB); uncompressed = g_malloc (size + 1); s = data; s_size = data_size; d = uncompressed; d_size = size; do { res = g_converter_convert (G_CONVERTER (decompressor), s, s_size, d, d_size, G_CONVERTER_INPUT_AT_END, &bytes_read, &bytes_written, NULL); if (res == G_CONVERTER_ERROR) { g_free (uncompressed); g_object_unref (decompressor); g_set_error (error, G_RESOURCE_ERROR, G_RESOURCE_ERROR_INTERNAL, _("The resource at '%s' failed to decompress"), path); return NULL; } s += bytes_read; s_size -= bytes_read; d += bytes_written; d_size -= bytes_written; } while (res != G_CONVERTER_FINISHED); uncompressed[size] = 0; /* Zero terminate */ g_object_unref (decompressor); return g_bytes_new_take (uncompressed, size); } else return g_bytes_new_with_free_func (data, data_size, (GDestroyNotify)g_resource_unref, g_resource_ref (resource)); }
GkmDataResult gkm_data_der_read_private_pkcs8_crypted (GBytes *data, const gchar *password, gsize n_password, gcry_sexp_t *s_key) { GNode *asn = NULL; gcry_cipher_hd_t cih = NULL; gcry_error_t gcry; GkmDataResult ret, r; GQuark scheme; guchar *crypted = NULL; GNode *params; GBytes *bytes; gsize n_crypted; gint l; init_quarks (); ret = GKM_DATA_UNRECOGNIZED; asn = egg_asn1x_create_and_decode (pkix_asn1_tab, "pkcs-8-EncryptedPrivateKeyInfo", data); if (!asn) goto done; ret = GKM_DATA_FAILURE; /* Figure out the type of encryption */ scheme = egg_asn1x_get_oid_as_quark (egg_asn1x_node (asn, "encryptionAlgorithm", "algorithm", NULL)); if (!scheme) goto done; params = egg_asn1x_node (asn, "encryptionAlgorithm", "parameters", NULL); if (!params) goto done; /* * Parse the encryption stuff into a cipher. */ r = egg_symkey_read_cipher (scheme, password, n_password, params, &cih); if (r == GKM_DATA_UNRECOGNIZED) { ret = GKM_DATA_FAILURE; goto done; } else if (r != GKM_DATA_SUCCESS) { ret = r; goto done; } crypted = egg_asn1x_get_string_as_raw (egg_asn1x_node (asn, "encryptedData", NULL), egg_secure_realloc, &n_crypted); if (!crypted) goto done; gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0); gcry_cipher_close (cih); cih = NULL; if (gcry != 0) { g_warning ("couldn't decrypt pkcs8 data: %s", gcry_strerror (gcry)); goto done; } /* Unpad the DER data */ l = egg_asn1x_element_length (crypted, n_crypted); if (l <= 0 || l > n_crypted) { ret = GKM_DATA_LOCKED; goto done; } n_crypted = l; bytes = g_bytes_new_with_free_func (crypted, n_crypted, egg_secure_free, crypted); crypted = NULL; /* Try to parse the resulting key */ ret = gkm_data_der_read_private_pkcs8_plain (bytes, s_key); g_bytes_unref (bytes); /* If unrecognized we assume bad password */ if (ret == GKM_DATA_UNRECOGNIZED) ret = GKM_DATA_LOCKED; done: if (cih) gcry_cipher_close (cih); egg_asn1x_destroy (asn); egg_secure_free (crypted); return ret; }