|
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 |
}
|