Exemplo n.º 1
0
gboolean 
gitg_commit_add_ignore(GitgCommit *commit, GitgChangedFile *file, GError **error)
{
	g_return_if_fail(GITG_IS_COMMIT(commit));
	g_return_if_fail(GITG_IS_CHANGED_FILE(file));
	
	GFile *f = gitg_changed_file_get_file(file);
	gchar *path = gitg_repository_relative(commit->priv->repository, f);
	
	gchar *ignore = g_strdup_printf("%s/.gitignore", gitg_repository_get_path(commit->priv->repository));
	GFile *ig = g_file_new_for_path(ignore);
	
	GFileOutputStream *stream = g_file_append_to(ig, G_FILE_CREATE_NONE, NULL, error);
	gboolean ret = FALSE;
	
	if (stream)
	{
		gchar *line = g_strdup_printf("/%s\n", path);
		ret = g_output_stream_write_all(G_OUTPUT_STREAM(stream), line, strlen(line), NULL, NULL, error);
		g_output_stream_close(G_OUTPUT_STREAM(stream), NULL, NULL);

		g_object_unref(stream);
		g_free(line);
	}
	
	if (ret)
		remove_file(commit, file);

	g_object_unref(f);	
	g_free(ignore);
	g_free(path);
}
Exemplo n.º 2
0
gboolean media_append (gchar *path, gchar *buf, gssize size)
{
        GFile *gfile;
        GOutputStream *out;
        GError *err = NULL;
        gssize written;

        gfile = g_file_new_for_path (path);
        out = (GOutputStream *)g_file_append_to (gfile, G_FILE_CREATE_NONE, NULL, &err);
        if (out == NULL) {
                GST_ERROR ("Error opening file: %s\n", err->message);
                g_error_free (err);
                g_object_unref (gfile);
                return FALSE;
        }
        written = g_output_stream_write (out, buf, size, NULL, &err);
	if (written == -1) {
                GST_ERROR ("Error writing to stream: %s", err->message);
                g_error_free (err);
        }
        g_object_unref (out);
        g_object_unref (gfile);

        return TRUE;
}
Exemplo n.º 3
0
static void write_output_file (gpointer data)
{
	g_assert (data != NULL);

	GError *error = NULL;
	GDownloadable *download		 = G_DOWNLOADABLE (data);
	SoupDownload  *soup_download = SOUP_DOWNLOAD (data);

	if (soup_download->priv->need_to_write) {
		GFileOutputStream *ostream = g_file_append_to (download->priv->local_file, G_FILE_CREATE_NONE, NULL, &error);
		handle_error (error);

		SoupBuffer *buffer = soup_message_body_flatten (soup_download->priv->message->response_body);
		g_output_stream_write (G_OUTPUT_STREAM (ostream), buffer->data, buffer->length, NULL, &error);
		handle_error (error);

		g_output_stream_close (G_OUTPUT_STREAM (ostream), NULL, &error);
		handle_error (error);

		download->priv->downloaded_size = soup_download->priv->prev_downloaded + buffer->length;
		soup_buffer_free (buffer);

		soup_download->priv->need_to_write = FALSE;
	}
}
Exemplo n.º 4
0
gboolean
ostree_create_temp_regular_file (GFile            *dir,
                                 const char       *prefix,
                                 const char       *suffix,
                                 GFile           **out_file,
                                 GOutputStream   **out_stream,
                                 GCancellable     *cancellable,
                                 GError          **error)
{
  gboolean ret = FALSE;
  ot_lobj GFile *ret_file = NULL;
  ot_lobj GOutputStream *ret_stream = NULL;

  if (!ostree_create_temp_file_from_input (dir, prefix, suffix, NULL, NULL, NULL,
                                           &ret_file, cancellable, error))
    goto out;
  
  ret_stream = (GOutputStream*)g_file_append_to (ret_file, 0, cancellable, error);
  if (ret_stream == NULL)
    goto out;
  
  ret = TRUE;
  ot_transfer_out_value(out_file, &ret_file);
  ot_transfer_out_value(out_stream, &ret_stream);
 out:
  return ret;
}
/**
 * camel_stream_vfs_new_with_uri:
 * @uri: a file uri
 * @mode: opening mode for the uri file
 *
 * Creates a new #CamelStreamVFS corresponding to the named file and mode.
 *
 * Returns the new stream, or %NULL on error.
 **/
CamelStream *
camel_stream_vfs_new_with_uri (const char *uri, CamelStreamVFSOpenMethod mode)
{
	GFile *file;
	GObject *stream;
	GError *error = NULL;

	file = g_file_new_for_uri (uri);

	switch (mode) {
		case CAMEL_STREAM_VFS_CREATE:
			stream = G_OBJECT (g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error));
			break;
		case CAMEL_STREAM_VFS_APPEND:
			stream = G_OBJECT (g_file_append_to (file, G_FILE_CREATE_NONE, NULL, &error));
			break;
		case CAMEL_STREAM_VFS_READ:
			stream = G_OBJECT (g_file_read (file, NULL, &error));
			break;
		default:
			errno = EINVAL;
			g_return_val_if_reached (NULL);
	}

	g_object_unref (file);

	if (error) {
		errno = error->code;
		g_warning ("%s", error->message);
		g_error_free (error);
		return NULL;
	}

	return camel_stream_vfs_new_with_stream (stream);
}
Exemplo n.º 6
0
static void
do_append_to (GVfsBackend *backend,
	      GVfsJobOpenForWrite *job,
	      const char *filename,
	      GFileCreateFlags flags)
{
  GFile *file;
  GFileOutputStream *out;
  GError *error;
  
  file = g_vfs_get_file_for_path (g_vfs_get_local (),
				  filename);

  error = NULL;
  out = g_file_append_to (file, flags, G_VFS_JOB (job)->cancellable, &error);
  g_object_unref (file);
  if (out)
    {
      g_vfs_job_open_for_write_set_can_seek (job, FALSE);
      g_vfs_job_open_for_write_set_handle (job, out);
      g_vfs_job_succeeded (G_VFS_JOB (job));
    }
  else
    {
      g_vfs_job_failed_from_error (G_VFS_JOB (job), error);
      g_error_free (error);
    }
}
Exemplo n.º 7
0
static GFile *
get_g_file_with_encrypted_data (GFileInputStream *in_stream, goffset file_size)
{
    GError *err = NULL;
    GFileIOStream *ostream;
    gssize read_len;
    guchar *buf;
    gsize len_file_data = file_size - SHA512_DIGEST_SIZE;
    gsize done_size = 0;

    GFile *tmp_encrypted_file = g_file_new_tmp (NULL, &ostream, &err);
    if (tmp_encrypted_file == NULL) {
        g_printerr ("%s\n", err->message);
        // TODO
        return NULL;
    }

    GFileOutputStream *out_enc_stream = g_file_append_to (tmp_encrypted_file, G_FILE_CREATE_NONE, NULL, &err);
    if (out_enc_stream == NULL) {
        g_printerr ("%s\n", err->message);
        // TODO
        return NULL;
    }

    if (len_file_data < FILE_BUFFER) {
        buf = g_malloc (len_file_data);
        g_input_stream_read (G_INPUT_STREAM (in_stream), buf, len_file_data, NULL, &err);
        g_output_stream_write (G_OUTPUT_STREAM (out_enc_stream), buf, len_file_data, NULL, &err);
    }
    else {
        buf = g_malloc (FILE_BUFFER);
        while (done_size < len_file_data) {
            if ((len_file_data - done_size) > FILE_BUFFER) {
                read_len = g_input_stream_read (G_INPUT_STREAM (in_stream), buf, FILE_BUFFER, NULL, &err);
            }
            else {
                read_len = g_input_stream_read (G_INPUT_STREAM (in_stream), buf, len_file_data - done_size, NULL, &err);
            }
            if (read_len == -1) {
                g_printerr ("%s\n", err->message);
                // TODO
                return NULL;
            }
            g_output_stream_write (G_OUTPUT_STREAM (out_enc_stream), buf, read_len, NULL, &err);
            done_size += read_len;
            memset (buf, 0, FILE_BUFFER);
        }
    }

    g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL);
    g_output_stream_close (G_OUTPUT_STREAM (out_enc_stream), NULL, NULL);
    g_object_unref (out_enc_stream);
    g_free (buf);

    return tmp_encrypted_file;
}
Exemplo n.º 8
0
/**
* ly_log_logger_add:
* @logger: the logger
* @str: the string data to be write to log file.
*
* Add a log item to log file.
*/
void	ly_log_logger_add		(LyLogLogger *logger, gchar *str)
{
	LyLogLoggerPrivate *priv=LY_LOG_LOGGER_GET_PRIVATE(LY_LOG_LOGGER(logger));
	GFileOutputStream *ostream;
	ostream=g_file_append_to(G_FILE(priv->file), G_FILE_CREATE_NONE, \
		NULL, NULL);
	g_output_stream_write(G_OUTPUT_STREAM(ostream), (const void *)str, \
		strlen(str), NULL, NULL);
	g_output_stream_close(G_OUTPUT_STREAM(ostream), NULL, NULL);
	g_object_unref(ostream);
}
Exemplo n.º 9
0
/*
 * Function to use anywhere in the application to send a message to the LogList
 */
