From 5d3af0d492b50be58d206eb35b0107c7075c1c44 Mon Sep 17 00:00:00 2001 From: Peter Hudec Date: Tue, 18 Jun 2013 16:31:03 +0200 Subject: [PATCH] added suppoer for gnome-keyring RepoPass for encrypted library is stored in gnome-keyring instead of the sqlite3 database --- configure.ac | 11 +++ daemon/Makefile.am | 8 +- daemon/repo-mgr.c | 30 ++++++-- daemon/repokey/seafile-gnome-keyring.c | 100 +++++++++++++++++++++++++ daemon/repokey/seafile-gnome-keyring.h | 23 ++++++ 5 files changed, 166 insertions(+), 6 deletions(-) create mode 100644 daemon/repokey/seafile-gnome-keyring.c create mode 100644 daemon/repokey/seafile-gnome-keyring.h diff --git a/configure.ac b/configure.ac index 743e00e1..c61845b4 100644 --- a/configure.ac +++ b/configure.ac @@ -91,6 +91,9 @@ if test "$blinux" = true; then AC_ARG_ENABLE(ceph, AC_HELP_STRING([--enable-ceph], [enable ceph backend]), [compile_ceph=$enableval],[compile_ceph="no"]) + + AC_ARG_ENABLE(gnome-keyring, AC_HELP_STRING([--enable-gnome-keyring], [enable gnome keyring support]), + [compile_gnome_keyring=$enableval],[compile_gnome_keyring="no"]) fi AC_ARG_ENABLE(client, AC_HELP_STRING([--enable-client], [enable client]), @@ -372,6 +375,14 @@ if test "${compile_ceph}" = "yes"; then AC_DEFINE([HAVE_RADOS], [1], ["define if have rados"]) fi +AM_CONDITIONAL([HAVE_KEYSTORAGE_GK], [test "${compile_gnome_keyring}" = "yes"]) +if test "${compile_gnome_keyring}" = "yes"; then + PKG_CHECK_MODULES(GNOME_KEYRING, [gnome-keyring-1]) + AC_SUBST(GNOME_KEYRING_CFLAGS) + AC_SUBST(GNOME_KEYRING_LIBS) + AC_DEFINE(HAVE_KEYSTORAGE_GK, 1, [Have Gnome-Keyring support]) +fi + ac_configure_args="$ac_configure_args -q" AC_CONFIG_FILES( diff --git a/daemon/Makefile.am b/daemon/Makefile.am index 05eed904..c9ab764f 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -8,6 +8,7 @@ AM_CFLAGS = -DPKGDATADIR=\"$(pkgdatadir)\" \ @CCNET_CFLAGS@ \ @SEARPC_CFLAGS@ \ @GLIB2_CFLAGS@ \ + @GNOME_KEYRING_CFLAGS@ \ @MSVC_CFLAGS@ \ -Wall @@ -72,6 +73,10 @@ if MACOS wt_monitor_src = wt-monitor-macos.c endif +if HAVE_KEYSTORAGE_GK +key_storage_src = repokey/seafile-gnome-keyring.c +endif + common_src = \ transfer-mgr.c \ ../common/unpack-trees.c ../common/seaf-tree-walk.c \ @@ -92,6 +97,7 @@ common_src = \ ../common/block-backend.c \ ../common/block-backend-fs.c \ ../common/mq-mgr.c \ + $(key_storage_src) \ processors/check-tx-proc.c \ processors/check-tx-v2-proc.c \ processors/check-tx-v3-proc.c \ @@ -125,7 +131,7 @@ seaf_daemon_LDADD = $(top_builddir)/lib/libseafile_common.la \ @GLIB2_LIBS@ @GOBJECT_LIBS@ -lssl @LIB_RT@ @LIB_UUID@ -lsqlite3 -levent \ $(top_builddir)/common/cdc/libcdc.la \ $(top_builddir)/common/index/libindex.la ${LIB_WS32} \ - @SEARPC_LIBS@ @CCNET_LIBS@ + @SEARPC_LIBS@ @CCNET_LIBS@ @GNOME_KEYRING_LIBS@ seaf_daemon_LDFLAGS = @STATIC_COMPILE@ @CONSOLE@ diff --git a/daemon/repo-mgr.c b/daemon/repo-mgr.c index d8c1d219..42150926 100644 --- a/daemon/repo-mgr.c +++ b/daemon/repo-mgr.c @@ -35,6 +35,10 @@ #define INDEX_DIR "index" #define IGNORE_FILE "seafile-ignore.txt" +#ifdef HAVE_KEYSTORAGE_GK +#include "repokey/seafile-gnome-keyring.h" +#endif // HAVE_KEYSTORAGE_GK + struct _SeafRepoManagerPriv { avl_tree_t *repo_tree; sqlite3 *db; @@ -1561,11 +1565,13 @@ remove_repo_ondisk (SeafRepoManager *mgr, const char *repo_id) seaf_repo_manager_del_repo_property (mgr, repo_id); pthread_mutex_lock (&mgr->priv->db_lock); - +#ifdef HAVE_KEYSTORAGE_GK + gnome_keyring_sf_delete_password(repo_id, "password"); +#else snprintf (sql, sizeof(sql), "DELETE FROM RepoPasswd WHERE repo_id = '%s'", repo_id); sqlite_query_exec (mgr->priv->db, sql); - +#endif snprintf (sql, sizeof(sql), "DELETE FROM RepoKeys WHERE repo_id = '%s'", repo_id); sqlite_query_exec (mgr->priv->db, sql); @@ -1935,13 +1941,23 @@ load_repo_passwd (SeafRepoManager *manager, SeafRepo *repo) int n; pthread_mutex_lock (&manager->priv->db_lock); - +#ifdef HAVE_KEYSTORAGE_GK + guint gk_item_id; + char* gk_password; + gk_password = gnome_keyring_sf_get_password(repo->id, "password", &gk_item_id); + if (gk_password != NULL) { + repo->encrypted = TRUE; + repo->passwd = g_strdup(gk_password); + g_free(gk_password); + gk_password = NULL; + } +#else snprintf (sql, sizeof(sql), "SELECT passwd FROM RepoPasswd WHERE repo_id='%s'", repo->id); if (sqlite_foreach_selected_row (db, sql, load_passwd_cb, repo) < 0) return -1; - +#endif snprintf (sql, sizeof(sql), "SELECT key, iv FROM RepoKeys WHERE repo_id='%s'", repo->id); @@ -2360,12 +2376,16 @@ save_repo_enc_info (SeafRepoManager *manager, char sql[256]; char key[33], iv[33]; +#ifdef HAVE_KEYSTORAGE_GK + if (gnome_keyring_sf_set_password(repo->id, "password", repo->passwd) != 1) + return -1; +#else sqlite3_snprintf (sizeof(sql), sql, "REPLACE INTO RepoPasswd VALUES ('%s', '%q');", repo->id, repo->passwd); if (sqlite_query_exec (db, sql) < 0) return -1; - +#endif rawdata_to_hex (repo->enc_key, key, 16); rawdata_to_hex (repo->enc_iv, iv, 16); snprintf (sql, sizeof(sql), "REPLACE INTO RepoKeys VALUES ('%s', '%s', '%s')", diff --git a/daemon/repokey/seafile-gnome-keyring.c b/daemon/repokey/seafile-gnome-keyring.c new file mode 100644 index 00000000..b40dc0bf --- /dev/null +++ b/daemon/repokey/seafile-gnome-keyring.c @@ -0,0 +1,100 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#include +#include + +#include +#include "gnome-keyring.h" + +#include "seafile-gnome-keyring.h" + +#define SEAFILE_GK_ATTR_APP_NAME "seafile" +#define SEAFILE_GK_ATTR_APP_VALUE "seaf-daemon" +#define SEAFILE_GK_ATTR_REPO_NAME "repo_id" +#define SEAFILE_GK_ATTR_TYPE_NAME "type" + +char * gnome_keyring_sf_get_password(const char * repo_id, const char * type, guint *item_id) +{ + GnomeKeyringAttributeList * attributes; + GnomeKeyringResult result; + GList * found_list; + GList * i; + GnomeKeyringFound * found; + char * password = NULL; + + attributes = g_array_new(FALSE, FALSE, sizeof (GnomeKeyringAttribute)); + gnome_keyring_attribute_list_append_string(attributes, + SEAFILE_GK_ATTR_APP_NAME, + SEAFILE_GK_ATTR_APP_VALUE); + gnome_keyring_attribute_list_append_string(attributes, + SEAFILE_GK_ATTR_REPO_NAME, + repo_id); + gnome_keyring_attribute_list_append_string(attributes, + SEAFILE_GK_ATTR_TYPE_NAME, + type); + + result = gnome_keyring_find_items_sync(GNOME_KEYRING_ITEM_GENERIC_SECRET, + attributes, + &found_list); + + gnome_keyring_attribute_list_free(attributes); + + *item_id = -1; + if (result != GNOME_KEYRING_RESULT_OK) + return NULL; + + for (i = found_list; i != NULL; i = i->next) { + found = i->data; + password = g_strdup(found->secret); + *item_id = found->item_id; + break; + } + gnome_keyring_found_list_free(found_list); + + return password; +} + +int gnome_keyring_sf_set_password(const char * repo_id, const char * type, const char * password) +{ + GnomeKeyringAttributeList * attributes; + GnomeKeyringResult result; guint item_id; + + attributes = g_array_new(FALSE, + FALSE, + sizeof (GnomeKeyringAttribute)); + + gnome_keyring_attribute_list_append_string(attributes, + SEAFILE_GK_ATTR_APP_NAME, + SEAFILE_GK_ATTR_APP_VALUE); + gnome_keyring_attribute_list_append_string(attributes, + SEAFILE_GK_ATTR_REPO_NAME, + repo_id); + gnome_keyring_attribute_list_append_string(attributes, + SEAFILE_GK_ATTR_TYPE_NAME, + type); + + result = gnome_keyring_item_create_sync(NULL, + GNOME_KEYRING_ITEM_GENERIC_SECRET, + "seafile repository", + attributes, + password, + TRUE, + &item_id); + + gnome_keyring_attribute_list_free(attributes); + + return (result == GNOME_KEYRING_RESULT_OK); +} + +int gnome_keyring_sf_delete_password(const char * repo_id, const char * type) +{ + guint item_id; + GnomeKeyringResult result; + char * tmp = NULL; + + tmp = gnome_keyring_sf_get_password(repo_id, type, &item_id); + g_free(tmp); + result = gnome_keyring_item_delete_sync(NULL, item_id); + + return (result == GNOME_KEYRING_RESULT_OK); +} diff --git a/daemon/repokey/seafile-gnome-keyring.h b/daemon/repokey/seafile-gnome-keyring.h new file mode 100644 index 00000000..cb61c93a --- /dev/null +++ b/daemon/repokey/seafile-gnome-keyring.h @@ -0,0 +1,23 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +#ifndef SEAF_GNOME_KEYRING_H +#define SEAF_GNOME_KEYRING_H + +#include +#include + + +char * +gnome_keyring_sf_get_password(const char * repo_id, + const char * type, + guint *item_id); + +int +gnome_keyring_sf_set_password(const char * repo_id, + const char * type, + const char * password); + +int +gnome_keyring_sf_delete_password(const char * repo_id, + const char * type); +#endif /* SEAF_GNOME_KEYRING_H */ \ No newline at end of file