Blame src/cli/abrt-cli-core.c

Packit 8ea169
/*
Packit 8ea169
    Copyright (C) 2011  ABRT Team
Packit 8ea169
    Copyright (C) 2011  RedHat inc.
Packit 8ea169
Packit 8ea169
    This program is free software; you can redistribute it and/or modify
Packit 8ea169
    it under the terms of the GNU General Public License as published by
Packit 8ea169
    the Free Software Foundation; either version 2 of the License, or
Packit 8ea169
    (at your option) any later version.
Packit 8ea169
Packit 8ea169
    This program is distributed in the hope that it will be useful,
Packit 8ea169
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 8ea169
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 8ea169
    GNU General Public License for more details.
Packit 8ea169
Packit 8ea169
    You should have received a copy of the GNU General Public License along
Packit 8ea169
    with this program; if not, write to the Free Software Foundation, Inc.,
Packit 8ea169
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Packit 8ea169
*/
Packit 8ea169
Packit 8ea169
#include "libabrt.h"
Packit 8ea169
#include "abrt-cli-core.h"
Packit 8ea169
Packit 8ea169
/* It is not possible to include polkitagent.h without the following define.
Packit 8ea169
 * Check out the included header file.
Packit 8ea169
 */
Packit 8ea169
#ifdef HAVE_POLKIT
Packit 8ea169
#define POLKIT_AGENT_I_KNOW_API_IS_SUBJECT_TO_CHANGE
Packit 8ea169
#include <polkitagent/polkitagent.h>
Packit 8ea169
#endif
Packit 8ea169
Packit 8ea169
int g_cli_authenticate;
Packit 8ea169
Packit 8ea169
#ifdef HAVE_POLKIT
Packit 8ea169
static PolkitAgentListener *s_local_polkit_agent = NULL;
Packit 8ea169
static gpointer s_local_agent_handle = NULL;
Packit 8ea169
#endif
Packit 8ea169
Packit 8ea169
/* Vector of problems: */
Packit 8ea169
/* problem_data_vector[i] = { "name" = { "content", CD_FLAG_foo_bits } } */
Packit 8ea169
Packit 8ea169
inline problem_data_t *get_problem_data(vector_of_problem_data_t *vector, unsigned i)
Packit 8ea169
{
Packit 8ea169
    return (problem_data_t *)g_ptr_array_index(vector, i);
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
void free_vector_of_problem_data(vector_of_problem_data_t *vector)
Packit 8ea169
{
Packit 8ea169
    if (vector)
Packit 8ea169
        g_ptr_array_free(vector, TRUE);
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
vector_of_problem_data_t *new_vector_of_problem_data(void)
Packit 8ea169
{
Packit 8ea169
    return g_ptr_array_new_with_free_func((void (*)(void*)) &problem_data_free);
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
vector_of_problem_data_t *fetch_crash_infos(void)
Packit 8ea169
{
Packit 8ea169
    GList *problems = get_problems_over_dbus(g_cli_authenticate);
Packit 8ea169
    if (problems == ERR_PTR)
Packit 8ea169
        return NULL;
Packit 8ea169
Packit 8ea169
    vector_of_problem_data_t *vpd = new_vector_of_problem_data();
Packit 8ea169
Packit 8ea169
    for (GList *iter = problems; iter; iter = g_list_next(iter))
Packit 8ea169
    {
Packit 8ea169
        problem_data_t *problem_data = get_full_problem_data_over_dbus((const char *)(iter->data));
Packit 8ea169
        if (problem_data == ERR_PTR)
Packit 8ea169
            continue;
Packit 8ea169
Packit 8ea169
        g_ptr_array_add(vpd, problem_data);
Packit 8ea169
    }
Packit 8ea169
Packit 8ea169
    return vpd;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
Packit 8ea169
static bool isxdigit_str(const char *str)
Packit 8ea169
{
Packit 8ea169
    do
Packit 8ea169
    {
Packit 8ea169
        if (*str < '0' || *str > '9')
Packit 8ea169
            if ((*str|0x20) < 'a' || (*str|0x20) > 'f')
Packit 8ea169
                return false;
Packit 8ea169
        str++;
Packit 8ea169
    } while (*str);
Packit 8ea169
    return true;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
char *find_problem_by_hash(const char *hash, GList *problems)
Packit 8ea169
{
Packit 8ea169
    unsigned hash_len = strlen(hash);
Packit 8ea169
    if (!isxdigit_str(hash) || hash_len < 5)
Packit 8ea169
        return NULL;
Packit 8ea169
Packit 8ea169
    char *found_name = NULL;
Packit 8ea169
    for (GList *iter = problems; iter; iter = g_list_next(iter))
Packit 8ea169
    {
Packit 8ea169
        char hash_str[SHA1_RESULT_LEN*2 + 1];
Packit 8ea169
        str_to_sha1str(hash_str, (const char *)(iter->data));
Packit 8ea169
        if (strncasecmp(hash, hash_str, hash_len) == 0)
Packit 8ea169
        {
Packit 8ea169
            if (found_name)
Packit 8ea169
                error_msg_and_die(_("'%s' identifies more than one problem directory"), hash);
Packit 8ea169
            found_name = xstrdup((const char *)(iter->data));
Packit 8ea169
        }
Packit 8ea169
    }
Packit 8ea169
Packit 8ea169
    return found_name;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
char *hash2dirname(const char *hash)
Packit 8ea169
{
Packit 8ea169
    /* Try loading by dirname hash */
Packit 8ea169
    GList *problems = get_problems_over_dbus(g_cli_authenticate);
Packit 8ea169
    if (problems == ERR_PTR)
Packit 8ea169
        return NULL;
Packit 8ea169
Packit 8ea169
    char *found_name = find_problem_by_hash(hash, problems);
Packit 8ea169
Packit 8ea169
    g_list_free_full(problems, free);
Packit 8ea169
Packit 8ea169
    return found_name;
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
char *hash2dirname_if_necessary(const char *input)
Packit 8ea169
{
Packit 8ea169
    return isxdigit_str(input) ? hash2dirname(input) : xstrdup(input);
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
void initialize_polkit_agent(void)
Packit 8ea169
{
Packit 8ea169
#ifdef HAVE_POLKIT
Packit 8ea169
    GError *error = NULL;
Packit 8ea169
    PolkitSubject *subject = polkit_unix_process_new_for_owner(
Packit 8ea169
                                getpid(),
Packit 8ea169
                                /*start time from /proc*/0,
Packit 8ea169
                                getuid());
Packit 8ea169
Packit 8ea169
    s_local_polkit_agent = polkit_agent_text_listener_new(NULL, &error);
Packit 8ea169
    if (s_local_polkit_agent == NULL)
Packit 8ea169
    {
Packit 8ea169
        error_msg_and_die("polkit_agent_text_listener_new: %s (%s, %d)\n",
Packit 8ea169
                error->message, g_quark_to_string (error->domain), error->code);
Packit 8ea169
    }
Packit 8ea169
Packit 8ea169
    s_local_agent_handle = polkit_agent_listener_register(s_local_polkit_agent,
Packit 8ea169
            POLKIT_AGENT_REGISTER_FLAGS_RUN_IN_THREAD, subject, NULL, NULL, &error);
Packit 8ea169
    if (s_local_agent_handle == NULL)
Packit 8ea169
    {
Packit 8ea169
        error_msg_and_die("polkit_agent_listener_register: %s (%s, %d)\n",
Packit 8ea169
                error->message, g_quark_to_string (error->domain), error->code);
Packit 8ea169
    }
Packit 8ea169
Packit 8ea169
    g_object_unref(subject);
Packit 8ea169
#else
Packit 8ea169
    log_info("Polkit support is currently disabled");
Packit 8ea169
#endif
Packit 8ea169
}
Packit 8ea169
Packit 8ea169
void uninitialize_polkit_agent(void)
Packit 8ea169
{
Packit 8ea169
#ifdef HAVE_POLKIT
Packit 8ea169
    if (s_local_agent_handle != NULL)
Packit 8ea169
        polkit_agent_listener_unregister(s_local_agent_handle);
Packit 8ea169
Packit 8ea169
    if (s_local_polkit_agent != NULL)
Packit 8ea169
        g_object_unref(s_local_polkit_agent);
Packit 8ea169
#endif
Packit 8ea169
}