void Log_Print (Log_Error_Type error_type, gchar const *format, ...)
{
    va_list args;
    gchar *string;

    GtkTreeIter iter;
    static gboolean first_time = TRUE;
    static gchar *file_path = NULL;
    GFile *file;
    GFileOutputStream *file_ostream;
    GError *error = NULL;

    va_start (args, format);
    string = g_strdup_vprintf(format, args);
    va_end (args);

    // If the log window is displayed then messages are displayed, else
    // the messages are stored in a temporary list.
    if (LogList && logListModel)
    {
        gint n_items;
        gchar *time = Log_Format_Date();

        /* Remove lines that exceed the limit. */
        n_items = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (logListModel),
                                                  NULL);

        if (n_items > LOG_MAX_LINES - 1
        &&  gtk_tree_model_get_iter_first(GTK_TREE_MODEL(logListModel), &iter))
        {
            gtk_list_store_remove(GTK_LIST_STORE(logListModel), &iter);
        }

        gtk_list_store_insert_with_values (logListModel, &iter, G_MAXINT,
                                           LOG_PIXBUF,
                                           Log_Get_Stock_Id_From_Error_Type (error_type),
                                           LOG_TIME_TEXT, time, LOG_TEXT,
                                           string, -1);
        Log_List_Set_Row_Visible(GTK_TREE_MODEL(logListModel), &iter);
        g_free(time);
    }else
    {
        Log_Data *LogData = g_malloc0(sizeof(Log_Data));
        LogData->time       = Log_Format_Date();
        LogData->error_type = error_type;
        LogData->string     = g_strdup(string);

        LogPrintTmpList = g_list_append(LogPrintTmpList,LogData);
        //g_print("%s",string);
    }

    // Store also the messages in the log file.
    if (!file_path)
    {
        gchar *cache_path = g_build_filename (g_get_user_cache_dir (),
                                              PACKAGE_TARNAME, NULL);

        if (!g_file_test (cache_path, G_FILE_TEST_IS_DIR))
        {
            gint result = g_mkdir_with_parents (cache_path, S_IRWXU);

            if (result == -1)
            {
                g_printerr ("%s", "Unable to create cache directory");
                g_free (cache_path);
                g_free (string);

                return;
            }
        }

        file_path = g_build_filename (cache_path, LOG_FILE, NULL);
        g_free (cache_path);
    }

    file = g_file_new_for_path (file_path);

    /* On startup, the log is cleared. The log is then appended to for the
     * remainder of the application lifetime. */
    if (first_time)
    {
        file_ostream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE,
                                       NULL, &error);
    }
    else
    {
        file_ostream = g_file_append_to (file, G_FILE_CREATE_NONE, NULL,
                                         &error);
    }

    if (file_ostream)
    {
        gchar *time;
        GString *data;
        gsize bytes_written;

        time = Log_Format_Date ();
        data = g_string_new (time);
        g_free (time);

        data = g_string_append_c (data, ' ');
        data = g_string_append (data, string);
        g_free (string);

        data = g_string_append_c (data, '\n');

        if (!g_output_stream_write_all (G_OUTPUT_STREAM (file_ostream),
                                        data->str, data->len, &bytes_written,
                                        NULL, &error))
        {
            g_debug ("Only %" G_GSIZE_FORMAT " bytes out of %" G_GSIZE_FORMAT
                     "bytes of data were written", bytes_written, data->len);

            /* To avoid recursion of Log_Print. */
            g_warning ("Error writing to the log file '%s' ('%s')", file_path,
                       error->message);

            g_error_free (error);

            g_string_free (data, TRUE);
            g_object_unref (file_ostream);
            g_object_unref (file);

            return;
        }

        first_time = FALSE;

        g_string_free (data, TRUE);
    }
    else
    {
        g_warning ("Error opening output stream of file '%s' ('%s')",
                   file_path, error->message);
        g_error_free (error);
    }

    g_object_unref (file_ostream);
    g_object_unref (file);
}
Exemplo n.º 10
0
static void
scrollback_save (session *sess, char *text, time_t stamp)
{
	GOutputStream *ostream;
	char *buf;

	if (sess->type == SESS_SERVER && prefs.hex_gui_tab_server == 1)
		return;

	if (sess->text_scrollback == SET_DEFAULT)
	{
		if (!prefs.hex_text_replay)
			return;
	}
	else
	{
		if (sess->text_scrollback != SET_ON)
			return;
	}

	if (!sess->scrollfile)
	{
		if ((buf = scrollback_get_filename (sess)) == NULL)
			return;

		sess->scrollfile = g_file_new_for_path (buf);
		g_free (buf);
	}
	else
	{
		/* Users can delete the folder after it's created... */
		GFile *parent = g_file_get_parent (sess->scrollfile);
		g_file_make_directory_with_parents (parent, NULL, NULL);
		g_object_unref (parent);
	}

	ostream = G_OUTPUT_STREAM(g_file_append_to (sess->scrollfile, G_FILE_CREATE_PRIVATE, NULL, NULL));
	if (!ostream)
		return;

	if (!stamp)
		stamp = time(0);
	if (sizeof (stamp) == 4)	/* gcc will optimize one of these out */
		buf = g_strdup_printf ("T %d ", (int) stamp);
	else
		buf = g_strdup_printf ("T %" G_GINT64_FORMAT " ", (gint64)stamp);

	g_output_stream_write (ostream, buf, strlen (buf), NULL, NULL);
	g_output_stream_write (ostream, text, strlen (text), NULL, NULL);
	if (!g_str_has_suffix (text, "\n"))
		g_output_stream_write (ostream, "\n", 1, NULL, NULL);

	g_free (buf);
	g_object_unref (ostream);

	sess->scrollwritten++;

	if ((sess->scrollwritten > prefs.hex_text_max_lines && prefs.hex_text_max_lines > 0) ||
       sess->scrollwritten > SCROLLBACK_MAX)
		scrollback_shrink (sess);
}
Exemplo n.º 11
0
gboolean create_bundle(const gchar *bundlename, const gchar *contentdir, GError **error) {
	GError *ierror = NULL;
	GBytes *sig = NULL;
	GFile *bundlefile = NULL;
	GFileOutputStream *bundlestream = NULL;
	gboolean res = FALSE;
	guint64 offset;

	g_assert_nonnull(r_context()->certpath);
	g_assert_nonnull(r_context()->keypath);

	res = mksquashfs(bundlename, contentdir, &ierror);
	if (!res) {
		g_propagate_error(error, ierror);
		goto out;
	}

	sig = cms_sign_file(bundlename,
			    r_context()->certpath,
			    r_context()->keypath,
			    &ierror);
	if (sig == NULL) {
		g_propagate_prefixed_error(
				error,
				ierror,
				"failed signing bundle: ");
		goto out;
	}

	bundlefile = g_file_new_for_path(bundlename);
	bundlestream = g_file_append_to(bundlefile, G_FILE_CREATE_NONE, NULL, &ierror);
	if (bundlestream == NULL) {
		g_propagate_prefixed_error(
				error,
				ierror,
				"failed to open bundle for appending: ");
		goto out;
	}

	res = g_seekable_seek(G_SEEKABLE(bundlestream),
			      0, G_SEEK_END, NULL, &ierror);
	if (!res) {
		g_propagate_prefixed_error(
				error,
				ierror,
				"failed to seek to end of bundle: ");
		goto out;
	}

	offset = g_seekable_tell((GSeekable *)bundlestream);
	res = output_stream_write_bytes_all((GOutputStream *)bundlestream, sig, NULL, &ierror);
	if (!res) {
		g_propagate_prefixed_error(
				error,
				ierror,
				"failed to append signature to bundle: ");
		goto out;
	}


	offset = g_seekable_tell((GSeekable *)bundlestream) - offset;
	res = output_stream_write_uint64_all((GOutputStream *)bundlestream, offset, NULL, &ierror);
	if (!res) {
		g_propagate_prefixed_error(
				error,
				ierror,
				"failed to append signature size to bundle: ");
		goto out;
	}


	res = TRUE;
out:
	g_clear_object(&bundlestream);
	g_clear_object(&bundlefile);
	g_clear_pointer(&sig, g_bytes_unref);
	return res;
}
Exemplo n.º 12
0
static gboolean
handle_install_authorized_keys (MinCloudAgentApp      *self,
                                GInputStream               *instream,
                                GCancellable               *cancellable,
                                GError                    **error)
{
  gboolean ret = FALSE;
  int fd;
  guint i;
  gs_unref_object GOutputStream *outstream = NULL;
  gs_unref_object GDataInputStream *datain = NULL;
  gs_unref_ptrarray GPtrArray *lines = g_ptr_array_new_with_free_func (g_free);

  datain = g_data_input_stream_new (instream);

  while (TRUE)
    {
      gsize len;
      GError *temp_error = NULL;
      char *line = g_data_input_stream_read_line_utf8 (datain, &len, cancellable, &temp_error);
      if (temp_error != NULL)
        {
          g_propagate_error (error, temp_error);
          g_prefix_error (error, "Reading ssh keys: ");
          goto out;
        }
      if (!line)
        break;
      g_ptr_array_add (lines, line);
    }

  (void) g_input_stream_close ((GInputStream*)datain, NULL, NULL);

  outstream = (GOutputStream*)g_file_append_to (self->authorized_keys_path, 0, cancellable, error);
  if (!outstream)
    {
      g_prefix_error (error, "Appending to '%s': ",
                      gs_file_get_path_cached (self->authorized_keys_path));
      goto out;
    }

  fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)outstream);
  if (fchmod (fd, 0600) != 0)
    {
      int errsv = errno;
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                   "Failed to chmod authorized_keys: %s",
                   g_strerror (errsv));
      goto out;
    }

  for (i = 0; i < lines->len; i++)
    {
      const char *line = lines->pdata[i];
      char nl[] = { '\n' };
      gsize bytes_written;
      if (!g_output_stream_write_all (outstream, line, strlen (line),
                                      &bytes_written,
                                      cancellable, error))
        goto out;
      if (!g_output_stream_write_all (outstream, nl, sizeof (nl),
                                      &bytes_written,
                                      cancellable, error))
        goto out;
    }

  if (!g_output_stream_flush (outstream, cancellable, error))
    goto out;

  gs_log_structured_print_id_v (MCA_KEY_INSTALLED_SUCCESS_ID,
                                "Successfully installed ssh key for '%s'",
                                "root");

  ret = TRUE;
 out:
  return ret;
}
Exemplo n.º 13
0
static GOutputStream *
get_checksum_stream (CheckcopyFileList * list, GFile * dest)
{
  CheckcopyFileListPrivate *priv = GET_PRIVATE (list);

  gchar * basename;
  gchar * checksum_name;
  GFileOutputStream * out = NULL;
  GError *error = NULL;
  GCancellable * cancel;
  GFile *checksum = NULL;
  gint i;
  gchar *ext = "CHECKSUM";

  cancel = checkcopy_get_cancellable ();

  if (priv->checksum_file) {
    /* We already have a file. Just append to it. */
    out = g_file_append_to (priv->checksum_file, 0, cancel, &error);

    if (!out || error) {
      thread_show_gerror (dest, error);
      g_error_free (error);
      error = NULL;

      return NULL;
    } else {
      return G_OUTPUT_STREAM (out);
    }
  }


  /* We do not have a file yet, search for one */

  basename = g_file_get_basename (dest);

  i = 0;
  do {
    DBG ("Try %d to generate a checksum file name", i);
    if (checksum) {
      g_object_unref (checksum);
      checksum = NULL;
    }

    if (error) {
      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_EXISTS)) {
        /* There was an error, but it was not that the file already exists.
         * We should abort at this point. */

        thread_show_error (_("Failed to create checksum file: %s"), error->message);
        g_error_free (error);
        error = NULL;
        break;
      } else {
        /* continue with next iteration */

        g_error_free (error);
        error = NULL;

        if (i > MAX_CHECKSUM_FILE_RETRIES) {
          thread_show_error (_("Maximum number of retries reached.\nCould not create a checksum file."));
          break;
        }
      }
    }

    if (basename == NULL) {
      checksum_name = g_strdup (ext);
    } else {
      if (i==0)
        checksum_name = g_strconcat (basename, ".", ext, NULL);
      else
        checksum_name = g_strdup_printf ("%s-%d.%s", basename, i, ext);
    }

    checksum = g_file_resolve_relative_path (dest, checksum_name);
    i++;

    if (g_cancellable_set_error_if_cancelled (cancel, &error)) {
      break;
    }

  } while ((out = g_file_create (checksum, 0, cancel, &error)) == NULL);

  g_free (basename);

  if (out) {
    priv->checksum_file = checksum;

    return G_OUTPUT_STREAM (out);
  } else {
    if (checksum)
      g_object_unref (checksum);

    return NULL;
  }
}
Exemplo n.º 14
0
int
main(int argc, char *argv[])
{
    EventdCoreContext *context;

    gchar *runtime_dir = NULL;
    gchar *control_socket = NULL;
    gchar **binds = NULL;
    gboolean take_over_socket = FALSE;
    gboolean enable_relay = TRUE;
    gboolean enable_sd_modules = TRUE;
    gchar *config_dir = NULL;
    gboolean daemonize = FALSE;
    gboolean print_paths = FALSE;
    gboolean print_version = FALSE;

    EventdReturnCode retval = EVENTD_RETURN_CODE_OK;
    GError *error = NULL;
    GOptionContext *option_context = NULL;

#ifdef EVENTD_DEBUG
    g_setenv("G_MESSAGES_DEBUG", "all", FALSE);
#endif /* EVENTD_DEBUG */

    setlocale(LC_ALL, "");
#ifdef ENABLE_NLS
    bindtextdomain(GETTEXT_PACKAGE, EVENTD_LOCALEDIR);
    bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
#endif /* ENABLE_NLS */

    if ( ! g_get_filename_charsets(NULL) )
    {
        g_warning(PACKAGE_NAME " does not support non-UTF-8 filename encoding");
        return EVENTD_RETURN_CODE_FILESYSTEM_ENCODING_ERROR;
    }

    if ( G_UNLIKELY(! g_module_supported()) )
    {
        g_warning("No loadable module support");
        return EVENTD_RETURN_CODE_NO_MODULE_SUPPORT_ERROR;
    }

#ifdef EVENTD_DEBUG
    setvbuf(stdout, NULL, _IOLBF, 0);
    const gchar *debug_log_filename =  g_getenv("EVENTD_DEBUG_LOG_FILENAME");
    GDataOutputStream *debug_stream = NULL;

    if ( debug_log_filename != NULL )
    {
        GFile *debug_log;

        debug_log = g_file_new_for_path(debug_log_filename);

        GError *error = NULL;
        GFileOutputStream *debug_log_stream;

        debug_log_stream = g_file_append_to(debug_log, G_FILE_CREATE_NONE, NULL, &error);

        if ( debug_log_stream == NULL )
        {
            g_warning("Couldn't open debug log file: %s", error->message);
            g_clear_error(&error);
        }
        else
        {
            debug_stream = g_data_output_stream_new(G_OUTPUT_STREAM(debug_log_stream));
            g_object_unref(debug_log_stream);

            g_log_set_default_handler(_eventd_core_debug_log_handler, debug_stream);
        }
        g_object_unref(debug_log);
    }
#endif /* EVENTD_DEBUG */

    context = g_new0(EventdCoreContext, 1);
    context->interface.get_sockets = eventd_core_get_sockets;
    context->interface.push_event = eventd_core_push_event;

#ifdef G_OS_UNIX
    context->system_mode = ( g_getenv("XDG_RUNTIME_DIR") == NULL );
    if ( context->system_mode )
        g_setenv("XDG_RUNTIME_DIR", "/run", TRUE);
#endif /* G_OS_UNIX */

    GOptionEntry entries[] =
    {
        { "private-socket",       'i', 0,                     G_OPTION_ARG_FILENAME,     &control_socket,    "Socket to listen for internal control", "<socket>" },
        { "listen",               'l', 0,                     G_OPTION_ARG_STRING_ARRAY, &binds,             "Add a socket to listen to",             "<socket>" },
        { "take-over",            't', GIO_UNIX_OPTION_FLAG,  G_OPTION_ARG_NONE,         &take_over_socket,  "Take over socket",                      NULL },
        { "no-relay",             0,   G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE,         &enable_relay,      "Disable the relay feature",             NULL },
        { "no-service-discovery", 0,   G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE,         &enable_sd_modules, "Disable the service discovery feature", NULL },
        { "config-dir",           'c', 0,                     G_OPTION_ARG_FILENAME,     &config_dir,        "Additionnal configuration directory",   "<directory>" },
        { "daemonize",            0,   G_OPTION_FLAG_HIDDEN,  G_OPTION_ARG_NONE,         &daemonize,         NULL,                                    NULL },
        { "paths",                'P', 0,                     G_OPTION_ARG_NONE,         &print_paths,       "Print search paths",                    NULL },
        { "version",              'V', 0,                     G_OPTION_ARG_NONE,         &print_version,     "Print version",                         NULL },
        { .long_name = NULL }
    };
Exemplo n.º 15
0
static void * gio_fopen (const char * filename, const char * mode)
{
    GError * error = 0;

    FileData * data = g_new0 (FileData, 1);

    data->file = g_file_new_for_uri (filename);

    switch (mode[0])
    {
    case 'r':
        if (strchr (mode, '+'))
        {
            data->iostream = (GIOStream *) g_file_open_readwrite (data->file, 0, & error);
            CHECK_ERROR ("open", filename);
            data->istream = g_io_stream_get_input_stream (data->iostream);
            data->ostream = g_io_stream_get_output_stream (data->iostream);
            data->seekable = (GSeekable *) data->iostream;
        }
        else
        {
            data->istream = (GInputStream *) g_file_read (data->file, 0, & error);
            CHECK_ERROR ("open", filename);
            data->seekable = (GSeekable *) data->istream;
        }
        break;
    case 'w':
        if (strchr (mode, '+'))
        {
            data->iostream = (GIOStream *) g_file_replace_readwrite (data->file, 0, 0, 0, 0, & error);
            CHECK_ERROR ("open", filename);
            data->istream = g_io_stream_get_input_stream (data->iostream);
            data->ostream = g_io_stream_get_output_stream (data->iostream);
            data->seekable = (GSeekable *) data->iostream;
        }
        else
        {
            data->ostream = (GOutputStream *) g_file_replace (data->file, 0, 0, 0, 0, & error);
            CHECK_ERROR ("open", filename);
            data->seekable = (GSeekable *) data->ostream;
        }
        break;
    case 'a':
        if (strchr (mode, '+'))
        {
            gio_error ("Cannot open %s: GIO does not support read-and-append mode.", filename);
            goto FAILED;
        }
        else
        {
            data->ostream = (GOutputStream *) g_file_append_to (data->file, 0, 0, & error);
            CHECK_ERROR ("open", filename);
            data->seekable = (GSeekable *) data->ostream;
        }
        break;
    default:
        gio_error ("Cannot open %s: invalid mode.", filename);
        goto FAILED;
    }

    return data;

FAILED:
    g_free (data);
    return 0;
}
Exemplo n.º 16
0
void
decrypt_file (const gchar *input_file_path, const gchar *pwd)
{
    GError *err = NULL;

    goffset file_size = get_file_size (input_file_path);
    if (file_size == -1) {
        return;
    }
    if (file_size < (goffset) (sizeof (Metadata) + SHA512_DIGEST_SIZE)) {
        g_printerr ("The selected file is not encrypted.\n");
        return;
    }

    GFile *in_file = g_file_new_for_path (input_file_path);
    GFileInputStream *in_stream = g_file_read (in_file, NULL, &err);
    if (err != NULL) {
        g_printerr ("%s\n", err->message);
        // TODO
        return;
    }

    gchar *output_file_path;
    if (!g_str_has_suffix (input_file_path, ".enc")) {
        g_printerr ("The selected file may not be encrypted\n");
        output_file_path = g_strconcat (input_file_path, ".decrypted", NULL);
    }
    else {
        output_file_path = g_strndup (input_file_path, (gsize) g_utf8_strlen (input_file_path, -1) - 4); // remove .enc
    }
    GFile *out_file = g_file_new_for_path (output_file_path);
    GFileOutputStream *out_stream = g_file_append_to (out_file, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &err);
    if (err != NULL) {
        g_printerr ("%s\n", err->message);
        // TODO
        return;
    }

    Metadata *header_metadata = g_new0 (Metadata, 1);
    CryptoKeys *decryption_keys = g_new0 (CryptoKeys, 1);

    gssize rw_len = g_input_stream_read (G_INPUT_STREAM (in_stream), header_metadata, sizeof (Metadata), NULL, &err);
    if (rw_len == -1) {
        g_printerr ("%s\n", err->message);
        // TODO
        return;
    }

    guchar *original_hmac = g_malloc (SHA512_DIGEST_SIZE);
    if (!g_seekable_seek (G_SEEKABLE (in_stream), file_size - SHA512_DIGEST_SIZE, G_SEEK_SET, NULL, &err)) {
        g_printerr ("Couldn't set the position, exiting...\n");
        //TODO
        return;
    }
    rw_len = g_input_stream_read (G_INPUT_STREAM (in_stream), original_hmac, SHA512_DIGEST_SIZE, NULL, &err);
    if (rw_len == -1) {
        g_printerr ("%s\n", err->message);
        // TODO
        return;
    }

    if (!g_seekable_seek (G_SEEKABLE (in_stream), 0, G_SEEK_SET, NULL, &err)) {
        g_printerr ("Couldn't set the position, exiting...\n");
        //TODO
        return;
    }
    GFile *file_encrypted_data = get_g_file_with_encrypted_data (in_stream, file_size);
    if (file_encrypted_data == NULL) {
        // TODO
        return;
    }

    if (!setup_keys (pwd, gcry_cipher_get_algo_keylen (header_metadata->algo), header_metadata, decryption_keys)) {
        g_printerr ("Error during key derivation or during memory allocation\n");
        //TODO
        return;
    }

    if (!compare_hmac (decryption_keys->hmac_key, original_hmac, file_encrypted_data)) {
        g_printerr ("HMAC differs from the one stored inside the file.\nEither the password is wrong or the file has been corrupted.\n");
        // TODO
        return;
    }

    decrypt (header_metadata, decryption_keys, file_encrypted_data, file_size - sizeof (Metadata) - SHA512_DIGEST_SIZE, out_stream);

    g_unlink (g_file_get_path (file_encrypted_data));
    // TODO remove encrypted file? Give option to the user

    multiple_unref (5, (gpointer) &file_encrypted_data,
                    (gpointer) &in_stream,
                    (gpointer) &out_stream,
                    (gpointer) &in_file,
                    (gpointer) &out_file);

    multiple_gcry_free (3, (gpointer) &decryption_keys->crypto_key,
                        (gpointer) &decryption_keys->derived_key,
                        (gpointer) &decryption_keys->hmac_key);

    multiple_free (4, (gpointer) &header_metadata,
                   (gpointer) &output_file_path,
                   (gpointer) &original_hmac,
                   (gpointer) &decryption_keys);
}
Exemplo n.º 17
0
static GjsAutoUnref<GFile>
write_statistics_internal(GjsCoverage *coverage,
                          JSContext   *cx,
                          GError     **error)
{
    using AutoCChar = std::unique_ptr<char, decltype(&free)>;
    using AutoStrv = std::unique_ptr<char *, decltype(&g_strfreev)>;

    GjsCoveragePrivate *priv = (GjsCoveragePrivate *) gjs_coverage_get_instance_private(coverage);

    /* Create output directory if it doesn't exist */
    if (!g_file_make_directory_with_parents(priv->output_dir, nullptr, error)) {
        if (!g_error_matches(*error, G_IO_ERROR, G_IO_ERROR_EXISTS))
            return nullptr;
        g_clear_error(error);
    }

    GFile *output_file = g_file_get_child(priv->output_dir, "coverage.lcov");

    size_t lcov_length;
    AutoCChar lcov(js::GetCodeCoverageSummary(cx, &lcov_length), free);

    GjsAutoUnref<GOutputStream> ostream =
        G_OUTPUT_STREAM(g_file_append_to(output_file,
                                         G_FILE_CREATE_NONE,
                                         NULL,
                                         error));
    if (!ostream)
        return nullptr;

    AutoStrv lcov_lines(g_strsplit(lcov.get(), "\n", -1), g_strfreev);
    GjsAutoChar test_name;
    bool ignoring_file = false;

    for (const char * const *iter = lcov_lines.get(); *iter; iter++) {
        if (ignoring_file) {
            if (strcmp(*iter, "end_of_record") == 0)
                ignoring_file = false;
            continue;
        }

        if (g_str_has_prefix(*iter, "TN:")) {
            /* Don't write the test name if the next line shows we are
             * ignoring the source file */
            test_name = *iter;
            continue;
        } else if (g_str_has_prefix(*iter, "SF:")) {
            const char *filename = *iter + 3;
            if (!filename_has_coverage_prefixes(coverage, filename)) {
                ignoring_file = true;
                continue;
            }

            /* Now we can write the test name before writing the source file */
            if (!write_line(ostream, test_name.get(), error))
                return nullptr;

            /* The source file could be a resource, so we must use
             * g_file_new_for_commandline_arg() to disambiguate between URIs and
             * filesystem paths. */
            GjsAutoUnref<GFile> source_file = g_file_new_for_commandline_arg(filename);
            GjsAutoChar diverged_paths =
                find_diverging_child_components(source_file, priv->output_dir);
            GjsAutoUnref<GFile> destination_file =
                g_file_resolve_relative_path(priv->output_dir, diverged_paths);
            if (!copy_source_file_to_coverage_output(source_file, destination_file, error))
                return nullptr;

            /* Rewrite the source file path to be relative to the output
             * dir so that genhtml will find it */
            if (!write_source_file_header(ostream, destination_file, error))
                return nullptr;
            continue;
        }

        if (!write_line(ostream, *iter, error))
            return nullptr;
    }

    return output_file;
}
Exemplo n.º 18
0
int
main(int argc, char *argv[])
{
    gboolean print_version = FALSE;
    gboolean one_shot = FALSE;
    gchar *output_plugin = NULL;
    gchar **servers_desc = NULL;
    gchar **streams_desc = NULL;
    gchar **input_plugins = NULL;
    gchar **order = NULL;
    gchar *config = NULL;

    int retval = 0;
    GError *error = NULL;
    GOptionContext *option_context = NULL;
    GOptionGroup *option_group;

#if DEBUG
    g_setenv("G_MESSAGES_DEBUG", "all", FALSE);
#endif /* ! DEBUG */

    setlocale(LC_ALL, "");
#ifdef ENABLE_NLS
    bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
    bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
#endif /* ENABLE_NLS */

#if DEBUG
    const gchar *debug_log_filename =  g_getenv("J4STATUS_DEBUG_LOG_FILENAME");
    GDataOutputStream *debug_stream = NULL;

    if ( debug_log_filename != NULL )
    {
        GFile *debug_log;

        debug_log = g_file_new_for_path(debug_log_filename);

        GError *error = NULL;
        GFileOutputStream *debug_log_stream;

        debug_log_stream = g_file_append_to(debug_log, G_FILE_CREATE_NONE, NULL, &error);

        if ( debug_log_stream == NULL )
        {
            g_warning("Couldn't open debug log file: %s", error->message);
            g_clear_error(&error);
        }
        else
        {
            debug_stream = g_data_output_stream_new(G_OUTPUT_STREAM(debug_log_stream));
            g_object_unref(debug_log_stream);

            g_log_set_default_handler(_j4status_core_debug_log_handler, debug_stream);
        }
        g_object_unref(debug_log);
    }
#endif /* DEBUG */

    GOptionEntry entries[] =
    {
        { "output",     'o', 0, G_OPTION_ARG_STRING,       &output_plugin, "Output plugin to use", "<plugin>" },
        { "listen",     'l', 0, G_OPTION_ARG_STRING_ARRAY, &servers_desc,  "Socket to listen on, will create a stream on connection (may be specified several times)", "<listen description>" },
        { "stream",     't', 0, G_OPTION_ARG_STRING_ARRAY, &streams_desc,  "Stream to read from/write to (may be specified several times)", "<stream description>" },
        { "input",      'i', 0, G_OPTION_ARG_STRING_ARRAY, &input_plugins, "Input plugins to use (may be specified several times)", "<plugin>" },
        { "order",      'O', 0, G_OPTION_ARG_STRING_ARRAY, &order,         "Order of sections, specified once a section (see man)", "<section id>" },
        { "one-shot",   '1', 0, G_OPTION_ARG_NONE,         &one_shot,      "Tells j4status to stop right after starting",           NULL },
        { "config",     'c', 0, G_OPTION_ARG_STRING,       &config,        "Config file to use", "<config>" },
        { "version",    'V', 0, G_OPTION_ARG_NONE,         &print_version, "Print version",        NULL },
        { NULL }
    };


    option_context = g_option_context_new("- status line generator");

    option_group = g_option_group_new(NULL, NULL, NULL, NULL, NULL);
    g_option_group_set_translation_domain(option_group, GETTEXT_PACKAGE);
    g_option_group_add_entries(option_group, entries);
    g_option_context_set_main_group(option_context, option_group);

    if ( ! g_option_context_parse(option_context, &argc, &argv, &error) )
    {
        g_warning("Option parsing failed: %s\n", error->message);
        g_clear_error(&error);
        retval = 1;
        goto end;
    }
    g_option_context_free(option_context);

    if ( print_version )
    {
        g_fprintf(stdout, PACKAGE_NAME " " PACKAGE_VERSION "\n");
        goto end;
    }

    if ( config != NULL )
    {
        g_setenv("J4STATUS_CONFIG_FILE", config, TRUE);
        g_free(config);
    }

    GKeyFile *key_file;
    key_file = j4status_config_get_key_file("Plugins");
    if ( key_file != NULL )
    {
        if ( output_plugin == NULL )
            output_plugin = g_key_file_get_string(key_file, "Plugins", "Output", NULL);

        if ( input_plugins == NULL )
            input_plugins = g_key_file_get_string_list(key_file, "Plugins", "Input", NULL, NULL);

        if ( order == NULL )
            order = g_key_file_get_string_list(key_file, "Plugins", "Order", NULL, NULL);

        g_key_file_free(key_file);
    }

    J4statusCoreContext *context;
    context = g_new0(J4statusCoreContext, 1);

    J4statusCoreInterface interface = {
        .context = context,
        .add_section = _j4status_core_add_section,
        .remove_section = _j4status_core_remove_section,
        .trigger_generate = _j4status_core_trigger_generate,
        .trigger_action = _j4status_core_trigger_action,
    };

#ifdef G_OS_UNIX
    g_unix_signal_add(SIGTERM, _j4status_core_source_quit, context);

    g_unix_signal_add(SIGINT, _j4status_core_source_quit, context);
    g_unix_signal_add(SIGUSR1, _j4status_core_signal_usr1, context);
    g_unix_signal_add(SIGUSR2, _j4status_core_signal_usr2, context);

    /* Ignore SIGPIPE as it is useless */
    signal(SIGPIPE, SIG_IGN);
#endif /* G_OS_UNIX */

    context->output_plugin = j4status_plugins_get_output_plugin(&interface, output_plugin);
    if ( context->output_plugin == NULL )
    {
        g_warning("No usable output plugin, tried '%s'", output_plugin);
        retval = 10;
        goto end;
    }

    gchar *header = NULL;
    if ( context->output_plugin->interface.generate_header != NULL )
        header = context->output_plugin->interface.generate_header(context->output_plugin->context);

    /* Creating input/output stream */
    context->io = j4status_io_new(context, header, (const gchar * const *) servers_desc, (const gchar * const *) streams_desc);
    if ( context->io == NULL )
    {
        g_warning("Couldn't create input/output streams");
        retval = 2;
        goto end;
    }

    if ( order != NULL )
    {
        context->order_weights = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
        gchar **id;
        for ( id = order ; *id != NULL ; ++id )
            g_hash_table_insert(context->order_weights, *id, GINT_TO_POINTER(1 + id - order));
        g_free(order);
    }

    context->sections_hash = g_hash_table_new(g_str_hash, g_str_equal);

    context->input_plugins = j4status_plugins_get_input_plugins(&interface, input_plugins);
    if ( context->input_plugins == NULL )
    {
        g_warning("No input plugins, will stop early");
        one_shot = TRUE;
        retval = 11;
    }
    context->sections = g_list_reverse(context->sections);
    if ( context->order_weights != NULL )
        context->sections = g_list_sort(context->sections, _j4status_core_compare_sections);

    _j4status_core_start(context);

    if ( one_shot )
        g_idle_add(_j4status_core_source_quit, context);

    context->loop = g_main_loop_new(NULL, FALSE);
    g_main_loop_run(context->loop);
    g_main_loop_unref(context->loop);
    context->loop = NULL;

    GList *input_plugin_;
    J4statusInputPlugin *input_plugin;
    for ( input_plugin_ = context->input_plugins ; input_plugin_ != NULL ; input_plugin_ = g_list_next(input_plugin_) )
    {
        input_plugin = input_plugin_->data;
        input_plugin->interface.uninit(input_plugin->context);
    }

    if ( context->output_plugin->interface.uninit != NULL )
        context->output_plugin->interface.uninit(context->output_plugin->context);

    j4status_io_free(context->io);

    if ( context->order_weights != NULL )
        g_hash_table_unref(context->order_weights);

    g_hash_table_unref(context->sections_hash);

end:
#if DEBUG
    if ( debug_stream != NULL )
        g_object_unref(debug_stream);
#endif /* DEBUG */

    return retval;
}
Exemplo n.º 19
0
gpointer
sign_file (const gchar *input_file_path, const gchar *fpr)
{
    gpgme_error_t error;
    gpgme_ctx_t context;
    gpgme_key_t signing_key;
    gpgme_data_t clear_text, signed_text;
    gpgme_sign_result_t result;
    gchar *buffer;
    gssize nbytes;

    error = gpgme_new (&context);
    if (error) {
        g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error));
        return GPGME_ERROR;
    }

    gpgme_set_armor (context, 0);

    error = gpgme_engine_check_version (GPGME_PROTOCOL_OpenPGP);
    if (error) {
        g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error));
        gpgme_release (context);
        return GPGME_ERROR;
    }

    const char *keyring_dir = gpgme_get_dirinfo ("homedir");
    error = gpgme_ctx_set_engine_info (context, GPGME_PROTOCOL_OpenPGP, NULL, keyring_dir);
    if (error) {
        g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error));
        gpgme_release (context);
        return GPGME_ERROR;
    }

    error = gpgme_get_key (context, fpr, &signing_key, 1);
    if (error) {
        g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error));
        gpgme_release (context);
        return GPGME_ERROR;
    }

    error = gpgme_signers_add (context, signing_key);
    if (error) {
        g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error));
        cleanup (NULL, NULL, NULL, NULL, &signing_key, &context);
        return GPGME_ERROR;
    }

    FILE *infp = g_fopen (input_file_path, "r");
    if (infp == NULL) {
        g_printerr ("Couldn't open input file\n");
        cleanup (NULL, NULL, NULL, NULL, &signing_key, &context);
        return FILE_OPEN_ERROR;
    }

    error = gpgme_data_new_from_stream (&clear_text, infp);
    if (error) {
        g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error));
        cleanup (infp, NULL, NULL, NULL, &signing_key, &context);
        return GPGME_ERROR;
    }

    error = gpgme_data_new (&signed_text);
    if (error) {
        g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error));
        cleanup (infp, NULL, NULL, NULL, &signing_key, &context);
        return GPGME_ERROR;
    }

    error = gpgme_op_sign (context, clear_text, signed_text, GPGME_SIG_MODE_DETACH);
    if (error) {
        g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error));
        cleanup (infp, NULL, NULL, NULL, &signing_key, &context);
        return GPGME_ERROR;
    }

    result = gpgme_op_sign_result (context);
    if (result->invalid_signers) {
        g_printerr ("Invalid signer found: %s\n", result->invalid_signers->fpr);
        cleanup (infp, NULL, NULL, NULL, &signing_key, &context);
        return GPGME_ERROR;
    }
    if (!result->signatures || result->signatures->next) {
        g_printerr ("Unexpected number of signatures created\n");
        cleanup (infp, NULL, NULL, NULL, &signing_key, &context);
        return GPGME_ERROR;
    }

    error = gpgme_data_seek (signed_text, 0, SEEK_SET);
    if (error) {
        g_printerr ("%s:%d: %s: %s\n", __FILE__, __LINE__, gpgme_strsource (error), gpgme_strerror (error));
        cleanup (infp, NULL, NULL, NULL, &signing_key, &context);
        return GPGME_ERROR;
    }

    buffer = g_try_malloc0 (SIG_MAXLEN);
    if (buffer == NULL) {
        g_printerr ("Couldn't allocate memory\n");
        cleanup (infp, NULL, NULL, NULL, &signing_key, &context);
        return MEMORY_ALLOCATION_ERROR;
    }

    nbytes = gpgme_data_read (signed_text, buffer, SIG_MAXLEN);
    if (nbytes == -1) {
        g_printerr ("Error while reading data\n");
        cleanup (infp, NULL, NULL, NULL, &signing_key, &context);
        return GPGME_ERROR;
    }

    GError *gerr = NULL;
    gchar *output_file_path = g_strconcat (input_file_path, ".sig", NULL);
    GFile *fpout = g_file_new_for_path (output_file_path);
    GFileOutputStream *ostream = g_file_append_to (fpout, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &gerr);
    if (gerr != NULL) {
        g_printerr ("Couldn't open output file for writing\n");
        cleanup (infp, fpout, NULL, output_file_path, &signing_key, &context);
        return FILE_OPEN_ERROR;
    }

    gssize wbytes = g_output_stream_write (G_OUTPUT_STREAM (ostream), buffer, nbytes, NULL, &gerr);
    if (wbytes == -1) {
        g_printerr ("Couldn't write the request number of bytes (%s)\n", gerr->message);
        cleanup (infp, fpout, ostream, output_file_path, &signing_key, &context);
        return FILE_WRITE_ERROR;
    }

    cleanup (infp, fpout, ostream, output_file_path, &signing_key, &context);

    return SIGN_OK;
}
Exemplo n.º 20
0
gpointer
encrypt_file (const gchar *input_file_path, const gchar *pwd, const gchar *algo, const gchar *algo_mode)
{
    Metadata *header_metadata = g_new0 (Metadata, 1);
    CryptoKeys *encryption_keys = g_new0 (CryptoKeys, 1);

    set_algo_and_mode (header_metadata, algo, algo_mode);
    gsize algo_key_len = gcry_cipher_get_algo_keylen (header_metadata->algo);
    gsize algo_blk_len = gcry_cipher_get_algo_blklen (header_metadata->algo);

    header_metadata->iv_size = algo_blk_len;  // iv must be the same size as the block size

    gcry_create_nonce (header_metadata->iv, header_metadata->iv_size);
    gcry_create_nonce (header_metadata->salt, KDF_SALT_SIZE);

    if (!setup_keys (pwd, algo_key_len, header_metadata, encryption_keys)) {
        multiple_free (2, (gpointer) &encryption_keys, (gpointer) &header_metadata);
        return g_strdup ("Couldn't setup the encryption keys, exiting...");
    }

    goffset filesize = get_file_size (input_file_path);

    GError *err = NULL;

    GFile *in_file = g_file_new_for_path (input_file_path);
    GFileInputStream *in_stream = g_file_read (in_file, NULL, &err);
    if (err != NULL) {
        multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key,
                            (gpointer) &encryption_keys->hmac_key);
        multiple_free (2, (gpointer) &encryption_keys, (gpointer) &header_metadata);
        g_object_unref (in_file);

        return g_strdup (err->message);
    }

    gchar *output_file_path = g_strconcat (input_file_path, ".enc", NULL);
    GFile *out_file = g_file_new_for_path (output_file_path);
    GFileOutputStream *out_stream = g_file_append_to (out_file, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &err);
    if (err != NULL) {
        multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key,
                            (gpointer) &encryption_keys->hmac_key);
        multiple_free (3, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &output_file_path);
        multiple_unref (3, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream);
        g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL);

        return g_strdup (err->message);
    }

    gcry_cipher_hd_t hd;
    gcry_cipher_open (&hd, header_metadata->algo, header_metadata->algo_mode, 0);
    gcry_cipher_setkey (hd, encryption_keys->crypto_key, algo_key_len);

    gint64 number_of_blocks;
    gint number_of_padding_bytes;
    gchar *ret_msg;
    if (header_metadata->algo_mode == GCRY_CIPHER_MODE_CBC) {
        set_number_of_blocks_and_padding_bytes (filesize, algo_blk_len, &number_of_blocks, &number_of_padding_bytes);
        gcry_cipher_setiv (hd, header_metadata->iv, header_metadata->iv_size);
        ret_msg = encrypt_using_cbc_mode (header_metadata, &hd, number_of_blocks, number_of_padding_bytes, algo_blk_len, in_stream, out_stream);
    }
    else {
        gcry_cipher_setctr (hd, header_metadata->iv, header_metadata->iv_size);
        ret_msg = encrypt_using_ctr_mode (header_metadata, &hd, filesize, in_stream, out_stream);
    }
    if (ret_msg != NULL) {
        multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key,
                            (gpointer) &encryption_keys->hmac_key);
        multiple_free (3, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &output_file_path);
        multiple_unref (4, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream,
                        (gpointer) &out_stream);
        g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL);
        g_output_stream_close (G_OUTPUT_STREAM (out_stream), NULL, NULL);

        return g_strdup (ret_msg);

    }

    gcry_cipher_close (hd);

    guchar *hmac = calculate_hmac (output_file_path, encryption_keys->hmac_key, NULL);
    gssize written_bytes = g_output_stream_write (G_OUTPUT_STREAM (out_stream), hmac, SHA512_DIGEST_SIZE, NULL, &err);
    if (written_bytes == -1) {
        multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key,
                            (gpointer) &encryption_keys->hmac_key);
        multiple_free (4, (gpointer) &encryption_keys, (gpointer) &header_metadata, (gpointer) &output_file_path,
                       (gpointer) &hmac);
        multiple_unref (4, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream,
                        (gpointer) &out_stream);
        g_output_stream_close (G_OUTPUT_STREAM (out_stream), NULL, NULL);

        return g_strdup (err->message);
    }

    g_input_stream_close (G_INPUT_STREAM (in_stream), NULL, NULL);
    g_output_stream_close (G_OUTPUT_STREAM (out_stream), NULL, NULL);

    multiple_gcry_free (3, (gpointer) &encryption_keys->derived_key, (gpointer) &encryption_keys->crypto_key,
                        (gpointer) &encryption_keys->hmac_key);

    multiple_free (4, (gpointer) &output_file_path, (gpointer) &encryption_keys, (gpointer) &header_metadata,
                   (gpointer) &hmac);

    multiple_unref (4, (gpointer) &in_file, (gpointer) &out_file, (gpointer) &in_stream,
                    (gpointer) &out_stream);

    return NULL;
}
Exemplo n.º 21
0
static gboolean
save (GFile *file)
{
  GOutputStream *out;
  GFileCreateFlags flags;
  char buffer[1025];
  char *p;
  gssize res;
  gboolean close_res;
  GError *error;
  gboolean save_res;

  error = NULL;

  flags = priv ? G_FILE_CREATE_PRIVATE : G_FILE_CREATE_NONE;
  flags |= replace_dest ? G_FILE_CREATE_REPLACE_DESTINATION : 0;

  if (create)
    out = (GOutputStream *)g_file_create (file, flags, NULL, &error);
  else if (append)
    out = (GOutputStream *)g_file_append_to (file, flags, NULL, &error);
  else
    out = (GOutputStream *)g_file_replace (file, etag, backup, flags, NULL, &error);
  if (out == NULL)
    {
      g_printerr (_("Error opening file: %s\n"), error->message);
      g_error_free (error);
      return FALSE;
    }

  save_res = TRUE;

  while (1)
    {
      res = read (STDIN_FILENO, buffer, 1024);
      if (res > 0)
	{
	  ssize_t written;

	  p = buffer;
	  while (res > 0)
	    {
	      error = NULL;
	      written = g_output_stream_write (out, p, res, NULL, &error);
	      if (written == -1)
		{
		  save_res = FALSE;
		  g_printerr ("Error writing to stream: %s", error->message);
		  g_error_free (error);
		  goto out;
		}
	      res -= written;
	      p += written;
	    }
	}
      else if (res < 0)
	{
	  save_res = FALSE;
	  perror (_("Error reading stdin"));
	  break;
	}
      else if (res == 0)
	break;
    }

 out:

  close_res = g_output_stream_close (out, NULL, &error);
  if (!close_res)
    {
      save_res = FALSE;
      g_printerr (_("Error closing: %s\n"), error->message);
      g_error_free (error);
    }

  if (close_res && print_etag)
    {
      char *etag;
      etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (out));

      if (etag)
	g_print ("Etag: %s\n", etag);
      else
	/* Translators: The "etag" is a token allowing to verify whether a file has been modified */
	g_print (_("Etag not available\n"));
      g_free (etag);
    }

  g_object_unref (out);

  return save_res;
}