diff --git a/README.md b/README.md index 4ff65ba5449a5aca6e64f216453c0e34dbeb0701..0550076431f85d7c081b2fab986054989d688442 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ run `tools/list_keyrings.sh` to check name of your keyrings. The `login` keyring - Working on keyring `Login`: GNOME\_KEYRING\_RESULT\_BAD\_ARGUMENTS. -Seahorse sometimes show an incorrect name for "Login" keyring. It's real name is `login` instead of `Login`. You may confirm this by running `tools/list_keyrings.sh`. +Seahorse is showing "label" of your keyring but you need "name" of it. It's real name is `login` instead of `Login`. You may confirm this by running `tools/list_keyrings.sh`. - It's simply not working. How do I debug this program? diff --git a/src/Makefile b/src/Makefile index a6f861cc9a7f4bad8472a70d66957d28f1272e82..1332f60a87550f886dbf8c3635c76d5da1e35636 100644 --- a/src/Makefile +++ b/src/Makefile @@ -6,5 +6,9 @@ EXTRA_FLAGS ?= secret: mkdir -p ../bin/ - $(CXX) unlock_keyrings.cc -o ../bin/unlock_keyrings $(CXXFLAGS) $(EXTRA_FLAGS) + $(CXX) unlock_keyrings.cc -DUSE_LIBGNOMEKEYRING -o ../bin/unlock_keyrings $(CXXFLAGS) $(EXTRA_FLAGS) + +libsecret_test: + mkdir -p ../bin/ + $(CXX) unlock_keyrings.cc -DUSE_LIBSECRET -o ../bin/unlock_keyrings $(CXXFLAGS) $(EXTRA_FLAGS) diff --git a/src/keyring_op.hpp b/src/keyring_op.hpp index 1a295835cdfa2ede368be081555df8d24fa69982..ad24e1c31a2f7a939768520aa97eb4e296583fe7 100644 --- a/src/keyring_op.hpp +++ b/src/keyring_op.hpp @@ -1,14 +1,14 @@ #include <gnome-keyring-1/gnome-keyring.h> #include <string> #include <rlib/macro.hpp> +using namespace std::literals; #include <libsecret/secret.h> #include <gmodule.h> #include <rlib/stdio.hpp> -// TODO: read https://gnome.pages.gitlab.gnome.org/libsecret/class.Service.html -// https://gnome.pages.gitlab.gnome.org/libsecret/method.Service.prompt.html -inline std::string do_unlock_2(std::string keyring, std::string password) { +#if defined(USE_LIBSECRET) +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); if(err != NULL or service_proxy_ptr == NULL) { @@ -18,6 +18,8 @@ inline std::string do_unlock_2(std::string keyring, std::string password) { 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) @@ -27,16 +29,33 @@ inline std::string do_unlock_2(std::string keyring, std::string password) { if(label == NULL) break; rlib_defer([&]{g_free(label);}); rlib::println("DEBUG: LABEL=", label); + if(std::string(label) == keyring_label) { + collections_to_unlock = g_list_append(collections_to_unlock, iter); + rlib::println("APPEND!"); + } curr = curr->next; } - return ""; -} + if(g_list_length(collections_to_unlock) == 0) { + return "No such keyring with label: "s + keyring_label; + } + auto unlocked_count = secret_service_unlock_sync(service_proxy_ptr, collections_to_unlock, NULL, &collections_unlocked, &err); + if(unlocked_count == g_list_length(collections_to_unlock)) + return "SUCCESS"; + else { + if(err != NULL) + return rlib::string("{}/{} collections(keyrings) successfully unlocked, some of them failed. Error message: {}").format(unlocked_count, g_list_length(collections_to_unlock), err->message); + else + return rlib::string("{}/{} collections(keyrings) successfully unlocked, some of them failed. No error message from libsecret").format(unlocked_count, g_list_length(collections_to_unlock)); + } +} +#define keyringResultToString(r) (r) +constexpr auto UNLOCK_RESULT_SUCCESS = "SUCCESS"; +#elif defined(USE_LIBGNOMEKEYRING) inline GnomeKeyringResult do_unlock(std::string keyring, std::string password) { return gnome_keyring_unlock_sync(keyring.c_str(), password.c_str()); } - inline std::string keyringResultToString(GnomeKeyringResult res) { switch(res) { #define RLIB_IMPL_GEN_RESULT(value) RLIB_IMPL_GEN_RESULT_1(value, RLIB_MACRO_TO_CSTR(value)) @@ -47,12 +66,19 @@ inline std::string keyringResultToString(GnomeKeyringResult res) { RLIB_IMPL_GEN_RESULT(GNOME_KEYRING_RESULT_NO_KEYRING_DAEMON); RLIB_IMPL_GEN_RESULT(GNOME_KEYRING_RESULT_ALREADY_UNLOCKED); RLIB_IMPL_GEN_RESULT(GNOME_KEYRING_RESULT_NO_SUCH_KEYRING); - RLIB_IMPL_GEN_RESULT(GNOME_KEYRING_RESULT_BAD_ARGUMENTS); RLIB_IMPL_GEN_RESULT(GNOME_KEYRING_RESULT_IO_ERROR); RLIB_IMPL_GEN_RESULT(GNOME_KEYRING_RESULT_CANCELLED); RLIB_IMPL_GEN_RESULT(GNOME_KEYRING_RESULT_KEYRING_ALREADY_EXISTS); RLIB_IMPL_GEN_RESULT(GNOME_KEYRING_RESULT_NO_MATCH); + + case GNOME_KEYRING_RESULT_BAD_ARGUMENTS: + return std::string("GNOME_KEYRING_RESULT_BAD_ARGUMENTS, this error usually caused by incorrect keyring name. You need keyring NAME instead of LABEL. "); default: return std::string("Unknown Result Code: ") + std::to_string(res); } } +constexpr auto UNLOCK_RESULT_SUCCESS = GNOME_KEYRING_RESULT_OK; +#else +#error You must define either USE_LIBGNOMEKEYRING(deprecated) or USE_LIBSECRET(new), to select which backend implementation to use +#endif + diff --git a/src/unlock_keyrings.cc b/src/unlock_keyrings.cc index 46eb59e96e52b7e0d943548722ff9cfeea95997c..9240c2907569983caabc484ea5e0ed9dcdda9b80 100644 --- a/src/unlock_keyrings.cc +++ b/src/unlock_keyrings.cc @@ -41,7 +41,7 @@ int main(int argc, char **argv) { auto res = do_unlock(keyring_and_pswd.at(0), keyring_and_pswd.at(1)); auto msg = keyringResultToString(res); - if(res == GNOME_KEYRING_RESULT_OK) + if(res == UNLOCK_RESULT_SUCCESS) rlog.info("line {}: Working on keyring `{}`: {}.", line_num, keyring_and_pswd.at(0), msg); else { rlog.error("line {}: Working on keyring `{}`: {}.", line_num, keyring_and_pswd.at(0), msg);