diff --git a/.gitignore b/.gitignore index 7b8b26907e8559f01f508d6de8b89115db105d12..71f7de0cebf260be47aeb8ee818f3274a648e315 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,6 @@ *.out *.gi bin/unlock_keyrings +.idea +testinput diff --git a/src/Makefile b/src/Makefile index 1c4810cf49414b143c38775ecb9f9ea2a5d002f7..86d647549826ca1e043a9e627eb9ad29160f61e8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,9 +1,11 @@ CXX ?= g++ # Accepts CXXSTD >= C++14 -CXXFLAGS := -I ./lib -I . -std=c++14 +CXXFLAGS := -I ./lib -I . -std=c++14 -g -O0 EXTRA_FLAGS ?= +all: libsecret_test secret + secret: mkdir -p ../bin/ $(CXX) unlock_keyrings.cc -DUSE_LIBGNOMEKEYRING -o ../bin/unlock_keyrings $(CXXFLAGS) $(EXTRA_FLAGS) $(shell pkg-config --cflags --libs gnome-keyring-1) diff --git a/src/keyring_op.hpp b/src/keyring_op.hpp index fcbe4bcb76336a19bb345633fc8756aee1f9cfaf..29f4f8c59b7ae99f417950ee197d67096186d8d5 100644 --- a/src/keyring_op.hpp +++ b/src/keyring_op.hpp @@ -6,6 +6,51 @@ using namespace std::literals; #include <libsecret/secret.h> #include <gmodule.h> +//GVariant * hooked_prompt_sync (SecretService *self, +// SecretPrompt *prompt, +// GCancellable *cancellable, +// const GVariantType *return_type, +// GError **error) { +// auto original_funcptr = decltype(&hooked_prompt_sync)(gl_original_funcptr); +// auto res = original_funcptr(self, prompt, cancellable, return_type, error); +// +// g_variant_ref(res); +// rlib_defer([&]{ g_variant_unref(res); }); +// +// rlib::println("DEBUG: prompt res typestr: ", g_variant_get_type_string(res)); +// +// gsize output_strlen; +// auto output_str = g_variant_get_string(res, &output_strlen); +// // TODO: is this working in utf8 characters? +// rlib::println("DEBUG: prompt res: ", std::string(output_str, output_strlen)); +// +// return res; +//} + +void *gl_original_funcptr = nullptr; +GAsyncReadyCallback gl_real_async_callback = nullptr; +void hooked_fake_callback(GObject *source_object, + GAsyncResult *res, + gpointer user_dat) { + rlib::println("HIT"); + // rlib::println(g_async_result_get_user_data(res)) + gl_real_async_callback(source_object, res, user_dat); +} + +void hooked_prompt_async (SecretService *self, + SecretPrompt *prompt, + const GVariantType *return_type, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) { + // TODO: read secret_prompt_perform and secret_prompt_perform_sync + // to learn how to call the callback directly. + gl_real_async_callback = callback; + rlib::println("return type=", g_variant_type_peek_string(return_type)); + auto original_funcptr = decltype(&hooked_prompt_async)(gl_original_funcptr); + original_funcptr(self, prompt, return_type, cancellable, &hooked_fake_callback, user_data); +} + inline std::string do_unlock(std::string keyring_label, std::string password) { GError *err = NULL; SecretService *service_proxy_ptr = secret_service_get_sync(SECRET_SERVICE_LOAD_COLLECTIONS, NULL, &err); @@ -14,10 +59,12 @@ inline std::string do_unlock(std::string keyring_label, std::string password) { } rlib_defer([&]{g_object_unref(service_proxy_ptr);}); + gl_original_funcptr = (void *) SECRET_SERVICE_GET_CLASS(service_proxy_ptr)->prompt_async; + SECRET_SERVICE_GET_CLASS(service_proxy_ptr)->prompt_async = &hooked_prompt_async; + GList *collections = secret_service_get_collections(service_proxy_ptr); if(collections == NULL) return "collection gg"; GList *collections_to_unlock = NULL; - GList *collections_unlocked = NULL; auto curr = collections; while (curr != NULL) @@ -36,7 +83,7 @@ inline std::string do_unlock(std::string keyring_label, std::string password) { return "No such keyring with label: "s + keyring_label + ". You need keyring LABEL instead of NAME. "; } - auto unlocked_count = secret_service_unlock_sync(service_proxy_ptr, collections_to_unlock, NULL, &collections_unlocked, &err); + auto unlocked_count = secret_service_unlock_sync(service_proxy_ptr, collections_to_unlock, NULL, NULL, &err); if(unlocked_count == g_list_length(collections_to_unlock)) return "SUCCESS"; else {