summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/Makefile.am18
-rw-r--r--src/common/Makefile.in63
-rw-r--r--src/common/db/Makefile.in31
-rw-r--r--src/common/db/gsignond-db-error.h4
-rw-r--r--src/common/db/gsignond-db-secret-database.c38
-rw-r--r--src/common/db/gsignond-db-sql-database.c18
-rw-r--r--src/common/db/gsignond-secret-storage.c454
-rw-r--r--src/common/gsignond-access-control-manager.c62
-rw-r--r--src/common/gsignond-config.c108
-rw-r--r--src/common/gsignond-credentials.c66
-rw-r--r--src/common/gsignond-dictionary.c180
-rw-r--r--src/common/gsignond-enum.c.template2
-rw-r--r--src/common/gsignond-error.c115
-rw-r--r--src/common/gsignond-extension-interface.c90
-rw-r--r--src/common/gsignond-identity-info-internal.h2
-rw-r--r--src/common/gsignond-identity-info.c49
-rw-r--r--src/common/gsignond-identity-info.h187
-rw-r--r--src/common/gsignond-plugin-enum-types.h2
-rw-r--r--src/common/gsignond-plugin-interface.c326
-rw-r--r--src/common/gsignond-security-context.c107
-rw-r--r--src/common/gsignond-session-data.c197
-rw-r--r--src/common/gsignond-signonui-data.c408
-rw-r--r--src/common/gsignond-storage-manager.c97
-rw-r--r--src/common/gsignond-utils.c107
24 files changed, 2259 insertions, 472 deletions
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index 38ac909..b89d47e 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -13,16 +13,16 @@ BUILT_SOURCES = \
GSIGNOND_INCLUDE_DIR=$(top_srcdir)/include/gsignond
gsignond-plugin-enum-types.h: gsignond-enum.h.template $(GSIGNOND_INCLUDE_DIR)/gsignond-plugin-interface.h
- $(GLIB_MKENUMS) --template gsignond-enum.h.template \
- --fhead "#ifndef GSIGNOND_PLUGIN_ENUM_TYPES_H_\n#define GSIGNOND_PLUGIND_ENUM_TYPES_H_\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS" \
- --identifier-prefix gsignond \
+ $(GLIB_MKENUMS) --template $(srcdir)/gsignond-enum.h.template \
+ --fhead "#ifndef GSIGNOND_PLUGIN_ENUM_TYPES_H_\n#define GSIGNOND_PLUGIN_ENUM_TYPES_H_\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS" \
+ --identifier-prefix GSignond \
--ftail "\nG_END_DECLS\n\n#endif\n" \
$(GSIGNOND_INCLUDE_DIR)/gsignond-plugin-interface.h > $@
gsignond-plugin-enum-types.c: gsignond-enum.c.template $(GSIGNOND_INCLUDE_DIR)/gsignond-plugin-interface.h
- $(GLIB_MKENUMS) --template gsignond-enum.c.template \
+ $(GLIB_MKENUMS) --template $(srcdir)/gsignond-enum.c.template \
--fhead "#include \"gsignond-plugin-enum-types.h\"\n" \
- --identifier-prefix gsignond \
+ --identifier-prefix GSignond \
$(GSIGNOND_INCLUDE_DIR)/gsignond-plugin-interface.h > $@
@@ -30,6 +30,7 @@ libgsignond_common_la_CPPFLAGS = \
-I$(top_builddir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/include \
+ -I. \
$(GSIGNOND_CFLAGS) \
-DGSIGNOND_PLUGINS_DIR='"$(pluginsdir)"' \
-DGSIGNOND_EXTENSIONS_DIR='"$(extensionsdir)"' \
@@ -51,6 +52,7 @@ libgsignond_common_la_SOURCES = \
gsignond-access-control-manager.c \
gsignond-extension-interface.c \
gsignond-storage-manager.c \
+ gsignond-identity-info.h \
gsignond-identity-info-internal.h \
gsignond-identity-info.c \
gsignond-credentials.c \
@@ -75,5 +77,7 @@ dist_libgsignond_common_la_SOURCES = \
gsignond-enum.h.template \
$(NULL)
-CLEANFILES =
-
+CLEANFILES = \
+ gsignond-plugin-enum-types.h \
+ gsignond-plugin-enum-types.c \
+ $(NULL)
diff --git a/src/common/Makefile.in b/src/common/Makefile.in
index a166acb..ddf1481 100644
--- a/src/common/Makefile.in
+++ b/src/common/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -16,6 +16,23 @@
@SET_MAKE@
VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -39,9 +56,10 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
subdir = src/common
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_gnu_make.m4 \
- $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
- $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
- $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -142,6 +160,11 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
install-pdf-recursive install-ps-recursive install-recursive \
installcheck-recursive installdirs-recursive pdf-recursive \
ps-recursive uninstall-recursive
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
@@ -329,6 +352,7 @@ libgsignond_common_la_CPPFLAGS = \
-I$(top_builddir) \
-I$(top_srcdir)/src \
-I$(top_srcdir)/include \
+ -I. \
$(GSIGNOND_CFLAGS) \
-DGSIGNOND_PLUGINS_DIR='"$(pluginsdir)"' \
-DGSIGNOND_EXTENSIONS_DIR='"$(extensionsdir)"' \
@@ -350,6 +374,7 @@ libgsignond_common_la_SOURCES = \
gsignond-access-control-manager.c \
gsignond-extension-interface.c \
gsignond-storage-manager.c \
+ gsignond-identity-info.h \
gsignond-identity-info-internal.h \
gsignond-identity-info.c \
gsignond-credentials.c \
@@ -374,7 +399,11 @@ dist_libgsignond_common_la_SOURCES = \
gsignond-enum.h.template \
$(NULL)
-CLEANFILES =
+CLEANFILES = \
+ gsignond-plugin-enum-types.h \
+ gsignond-plugin-enum-types.c \
+ $(NULL)
+
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-recursive
@@ -413,7 +442,6 @@ $(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
- test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
@@ -421,6 +449,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES)
else :; fi; \
done; \
test -z "$$list2" || { \
+ echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
@@ -785,13 +815,10 @@ distdir: $(DISTFILES)
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
- test -d "$(distdir)/$$subdir" \
- || $(MKDIR_P) "$(distdir)/$$subdir" \
- || exit 1; \
- fi; \
- done
- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
+ $(am__make_dryrun) \
+ || test -d "$(distdir)/$$subdir" \
+ || $(MKDIR_P) "$(distdir)/$$subdir" \
+ || exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
@@ -946,16 +973,16 @@ uninstall-am: uninstall-libLTLIBRARIES
gsignond-plugin-enum-types.h: gsignond-enum.h.template $(GSIGNOND_INCLUDE_DIR)/gsignond-plugin-interface.h
- $(GLIB_MKENUMS) --template gsignond-enum.h.template \
- --fhead "#ifndef GSIGNOND_PLUGIN_ENUM_TYPES_H_\n#define GSIGNOND_PLUGIND_ENUM_TYPES_H_\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS" \
- --identifier-prefix gsignond \
+ $(GLIB_MKENUMS) --template $(srcdir)/gsignond-enum.h.template \
+ --fhead "#ifndef GSIGNOND_PLUGIN_ENUM_TYPES_H_\n#define GSIGNOND_PLUGIN_ENUM_TYPES_H_\n\n#include <glib-object.h>\n\nG_BEGIN_DECLS" \
+ --identifier-prefix GSignond \
--ftail "\nG_END_DECLS\n\n#endif\n" \
$(GSIGNOND_INCLUDE_DIR)/gsignond-plugin-interface.h > $@
gsignond-plugin-enum-types.c: gsignond-enum.c.template $(GSIGNOND_INCLUDE_DIR)/gsignond-plugin-interface.h
- $(GLIB_MKENUMS) --template gsignond-enum.c.template \
+ $(GLIB_MKENUMS) --template $(srcdir)/gsignond-enum.c.template \
--fhead "#include \"gsignond-plugin-enum-types.h\"\n" \
- --identifier-prefix gsignond \
+ --identifier-prefix GSignond \
$(GSIGNOND_INCLUDE_DIR)/gsignond-plugin-interface.h > $@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/src/common/db/Makefile.in b/src/common/db/Makefile.in
index fca2c67..6faf597 100644
--- a/src/common/db/Makefile.in
+++ b/src/common/db/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.3 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -16,6 +16,23 @@
@SET_MAKE@
VPATH = @srcdir@
+am__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -38,9 +55,10 @@ subdir = src/common/db
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_check_gnu_make.m4 \
- $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
- $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
- $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/configure.ac
+ $(top_srcdir)/m4/gtk-doc.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
@@ -89,6 +107,11 @@ am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
SOURCES = $(libgsignond_common_db_la_SOURCES)
DIST_SOURCES = $(libgsignond_common_db_la_SOURCES)
+am__can_run_installinfo = \
+ case $$AM_UPDATE_INFO_DIR in \
+ n|no|NO) false;; \
+ *) (install-info --version) >/dev/null 2>&1;; \
+ esac
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
diff --git a/src/common/db/gsignond-db-error.h b/src/common/db/gsignond-db-error.h
index 13a1b83..bd4bf11 100644
--- a/src/common/db/gsignond-db-error.h
+++ b/src/common/db/gsignond-db-error.h
@@ -31,10 +31,6 @@
G_BEGIN_DECLS
-/**
- * GSIGNOND_DB_ERROR:
- *
- */
#define GSIGNOND_DB_ERROR (gsignond_db_error_quark())
typedef enum {
diff --git a/src/common/db/gsignond-db-secret-database.c b/src/common/db/gsignond-db-secret-database.c
index 51fa0da..b723539 100644
--- a/src/common/db/gsignond-db-secret-database.c
+++ b/src/common/db/gsignond-db-secret-database.c
@@ -81,11 +81,23 @@ _gsignond_db_read_key_value (
GSignondDictionary* data)
{
const gchar *key = NULL;
+ gpointer v_data = 0;
GVariant *value = NULL;
+ const GVariantType *type;
+ gsize type_len ;
+ gsize size = (gsize) sqlite3_column_bytes(stmt, 1);
+
+ type = (const GVariantType *)sqlite3_column_blob(stmt, 1) ;
+ type_len = g_variant_type_get_string_length (type) + 1;
+
+ size -= type_len;
+ v_data = g_new0(gconstpointer, size);
+ mempcpy(v_data, sqlite3_column_blob(stmt, 1) + type_len, size);
+
key = (const gchar *)sqlite3_column_text (stmt, 0);
- value = g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE,
- (gconstpointer) sqlite3_column_blob(stmt, 1),
- (gsize) sqlite3_column_bytes(stmt, 1), sizeof(guchar));
+ value = g_variant_new_from_data (type,
+ (gconstpointer)v_data, size,
+ TRUE, (GDestroyNotify)g_free, v_data);
gsignond_dictionary_set (data, key, value);
return TRUE;
@@ -125,8 +137,8 @@ gsignond_db_secret_database_init (GSignondDbSecretDatabase *self)
* gsignond_db_secret_database_new:
*
* Creates new #GSignondDbSecretDatabase object
- * Returns : (transfer full) the #GSignondDbSecretDatabase object
*
+ * Returns: (transfer full): the #GSignondDbSecretDatabase object
*/
GSignondDbSecretDatabase *
gsignond_db_secret_database_new ()
@@ -350,7 +362,9 @@ gsignond_db_secret_database_update_data (
g_hash_table_iter_init (&iter, data);
while (g_hash_table_iter_next (&iter,(gpointer *) &key,
(gpointer *) &value)) {
- data_counter = data_counter + strlen (key) + g_variant_get_size(value);
+ data_counter = data_counter + strlen (key) +
+ g_variant_type_get_string_length (g_variant_get_type (value)) + 1 +
+ g_variant_get_size(value);
if (data_counter >= GSIGNOND_DB_MAX_DATA_STORAGE) {
gsignond_db_sql_database_rollback_transaction (parent);
DBG ("size limit is exceeded");
@@ -366,7 +380,9 @@ gsignond_db_secret_database_update_data (
while (g_hash_table_iter_next (&iter, (gpointer *)&key,
(gpointer *) &value )) {
gsize val_size;
- gconstpointer value_data;
+ const gchar *val_type;
+ gsize val_type_length;
+ gpointer value_data;
sqlite3_stmt *sql_stmt;
ret = sqlite3_prepare_v2 (parent->priv->db, statement, -1,
@@ -377,13 +393,19 @@ gsignond_db_secret_database_update_data (
gsignond_db_sql_database_rollback_transaction (parent);
return FALSE;
}
- value_data = g_variant_get_data (value);
+ val_type = g_variant_get_type_string(value);
+ val_type_length = g_variant_type_get_string_length (
+ (const GVariantType *)val_type) + 1;
val_size = g_variant_get_size (value);
+ value_data = g_new0(gconstpointer, val_size + val_type_length);
+ sprintf ((gchar*)value_data, "%s", val_type);
+ memcpy(value_data + val_type_length, g_variant_get_data (value), val_size);
+
sqlite3_bind_int(sql_stmt, 1, (int)id);
sqlite3_bind_int(sql_stmt, 2, (int)method);
sqlite3_bind_text(sql_stmt, 3, key, -1, SQLITE_STATIC);
- sqlite3_bind_blob(sql_stmt, 4, value_data, (int)val_size, SQLITE_STATIC);
+ sqlite3_bind_blob(sql_stmt, 4, value_data, (int)val_size + val_type_length, g_free);
ret = sqlite3_step (sql_stmt);
if (G_UNLIKELY (ret != SQLITE_DONE)) {
diff --git a/src/common/db/gsignond-db-sql-database.c b/src/common/db/gsignond-db-sql-database.c
index caddd98..0ba63be 100644
--- a/src/common/db/gsignond-db-sql-database.c
+++ b/src/common/db/gsignond-db-sql-database.c
@@ -356,7 +356,7 @@ gsignond_db_sql_database_clear (GSignondDbSqlDatabase *self)
*
* Prepares the statement from the query.
*
- * Returns: (transfer full) NULL if fails, valid sql statement otherwise.
+ * Returns: (transfer full): NULL if fails, valid sql statement otherwise.
*/
sqlite3_stmt *
gsignond_db_sql_database_prepare_statement (
@@ -382,7 +382,7 @@ gsignond_db_sql_database_prepare_statement (
/**
* gsignond_db_sql_database_exec:
* @self: instance of #GSignondDbSqlDatabase
- * @stmts: sql statements to be executed on the database
+ * @statements: sql statements to be executed on the database
*
* Executes SQL statements. transaction begin and commit statements should be
* explicitly called if needed.
@@ -462,7 +462,7 @@ _gsignond_db_read_string (
*
* Executes an SQL statement, and returns the fetched integer from the result.
*
- * Returns: (transfer full) string if rows fetched are greater than 0,
+ * Returns: (transfer full): string if rows fetched are greater than 0,
* NULL otherwise.
*/
gchar *
@@ -507,7 +507,7 @@ _gsignond_db_read_strings (
* Executes an SQL statement, and returns the fetched strings from the results
* in the list.
*
- * Returns: (transfer full) list if rows fetched are greater than 0,
+ * Returns: (transfer full): list if rows fetched are greater than 0,
* NULL otherwise. When done with list, it must be freed using
* g_list_free_full (list, g_free)
*/
@@ -554,7 +554,7 @@ _gsignond_db_read_string_tuple (
* Executes an SQL statement, and returns the fetched string tuples from
* the results into the hash table.
*
- * Returns: (transfer full) string tuples if rows fetched are greater than 0,
+ * Returns: (transfer full): string tuples if rows fetched are greater than 0,
* NULL otherwise. When done with tuples, it must be freed using
* g_hash_table_unref (tuples)
*/
@@ -609,7 +609,7 @@ _gsignond_db_read_int_string_tuple (
* Executes an SQL statement, and returns the fetched int-string tuples from
* the results into the hash table.
*
- * Returns: (transfer full) string tuples if rows fetched are greater than 0,
+ * Returns: (transfer full): string tuples if rows fetched are greater than 0,
* NULL otherwise.
*/
GHashTable *
@@ -702,7 +702,7 @@ _gsignond_db_read_array (
* Executes an SQL statement, and returns the fetched integers from the results
* in the array.
*
- * Returns: (transfer full) list if rows fetched are greater than 0, NULL otherwise.
+ * Returns: (transfer full): list if rows fetched are greater than 0, NULL otherwise.
*/
GArray *
gsignond_db_sql_database_query_exec_int_array (
@@ -732,7 +732,7 @@ gsignond_db_sql_database_query_exec_int_array (
/**
* gsignond_db_sql_database_query_exec_stmt:
* @self: instance of #GSignondDbSqlDatabase
- * @sql_stmt: (transfer full) sql statement executed on the database
+ * @sql_stmt: (transfer full): sql statement executed on the database
* @callback: callback to be invoked if not NULL for the result of each row
* @userdata: user_data to be relayed back through the callback
*
@@ -947,7 +947,7 @@ gsignond_db_sql_database_get_db_version (
/**
* gsignond_db_sql_database_set_last_error:
* @self: instance of #GSignondDbDefaultStorage
- * @error: (transfer full) last occurred #GError
+ * @error: (transfer full): last occurred #GError
*
* sets the last occurred error
*
diff --git a/src/common/db/gsignond-secret-storage.c b/src/common/db/gsignond-secret-storage.c
index 90209fa..97e021d 100644
--- a/src/common/db/gsignond-secret-storage.c
+++ b/src/common/db/gsignond-secret-storage.c
@@ -29,6 +29,26 @@
#include "gsignond/gsignond-log.h"
#include "gsignond/gsignond-secret-storage.h"
+/**
+ * SECTION:gsignond-secret-storage
+ * @short_description: provides access to the database that stores user credentials and identity/method cache
+ * @include: gsignond/gsignond-secret-storage.h
+ *
+ * #GSignondSecretStorage provides access to the database where sensitive identity
+ * data (#GSignondCredentials) and identity/method cache are stored. It's preferred
+ * that this database is protected against access by processes other than gSSO.
+ *
+ * gSSO can be configured to use a custom extension
+ * that provides a subclassed implementation of #GSignondSecretStorage
+ * (see #GSignondExtension), otherwise a default implementation is used.
+ *
+ */
+/**
+ * GSignondSecretStorage:
+ *
+ * Opaque #GSignondSecretStorage data structure.
+ */
+
#define GSIGNOND_SECRET_STORAGE_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
GSIGNOND_TYPE_SECRET_STORAGE, \
@@ -105,62 +125,8 @@ _gsignond_secret_storage_dispose (GObject *gobject)
gobject);
}
-static void
-gsignond_secret_storage_class_init (GSignondSecretStorageClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->set_property = _set_property;
- gobject_class->get_property = _get_property;
- gobject_class->dispose = _gsignond_secret_storage_dispose;
-
- properties[PROP_CONFIG] = g_param_spec_object ("config",
- "config",
- "Configuration object",
- GSIGNOND_TYPE_CONFIG,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties (gobject_class, N_PROPERTIES, properties);
-
- /* virtual methods */
- klass->open_db = gsignond_secret_storage_open_db;
- klass->close_db = gsignond_secret_storage_close_db;
- klass->clear_db = gsignond_secret_storage_clear_db;
- klass->is_open_db = gsignond_secret_storage_is_open_db;
- klass->load_credentials =
- gsignond_secret_storage_load_credentials;
- klass->update_credentials =
- gsignond_secret_storage_update_credentials;
- klass->remove_credentials =
- gsignond_secret_storage_remove_credentials;
- klass->load_data = gsignond_secret_storage_load_data;
- klass->update_data = gsignond_secret_storage_update_data;
- klass->remove_data = gsignond_secret_storage_remove_data;
-
- g_type_class_add_private (klass, sizeof (GSignondSecretStoragePrivate));
-}
-
-static void
-gsignond_secret_storage_init (GSignondSecretStorage *self)
-{
- self->priv = GSIGNOND_SECRET_STORAGE_GET_PRIVATE (self);
- self->priv->database = gsignond_db_secret_database_new ();
- self->config = NULL;
-}
-
-/**
- * gsignond_secret_storage_open_db:
- *
- * @self: instance of #GSignondSecretStorage
- *
- * Opens (and initializes) DB. The implementation should take
- * care of creating the DB, if it doesn't exist.
- *
- * Returns: TRUE if successful, FALSE otherwise.
- */
-gboolean
-gsignond_secret_storage_open_db (GSignondSecretStorage *self)
+static gboolean
+_open_db (GSignondSecretStorage *self)
{
const gchar *dir = NULL;
const gchar *filename = NULL;
@@ -211,71 +177,268 @@ gsignond_secret_storage_open_db (GSignondSecretStorage *self)
return TRUE;
}
+static gboolean
+_close_db (GSignondSecretStorage *self)
+{
+ g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
+
+ if (self->priv->database != NULL) {
+ gsignond_db_sql_database_close (GSIGNOND_DB_SQL_DATABASE (
+ self->priv->database));
+ }
+ return TRUE;
+}
+
+static gboolean
+_clear_db (GSignondSecretStorage *self)
+{
+ g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
+ return gsignond_db_sql_database_clear (GSIGNOND_DB_SQL_DATABASE (
+ self->priv->database));
+}
+
+static gboolean
+_is_open_db (GSignondSecretStorage *self)
+{
+ g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
+ return ((self->priv->database != NULL) &&
+ gsignond_db_sql_database_is_open (GSIGNOND_DB_SQL_DATABASE (
+ self->priv->database)));
+}
+
+static GSignondCredentials*
+_load_credentials (
+ GSignondSecretStorage *self,
+ const guint32 id)
+{
+ g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
+ return gsignond_db_secret_database_load_credentials (self->priv->database,
+ id);
+}
+
+static gboolean
+_update_credentials (
+ GSignondSecretStorage *self,
+ GSignondCredentials *creds)
+{
+ g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
+ return gsignond_db_secret_database_update_credentials (self->priv->database,
+ creds);
+}
+
+static gboolean
+_remove_credentials (
+ GSignondSecretStorage *self,
+ const guint32 id)
+{
+ g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
+ return gsignond_db_secret_database_remove_credentials (self->priv->database,
+ id);
+}
+
+static gboolean
+_check_credentials (
+ GSignondSecretStorage *self,
+ GSignondCredentials *creds)
+{
+ gboolean equal = FALSE;
+ GSignondCredentials *stored_creds = NULL;
+
+ g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
+ g_return_val_if_fail (creds != NULL, FALSE);
+
+ GSignondSecretStorageClass *klass =
+ GSIGNOND_SECRET_STORAGE_GET_CLASS (self);
+
+ stored_creds = klass->load_credentials (self,
+ gsignond_credentials_get_id(creds));
+
+ if (stored_creds) {
+ DBG ("Credentials from DB found");
+ equal = gsignond_credentials_equal(creds, stored_creds);
+ g_object_unref (stored_creds);
+ }
+
+ return equal;
+}
+
+static GHashTable*
+_load_data (
+ GSignondSecretStorage *self,
+ const guint32 id,
+ const guint32 method)
+{
+ g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), NULL);
+ return gsignond_db_secret_database_load_data (self->priv->database,
+ id, method);
+}
+
+static gboolean
+_update_data (
+ GSignondSecretStorage *self,
+ const guint32 id,
+ const guint32 method,
+ GHashTable *data)
+{
+ g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
+ return gsignond_db_secret_database_update_data (self->priv->database,
+ id, method, data);
+}
+
+static gboolean
+_remove_data (
+ GSignondSecretStorage *self,
+ const guint32 id,
+ const guint32 method)
+{
+ g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
+ return gsignond_db_secret_database_remove_data (self->priv->database,
+ id, method);
+}
+
+static const GError *
+_get_last_error (GSignondSecretStorage *self)
+{
+ g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), NULL);
+ if (self->priv->database != NULL) {
+ return gsignond_db_sql_database_get_last_error (
+ GSIGNOND_DB_SQL_DATABASE (self->priv->database));
+ }
+ return NULL;
+}
+
+
+
/**
- * gsignond_secret_storage_close_db:
+ * GSignondSecretStorageClass:
+ * @parent_class: parent class.
+ * @open_db: an implementation of gsignond_secret_storage_open_db()
+ * @close_db: an implementation of gsignond_secret_storage_close_db()
+ * @clear_db: an implementation of gsignond_secret_storage_clear_db()
+ * @is_open_db: an implementation of gsignond_secret_storage_is_open_db()
+ * @load_credentials: an implementation of gsignond_secret_storage_load_credentials()
+ * @update_credentials: an implementation of gsignond_secret_storage_update_credentials()
+ * @remove_credentials: an implementation of gsignond_secret_storage_remove_credentials()
+ * @check_credentials: an implementation of gsignond_secret_storage_check_credentials()
+ * @load_data: an implementation of gsignond_secret_storage_load_data()
+ * @update_data: an implementation of gsignond_secret_storage_update_data()
+ * @remove_data: an implementation of gsignond_secret_storage_remove_data()
+ * @get_last_error: an implementation of gsignond_secret_storage_get_last_error()
+ *
+ * #GSignondSecretStorageClass class containing pointers to class methods.
+ */
+static void
+gsignond_secret_storage_class_init (GSignondSecretStorageClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->set_property = _set_property;
+ gobject_class->get_property = _get_property;
+ gobject_class->dispose = _gsignond_secret_storage_dispose;
+
+ properties[PROP_CONFIG] = g_param_spec_object ("config",
+ "config",
+ "Configuration object",
+ GSIGNOND_TYPE_CONFIG,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+ g_object_class_install_properties (gobject_class, N_PROPERTIES, properties);
+
+ /* virtual methods */
+ klass->open_db = _open_db;
+ klass->close_db = _close_db;
+ klass->clear_db = _clear_db;
+ klass->is_open_db = _is_open_db;
+ klass->load_credentials = _load_credentials;
+ klass->update_credentials = _update_credentials;
+ klass->remove_credentials = _remove_credentials;
+ klass->check_credentials = _check_credentials;
+ klass->load_data = _load_data;
+ klass->update_data = _update_data;
+ klass->remove_data = _remove_data;
+ klass->get_last_error = _get_last_error;
+
+ g_type_class_add_private (klass, sizeof (GSignondSecretStoragePrivate));
+}
+
+static void
+gsignond_secret_storage_init (GSignondSecretStorage *self)
+{
+ self->priv = GSIGNOND_SECRET_STORAGE_GET_PRIVATE (self);
+ self->priv->database = gsignond_db_secret_database_new ();
+ self->config = NULL;
+}
+
+/**
+ * gsignond_secret_storage_open_db:
+ * @self: instance of #GSignondSecretStorage
*
+ * Opens (and initializes) the database. The implementation should take
+ * care of creating the DB, if it doesn't exist, and it should use
+ * #GSIGNOND_CONFIG_GENERAL_SECURE_DIR and #GSIGNOND_CONFIG_DB_SECRET_DB_FILENAME
+ * to determine database location in the filesystem.
+ *
+ * The default implementation is using SQLite for the storage.
+ *
+ * Returns: TRUE if successful, FALSE otherwise.
+ */
+gboolean
+gsignond_secret_storage_open_db (GSignondSecretStorage *self)
+{
+ return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->open_db (self);
+}
+
+/**
+ * gsignond_secret_storage_close_db:
* @self: instance of #GSignondSecretStorage
*
- * Closes the secrets DB. To reopen it, call open_db().
+ * Closes the database. To reopen it, call gsignond_secret_storage_open_db().
*
* Returns: TRUE if successful, FALSE otherwise.
*/
gboolean
gsignond_secret_storage_close_db (GSignondSecretStorage *self)
{
- g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
-
- if (self->priv->database != NULL) {
- gsignond_db_sql_database_close (GSIGNOND_DB_SQL_DATABASE (
- self->priv->database));
- }
- return TRUE;
+ return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->close_db (self);
}
/**
* gsignond_secret_storage_clear_db:
- *
* @self: instance of #GSignondSecretStorage
*
- * Removes all stored secrets.
+ * Removes all stored secrets from the database.
*
* Returns: TRUE if successful, FALSE otherwise.
*/
gboolean
gsignond_secret_storage_clear_db (GSignondSecretStorage *self)
{
- g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
- return gsignond_db_sql_database_clear (GSIGNOND_DB_SQL_DATABASE (
- self->priv->database));
+ return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->clear_db (self);
}
/**
* gsignond_secret_storage_is_open_db:
- *
* @self: instance of #GSignondSecretStorage
*
- * Checks if the db is open or not.
+ * Checks if the database is open or not.
*
* Returns: TRUE if successful, FALSE otherwise.
*/
gboolean
gsignond_secret_storage_is_open_db (GSignondSecretStorage *self)
{
- g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
- return ((self->priv->database != NULL) &&
- gsignond_db_sql_database_is_open (GSIGNOND_DB_SQL_DATABASE (
- self->priv->database)));
+ return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->is_open_db (self);
}
/**
* gsignond_secret_storage_load_credentials:
- *
* @self: instance of #GSignondSecretStorage
- * @id: the identity whose credentials are being loaded.
+ * @id: the identity id whose credentials are being loaded.
*
- * Loads the credentials.
+ * Loads the credentials from the database.
*
- * Returns: (transfer full) #GSignondCredentials if successful,
+ * Returns: (transfer full): #GSignondCredentials if successful,
* NULL otherwise.
*/
GSignondCredentials*
@@ -283,16 +446,13 @@ gsignond_secret_storage_load_credentials (
GSignondSecretStorage *self,
const guint32 id)
{
- g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
- return gsignond_db_secret_database_load_credentials (self->priv->database,
- id);
+ return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->load_credentials (self, id);
}
/**
* gsignond_secret_storage_update_credentials:
- *
* @self: instance of #GSignondSecretStorage
- * @creds: (transfer none) the credentials that are being updated.
+ * @creds: (transfer none): the credentials that are being updated.
*
* Stores/updates the credentials for the given identity.
*
@@ -303,14 +463,11 @@ gsignond_secret_storage_update_credentials (
GSignondSecretStorage *self,
GSignondCredentials *creds)
{
- g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
- return gsignond_db_secret_database_update_credentials (self->priv->database,
- creds);
+ return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->update_credentials (self, creds);
}
/**
* gsignond_secret_storage_remove_credentials:
- *
* @self: instance of #GSignondSecretStorage
* @id: the identity whose credentials are being updated.
*
@@ -323,19 +480,15 @@ gsignond_secret_storage_remove_credentials (
GSignondSecretStorage *self,
const guint32 id)
{
- g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
- return gsignond_db_secret_database_remove_credentials (self->priv->database,
- id);
+ return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->remove_credentials (self, id);
}
/**
* gsignond_secret_storage_check_credentials:
- *
* @self: instance of #GSignondSecretStorage
- * @creds: (transfer none) the credentials that are being checked.
+ * @creds: (transfer none): the credentials that are being checked.
*
- * Checks whether the given credentials are correct for the
- * given identity.
+ * Checks whether the given credentials match what is stored in the database.
*
* Returns: TRUE if successful, FALSE otherwise.
*/
@@ -344,60 +497,37 @@ gsignond_secret_storage_check_credentials (
GSignondSecretStorage *self,
GSignondCredentials *creds)
{
- gboolean equal = FALSE;
- GSignondCredentials *stored_creds = NULL;
-
- g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
- g_return_val_if_fail (creds != NULL, FALSE);
-
- GSignondSecretStorageClass *klass =
- GSIGNOND_SECRET_STORAGE_GET_CLASS (self);
-
- stored_creds = klass->load_credentials (self,
- gsignond_credentials_get_id(creds));
-
- if (stored_creds) {
- DBG ("Credentials from DB found");
- equal = gsignond_credentials_equal(creds, stored_creds);
- g_object_unref (stored_creds);
- }
-
- return equal;
+ return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->check_credentials (self, creds);
}
/**
* gsignond_secret_storage_load_data:
- *
* @self: instance of #GSignondSecretStorage
- * @id: the identity whose credentials are being fetched.
+ * @id: the identity id whose data are fetched
* @method: the authentication method the data is used for.
*
- * Loads secret data.
+ * Loads the secret data associated with a given identity and method.
*
- * Returns: (transfer full) #GHashTable (gchar*, GBytes*) data. When done data
- * should be freed with g_hash_table_unref (data)
+ * Returns: (transfer full): the secret data
*/
-GHashTable*
+GSignondDictionary*
gsignond_secret_storage_load_data (
GSignondSecretStorage *self,
const guint32 id,
const guint32 method)
{
- g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), NULL);
- return gsignond_db_secret_database_load_data (self->priv->database,
- id, method);
+ return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->load_data (self, id, method);
}
/**
* gsignond_secret_storage_update_data:
- *
* @self: instance of #GSignondSecretStorage
- * @id: the identity whose credentials are being fetched.
+ * @id: the identity whose data are fetched.
* @method: the authentication method the data is used for.
- * @data: (transfer none) the data as #GHashTable (gchar*, GBytes*)
+ * @data: (transfer none): the data to update
*
- * Stores/replaces secret data. Calling this method replaces any data
- * which was previously stored for the given id/method.
+ * Calling this method updates the secret data
+ * associated with the given id/method.
*
* Returns: TRUE if successful, FALSE otherwise.
*/
@@ -406,21 +536,18 @@ gsignond_secret_storage_update_data (
GSignondSecretStorage *self,
const guint32 id,
const guint32 method,
- GHashTable *data)
+ GSignondDictionary *data)
{
- g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
- return gsignond_db_secret_database_update_data (self->priv->database,
- id, method, data);
+ return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->update_data (self, id, method, data);
}
/**
* gsignond_secret_storage_remove_data:
- *
* @self: instance of #GSignondSecretStorage
- * @id: the identity whose credentials are being checked.
+ * @id: the identity whose data are fetched.
* @method: the authentication method the data is used for.
*
- * Removes secret data.
+ * Removes secret data associated with a given id/method.
*
* Returns: TRUE if successful, FALSE otherwise.
*/
@@ -430,67 +557,20 @@ gsignond_secret_storage_remove_data (
const guint32 id,
const guint32 method)
{
- g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), FALSE);
- return gsignond_db_secret_database_remove_data (self->priv->database,
- id, method);
-}
-
-/**
- * gsignond_secret_storage_set_last_error:
- * @self: instance of #GSignondDbDefaultStorage
- * @error : (transfer full) last occurred #GError
- *
- * sets the last occurred error
- *
- */
-void
-gsignond_secret_storage_set_last_error (
- GSignondSecretStorage *self,
- GError* error)
-{
- g_return_if_fail (GSIGNOND_IS_SECRET_STORAGE (self));
- g_return_if_fail (self->priv->database != NULL);
- gsignond_db_sql_database_set_last_error (
- GSIGNOND_DB_SQL_DATABASE (self->priv->database), error);
+ return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->remove_data (self, id, method);
}
/**
* gsignond_secret_storage_get_last_error:
- *
* @self: instance of #GSignondSecretStorage
*
- * retrieves the last occurred error
+ * Retrieves the last occurred error that has occured
*
- * Returns: (transfer none) last occurred #GError
+ * Returns: (transfer none): last occurred #GError
*/
const GError *
gsignond_secret_storage_get_last_error (GSignondSecretStorage *self)
{
- g_return_val_if_fail (GSIGNOND_IS_SECRET_STORAGE (self), NULL);
- if (self->priv->database != NULL) {
- return gsignond_db_sql_database_get_last_error (
- GSIGNOND_DB_SQL_DATABASE (self->priv->database));
- }
- return NULL;
-}
-
-/**
- * gsignond_secret_storage_clear_last_error:
- *
- * @self: instance of #GSignondSecretStorage
- *
- * clears the last occurred error
- */
-void
-gsignond_secret_storage_clear_last_error (GSignondSecretStorage *self)
-{
- g_return_if_fail (GSIGNOND_IS_SECRET_STORAGE (self));
- if (self->priv->database != NULL) {
- gsignond_db_sql_database_clear_last_error (
- GSIGNOND_DB_SQL_DATABASE (self->priv->database));
- }
+ return GSIGNOND_SECRET_STORAGE_GET_CLASS (self)->get_last_error (self);
}
-
-
-
diff --git a/src/common/gsignond-access-control-manager.c b/src/common/gsignond-access-control-manager.c
index 438b0f0..ef5d8f8 100644
--- a/src/common/gsignond-access-control-manager.c
+++ b/src/common/gsignond-access-control-manager.c
@@ -35,6 +35,22 @@
#include "gsignond/gsignond-log.h"
#include "gsignond/gsignond-access-control-manager.h"
+/**
+ * SECTION:gsignond-access-control-manager
+ * @short_description: an object that performs access control checks
+ * @include: gsignond/gsignond-access-control-manager.h
+ *
+ * #GSignondAccessControlManager performs access control checks using
+ * available system services. gSSO can be configured to use a custom extension
+ * that provides a subclassed implementation of #GSignondAccessControlManager
+ * (see #GSignondExtension), otherwise a default implementation is used.
+ */
+/**
+ * GSignondAccessControlManager:
+ *
+ * Opaque #GSignondAccessControlManager data structure.
+ */
+
#define GSIGNOND_ACCESS_CONTROL_MANAGER_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
GSIGNOND_TYPE_ACCESS_CONTROL_MANAGER, \
@@ -265,14 +281,27 @@ _security_context_of_keychain (GSignondAccessControlManager *self)
(void) self;
-# ifdef ENABLE_DEBUG
+# if defined(ENABLE_DEBUG)
keychain_sysctx = g_getenv ("SSO_KEYCHAIN_SYSCTX");
+# elif defined(KEYCHAIN_SYSCTX)
+ keychain_sysctx = KEYCHAIN_SYSCTX;
# endif
if (!keychain_sysctx)
keychain_sysctx = "";
return gsignond_security_context_new_from_values (keychain_sysctx, "");
}
+/**
+ * GSignondAccessControlManagerClass:
+ * @parent_class: parent class.
+ * @security_context_of_peer: an implementation of gsignond_access_control_manager_security_context_of_peer()
+ * @peer_is_allowed_to_use_identity: an implementation of gsignond_access_control_manager_peer_is_allowed_to_use_identity()
+ * @peer_is_owner_of_identity: an implementation of gsignond_access_control_manager_peer_is_owner_of_identity()
+ * @acl_is_valid: an implementation of gsignond_access_control_manager_acl_is_valid()
+ * @security_context_of_keychain: an implementation of gsignond_access_control_manager_security_context_of_keychain()
+ *
+ * #GSignondAccessControlManagerClass class containing pointers to class methods.
+ */
static void
gsignond_access_control_manager_class_init (
GSignondAccessControlManagerClass *klass)
@@ -313,10 +342,15 @@ gsignond_access_control_manager_init (GSignondAccessControlManager *self)
* gsignond_access_control_manager_security_context_of_peer:
* @self: object instance.
* @peer_ctx: instance of security context to be set.
- * @peer_fd: file descriptor of the peer connection.
+ * @peer_fd: file descriptor of the peer connection if using peer-to-peer dbus, -1 otherwise.
+ * @peer_service: g_dbus_method_invocation_get_sender() of the peer connection, if not using peer-to-peer dbus, NULL otherwise
* @peer_app_ctx: application context of the peer connection.
*
- * Retrieves #GSignondSecurityContext of the specified peer.
+ * Retrieves and sets #GSignondSecurityContext of the specified peer.
+ *
+ * The default implementation sets the app context as it was passed, and sets
+ * the system context to the binary path of the process that is determined from
+ * @peer_fd and @peer_service parameters.
*/
void
gsignond_access_control_manager_security_context_of_peer (
@@ -335,9 +369,12 @@ gsignond_access_control_manager_security_context_of_peer (
* @self: object instance.
* @peer_ctx: security context of the peer connection.
* @owner_ctx: security context of the identity owner.
- * @identity_acl: access control list for the identity in question.
+ * @identity_acl: access control list for the identity in question. Includes the @owner_ctx as well.
*
* Checks if specified peer is allowed to access the specified identity.
+ *
+ * The default implementation goes over items in @identity_acl, using
+ * gsignond_security_context_check() to check them against @peer_ctx.
*
* Returns: access is allowed?
*/
@@ -358,7 +395,10 @@ gsignond_access_control_manager_peer_is_allowed_to_use_identity (
* @peer_ctx: security context of the peer connection.
* @owner_ctx: security context of the identity owner.
*
- * Checks if the specified peer is owner of the identity.
+ * Checks if the peer specified in @peer_ctx is the owner of the identity.
+ *
+ * The default implementation is using gsignond_security_context_check()
+ * to check @peer_ctx against @owner_ctx directly.
*
* Returns: is owner?
*/
@@ -379,7 +419,10 @@ gsignond_access_control_manager_peer_is_owner_of_identity (
* @identity_acl: access control list for the identity.
*
* Checks if the specified peer is allowed to set the specified access
- * control list.
+ * control list. gsignond_access_control_manager_peer_is_owner_of_identity()
+ * is used before calling this method to verify identity ownership.
+ *
+ * The default implementation always returns TRUE.
*
* Returns: access control list is OK?
*/
@@ -398,7 +441,12 @@ gsignond_access_control_manager_acl_is_valid (
* @self: object instance.
*
* Retrieves security context of the keychain application. Keychain application
- * has a special management access to all stored identities.
+ * has a special management access to all stored identities and is able to
+ * perform deletion of all identities from storage.
+ *
+ * The default implementation returns an empty context. If gSSO was compiled
+ * with --enable-debug and SSO_KEYCHAIN_SYSCTX environment variable is set, then
+ * the value of that variable is used to set the returned system context instead.
*
* Returns: security context of the keychain application.
*/
diff --git a/src/common/gsignond-config.c b/src/common/gsignond-config.c
index 714622d..855777d 100644
--- a/src/common/gsignond-config.c
+++ b/src/common/gsignond-config.c
@@ -37,6 +37,54 @@
#include "gsignond/gsignond-log.h"
#include "gsignond/gsignond-dictionary.h"
+/**
+ * SECTION:gsignond-config
+ * @short_description: gSSO configuration information
+ * @include: gsignond/gsignond-config.h
+ *
+ * #GSignondConfig holds configuration information as a set of keys and values
+ * (integer or strings). The key names are defined in
+ * <link linkend="gsignond-General-configuration">general config keys</link>,
+ * <link linkend="gsignond-Database-configuration">database config keys</link>, and
+ * <link linkend="gsignond-DBus-configuration">DBus config keys</link>.
+ *
+ * The configuration is discovered from these sources, in decreasing order of
+ * priority:
+ * - environment variables, if gSSO has been compiled with --enable-debug switch.
+ * See the specific keys documentation for the variable names.
+ * - gSSO configuration file. See below for where the file is searched for.
+ * - default values. See the documentation for specific keys for those.
+ *
+ * <refsect1><title>Where the configuration file is searched for</title></refsect1>
+ *
+ * If gSSO has been compiled with --enable-debug, then these locations are used,
+ * in decreasing order of priority:
+ * - GSIGNOND_CONFIG environment variable
+ * - g_get_user_config_dir() + "gsignond/gsignond.conf"
+ * - each of g_get_system_config_dirs() + "gsignond/gsignond.conf"
+ *
+ * Otherwise, the config file location is determined at compilation time as
+ * $(sysconfdir) + "gsignond/gsignond.conf"
+ *
+ * <refsect1><title>Example configuration file</title></refsect1>
+ *
+ * See example configuration file here:
+ * <ulink url="http://code.google.com/p/accounts-sso/source/browse/gsignond.conf?repo=gsignond">
+ * http://code.google.com/p/accounts-sso/source/browse/gsignond.conf?repo=gsignond</ulink>
+ */
+
+/**
+ * GSignondConfig:
+ *
+ * Opaque structure for the object.
+ */
+/**
+ * GSignondConfigClass:
+ *
+ * Opaque structure for the class.
+ */
+
+
#define GSIGNOND_DB_METADATA_DEFAULT_DB_FILENAME "metadata.db"
#define GSIGNOND_DB_SECRET_DEFAULT_DB_FILENAME "secret.db"
@@ -195,7 +243,7 @@ _load_environment (GSignondConfig *self)
GSIGNOND_CONFIG_DBUS_IDENTITY_TIMEOUT,
e_val);
- e_val = g_getenv ("SSO_AUTHSESSION_TIMEOUT");
+ e_val = g_getenv ("SSO_AUTH_SESSION_TIMEOUT");
if (e_val && (timeout = atoi(e_val)))
gsignond_config_set_string (self,
GSIGNOND_CONFIG_DBUS_AUTH_SESSION_TIMEOUT,
@@ -234,15 +282,19 @@ _load_environment (GSignondConfig *self)
e_val = g_getenv ("SSO_STORAGE_PATH");
if (e_val)
_set_storage_path (self, e_val);
-
- e_val = g_getenv ("SSO_SECRET_PATH");
- if (e_val)
- gsignond_config_set_string (self,
- GSIGNOND_CONFIG_GENERAL_SECURE_DIR,
- e_val);
}
#endif /* ENABLE_DEBUG */
+/**
+ * gsignond_config_get_integer:
+ * @self: an instance of #GSignondConfig
+ * @key: the key name
+ *
+ * Get an integer configuration value.
+ *
+ * Returns: the value corresponding to the key as an integer. If the key does not
+ * exist or cannot be converted to the integer, 0 is returned.
+ */
gint
gsignond_config_get_integer (GSignondConfig *self, const gchar *key)
{
@@ -250,6 +302,14 @@ gsignond_config_get_integer (GSignondConfig *self, const gchar *key)
return (gint) (str_value ? atoi (str_value) : 0);
}
+/**
+ * gsignond_config_set_integer:
+ * @self: an instance of #GSignondConfig
+ * @key: the key name
+ * @value: the value
+ *
+ * Sets the configuration value to the provided integer.
+ */
void
gsignond_config_set_integer (GSignondConfig *self, const gchar *key,
gint value)
@@ -266,6 +326,16 @@ gsignond_config_set_integer (GSignondConfig *self, const gchar *key,
}
+/**
+ * gsignond_config_get_string:
+ * @self: an instance of #GSignondConfig
+ * @key: the key name
+ *
+ * Get a string configuration value.
+ *
+ * Returns: (transfer none): the value corresponding to the key as string. If the key does not
+ * exist, NULL is returned.
+ */
const gchar *
gsignond_config_get_string (GSignondConfig *self, const gchar *key)
{
@@ -278,6 +348,14 @@ gsignond_config_get_string (GSignondConfig *self, const gchar *key)
return g_variant_get_string (value, NULL);
}
+/**
+ * gsignond_config_set_string:
+ * @self: an instance of #GSignondConfig
+ * @key: the key name
+ * @value: (transfer none): the value
+ *
+ * Sets the configuration value to the provided string.
+ */
void
gsignond_config_set_string (GSignondConfig *self, const gchar *key,
const gchar *value)
@@ -340,15 +418,9 @@ gsignond_config_init (GSignondConfig *self)
(GSIGNOND_CONFIG_GENERAL_BIN_DIR),
(GSIGNOND_BIN_DIR));
- gchar *default_data_path =
- g_build_filename (g_get_user_data_dir (), "gsignond", NULL);
gsignond_config_set_string (self,
GSIGNOND_CONFIG_GENERAL_STORAGE_PATH,
- default_data_path);
- gsignond_config_set_string (self,
- GSIGNOND_CONFIG_GENERAL_SECURE_DIR,
- default_data_path);
- g_free (default_data_path);
+ "/var/db");
gsignond_config_set_string (self,
GSIGNOND_CONFIG_DB_SECRET_DB_FILENAME,
@@ -376,6 +448,14 @@ gsignond_config_class_init (GSignondConfigClass *klass)
}
+/**
+ * gsignond_config_new:
+ *
+ * Create a #GSignondConfig object.
+ *
+ * Returns: an instance of #GSignondConfig. gSSO extensions should not use this
+ * as they're already provided with a config object when they're created.
+ */
GSignondConfig *
gsignond_config_new ()
{
diff --git a/src/common/gsignond-credentials.c b/src/common/gsignond-credentials.c
index 397f88e..3697b8f 100644
--- a/src/common/gsignond-credentials.c
+++ b/src/common/gsignond-credentials.c
@@ -26,6 +26,26 @@
#include "gsignond/gsignond-log.h"
#include "gsignond/gsignond-credentials.h"
+/**
+ * SECTION:gsignond-credentials
+ * @short_description: credentials (username, password) associated with an identity
+ * @include: gsignond/gsignond-credentials.h
+ *
+ * #GSignondCredentials hold a username, password, and identity id, associated
+ * with an identity. This information in stored in secret storage using
+ * #GSignondSecretStorage.
+ */
+/**
+ * GSignondCredentials:
+ *
+ * Opaque #GSignondCredentials data structure.
+ */
+/**
+ * GSignondCredentialsClass:
+ *
+ * Opaque #GSignondCredentialsClass data structure.
+ */
+
#define GSIGNOND_CREDENTIALS_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
GSIGNOND_TYPE_CREDENTIALS, \
@@ -82,9 +102,9 @@ gsignond_credentials_init (GSignondCredentials *self)
/**
* gsignond_credentials_new:
*
- * Creates new #GSignondCredentials object
- * Returns : (transfer full) the #GSignondCredentials object
- *
+ * Creates a new empty #GSignondCredentials object
+ *
+ * Returns: (transfer full): the #GSignondCredentials object
*/
GSignondCredentials *
gsignond_credentials_new ()
@@ -95,13 +115,12 @@ gsignond_credentials_new ()
/**
* gsignond_credentials_set_data:
- *
* @self: the object whose data is to be set.
- * @id: the identity associated with the credentials.
- * @username: the username.
- * @password: the password.
+ * @id: the identity id associated with the credentials.
+ * @username: (transfer none): the username.
+ * @password: (transfer none):the password.
*
- * Sets the data of the object.
+ * Sets the data of the #GSignondCredentials.
*
* Returns: TRUE if successful, FALSE otherwise.
*/
@@ -121,11 +140,10 @@ gsignond_credentials_set_data(
/**
* gsignond_credentials_set_id:
- *
* @self: the object whose id is to be set.
* @id: the id.
*
- * Sets the id of the GSignondCredentials object
+ * Sets the identity id of the #GSignondCredentials object
*
* Returns: TRUE if successful, FALSE otherwise.
*/
@@ -141,12 +159,11 @@ gsignond_credentials_set_id(
/**
* gsignond_credentials_get_id:
- *
* @self: the object whose id is to be set.
*
- * Returns the id from the #GSignondCredentials object
+ * Gets the identity id
*
- * Returns: the id if the object is valid, NULL otherwise.
+ * Returns: the id
*/
guint32
gsignond_credentials_get_id(GSignondCredentials *self)
@@ -158,12 +175,10 @@ gsignond_credentials_get_id(GSignondCredentials *self)
/**
* gsignond_credentials_set_username:
- *
* @self: the object whose username is to be set.
- * @username: the username.
+ * @username: (transfer none): the username.
*
- * Sets the username of the GSignondCredentials object; old username is
- * freed if it exits
+ * Sets the username of the GSignondCredentials object
*
* Returns: TRUE if successful, FALSE otherwise.
*/
@@ -186,12 +201,11 @@ gsignond_credentials_set_username(
/**
* gsignond_credentials_get_username:
- *
* @self: the object whose username is to be set.
*
- * Returns the username from the #GSignondCredentials object
+ * Gets the username of the #GSignondCredentials object
*
- * Returns: the username if the object is valid, NULL otherwise.
+ * Returns: (transfer none): the username if the object is valid, NULL otherwise.
*/
const gchar*
gsignond_credentials_get_username(GSignondCredentials *self)
@@ -202,12 +216,10 @@ gsignond_credentials_get_username(GSignondCredentials *self)
/**
* gsignond_credentials_set_password:
- *
* @self: the object whose password is to be set.
- * @password: the password.
+ * @password: (transfer none): the password.
*
- * Sets the password of the GSignondCredentials object; old password is
- * freed if it exits
+ * Sets the password of the GSignondCredentials object
*
* Returns: TRUE if successful, FALSE otherwise.
*/
@@ -230,12 +242,11 @@ gsignond_credentials_set_password(
/**
* gsignond_credentials_get_password:
- *
* @self: the object whose password is to be set.
*
- * Returns the password from the #GSignondCredentials object
+ * Gets the password from the #GSignondCredentials object
*
- * Returns: the password if the object is valid, NULL otherwise.
+ * Returns: (transfer none): the password if the object is valid, NULL otherwise.
*/
const gchar*
gsignond_credentials_get_password(GSignondCredentials *self)
@@ -246,7 +257,6 @@ gsignond_credentials_get_password(GSignondCredentials *self)
/**
* gsignond_credentials_equal:
- *
* @one: the first credential to be compared.
* @two: the second credential to be compared.
*
diff --git a/src/common/gsignond-dictionary.c b/src/common/gsignond-dictionary.c
index 7d2c0c2..8ec88c3 100644
--- a/src/common/gsignond-dictionary.c
+++ b/src/common/gsignond-dictionary.c
@@ -27,12 +27,42 @@
#include <gsignond/gsignond-log.h>
/**
+ * SECTION:gsignond-dictionary
+ * @short_description: a dictionary container holding string keys and variant values
+ * @title: GSignondDictionary
+ * @include: gsignond/gsignond-dictionary.h
+ *
+ * A #GSignondDictionary is a dictionary data structure that maps string keys to #GVariant values.
+ * It's used in multiple places in gsignond and its public API to pass key-value
+ * data sets.
+ *
+ * |[ GSignondDictionary* dict = gsignond_dictionary_new();
+ * gsignond_dictionary_set_string(dict, "name", "John Smith");
+ * gsignond_dictionary_set_uint32(dict, "age", 32);
+ *
+ * guint32 age;
+ * gboolean success = gsignond_dictionary_get_uint32(dict, "age", &age);
+ * const gchar* name = gsignond_dictionary_get_string(dict, "name");
+ * gsignond_dictionary_unref(dict);
+ * ]|
+ */
+
+/**
+ * GSignondDictionary:
+ *
+ * #GSignondDictionary is a typedef for #GHashTable, which
+ * means the developers may also use methods associated with that structure.
+ */
+
+/**
* gsignond_dictionary_new_from_variant:
* @variant: instance of #GVariant
*
- * Converts the variant to GSignondDictionary.
+ * Converts the #GVariant to #GSignondDictionary. This is useful for example if
+ * the dictionary needs to be deserialized, or if it's contained in another
+ * #GSignondDictionary and has been retrieved using gsignond_dictionary_get().
*
- * Returns: (transfer full) object if successful, NULL otherwise.
+ * Returns: (transfer full): #GSignondDictionary if successful, NULL otherwise.
*/
GSignondDictionary *
gsignond_dictionary_new_from_variant (GVariant *variant)
@@ -58,9 +88,10 @@ gsignond_dictionary_new_from_variant (GVariant *variant)
* gsignond_dictionary_to_variant:
* @dict: instance of #GSignondDictionary
*
- * Converts the GSignondDictionary to variant.
+ * Converts the #GSignondDictionary to a #GVariant. The result can be serialized
+ * or put into another #GSignondDictionary using gsignond_dictionary_set().
*
- * Returns: (transfer full) #GVariant object if successful, NULL otherwise.
+ * Returns: (transfer full): #GVariant object if successful, NULL otherwise.
*/
GVariant *
gsignond_dictionary_to_variant (GSignondDictionary *dict)
@@ -90,9 +121,9 @@ gsignond_dictionary_to_variant (GSignondDictionary *dict)
/**
* gsignond_dictionary_new:
*
- * Creates new instance of GSignondDictionary.
+ * Creates a new instance of #GSignondDictionary.
*
- * Returns: (transfer full) #GSignondDictionary object if successful,
+ * Returns: (transfer full): #GSignondDictionary object if successful,
* NULL otherwise.
*/
GSignondDictionary *
@@ -108,21 +139,24 @@ gsignond_dictionary_new (void)
* gsignond_dictionary_ref:
* @dict: instance of #GSignondDictionary
*
- * Increment reference count of the dictionary structure.
+ * Increments the reference count of the dictionary structure.
+ *
+ * Returns: the pointer to the passed in #GSignondDictionary
*/
-void
+GSignondDictionary*
gsignond_dictionary_ref (GSignondDictionary *dict)
{
- g_return_if_fail (dict != NULL);
+ g_return_val_if_fail (dict != NULL, NULL);
- g_hash_table_ref (dict);
+ return (GSignondDictionary*)g_hash_table_ref (dict);
}
/**
* gsignond_dictionary_unref:
* @dict: instance of #GSignondDictionary
*
- * Decrement reference count of the dictionary structure.
+ * Decrements the reference count of the dictionary structure. If the reference
+ * count reaches zero, the structure is deallocated and shouldn't be used.
*
*/
void
@@ -137,10 +171,16 @@ gsignond_dictionary_unref (GSignondDictionary *dict)
/**
* gsignond_dictionary_get:
* @dict: instance of #GSignondDictionary
+ * @key: the key to look up in the dictionary
*
- * Retrieves a value from the dictionary.
+ * Retrieves a #GVariant value from the dictionary. This can be used to retrieve
+ * a value of an arbitrary type, and then convert it manually to a specific type
+ * using #GVariant methods. For most commonly used types, also getters that
+ * return the specific type directly are provided (gsignond_dictionary_get_string()
+ * and similar).
*
- * Returns: (transfer none) the value; NULL is returned in case of failure.
+ * Returns: (transfer none): the value; NULL is returned in case of failure (for
+ * example if the entry corresponding to the supplied key doesn't exist).
*/
GVariant *
gsignond_dictionary_get (GSignondDictionary *dict, const gchar *key)
@@ -154,11 +194,12 @@ gsignond_dictionary_get (GSignondDictionary *dict, const gchar *key)
/**
* gsignond_dictionary_set:
* @dict: instance of #GSignondDictionary
+ * @key: (transfer none): key to be set
+ * @value: (transfer full): value to be set
*
- * @key: key to be set
- * @value: value to be set
- *
- * Adds or replaces key-value pair in the dictionary.
+ * Adds or replaces key-value pair in the dictionary. This allows to set a value
+ * of an arbitrary type: it first needs to be converted to a #GVariant. For most
+ * commonly used types also type-specific setters are provided.
*
* Returns: TRUE if successful, FALSE otherwise.
*/
@@ -181,8 +222,13 @@ gsignond_dictionary_set (GSignondDictionary *dict,
/**
* gsignond_dictionary_get_boolean:
+ * @dict: instance of #GSignondDictionary
+ * @key: (transfer none): key to look up
+ * @value: points to the location where the value should be set
+ *
+ * Retrieves a gboolean value.
*
- * Overload, see #gsignond_dictionary_get for details.
+ * Returns: TRUE if the value was retrieved successfully, FALSE otherwise.
*/
gboolean
gsignond_dictionary_get_boolean (GSignondDictionary *dict, const gchar *key,
@@ -199,9 +245,14 @@ gsignond_dictionary_get_boolean (GSignondDictionary *dict, const gchar *key,
}
/**
- * gsignon_dictionary_set_boolean:
+ * gsignond_dictionary_set_boolean:
+ * @dict: instance of #GSignondDictionary
+ * @key: (transfer none): key to set
+ * @value: value to set
*
- * Overload, see #gsignond_dictionary_set for details.
+ * Sets or replaces a gboolean value in the dictionary.
+ *
+ * Returns: TRUE if the value was set or replaced successfully, FALSE otherwise.
*/
gboolean
gsignond_dictionary_set_boolean (GSignondDictionary *dict, const gchar *key,
@@ -212,8 +263,13 @@ gsignond_dictionary_set_boolean (GSignondDictionary *dict, const gchar *key,
/**
* gsignond_dictionary_get_int32:
+ * @dict: instance of #GSignondDictionary
+ * @key: (transfer none): key to look up
+ * @value: points to the location where the value should be set
*
- * Overload, see #gsignond_dictionary_get for details.
+ * Retrieves a int32 value.
+ *
+ * Returns: TRUE if the value was retrieved successfully, FALSE otherwise.
*/
gboolean
gsignond_dictionary_get_int32 (GSignondDictionary *dict, const gchar *key,
@@ -230,9 +286,14 @@ gsignond_dictionary_get_int32 (GSignondDictionary *dict, const gchar *key,
}
/**
- * gsignon_dictionary_set_int32:
+ * gsignond_dictionary_set_int32:
+ * @dict: instance of #GSignondDictionary
+ * @key: (transfer none): key to set
+ * @value: value to set
*
- * Overload, see #gsignond_dictionary_set for details.
+ * Sets or replaces a int32 value in the dictionary.
+ *
+ * Returns: TRUE if the value was set or replaced successfully, FALSE otherwise.
*/
gboolean
gsignond_dictionary_set_int32 (GSignondDictionary *dict, const gchar *key,
@@ -242,9 +303,14 @@ gsignond_dictionary_set_int32 (GSignondDictionary *dict, const gchar *key,
}
/**
- * gsignond_dictionary_get_guint32:
+ * gsignond_dictionary_get_uint32:
+ * @dict: instance of #GSignondDictionary
+ * @key: (transfer none): key to look up
+ * @value: points to the location where the value should be set
*
- * Overload, see #gsignond_dictionary_get for details.
+ * Retrieves a uint32 value.
+ *
+ * Returns: TRUE if the value was retrieved successfully, FALSE otherwise.
*/
gboolean
gsignond_dictionary_get_uint32 (GSignondDictionary *dict, const gchar *key,
@@ -261,9 +327,14 @@ gsignond_dictionary_get_uint32 (GSignondDictionary *dict, const gchar *key,
}
/**
- * gsignon_dictionary_set_guint32:
+ * gsignond_dictionary_set_uint32:
+ * @dict: instance of #GSignondDictionary
+ * @key: (transfer none): key to set
+ * @value: value to set
*
- * Overload, see #gsignond_dictionary_set for details.
+ * Sets or replaces a uint32 value in the dictionary.
+ *
+ * Returns: TRUE if the value was set or replaced successfully, FALSE otherwise.
*/
gboolean
gsignond_dictionary_set_uint32 (GSignondDictionary *dict, const gchar *key,
@@ -274,8 +345,13 @@ gsignond_dictionary_set_uint32 (GSignondDictionary *dict, const gchar *key,
/**
* gsignond_dictionary_get_int64:
+ * @dict: instance of #GSignondDictionary
+ * @key: (transfer none): key to look up
+ * @value: points to the location where the value should be set
*
- * Overload, see #gsignond_dictionary_get for details.
+ * Retrieves a int64 value.
+ *
+ * Returns: TRUE if the value was retrieved successfully, FALSE otherwise.
*/
gboolean
gsignond_dictionary_get_int64 (GSignondDictionary *dict, const gchar *key,
@@ -292,9 +368,14 @@ gsignond_dictionary_get_int64 (GSignondDictionary *dict, const gchar *key,
}
/**
- * gsignon_dictionary_set_int32:
+ * gsignond_dictionary_set_int64:
+ * @dict: instance of #GSignondDictionary
+ * @key: (transfer none): key to set
+ * @value: value to set
*
- * Overload, see #gsignond_dictionary_set for details.
+ * Sets or replaces a int64 value in the dictionary.
+ *
+ * Returns: TRUE if the value was set or replaced successfully, FALSE otherwise.
*/
gboolean
gsignond_dictionary_set_int64 (GSignondDictionary *dict, const gchar *key,
@@ -304,9 +385,14 @@ gsignond_dictionary_set_int64 (GSignondDictionary *dict, const gchar *key,
}
/**
- * gsignond_dictionary_get_guint32:
+ * gsignond_dictionary_get_uint64:
+ * @dict: instance of #GSignondDictionary
+ * @key: (transfer none): key to look up
+ * @value: points to the location where the value should be set
*
- * Overload, see #gsignond_dictionary_get for details.
+ * Retrieves a uint64 value.
+ *
+ * Returns: TRUE if the value was retrieved successfully, FALSE otherwise.
*/
gboolean
gsignond_dictionary_get_uint64 (GSignondDictionary *dict, const gchar *key,
@@ -323,9 +409,14 @@ gsignond_dictionary_get_uint64 (GSignondDictionary *dict, const gchar *key,
}
/**
- * gsignon_dictionary_set_guint32:
+ * gsignond_dictionary_set_uint64:
+ * @dict: instance of #GSignondDictionary
+ * @key: (transfer none): key to set
+ * @value: value to set
*
- * Overload, see #gsignond_dictionary_set for details.
+ * Sets or replaces a uint64 value in the dictionary.
+ *
+ * Returns: TRUE if the value was set or replaced successfully, FALSE otherwise.
*/
gboolean
gsignond_dictionary_set_uint64 (GSignondDictionary *dict, const gchar *key,
@@ -337,8 +428,12 @@ gsignond_dictionary_set_uint64 (GSignondDictionary *dict, const gchar *key,
/**
* gsignond_dictionary_get_string:
+ * @dict: instance of #GSignondDictionary
+ * @key: (transfer none): key to look up
*
- * Overload, see #gsignond_dictionary_get for details.
+ * Retrieves a string value.
+ *
+ * Returns: (transfer none): the value if it was retrieved successfully, NULL otherwise.
*/
const gchar *
gsignond_dictionary_get_string (GSignondDictionary *dict, const gchar *key)
@@ -352,9 +447,14 @@ gsignond_dictionary_get_string (GSignondDictionary *dict, const gchar *key)
}
/**
- * gsignon_dictionary_set_string:
+ * gsignond_dictionary_set_string:
+ * @dict: instance of #GSignondDictionary
+ * @key: (transfer none): key to set
+ * @value: (transfer none): value to set
*
- * Overload, see #gsignond_dictionary_set for details.
+ * Sets or replaces a string value in the dictionary.
+ *
+ * Returns: TRUE if the value was set or replaced successfully, FALSE otherwise.
*/
gboolean
gsignond_dictionary_set_string (GSignondDictionary *dict, const gchar *key,
@@ -366,9 +466,7 @@ gsignond_dictionary_set_string (GSignondDictionary *dict, const gchar *key,
/**
* gsignond_dictionary_remove:
* @dict: instance of #GSignondDictionary
- *
- * @key: key which needs to be removed from the dictionary
- * @value: value to be set
+ * @key: (transfer none): key which needs to be removed from the dictionary
*
* Removes key-value pair in the dictionary as per key.
*
@@ -391,7 +489,7 @@ gsignond_dictionary_remove (GSignondDictionary *dict, const gchar *key)
*
* Creates a copy of the dictionary.
*
- * Returns: (transfer full) #GSignondDictionary object if successful,
+ * Returns: (transfer full): #GSignondDictionary object if the copy was successful,
* NULL otherwise.
*/
GSignondDictionary *
diff --git a/src/common/gsignond-enum.c.template b/src/common/gsignond-enum.c.template
index 6391b95..d8ce58a 100644
--- a/src/common/gsignond-enum.c.template
+++ b/src/common/gsignond-enum.c.template
@@ -23,7 +23,7 @@ GType
};
the_type = g_@type@_register_static (
- g_intern_static_string ("GSignond@EnumName@"),
+ g_intern_static_string ("@EnumName@"),
values);
}
diff --git a/src/common/gsignond-error.c b/src/common/gsignond-error.c
index 462b43c..7a5dd90 100644
--- a/src/common/gsignond-error.c
+++ b/src/common/gsignond-error.c
@@ -27,6 +27,85 @@
#include <string.h>
#include <gio/gio.h>
+/**
+ * SECTION:gsignond-error
+ * @short_description: error definitions and utilities
+ * @title: Errors
+ * @include: gsignond/gsignond-error.h
+ *
+ * This file provides GSignond error definitions and utilities.
+ * When creating an error, use #GSIGNOND_ERROR for the error domain and errors
+ * from #GSignondError for the error code.
+ *
+ * |[ GError* err = g_error_new(GSIGNOND_ERROR, GSIGNOND_ERROR_MISSING_DATA,
+ * "Not enough data");
+ * ]|
+ */
+
+/**
+ * GSIGNOND_ERROR:
+ *
+ * This macro should be used when creating a #GError in GSignond plugins and extensions.
+ * (for example with g_error_new() )
+ */
+
+/**
+ * GSignondError:
+ * @GSIGNOND_ERROR_NONE: No error
+ * @GSIGNOND_ERROR_UNKNOWN: Catch-all for errors not distinguished by another code.
+ * @GSIGNOND_ERROR_INTERNAL_SERVER: Signon Daemon internal error.
+ * @GSIGNOND_ERROR_INTERNAL_COMMUNICATION: Communication with Signon Daemon error.
+ * @GSIGNOND_ERROR_PERMISSION_DENIED: The operation cannot be performed due to insufficient client permissions.
+ * @GSIGNOND_ERROR_ENCRYPTION_FAILURE: Failure during data encryption/decryption.
+ * @GSIGNOND_ERROR_AUTH_SERVICE_ERR: Placeholder to rearrange enumeration - AuthService specific
+ * @GSIGNOND_ERROR_METHOD_NOT_KNOWN: The method with this name is not found.
+ * @GSIGNOND_ERROR_SERVICE_NOT_AVAILABLE: The service is temporarily unavailable.
+ * @GSIGNOND_ERROR_INVALID_QUERY: Parameters for the query are invalid.
+ * @GSIGNOND_ERROR_IDENTITY_ERR: Placeholder to rearrange enumeration - Identity specific
+ * @GSIGNOND_ERROR_METHOD_NOT_AVAILABLE: The requested method is not available.
+ * @GSIGNOND_ERROR_IDENTITY_NOT_FOUND: The identity matching this Identity object was not found on the service.
+ * @GSIGNOND_ERROR_STORE_FAILED: Storing credentials failed.
+ * @GSIGNOND_ERROR_REMOVE_FAILED: Removing credentials failed.
+ * @GSIGNOND_ERROR_SIGN_OUT_FAILED: SignOut failed.
+ * @GSIGNOND_ERROR_IDENTITY_OPERATION_CANCELED: Identity operation was canceled by user.
+ * @GSIGNOND_ERROR_CREDENTIALS_NOT_AVAILABLE: Query failed.
+ * @GSIGNOND_ERROR_REFERENCE_NOT_FOUND: Trying to remove nonexistent reference.
+ * @GSIGNOND_ERROR_AUTH_SESSION_ERR: Placeholder to rearrange enumeration - AuthSession/PluginInterface specific
+ * @GSIGNOND_ERROR_MECHANISM_NOT_AVAILABLE: The requested mechanism is not available.
+ * @GSIGNOND_ERROR_MISSING_DATA: The SessionData object does not contain necessary information.
+ * @GSIGNOND_ERROR_INVALID_CREDENTIALS: The supplied credentials are invalid for the mechanism implementation.
+ * @GSIGNOND_ERROR_NOT_AUTHORIZED: Authorization failed.
+ * @GSIGNOND_ERROR_WRONG_STATE: An operation method has been called in a wrong state.
+ * @GSIGNOND_ERROR_OPERATION_NOT_SUPPORTED: The operation is not supported by the mechanism implementation.
+ * @GSIGNOND_ERROR_NO_CONNECTION: No Network connetion.
+ * @GSIGNOND_ERROR_NETWORK: Network connetion failed.
+ * @GSIGNOND_ERROR_SSL: Ssl connection failed.
+ * @GSIGNOND_ERROR_RUNTIME: Casting SessionData into subclass failed
+ * @GSIGNOND_ERROR_SESSION_CANCELED: Challenge was cancelled.
+ * @GSIGNOND_ERROR_TIMED_OUT: Challenge was timed out.
+ * @GSIGNOND_ERROR_USER_INTERACTION: User interaction dialog failed
+ * @GSIGNOND_ERROR_OPERATION_FAILED: Temporary failure in authentication.
+ * @GSIGNOND_ERROR_ENCRYPTION_FAILED: Failure during data encryption/decryption.
+ * @GSIGNOND_ERROR_TOS_NOT_ACCEPTED: User declined Terms of Service.
+ * @GSIGNOND_ERROR_FORGOT_PASSWORD: User requested reset password sequence.
+ * @GSIGNOND_ERROR_METHOD_OR_MECHANISM_NOT_ALLOWED: Method or mechanism not allowed for this identity.
+ * @GSIGNOND_ERROR_INCORRECT_DATE: Date time incorrect on device.
+ * @GSIGNOND_ERROR_USER_ERR: Placeholder to rearrange enumeration - User space specific
+ *
+ * This enum provides a list of errors that plugins and extensions can use.
+ *
+ */
+
+/**
+ * gsignond_get_gerror_for_id:
+ * @err: A #GSignondError specifying the error
+ * @message: Format string for the error message
+ * @...: parameters for the error string
+ *
+ * A helper macro that creates a #GError with the proper gsignond domain
+ */
+
+#define GSIGNOND_ERROR_DOMAIN "gsignond"
#define _ERROR_PREFIX "com.google.code.AccountsSSO.gSingleSignOn.Error"
GDBusErrorEntry _gsignond_errors[] =
@@ -53,7 +132,7 @@ GDBusErrorEntry _gsignond_errors[] =
{GSIGNOND_ERROR_MECHANISM_NOT_AVAILABLE, _ERROR_PREFIX".MechanismNotAvailable"},
{GSIGNOND_ERROR_MISSING_DATA, _ERROR_PREFIX".MissingData"},
{GSIGNOND_ERROR_INVALID_CREDENTIALS, _ERROR_PREFIX".InvalidCredentials"},
- {GSIGNOND_ERROR_NOT_AUTHORIZED, _ERROR_PREFIX".NotAutherized"},
+ {GSIGNOND_ERROR_NOT_AUTHORIZED, _ERROR_PREFIX".NotAuthorized"},
{GSIGNOND_ERROR_WRONG_STATE, _ERROR_PREFIX".WrongState"},
{GSIGNOND_ERROR_OPERATION_NOT_SUPPORTED, _ERROR_PREFIX".OperationNotSupported"},
{GSIGNOND_ERROR_NO_CONNECTION, _ERROR_PREFIX".NoConnection"},
@@ -72,6 +151,11 @@ GDBusErrorEntry _gsignond_errors[] =
{GSIGNOND_ERROR_INCORRECT_DATE, _ERROR_PREFIX".IncorrectDate"},
} ;
+/**
+ * gsignond_error_quark:
+ *
+ * Creates and returns a domain for GSignond errors.
+ */
GQuark
gsignond_error_quark (void)
{
@@ -85,38 +169,13 @@ gsignond_error_quark (void)
return (GQuark) quark_volatile;
}
-GString*
-gsignond_concat_domain_and_error (
- const gchar *str1,
- const gchar *str2)
-{
- GString *str = NULL;
- g_return_val_if_fail (str1 != NULL && str2 != NULL, NULL);
- str = g_string_sized_new (strlen(str1)+strlen(str2)-1);
- g_string_printf (str,"[%s].%s\n",str1,str2);
- return str;
-}
-
-GString*
-gsignond_prepend_domain_to_error_msg (const GError *err)
-{
- GString *msg = NULL;
- const gchar *domain = NULL;
- g_return_val_if_fail (err != NULL, NULL);
- if (err->message != NULL) {
- domain = g_quark_to_string(err->domain);
- msg = gsignond_concat_domain_and_error(domain, err->message);
- }
- return msg;
-}
-
/**
* gsignond_error_new_from_variant:
* @var: instance of #GVariant
*
* Converts the GVariant to GError.
*
- * Returns: (transfer full) #GError object if successful, NULL otherwise.
+ * Returns: (transfer full): #GError object if successful, NULL otherwise.
*/
GError *
gsignond_error_new_from_variant (
@@ -143,7 +202,7 @@ gsignond_error_new_from_variant (
*
* Converts the GError to GVariant.
*
- * Returns: (transfer full) #GVariant object if successful, NULL otherwise.
+ * Returns: (transfer full): #GVariant object if successful, NULL otherwise.
*/
GVariant *
gsignond_error_to_variant (
diff --git a/src/common/gsignond-extension-interface.c b/src/common/gsignond-extension-interface.c
index 45362b4..96510d7 100644
--- a/src/common/gsignond-extension-interface.c
+++ b/src/common/gsignond-extension-interface.c
@@ -25,6 +25,41 @@
#include "gsignond/gsignond-extension-interface.h"
+/**
+ * SECTION:gsignond-extension-interface
+ * @short_description: provides platform adaptation functionality
+ * @include: gsignond/gsignond-plugin-interface.h
+ *
+ * #GSignondExtension provides access to platform adaptation functionality. It
+ * contains getter methods for default implementations of #GSignondAccessControlManager,
+ * #GSignondSecretStorage and #GSignondStorageManager.
+ *
+ * gSSO can be adapted to a specific platform environment by implementing a
+ * custom extension module. The following steps need to be taken:
+ *
+ * a) subclass and re-implement some (or all) of the functionality of the above
+ * three classes.
+ *
+ * b) subclass #GSignondExtension and provide implementations of its getter methods for those
+ * of the adaptation classes that have been changed.
+ *
+ * d) provide a function <function>GSignondExtension * extensionname_extension_init(void)</function>
+ * that returns an instance of the #GSignondExtension subclass.
+ *
+ * c) build and install these implementations as a gSSO extension module and
+ * configure gSSO to use it.
+ *
+ * Examples of custom extensions can be seen here:
+ * <ulink url="https://code.google.com/p/accounts-sso/source/browse/?repo=gsignond#git%2Fsrc%2Fextensions">
+ * https://code.google.com/p/accounts-sso/source/browse/?repo=gsignond#git%2Fsrc%2Fextensions</ulink>
+ * and gSSO configuration is described in #GSignondConfig.
+ */
+/**
+ * GSignondExtension:
+ *
+ * Opaque #GSignondExtension data structure.
+ */
+
G_DEFINE_TYPE (GSignondExtension, gsignond_extension, G_TYPE_OBJECT);
#define GSIGNOND_EXTENSION_PRIV(obj) G_TYPE_INSTANCE_GET_PRIVATE ((obj), GSIGNOND_TYPE_EXTENSION, GSignondExtensionPrivate)
@@ -112,6 +147,17 @@ _get_access_control_manager (GSignondExtension *self, GSignondConfig *config)
return priv->access_control_manager;
}
+/**
+ * GSignondExtensionClass:
+ * @parent_class: the parent class
+ * @get_extension_name: implementation of gsignond_extension_get_name()
+ * @get_extension_version: implementation of gsignond_extension_get_version()
+ * @get_storage_manager: implementation of gsignond_extension_get_storage_manager()
+ * @get_secret_storage: implementation of gsignond_extension_get_secret_storage()
+ * @get_access_control_manager: implementation of gsignond_extension_get_access_control_manager()
+ *
+ * #GSignondExtensionClass class containing pointers to class methods.
+ */
static void
gsignond_extension_class_init (GSignondExtensionClass *klass)
{
@@ -137,35 +183,14 @@ gsignond_extension_init (GSignondExtension *self)
self->priv->secret_storage = NULL;
}
-static void
-_on_extension_dispose (gpointer data, GObject *object)
-{
- if (data) *(GSignondExtension **)data = NULL;
-}
-
-GSignondExtension * default_extension_init ()
-{
- static GSignondExtension *default_extension = NULL;
-
- if (!default_extension) {
- default_extension =
- g_object_new (GSIGNOND_TYPE_EXTENSION, NULL);
-
- g_object_weak_ref (G_OBJECT (default_extension),
- _on_extension_dispose,
- &default_extension);
- }
-
- return default_extension;
-}
-
/**
* gsignond_extension_get_name:
* @self: object instance.
*
- * Get human readable name of the extension.
+ * Get a human readable name of the extension. Default implementation
+ * returns "default".
*
- * Returns: (transfer none) name of the extension.
+ * Returns: (transfer none): name of the extension.
*/
const gchar *
gsignond_extension_get_name (GSignondExtension *self)
@@ -178,7 +203,7 @@ gsignond_extension_get_name (GSignondExtension *self)
* @self: object instance.
*
* Get version of the extension, split into four bytes in order from MSB to LSB;
- * major, minor, patchlevel, build.
+ * major, minor, patchlevel, build. Default implementation returns 0.
*/
guint32
gsignond_extension_get_version (GSignondExtension *self)
@@ -191,9 +216,10 @@ gsignond_extension_get_version (GSignondExtension *self)
* @self: object instance.
* @config: configuration object instance.
*
- * Factory method to get a singleton storage manager object.
+ * Factory method to get a singleton storage manager object. See
+ * #GSignondStorageManager for the description of the default implementation.
*
- * Returns: (transfer none) storage manager object instance.
+ * Returns: (transfer none): storage manager object instance.
*/
GSignondStorageManager *
gsignond_extension_get_storage_manager (GSignondExtension *self,
@@ -208,9 +234,10 @@ gsignond_extension_get_storage_manager (GSignondExtension *self,
* @self: object instance.
* @config: configuration object instance.
*
- * Factory method to get a singleton secret storage object.
+ * Factory method to get a singleton secret storage object. See
+ * #GSignondSecretStorage for the description of the default implementation.
*
- * Returns: (transfer none) secret storage object instance.
+ * Returns: (transfer none): secret storage object instance.
*/
GSignondSecretStorage *
gsignond_extension_get_secret_storage (GSignondExtension *self,
@@ -225,9 +252,10 @@ gsignond_extension_get_secret_storage (GSignondExtension *self,
* @self: object instance.
* @config: configuration object instance.
*
- * Factory method to get a singleton access control manager object.
+ * Factory method to get a singleton access control manager object. See
+ * #GSignondAccessControlManager for the description of the default implementation.
*
- * Returns: (transfer none) access control manager object instance.
+ * Returns: (transfer none): access control manager object instance.
*/
GSignondAccessControlManager *
gsignond_extension_get_access_control_manager (GSignondExtension *self,
diff --git a/src/common/gsignond-identity-info-internal.h b/src/common/gsignond-identity-info-internal.h
index 2375cbe..60ce7a1 100644
--- a/src/common/gsignond-identity-info-internal.h
+++ b/src/common/gsignond-identity-info-internal.h
@@ -27,7 +27,7 @@
#define __GSIGNOND_IDENTITY_INFO_INTERNAL_H__
#include <glib.h>
-#include <gsignond/gsignond-identity-info.h>
+#include "gsignond-identity-info.h"
G_BEGIN_DECLS
diff --git a/src/common/gsignond-identity-info.c b/src/common/gsignond-identity-info.c
index 9e41a41..02af6c3 100644
--- a/src/common/gsignond-identity-info.c
+++ b/src/common/gsignond-identity-info.c
@@ -23,7 +23,7 @@
* 02110-1301 USA
*/
-#include <gsignond/gsignond-identity-info.h>
+#include "gsignond-identity-info.h"
#include "gsignond-identity-info-internal.h"
@@ -35,16 +35,25 @@ _gsignond_identity_info_seq_cmp (
GSequenceIter *iter1 = NULL, *iter2 = NULL;
gboolean equal = TRUE;
- if (one == NULL && two == NULL)
+ if (one == two)
return TRUE;
- if ((one != NULL && two == NULL) ||
- (one == NULL && two != NULL) ||
- (g_sequence_get_length (one) != g_sequence_get_length (two)))
- return FALSE;
+ if (one == NULL) {
+ if (g_sequence_get_length (two) == 0)
+ return TRUE;
+ else
+ return FALSE;
+ }
+
+ if (two == NULL) {
+ if (g_sequence_get_length (one) == 0)
+ return TRUE;
+ else
+ return FALSE;
+ }
- if (one == two)
- return TRUE;
+ if (g_sequence_get_length (one) != g_sequence_get_length (two))
+ return FALSE;
iter1 = g_sequence_get_begin_iter (one);
while (!g_sequence_iter_is_end (iter1)) {
@@ -222,7 +231,7 @@ _gsignond_identity_info_methods_cmp (
*
* Creates new instance of GSignondIdentityInfo.
*
- * Returns: (transfer full) #GSignondIdentityInfo object if successful,
+ * Returns: (transfer full): #GSignondIdentityInfo object if successful,
* NULL otherwise.
*/
GSignondIdentityInfo *
@@ -629,7 +638,7 @@ gsignond_identity_info_set_caption (
*
* Retrieves the realms from the info.
*
- * Returns: (transfer full) the realms if successful, NULL Otherwise.
+ * Returns: (transfer full): the realms if successful, NULL Otherwise.
* when done realms should be freed using g_sequence_free.
*/
GSequence *
@@ -649,7 +658,7 @@ gsignond_identity_info_get_realms (GSignondIdentityInfo *info)
* gsignond_identity_info_set_realms:
* @info: instance of #GSignondIdentityInfo
*
- * @realms: (transfer none) realms to be set
+ * @realms: (transfer none): realms to be set
*
* Sets the realms of the info.
*
@@ -674,9 +683,9 @@ gsignond_identity_info_set_realms (
* @info: instance of #GSignondIdentityInfo
*
* Retrieves the methods from the info whereas #GHashTable consists of
- * <gchar*,GSequence*> and #GSequence is a sequence of gchar *.
+ * (gchar*,GSequence*) and #GSequence is a sequence of gchar *.
*
- * Returns: (transfer full) the methods if successful, NULL otherwise.
+ * Returns: (transfer full): the methods if successful, NULL otherwise.
* when done, methods should be freed using g_hash_table_unref.
*/
GHashTable *
@@ -714,8 +723,8 @@ gsignond_identity_info_get_methods (GSignondIdentityInfo *info)
* gsignond_identity_info_set_methods:
* @info: instance of #GSignondIdentityInfo
*
- * @methods: (transfer none) methods to be set whereas #GHashTable consists of
- * <gchar*,#GSequence*> and #GSequence is a sequence of gchar *.
+ * @methods: (transfer none): methods to be set whereas #GHashTable consists of
+ * (gchar*,#GSequence*) and #GSequence is a sequence of gchar *.
*
* Sets the methods of the info.
*
@@ -762,7 +771,7 @@ gsignond_identity_info_set_methods (
*
* Retrieves the mechanisms from the info.
*
- * Returns: (transfer full) the mechanisms if successful, NULL otherwise.
+ * Returns: (transfer full): the mechanisms if successful, NULL otherwise.
* when done, mechanisms should be freed using g_sequence_free; #GSequence is a
* sequence of gchar *.
*/
@@ -837,7 +846,7 @@ gsignond_identity_info_remove_method (
*
* Retrieves the access control list from the info.
*
- * Returns: (transfer full) the list if successful, NULL otherwise.
+ * Returns: (transfer full): the list if successful, NULL otherwise.
* when done, list should be freed using gsignond_security_context_list_free.
*/
GSignondSecurityContextList *
@@ -857,7 +866,7 @@ gsignond_identity_info_get_access_control_list (GSignondIdentityInfo *info)
* gsignond_identity_info_set_access_control_list:
* @info: instance of #GSignondIdentityInfo
*
- * @acl: (transfer none) access control list to be set
+ * @acl: (transfer none): access control list to be set
*
* Sets the access control list of the info.
*
@@ -883,7 +892,7 @@ gsignond_identity_info_set_access_control_list (
*
* Retrieves the id from the info.
*
- * Returns: (transfer full) the owner if successful, NULL otherwise.
+ * Returns: (transfer full): the owner if successful, NULL otherwise.
* when done, owner list should be freed using
* gsignond_security_context_free.
*/
@@ -904,7 +913,7 @@ gsignond_identity_info_get_owner (GSignondIdentityInfo *info)
* gsignond_identity_info_set_owner:
* @info: instance of #GSignondIdentityInfo
*
- * @owners: (transfer none) owner to be set
+ * @owners: (transfer none): owner to be set
*
* Sets the owner of the info.
*
diff --git a/src/common/gsignond-identity-info.h b/src/common/gsignond-identity-info.h
new file mode 100644
index 0000000..be6d318
--- /dev/null
+++ b/src/common/gsignond-identity-info.h
@@ -0,0 +1,187 @@
+/* vi: set et sw=4 ts=4 cino=t0,(0: */
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of gsignond
+ *
+ * Copyright (C) 2012-2013 Intel Corporation.
+ *
+ * Contact: Imran Zaman <imran.zaman@linux.intel.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef __GSIGNOND_IDENTITY_INFO_H__
+#define __GSIGNOND_IDENTITY_INFO_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gsignond/gsignond-security-context.h>
+#include <gsignond/gsignond-dictionary.h>
+
+G_BEGIN_DECLS
+
+#define GSIGNOND_TYPE_IDENTITY_INFO (GSIGNOND_TYPE_DICTIONARY)
+
+#define GSIGNOND_IDENTITY_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GSIGNOND_TYPE_IDENTITY_INFO, \
+ GSignondIdentityInfo))
+#define GSIGNOND_IS_IDENTITY_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj),\
+ GSIGNOND_TYPE_IDENTITY_INFO))
+
+typedef GSignondDictionary GSignondIdentityInfo;
+typedef GList GSignondIdentityInfoList;
+
+GSignondIdentityInfo *
+gsignond_identity_info_new (void);
+
+GSignondIdentityInfo *
+gsignond_identity_info_copy (GSignondIdentityInfo *info);
+
+void
+gsignond_identity_info_ref (GSignondIdentityInfo *info);
+
+void
+gsignond_identity_info_unref (GSignondIdentityInfo *info);
+
+guint32
+gsignond_identity_info_get_id (GSignondIdentityInfo *info);
+
+gboolean
+gsignond_identity_info_set_id (
+ GSignondIdentityInfo *info,
+ guint32 id);
+
+gboolean
+gsignond_identity_info_get_is_identity_new (GSignondIdentityInfo *info);
+
+gboolean
+gsignond_identity_info_set_identity_new (GSignondIdentityInfo *info);
+
+const gchar *
+gsignond_identity_info_get_username (GSignondIdentityInfo *info);
+
+gboolean
+gsignond_identity_info_set_username (
+ GSignondIdentityInfo *info,
+ const gchar *username);
+
+void
+gsignond_identity_info_remove_username (GSignondIdentityInfo *info);
+
+gboolean
+gsignond_identity_info_get_is_username_secret (GSignondIdentityInfo *info);
+
+gboolean
+gsignond_identity_info_set_username_secret (
+ GSignondIdentityInfo *info,
+ gboolean username_secret);
+
+const gchar *
+gsignond_identity_info_get_secret (GSignondIdentityInfo *info);
+
+gboolean
+gsignond_identity_info_set_secret (
+ GSignondIdentityInfo *info,
+ const gchar *secret);
+
+void
+gsignond_identity_info_remove_secret (GSignondIdentityInfo *info);
+
+gboolean
+gsignond_identity_info_get_store_secret (GSignondIdentityInfo *info);
+
+gboolean
+gsignond_identity_info_set_store_secret (
+ GSignondIdentityInfo *info,
+ gboolean store_secret);
+
+const gchar *
+gsignond_identity_info_get_caption (GSignondIdentityInfo *info);
+
+gboolean
+gsignond_identity_info_set_caption (
+ GSignondIdentityInfo *info,
+ const gchar *caption);
+
+GSequence *
+gsignond_identity_info_get_realms (GSignondIdentityInfo *info);
+
+gboolean
+gsignond_identity_info_set_realms (
+ GSignondIdentityInfo *info,
+ GSequence *realms);
+
+GHashTable *
+gsignond_identity_info_get_methods (GSignondIdentityInfo *info);
+
+gboolean
+gsignond_identity_info_set_methods (
+ GSignondIdentityInfo *info,
+ GHashTable *methods);
+
+GSequence *
+gsignond_identity_info_get_mechanisms (
+ GSignondIdentityInfo *info,
+ const gchar *method);
+
+gboolean
+gsignond_identity_info_remove_method (
+ GSignondIdentityInfo *info,
+ const gchar *method);
+
+GSignondSecurityContextList *
+gsignond_identity_info_get_access_control_list (GSignondIdentityInfo *info);
+
+gboolean
+gsignond_identity_info_set_access_control_list (
+ GSignondIdentityInfo *info,
+ const GSignondSecurityContextList *acl);
+
+GSignondSecurityContext *
+gsignond_identity_info_get_owner (GSignondIdentityInfo *info);
+
+gboolean
+gsignond_identity_info_set_owner (
+ GSignondIdentityInfo *info,
+ const GSignondSecurityContext *owner);
+
+gboolean
+gsignond_identity_info_get_validated (GSignondIdentityInfo *info);
+
+gboolean
+gsignond_identity_info_set_validated (
+ GSignondIdentityInfo *info,
+ gboolean validated);
+
+guint32
+gsignond_identity_info_get_identity_type (GSignondIdentityInfo *info);
+
+gboolean
+gsignond_identity_info_set_identity_type (
+ GSignondIdentityInfo *info,
+ guint32 type);
+
+gboolean
+gsignond_identity_info_compare (
+ GSignondIdentityInfo *info,
+ GSignondIdentityInfo *other);
+
+void
+gsignond_identity_info_list_free (GSignondIdentityInfoList *list);
+
+G_END_DECLS
+
+#endif /* __GSIGNOND_IDENTITY_INFO_H__ */
diff --git a/src/common/gsignond-plugin-enum-types.h b/src/common/gsignond-plugin-enum-types.h
index a301213..a894461 100644
--- a/src/common/gsignond-plugin-enum-types.h
+++ b/src/common/gsignond-plugin-enum-types.h
@@ -2,7 +2,7 @@
/* Generated data (by glib-mkenums) */
#ifndef GSIGNOND_PLUGIN_ENUM_TYPES_H_
-#define GSIGNOND_PLUGIND_ENUM_TYPES_H_
+#define GSIGNOND_PLUGIN_ENUM_TYPES_H_
#include <glib-object.h>
diff --git a/src/common/gsignond-plugin-interface.c b/src/common/gsignond-plugin-interface.c
index fa9d131..be98631 100644
--- a/src/common/gsignond-plugin-interface.c
+++ b/src/common/gsignond-plugin-interface.c
@@ -27,8 +27,148 @@
#include "gsignond/gsignond-plugin-interface.h"
#include "gsignond-plugin-enum-types.h"
+/**
+ * SECTION:gsignond-plugin-interface
+ * @short_description: an interface for implementing authentication plugins
+ * @include: gsignond/gsignond-plugin-interface.h
+ *
+ * #GSignondPlugin is an interface for implementing authentication plugins.
+ *
+ * When creating a plugin, write the #GObject boilerplate code as usual, but
+ *
+ * a) declare the type as follows:
+ *
+ * |[ G_DEFINE_TYPE_WITH_CODE (GSignondPasswordPlugin, gsignond_password_plugin,
+ * G_TYPE_OBJECT,
+ * G_IMPLEMENT_INTERFACE (GSIGNOND_TYPE_PLUGIN,
+ * gsignond_plugin_interface_init));
+ * ]|
+ *
+ * b) implement <function>gsignond_plugin_interface_init</function> as follows:
+ *
+ * |[ static void
+ * gsignond_plugin_interface_init (GSignondPluginInterface *iface)
+ * {
+ * iface->cancel = gsignond_password_plugin_cancel;
+ * iface->request_initial = gsignond_password_plugin_request_initial;
+ * iface->request = gsignond_password_plugin_request;
+ * iface->user_action_finished = gsignond_password_plugin_user_action_finished;
+ * iface->refresh = gsignond_password_plugin_refresh;
+ * }
+ * ]|
+ *
+ * where the <function>gsignond_password_plugin_cancel</function> etc. are specific implementations of
+ * plugin interface methods that every plugin must provide (see below for when
+ * and how they're used by the daemon).
+ *
+ * c) override #GSignondPlugin:type and #GSignondPlugin:mechanisms property
+ * implementations in the plugin class constructor like this:
+ *
+ * |[static void
+ * gsignond_password_plugin_class_init (GSignondPasswordPluginClass *klass)
+ * {
+ * GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ *
+ * gobject_class->set_property = gsignond_password_plugin_set_property;
+ * gobject_class->get_property = gsignond_password_plugin_get_property;
+ *
+ * g_object_class_override_property (gobject_class, PROP_TYPE, "type");
+ * g_object_class_override_property (gobject_class, PROP_MECHANISMS,
+ * "mechanisms");
+ * }
+ * ]|
+ * (naturally, plugin's property setter should ignore attempts to set these properties,
+ * and plugin's property getter should provide their values when asked)
+ *
+ * <refsect1><title>The plugin API</title></refsect1>
+ *
+ * Plugins implement authentication sessions which are controlled through the
+ * plugin API. Authentication sessions follow one another so there is only one active
+ * session at a time.
+ *
+ * The plugin API is a set of methods and signals that should be used in a specific
+ * sequence:
+ *
+ * - successful authentication session begins with gsignond_plugin_request_initial() and ends
+ * with the plugin issuing a #GSignondPlugin::response-final signal
+ * - at any point the application can cancel an active session with
+ * gsignond_plugin_cancel()
+ * - at any point the plugin can cancel an active session by issuing #GSignondPlugin::error
+ * signal, which also provides some details about the cancellation reason.
+ * - if a session is active, and the plugin has an intermediate response or needs
+ * additional information, it issues #GSignondPlugin::response signal, which the
+ * application should respond to with gsignond_plugin_request() method. This can
+ * happen more than once.
+ * - if the plugin needs to launch UI interaction with the user, it's issuing
+ * #GSignondPlugin::user-action-required signal, which the application should
+ * follow up with gsignond_plugin_user_action_finished() method. This can happen
+ * more than once as well.
+ * - if, during an active UI session, the application needs a UI refresh
+ * (for example, to fetch a new captcha image), it's
+ * requested from the plugin with gsignond_plugin_refresh() method, followed
+ * by the plugin's response via #GSignondPlugin::refreshed signal. This can happen
+ * more than once.
+ * - changes in plugin state are reported through #GSignondPlugin::status-changed signal.
+ * - if the plugin needs to store information in persistent storage, it issues
+ * #GSignondPlugin::store signal. Later, that same information is provided as a
+ * parameter to gsignond_plugin_request_initial().
+ *
+ * <refsect1><title>Example plugins</title></refsect1>
+ *
+ * See example plugin implementation here:
+ * <ulink url="https://code.google.com/p/accounts-sso/source/browse/?repo=gsignond#git%2Fsrc%2Fplugins">
+ * https://code.google.com/p/accounts-sso/source/browse/?repo=gsignond#git%2Fsrc%2Fplugins</ulink>.
+ *
+ * For examples of out of tree plugins, you can have a look at SASL or OAuth plugin
+ * implementations:
+ * <ulink url="http://code.google.com/p/accounts-sso/source/browse?repo=gsignond-plugin-sasl">
+ * http://code.google.com/p/accounts-sso/source/browse?repo=gsignond-plugin-sasl</ulink>.
+ *
+ * <ulink url="http://code.google.com/p/accounts-sso/source/browse?repo=gsignond-plugin-oa">
+ * http://code.google.com/p/accounts-sso/source/browse?repo=gsignond-plugin-oa</ulink>.
+ *
+ */
+
+
+/**
+ * GSignondPluginState:
+ * @GSIGNOND_PLUGIN_STATE_NONE: State unknown
+ * @GSIGNOND_PLUGIN_STATE_RESOLVING: Resolving remote server host name
+ * @GSIGNOND_PLUGIN_STATE_CONNECTING: Connecting to remote server
+ * @GSIGNOND_PLUGIN_STATE_SENDING_DATA: Sending data to remote server
+ * @GSIGNOND_PLUGIN_STATE_WAITING: Waiting for reply from remote server
+ * @GSIGNOND_PLUGIN_STATE_USER_PENDING: Waiting for response from user
+ * @GSIGNOND_PLUGIN_STATE_REFRESHING: Refreshing ui request
+ * @GSIGNOND_PLUGIN_STATE_PROCESS_PENDING: Request has been queued
+ * @GSIGNOND_PLUGIN_STATE_STARTED: Request has been dequeued
+ * @GSIGNOND_PLUGIN_STATE_CANCELING: Canceling current process
+ * @GSIGNOND_PLUGIN_STATE_DONE: Process is finished
+ * @GSIGNOND_PLUGIN_STATE_HOLDING: Holding long non-expired token
+ *
+ * The plugin provides state updates by emitting #GSignondPlugin::status-changed
+ * signal with this enum and a string describing what happened.
+ */
+
+/**
+ * GSignondPlugin:
+ *
+ * Opaque #GSignondPlugin data structure.
+ */
G_DEFINE_INTERFACE (GSignondPlugin, gsignond_plugin, 0)
+/**
+ * GSignondPluginInterface:
+ * @parent: parent interface type.
+ * @cancel: implementation of gsignond_plugin_cancel()
+ * @request_initial: implementation of gsignond_plugin_request_initial()
+ * @request: implementation of gsignond_plugin_request()
+ * @user_action_finished: implementation of gsignond_plugin_user_action_finished()
+ * @refresh: implementation of gsignond_plugin_refresh()
+ *
+ * #GSignondPluginInterface interface containing pointers to methods that all
+ * plugin implementations should provide.
+ */
+
/* signals */
enum
{
@@ -46,46 +186,135 @@ static guint signals[LAST_SIGNAL] = { 0 };
static void gsignond_plugin_default_init (GSignondPluginInterface *g_class)
{
+ /**
+ * GSignondPlugin::response:
+ * @plugin: the plugin which emitted the signal
+ * @session_data: a #GSignondSessionData containing signal parameters
+ *
+ * This signal is issued by the plugin when it wants to provide an intermediate
+ * response to the application or needs additional information from the application.
+ *
+ * After issuing this signal the plugin expects a gsignond_plugin_response() call.
+ */
signals[RESPONSE] = g_signal_new ("response", G_TYPE_FROM_CLASS (g_class),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
1, GSIGNOND_TYPE_SESSION_DATA);
+ /**
+ * GSignondPlugin::response-final:
+ * @plugin: the plugin which emitted the signal
+ * @session_data: a #GSignondSessionData containing signal parameters
+ *
+ * This signal is issued by the plugin when it has completed the authentication
+ * sequence and is used to provide the final response to the application.
+ *
+ * After issuing this signal the plugin is idle and is ready for a new
+ * authentication session.
+ */
signals[RESPONSE_FINAL] = g_signal_new ("response-final", G_TYPE_FROM_CLASS (g_class),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
1, GSIGNOND_TYPE_SESSION_DATA);
+ /**
+ * GSignondPlugin::store:
+ * @plugin: the plugin which emitted the signal
+ * @data: a #GSignondDictionary containing data to place in persistent storage
+ *
+ * This signal is issued by the plugin when it has data to store in persistant
+ * storage. The same data would later be provided to plugin via
+ * gsignond_plugin_request_initial @identity_method_cache parameter.
+ */
signals[STORE] = g_signal_new ("store", G_TYPE_FROM_CLASS (g_class),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
1, GSIGNOND_TYPE_DICTIONARY);
+ /**
+ * GSignondPlugin::error:
+ * @plugin: the plugin which emitted the signal
+ * @error: the details of the error
+ *
+ * This signal is issued by the plugin when an error has occured, or the
+ * plugin otherwise has a reason to cancel the authentication session. The
+ * @error should be specified according to
+ * <link linkend="gsignond-Errors">GSignond errors.</link>
+ *
+ */
signals[ERROR] = g_signal_new ("error", G_TYPE_FROM_CLASS (g_class),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
1, G_TYPE_ERROR);
+ /**
+ * GSignondPlugin::user-action-required:
+ * @plugin: the plugin which emitted the signal
+ * @ui_data: parameters for UI interaction
+ *
+ * This signal is issued by the plugin when it needs a UI interaction with
+ * the user to happen. When the interaction is complete, gsignond_plugin_user_action_finished()
+ * should be issued.
+ */
signals[USER_ACTION_REQUIRED] = g_signal_new ("user-action-required",
G_TYPE_FROM_CLASS (g_class),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
1, GSIGNOND_TYPE_SIGNONUI_DATA);
+ /**
+ * GSignondPlugin::refreshed:
+ * @plugin: the plugin which emitted the signal
+ * @ui_data: parameters for UI refresh
+ *
+ * This signal is issued by the plugin when the UI interaction is ongoing
+ * and the UI needs to be refreshed. This can be used for example to update
+ * captcha image in the UI.
+ */
signals[REFRESHED] = g_signal_new ("refreshed", G_TYPE_FROM_CLASS (g_class),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
1, GSIGNOND_TYPE_SIGNONUI_DATA);
+ /**
+ * GSignondPlugin::status-changed:
+ * @plugin: the plugin which emitted the signal
+ * @state: the plugin state
+ * @message: the message that accompanies the state change
+ *
+ * This signal is issued by the plugin when plugin state has changed. This
+ * can be used by applications to report authentication progress.
+ */
signals[STATUS_CHANGED] = g_signal_new ("status-changed",
G_TYPE_FROM_CLASS (g_class),
G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE,
2, GSIGNOND_TYPE_PLUGIN_STATE, G_TYPE_STRING);
+ /**
+ * GSignondPlugin:type:
+ *
+ * This property holds a plugin type, or authentication method it implements
+ * (for example "oauth" or "sasl").
+ */
g_object_interface_install_property (g_class, g_param_spec_string ("type",
"Type", "Plugin type", "none",
G_PARAM_READABLE|G_PARAM_STATIC_STRINGS));
+ /**
+ * GSignondPlugin:mechanisms:
+ *
+ * This property holds a list of authentication mechanisms that the plugin
+ * implements, all specified within the authentication method. For example,
+ * OAuth plugin could implement "oauth1" and "oauth2" mechanisms.
+ */
g_object_interface_install_property (g_class, g_param_spec_boxed (
"mechanisms", "Mechanisms", "List of plugin mechanisms",
G_TYPE_STRV, G_PARAM_READABLE|G_PARAM_STATIC_STRINGS));
}
+/**
+ * gsignond_plugin_cancel:
+ * @self: plugin instance
+ *
+ * This method cancels an ongoing authentication session. The plugin implementations
+ * should issue a #GSignondPlugin::error signal with #GSIGNOND_ERROR_SESSION_CANCELED
+ * error, and prepare for a new authentication session.
+ */
void gsignond_plugin_cancel (GSignondPlugin *self)
{
g_return_if_fail (GSIGNOND_IS_PLUGIN (self));
@@ -93,16 +322,36 @@ void gsignond_plugin_cancel (GSignondPlugin *self)
GSIGNOND_PLUGIN_GET_INTERFACE (self)->cancel (self);
}
+/**
+ * gsignond_plugin_request_initial:
+ * @self: plugin instance
+ * @session_data: parameters for the session
+ * @identity_method_cache: data from persistent storage, saved previously via
+ * #GSignondPlugin::store signal
+ * @mechanism: mechanism to use for the authentication
+ *
+ * This method starts a new authentication session.
+ */
void gsignond_plugin_request_initial (GSignondPlugin *self,
GSignondSessionData *session_data,
+ GSignondDictionary *identity_method_cache,
const gchar *mechanism)
{
g_return_if_fail (GSIGNOND_IS_PLUGIN (self));
GSIGNOND_PLUGIN_GET_INTERFACE (self)->request_initial (self, session_data,
+ identity_method_cache,
mechanism);
}
+/**
+ * gsignond_plugin_request:
+ * @self: plugin instance
+ * @session_data: additional parameters for the session
+ *
+ * This method provides the plugin with additional parameters for the session
+ * after the plugin has asked for it via #GSignondPlugin::response signal.
+ */
void gsignond_plugin_request (GSignondPlugin *self,
GSignondSessionData *session_data)
{
@@ -111,6 +360,14 @@ void gsignond_plugin_request (GSignondPlugin *self,
GSIGNOND_PLUGIN_GET_INTERFACE (self)->request (self, session_data);
}
+/**
+ * gsignond_plugin_user_action_finished:
+ * @self: plugin instance
+ * @ui_data: results of UI interaction
+ *
+ * This method provides the plugin with the results of UI interaction
+ * after the plugin has asked for it via #GSignondPlugin::user-action-required signal.
+ */
void gsignond_plugin_user_action_finished (GSignondPlugin *self,
GSignondSignonuiData *ui_data)
{
@@ -120,6 +377,14 @@ void gsignond_plugin_user_action_finished (GSignondPlugin *self,
ui_data);
}
+/**
+ * gsignond_plugin_refresh:
+ * @self: plugin instance
+ * @ui_data: UI refresh parameters
+ *
+ * This method asks the plugin to refresh the UI. The plugin responds with
+ * #GSignondPlugin::refreshed signal.
+ */
void gsignond_plugin_refresh (GSignondPlugin *self,
GSignondSignonuiData *ui_data)
{
@@ -128,41 +393,98 @@ void gsignond_plugin_refresh (GSignondPlugin *self,
GSIGNOND_PLUGIN_GET_INTERFACE (self)->refresh (self, ui_data);
}
+/**
+ * gsignond_plugin_response:
+ * @self: plugin instance
+ * @session_data: session data
+ *
+ * Plugin implementations should use this to issue #GSignondPlugin::response
+ * signal. This method should not be used otherwise.
+ */
void gsignond_plugin_response (GSignondPlugin *self,
GSignondSessionData *session_data)
{
g_signal_emit (self, signals[RESPONSE], 0, session_data);
}
+/**
+ * gsignond_plugin_response_final:
+ * @self: plugin instance
+ * @session_data: session data
+ *
+ * Plugin implementations should use this to issue #GSignondPlugin::response-final
+ * signal. This method should not be used otherwise.
+ */
void gsignond_plugin_response_final (GSignondPlugin *self,
GSignondSessionData *session_data)
{
g_signal_emit (self, signals[RESPONSE_FINAL], 0, session_data);
}
+/**
+ * gsignond_plugin_store:
+ * @self: plugin instance
+ * @identity_method_cache: data to store
+ *
+ * Plugin implementations should use this to issue #GSignondPlugin::store
+ * signal. This method should not be used otherwise.
+ */
void gsignond_plugin_store (GSignondPlugin *self,
- GSignondDictionary *token_data)
+ GSignondDictionary *identity_method_cache)
{
- g_signal_emit (self, signals[STORE], 0, token_data);
+ g_signal_emit (self, signals[STORE], 0, identity_method_cache);
}
+/**
+ * gsignond_plugin_error:
+ * @self: plugin instance
+ * @error: the error
+ *
+ * Plugin implementations should use this to issue #GSignondPlugin::error
+ * signal. This method should not be used otherwise.
+ */
void gsignond_plugin_error (GSignondPlugin *self, GError *error)
{
g_signal_emit (self, signals[ERROR], 0, error);
}
+/**
+ * gsignond_plugin_user_action_required:
+ * @self: plugin instance
+ * @ui_data: UI data
+ *
+ * Plugin implementations should use this to issue #GSignondPlugin::user-action-required
+ * signal. This method should not be used otherwise.
+ */
void gsignond_plugin_user_action_required (GSignondPlugin *self,
GSignondSignonuiData *ui_data)
{
g_signal_emit (self, signals[USER_ACTION_REQUIRED], 0, ui_data);
}
+/**
+ * gsignond_plugin_refreshed:
+ * @self: plugin instance
+ * @ui_data: UI data
+ *
+ * Plugin implementations should use this to issue #GSignondPlugin::refreshed
+ * signal. This method should not be used otherwise.
+ */
void gsignond_plugin_refreshed (GSignondPlugin *self,
GSignondSignonuiData *ui_data)
{
g_signal_emit (self, signals[REFRESHED], 0, ui_data);
}
+/**
+ * gsignond_plugin_status_changed:
+ * @self: plugin instance
+ * @state: the new state
+ * @message: the message
+ *
+ * Plugin implementations should use this to issue #GSignondPlugin::status-changed
+ * signal. This method should not be used otherwise.
+ */
void gsignond_plugin_status_changed (GSignondPlugin *self,
GSignondPluginState state, const gchar *message)
{
diff --git a/src/common/gsignond-security-context.c b/src/common/gsignond-security-context.c
index 7b1c3f0..4de8461 100644
--- a/src/common/gsignond-security-context.c
+++ b/src/common/gsignond-security-context.c
@@ -25,6 +25,45 @@
#include "gsignond/gsignond-security-context.h"
+
+/**
+ * SECTION:gsignond-security-context
+ * @title: GSignondSecurityContext
+ * @short_description: security context descriptor used in access control checks
+ * @include: gsignond/gsignond-security-context.h
+ *
+ * Security context is a string tuple of system context and application context.
+ *
+ * System context can be a binary path, SMACK-label, or MSSF token.
+ *
+ * Application context identifies a script or a webpage within an application,
+ * and it's used for providing access control to runtime environments (when making an access
+ * control decision requires not only a binary identifier, but also information
+ * about what the binary is doing).
+ *
+ * When an application is trying to access the gSSO service, the system context
+ * is determined by a specific #GSignondAccessControlManager instance using
+ * system services of a specific platform. Application context is set by the
+ * application itself. Then both contexts are used by #GSignondAccessControlManager
+ * to perform an access control check.
+ */
+
+/**
+ * GSignondSecurityContext:
+ * @sys_ctx: system context
+ * @app_ctx: application context
+ *
+ * Security context descriptor used for access control checks. System context
+ * and application context can contain a wildcard match "*" which has special
+ * meaning in gsignond_security_context_match() and
+ * gsignond_security_context_check().
+ */
+
+/**
+ * GSignondSecurityContextList:
+ *
+ * GList of #GSignondSecurityContext items.
+ */
static void
_security_context_free (gpointer ptr)
{
@@ -36,9 +75,9 @@ _security_context_free (gpointer ptr)
/**
* gsignond_security_context_new:
*
- * Allocates a new security context item.
+ * Allocates a new security context item. System and app context are empty strings.
*
- * Returns: (transfer full) allocated #GSignondSecurityContext.
+ * Returns: (transfer full): allocated #GSignondSecurityContext.
*/
GSignondSecurityContext *
gsignond_security_context_new ()
@@ -53,13 +92,13 @@ gsignond_security_context_new ()
}
/**
- * gsignond_security_context_new_from_vaues:
- * @system_context: system security context (such as SMACK/MSSF label/token).
- * @application_context: application security context (such as a script name).
+ * gsignond_security_context_new_from_values:
+ * @system_context: system security context
+ * @application_context: application security context
*
* Allocates and initializes a new security context item.
*
- * Returns: (transfer full) allocated #GSignondSecurityContext.
+ * Returns: (transfer full): allocated #GSignondSecurityContext.
*/
GSignondSecurityContext *
gsignond_security_context_new_from_values (const gchar *system_context,
@@ -83,9 +122,9 @@ gsignond_security_context_new_from_values (const gchar *system_context,
* gsignond_security_context_copy:
* @src_ctx: source security context to copy.
*
- * Copy a security context item.
+ * Copies a security context item.
*
- * Returns: (transfer full) a copy of the #GSignondSecurityContext item.
+ * Returns: (transfer full): a copy of the #GSignondSecurityContext item.
*/
GSignondSecurityContext *
gsignond_security_context_copy (const GSignondSecurityContext *src_ctx)
@@ -117,7 +156,7 @@ gsignond_security_context_free (GSignondSecurityContext *ctx)
* @ctx: #GSignondSecurityContext item.
* @system_context: system security context.
*
- * Sets the system context part (such as SMACK label or MSSF token) of the
+ * Sets the system context part of the
* #GSignondSecurityContext.
*/
void
@@ -135,10 +174,10 @@ gsignond_security_context_set_system_context (GSignondSecurityContext *ctx,
* gsignond_security_context_get_system_context:
* @ctx: #GSignondSecurityContext item.
*
- * Get the system context part (such as SMACK label or MSSF token) of the
+ * Get the system context partof the
* #GSignondSecurityContext.
*
- * Returns: (transfer none) system context.
+ * Returns: (transfer none): system context.
*/
const gchar *
gsignond_security_context_get_system_context (
@@ -154,7 +193,7 @@ gsignond_security_context_get_system_context (
* @ctx: #GSignondSecurityContext item.
* @application_context: application security context.
*
- * Sets the application context part (such as a script name or a web page) of
+ * Sets the application context part of
* the #GSignondSecurityContext.
*/
void
@@ -173,10 +212,10 @@ gsignond_security_context_set_application_context (
* gsignond_security_context_get_application_context:
* @ctx: #GSignondSecurityContext item.
*
- * Get the application context part (such as script name or a web page) of
+ * Get the application context part of
* the #GSignondSecurityContext.
*
- * Returns: (transfer none) application context.
+ * Returns: (transfer none): application context.
*/
const gchar *
gsignond_security_context_get_application_context (
@@ -188,12 +227,12 @@ gsignond_security_context_get_application_context (
}
/**
- * signon_security_conetxt_to_variant:
+ * gsignond_security_context_to_variant:
* @ctx: #GSignondSecurityContext item.
*
* Build a GVariant of type "(ss)" from a #GSignondSecurityContext item.
*
- * Returns: (transfer full) GVariant construct of a #GSignondSecurityContext.
+ * Returns: (transfer full): GVariant construct of a #GSignondSecurityContext.
*/
GVariant *
gsignond_security_context_to_variant (const GSignondSecurityContext *ctx)
@@ -215,7 +254,7 @@ gsignond_security_context_to_variant (const GSignondSecurityContext *ctx)
*
* Builds a #GSignondSecurityContext item from a GVariant of type "(ss)".
*
- * Returns: (transfer full) #GSignondSecurityContext item.
+ * Returns: (transfer full): #GSignondSecurityContext item.
*/
GSignondSecurityContext *
gsignond_security_context_from_variant (GVariant *variant)
@@ -238,7 +277,7 @@ gsignond_security_context_from_variant (GVariant *variant)
* @ctx1: first item to compare.
* @ctx2: second item to compare.
*
- * Compare two #GSignondSecurityContext items similar in a way to strcmp().
+ * Compare two #GSignondSecurityContext items in a similar way to strcmp().
*
* Returns: negative if ctx1 < ctx2, 0 if ctx1 == ctx2 and positive if ctx1 > ctx2.
*/
@@ -250,8 +289,10 @@ gsignond_security_context_compare (const GSignondSecurityContext *ctx1,
if (ctx1 == ctx2) return 0;
- g_return_val_if_fail (ctx1 != NULL, -1);
- g_return_val_if_fail (ctx2 != NULL, 1);
+ if (ctx1 == NULL)
+ return -1;
+ if (ctx2 == NULL)
+ return 1;
res = g_strcmp0(ctx1->sys_ctx, ctx2->sys_ctx);
if (res == 0)
@@ -267,7 +308,10 @@ gsignond_security_context_compare (const GSignondSecurityContext *ctx1,
*
* Compare two #GSignondSecurityContext items match.
*
- * Returns: TRUE if contexts are equal or either side has wildcard match, otherwise FALSE. Two NULL contexts match.
+ * Returns: TRUE if contexts are equal or if either side has a wildcard match for
+ * system context, or if system contexts are equal and either side has a wildcard
+ * match for the app context,
+ * otherwise FALSE. Two NULL contexts match.
*/
gboolean
gsignond_security_context_match (const GSignondSecurityContext *ctx1,
@@ -275,7 +319,8 @@ gsignond_security_context_match (const GSignondSecurityContext *ctx1,
{
if (ctx1 == ctx2) return TRUE;
- g_return_val_if_fail (ctx1 != NULL && ctx2 != NULL, FALSE);
+ if (ctx1 == NULL || ctx2 == NULL)
+ return FALSE;
if (g_strcmp0(ctx1->sys_ctx, "*") == 0 ||
g_strcmp0(ctx2->sys_ctx, "*") == 0) return TRUE;
@@ -294,15 +339,19 @@ gsignond_security_context_match (const GSignondSecurityContext *ctx1,
* @reference: reference security context item to check against.
* @test: security context item to be checked.
*
- * Check if item @test is covered by @reference.
+ * Check if @test is covered by @reference.
*
- * Returns: TRUE if contexts are equal or wildcards of the @reference arguments match, otherwise FALSE. If either or both contexts are NULL, FALSE is returned.
+ * Returns: TRUE if contexts are equal or the @reference has a wildcard
+ * system context, or if system contexts are equal and @reference has a wildcard
+ * application context, otherwise FALSE. If either or both contexts are NULL,
+ * FALSE is returned.
*/
gboolean
gsignond_security_context_check (const GSignondSecurityContext *reference,
const GSignondSecurityContext *test)
{
- g_return_val_if_fail (reference != NULL && test != NULL, FALSE);
+ if (reference == NULL || test == NULL)
+ return FALSE;
if (g_strcmp0(reference->sys_ctx, "*") == 0) return TRUE;
if (g_strcmp0(reference->sys_ctx, test->sys_ctx) == 0) {
@@ -320,7 +369,7 @@ gsignond_security_context_check (const GSignondSecurityContext *reference,
* Builds a GVariant of type "a(ss)" from a GList of #GSignondSecurityContext
* items.
*
- * Returns: (transfer full) GVariant construct of a #GSignondSecurityContextList.
+ * Returns: (transfer full): GVariant construct of a #GSignondSecurityContextList.
*/
GVariant *
gsignond_security_context_list_to_variant (
@@ -349,7 +398,7 @@ gsignond_security_context_list_to_variant (
* Builds a GList of #GSignondSecurityContext items from a GVariant of type
* "a(ss)".
*
- * Returns: (transfer full) #GSignondSecurityContextList item.
+ * Returns: (transfer full): #GSignondSecurityContextList item.
*/
GSignondSecurityContextList *
gsignond_security_context_list_from_variant (GVariant *variant)
@@ -376,7 +425,7 @@ gsignond_security_context_list_from_variant (GVariant *variant)
*
* Copies a GList of #GSignondSecurityContext items.
*
- * Returns: (transfer full) #GSignondSecurityContextList item.
+ * Returns: (transfer full): #GSignondSecurityContextList item.
*/
GSignondSecurityContextList *
gsignond_security_context_list_copy (
@@ -396,7 +445,7 @@ gsignond_security_context_list_copy (
/**
* gsignond_security_context_list_free:
- * @seclist: (transfer full) #GSignondSecurityContextList item.
+ * @seclist: (transfer full): #GSignondSecurityContextList item.
*
* Frees all items and the GList of #GSignondSecurityContext.
*/
diff --git a/src/common/gsignond-session-data.c b/src/common/gsignond-session-data.c
index b07f23c..a8583f3 100644
--- a/src/common/gsignond-session-data.c
+++ b/src/common/gsignond-session-data.c
@@ -25,12 +25,63 @@
#include <gsignond/gsignond-session-data.h>
+
+/**
+ * SECTION:gsignond-session-data
+ * @short_description: definitions for authentication session parameters
+ * @title: GSignondSessionData
+ * @include: gsignond/gsignond-session-data.h
+ *
+ * This file provides commonly used parameters for authentication sessions.
+ * For each of those a getter and setter is defined, on #GSignondSessionData
+ * container. The plugins may not use all of these parameters, and they commonly
+ * require additional, custom parameters which are set using #GSignondDictionary
+ * setters with explicit key string.
+ */
+
+
+/**
+ * GSignondSessionData:
+ *
+ * #GSignondSessionData is simply a typedef for #GSignondDictionary, which
+ * means the developers may also freely use methods associated with that structure,
+ * in particular for creating a #GSignondSessionData object with
+ * gsignond_dictionary_new().
+ */
+
+/**
+ * GSignondUiPolicy:
+ * @GSIGNOND_UI_POLICY_DEFAULT: use a default user interaction scenario
+ * @GSIGNOND_UI_POLICY_REQUEST_PASSWORD: force an authorization request from the user;
+ * any cached access tokens should be discarded by the plugin.
+ * @GSIGNOND_UI_POLICY_NO_USER_INTERACTION: force no interaction with the user
+ * @GSIGNOND_UI_POLICY_VALIDATION: interaction with the user is only allowed
+ * for validation captchas and similar security measures
+ *
+ * Policy setting to define how plugins should handle interaction with the user.
+ */
+
+/**
+ * gsignond_session_data_get_username:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for a username associated with the authentication session.
+ *
+ * Returns: (transfer none)
+ */
const gchar *
gsignond_session_data_get_username (GSignondSessionData *data)
{
return gsignond_dictionary_get_string (data, "UserName");
}
+/**
+ * gsignond_session_data_set_username:
+ * @data: a #GSignondDictionary structure
+ * @username: username to set
+ *
+ * A setter for a username associated with the authentication session.
+ */
void
gsignond_session_data_set_username (GSignondSessionData *data,
const gchar *username)
@@ -38,12 +89,27 @@ gsignond_session_data_set_username (GSignondSessionData *data,
gsignond_dictionary_set_string (data, "UserName", username);
}
+/**
+ * gsignond_session_data_get_secret:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for a secret (e.g. a password) associated with the authentication session.
+ *
+ * Returns: (transfer none)
+ */
const gchar *
gsignond_session_data_get_secret (GSignondSessionData *data)
{
return gsignond_dictionary_get_string (data, "Secret");
}
+/**
+ * gsignond_session_data_set_secret:
+ * @data: a #GSignondDictionary structure
+ * @secret: a secret to set
+ *
+ * A setter for a secret (e.g. a password) associated with the authentication session.
+ */
void
gsignond_session_data_set_secret (GSignondSessionData *data,
const gchar *secret)
@@ -51,12 +117,27 @@ gsignond_session_data_set_secret (GSignondSessionData *data,
gsignond_dictionary_set_string (data, "Secret", secret);
}
+/**
+ * gsignond_session_data_get_realm:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for a realm associated with the authentication session.
+ *
+ * Returns: (transfer none)
+ */
const gchar *
gsignond_session_data_get_realm (GSignondSessionData *data)
{
return gsignond_dictionary_get_string (data, "Realm");
}
+/**
+ * gsignond_session_data_set_realm:
+ * @data: a #GSignondDictionary structure
+ * @realm: a realm to set
+ *
+ * A setter for a realm associated with the authentication session.
+ */
void
gsignond_session_data_set_realm (GSignondSessionData *data,
const gchar *realm)
@@ -64,12 +145,31 @@ gsignond_session_data_set_realm (GSignondSessionData *data,
gsignond_dictionary_set_string (data, "Realm", realm);
}
+/**
+ * gsignond_session_data_get_caption:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for a caption associated with the authentication session.
+ * Caption tells the user which application/credentials/provider is requestion
+ * authentication.
+ *
+ * Returns: (transfer none)
+ */
const gchar *
gsignond_session_data_get_caption (GSignondSessionData *data)
{
return gsignond_dictionary_get_string (data, "Caption");
}
+/**
+ * gsignond_session_data_set_caption:
+ * @data: a #GSignondDictionary structure
+ * @caption: a caption to set
+ *
+ * A setter for a caption associated with the authentication session.
+ * Caption tells the user which application/credentials/provider is requestion
+ * authentication.
+ */
void
gsignond_session_data_set_caption (GSignondSessionData *data,
const gchar *caption)
@@ -77,6 +177,17 @@ gsignond_session_data_set_caption (GSignondSessionData *data,
gsignond_dictionary_set_string (data, "Caption", caption);
}
+/**
+ * gsignond_session_data_get_renew_token:
+ * @data: a #GSignondDictionary structure
+ * @renew_token: the value for the parameter is written here
+ *
+ * A getter for a renew token property associated with the authentication session.
+ * This property tells the plugin to discard any cached tokens and start
+ * the authentication process anew.
+ *
+ * Returns: whether the key-value pair exists in the @data dictionary or not.
+ */
gboolean
gsignond_session_data_get_renew_token (GSignondSessionData *data,
gboolean *renew_token)
@@ -84,6 +195,15 @@ gsignond_session_data_get_renew_token (GSignondSessionData *data,
return gsignond_dictionary_get_boolean (data, "RenewToken", renew_token);
}
+/**
+ * gsignond_session_data_set_renew_token:
+ * @data: a #GSignondDictionary structure
+ * @renew_token: whether to renew the token set
+ *
+ * A setter for a renew token property associated with the authentication session.
+ * This property tells the plugin to discard any cached tokens and start
+ * the authentication process anew.
+ */
void
gsignond_session_data_set_renew_token (GSignondSessionData *data,
gboolean renew_token)
@@ -91,26 +211,61 @@ gsignond_session_data_set_renew_token (GSignondSessionData *data,
gsignond_dictionary_set_boolean (data, "RenewToken", renew_token);
}
+/**
+ * gsignond_session_data_get_ui_policy:
+ * @data: a #GSignondDictionary structure
+ * @ui_policy: the value for the parameter is written here
+ *
+ * A getter for UI policy setting associated with the authentication session.
+ * The UI policy indicates how the authentication plugin should interact with the user.
+ *
+ * Returns: whether the key-value pair exists in the @data dictionary or not.
+ */
gboolean
gsignond_session_data_get_ui_policy (GSignondSessionData *data,
- guint32 *ui_policy)
+ GSignondUiPolicy *ui_policy)
{
return gsignond_dictionary_get_uint32 (data, "UiPolicy", ui_policy);
}
+/**
+ * gsignond_session_data_set_ui_policy:
+ * @data: a #GSignondDictionary structure
+ * @ui_policy: ui policy to set
+ *
+ * A getter for UI policy setting associated with the authentication session.
+ * The UI policy indicates how the authentication plugin should interact with the user.
+ */
void
gsignond_session_data_set_ui_policy (GSignondSessionData *data,
- guint32 ui_policy)
+ GSignondUiPolicy ui_policy)
{
gsignond_dictionary_set_uint32 (data, "UiPolicy", ui_policy);
}
+/**
+ * gsignond_session_data_get_network_proxy:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for a network proxy setting associated with the authentication session.
+ * If this property is not set, the default system proxy settings should be used.
+ *
+ * Returns: (transfer none)
+ */
const gchar *
gsignond_session_data_get_network_proxy (GSignondSessionData *data)
{
return gsignond_dictionary_get_string (data, "NetworkProxy");
}
+/**
+ * gsignond_session_data_set_network_proxy:
+ * @data: a #GSignondDictionary structure
+ * @network_proxy: network proxy to use
+ *
+ * A setter for a network proxy setting associated with the authentication session.
+ * If this property is not set, the default system proxy settings should be used.
+ */
void
gsignond_session_data_set_network_proxy (GSignondSessionData *data,
const gchar *network_proxy)
@@ -118,6 +273,16 @@ gsignond_session_data_set_network_proxy (GSignondSessionData *data,
gsignond_dictionary_set_string (data, "NetworkProxy", network_proxy);
}
+/**
+ * gsignond_session_data_get_network_timeout:
+ * @data: a #GSignondDictionary structure
+ * @network_timeout: the value for the parameter is written here
+ *
+ * A getter for a network timeout setting associated with the authentication session.
+ * This can be used to change the default timeout in case of unresponsive servers.
+ *
+ * Returns: whether the key-value pair exists in the @data dictionary or not.
+ */
gboolean
gsignond_session_data_get_network_timeout (GSignondSessionData *data,
guint32 *network_timeout)
@@ -126,6 +291,14 @@ gsignond_session_data_get_network_timeout (GSignondSessionData *data,
network_timeout);
}
+/**
+ * gsignond_session_data_set_network_timeout:
+ * @data: a #GSignondDictionary structure
+ * @network_timeout: network timeout to use
+ *
+ * A setter for a network timeout setting associated with the authentication session.
+ * This can be used to change the default timeout in case of unresponsive servers.
+ */
void
gsignond_session_data_set_network_timeout (GSignondSessionData *data,
guint32 network_timeout)
@@ -134,6 +307,17 @@ gsignond_session_data_set_network_timeout (GSignondSessionData *data,
network_timeout);
}
+/**
+ * gsignond_session_data_get_window_id:
+ * @data: a #GSignondDictionary structure
+ * @window_id: the value for the parameter is written here
+ *
+ * A getter for a window id setting associated with the authentication session.
+ * This can be used to embed the user interaction window produced by the authentication
+ * session into an application window.
+ *
+ * Returns: whether the key-value pair exists in the @data dictionary or not.
+ */
gboolean
gsignond_session_data_get_window_id (GSignondSessionData *data,
guint32 *window_id)
@@ -141,6 +325,15 @@ gsignond_session_data_get_window_id (GSignondSessionData *data,
return gsignond_dictionary_get_uint32 (data, "WindowId", window_id);
}
+/**
+ * gsignond_session_data_set_window_id:
+ * @data: a #GSignondDictionary structure
+ * @window_id: window id to use
+ *
+ * A setter for a window id setting associated with the authentication session.
+ * This can be used to embed the user interaction window produced by the authentication
+ * session into an application window.
+ */
void
gsignond_session_data_set_window_id (GSignondSessionData *data,
guint32 window_id)
diff --git a/src/common/gsignond-signonui-data.c b/src/common/gsignond-signonui-data.c
index c489b9b..af53312 100644
--- a/src/common/gsignond-signonui-data.c
+++ b/src/common/gsignond-signonui-data.c
@@ -25,6 +25,59 @@
#include <gsignond/gsignond-signonui-data.h>
+/**
+ * SECTION:gsignond-signonui-data
+ * @short_description: definitions for user interaction parameters
+ * @title: GSignondSignonuiData
+ * @include: gsignond/gsignond-signonui-data.h
+ *
+ * This file provides commonly used parameters for user interaction during
+ * authentication sessions.
+ * For each of those a getter and setter is defined, on #GSignondSessionData
+ * container.
+ *
+ * This container is used in two directions: by plugins to specify the parameters
+ * for user interaction that is then performed by SignonUI component, and by SignonUI
+ * to return the results of that interaction to the plugins. See #GSignondPlugin
+ * for the user interaction API from the plugins' perspective.
+ *
+ * The parameters that are set by the plugin and read by signon UI are captcha url,
+ * caption, confirm, final url, forgot password, forgot password url, message,
+ * open url, password, query password, query username, remember
+ * password, request id, test reply values, title, username.
+ *
+ * The parameters that are returned by signon UI to the plugin are captcha response,
+ * password, query error code, remember password, url response.
+ */
+
+/**
+ * GSignondSignonuiData:
+ *
+ * #GSignondSignonuiData is simply a typedef for #GSignondDictionary, which
+ * means the developers may also freely use methods associated with that structure,
+ * in particular for creating a #GSignondSignonuiData object with
+ * gsignond_dictionary_new().
+ */
+
+/**
+ * GSignondSignonuiError:
+ * @SIGNONUI_ERROR_NONE: No errors
+ * @SIGNONUI_ERROR_GENERAL: Generic error during interaction
+ * @SIGNONUI_ERROR_NO_SIGNONUI: Cannot send request to signon-ui
+ * @SIGNONUI_ERROR_BAD_PARAMETERS: Signon-Ui cannot create dialog based on the given UiSessionData
+ * @SIGNONUI_ERROR_CANCELED: User canceled action. Plugin should not retry automatically after this
+ * @SIGNONUI_ERROR_NOT_AVAILABLE: Requested ui is not available. For example browser cannot be started
+ * @SIGNONUI_ERROR_BAD_URL: Given url was not valid
+ * @SIGNONUI_ERROR_BAD_CAPTCHA: Given captcha image was not valid
+ * @SIGNONUI_ERROR_BAD_CAPTCHA_URL: Given url for capctha loading was not valid
+ * @SIGNONUI_ERROR_REFRESH_FAILED: Refresh failed
+ * @SIGNONUI_ERROR_FORBIDDEN: Showing ui forbidden by ui policy
+ * @SIGNONUI_ERROR_FORGOT_PASSWORD: User pressed forgot password
+ *
+ * This enum defines errors that may happen during user interaction.
+ */
+
+
#define SIGNONUI_KEY_CAPTCHA_RESPONSE "CaptchaResponse"
#define SIGNONUI_KEY_CAPTCHA_URL "CaptchaUrl"
#define SIGNONUI_KEY_CAPTION "Caption"
@@ -45,12 +98,27 @@
#define SIGNONUI_KEY_URL_RESPONSE "UrlResponse"
#define SIGNONUI_KEY_USERNAME "UserName"
+/**
+ * gsignond_signonui_data_get_captcha_response:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for the user's response to a captcha query.
+ *
+ * Returns: (transfer none): the string entered by the user in response to a captcha query.
+ */
const gchar*
gsignond_signonui_data_get_captcha_response (GSignondSignonuiData *data)
{
return gsignond_dictionary_get_string (data, SIGNONUI_KEY_CAPTCHA_RESPONSE);
}
+/**
+ * gsignond_signonui_data_set_captcha_response:
+ * @data: a #GSignondDictionary structure
+ * @response: the string entered by the user in response to a captcha query.
+ *
+ * A setter for the user's response to a captcha query.
+ */
void
gsignond_signonui_data_set_captcha_response (GSignondSignonuiData *data,
const gchar *response)
@@ -58,12 +126,27 @@ gsignond_signonui_data_set_captcha_response (GSignondSignonuiData *data,
gsignond_dictionary_set_string (data, SIGNONUI_KEY_CAPTCHA_RESPONSE, response);
}
+/**
+ * gsignond_signonui_data_get_captcha_url:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for the captcha URL.
+ *
+ * Returns: (transfer none): the URL to the captcha image to be verified by user.
+ */
const gchar*
gsignond_signonui_data_get_captcha_url (GSignondSignonuiData *data)
{
return gsignond_dictionary_get_string (data, SIGNONUI_KEY_CAPTCHA_URL);
}
+/**
+ * gsignond_signonui_data_set_captcha_url:
+ * @data: a #GSignondDictionary structure
+ * @url: the URL to the captcha image to be verified by user
+ *
+ * A setter for the captcha URL.
+ */
void
gsignond_signonui_data_set_captcha_url (GSignondSignonuiData *data,
const gchar *url)
@@ -71,12 +154,30 @@ gsignond_signonui_data_set_captcha_url (GSignondSignonuiData *data,
gsignond_dictionary_set_string (data, SIGNONUI_KEY_CAPTCHA_URL, url);
}
+/**
+ * gsignond_signonui_data_get_caption:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for the caption string. Caption tells the user which
+ * application/credentials/provider is requestion authentication.
+ *
+ * Returns: (transfer none)
+ */
const gchar*
gsignond_signonui_data_get_caption (GSignondSignonuiData *data)
{
return gsignond_dictionary_get_string (data, SIGNONUI_KEY_CAPTION);
}
+/**
+ * gsignond_signonui_data_set_caption:
+ * @data: a #GSignondDictionary structure
+ * @caption: the caption string
+ *
+ * A setter for the caption string. Caption tells the user which
+ * application/credentials/provider is requestion authentication.
+ *
+ */
void
gsignond_signonui_data_set_caption (GSignondSignonuiData *data,
const gchar *caption)
@@ -84,6 +185,17 @@ gsignond_signonui_data_set_caption (GSignondSignonuiData *data,
gsignond_dictionary_set_string (data, SIGNONUI_KEY_CAPTION, caption);
}
+/**
+ * gsignond_signonui_data_get_confirm:
+ * @data: a #GSignondDictionary structure
+ * @confirm: the value for the property is written here
+ *
+ * A getter for the confirm mode. In confirm mode the user is asked to enter
+ * an old password (which is compared to the supplied password), and a new password twice
+ * (which is returned).
+ *
+ * Returns: whether this property exists in the @data dictionary or not.
+ */
gboolean
gsignond_signonui_data_get_confirm (GSignondSignonuiData *data,
gboolean *confirm)
@@ -91,6 +203,16 @@ gsignond_signonui_data_get_confirm (GSignondSignonuiData *data,
return gsignond_dictionary_get_boolean (data, SIGNONUI_KEY_CONFIRM, confirm);
}
+/**
+ * gsignond_signonui_data_set_confirm:
+ * @data: a #GSignondDictionary structure
+ * @confirm: the value for the property
+ *
+ * A setter for the confirm mode. In confirm mode the user is asked to enter
+ * an old password (which is compared to the supplied password), and a new password twice
+ * (which is returned).
+ *
+ */
void
gsignond_signonui_data_set_confirm (GSignondSignonuiData *data,
gboolean confirm)
@@ -98,12 +220,34 @@ gsignond_signonui_data_set_confirm (GSignondSignonuiData *data,
gsignond_dictionary_set_boolean (data, SIGNONUI_KEY_CONFIRM, confirm);
}
+/**
+ * gsignond_signonui_data_get_final_url:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for the final URL. When the signon UI detects that the user is at
+ * the final URL (possibly with additional query or fragment parameters), it
+ * will close the window and return the full URL via url response property.
+ * This is used by redirection-based authentication, such as OAuth.
+ *
+ * Returns: (transfer none)
+ */
const gchar*
gsignond_signonui_data_get_final_url (GSignondSignonuiData *data)
{
return gsignond_dictionary_get_string (data, SIGNONUI_KEY_FINAL_URL);
}
+/**
+ * gsignond_signonui_data_set_final_url:
+ * @data: a #GSignondDictionary structure
+ * @url: the final url
+ *
+ * A setter for the final URL. When the signon UI detects that the user is at
+ * the final URL (possibly with additional query or fragment parameters), it
+ * will close the window and return the full URL via url response property.
+ * This is used by redirection-based authentication, such as OAuth.
+ *
+ */
void
gsignond_signonui_data_set_final_url (GSignondSignonuiData *data,
const gchar *url)
@@ -111,28 +255,64 @@ gsignond_signonui_data_set_final_url (GSignondSignonuiData *data,
gsignond_dictionary_set_string (data, SIGNONUI_KEY_FINAL_URL, url);
}
-gboolean
-gsignond_signonui_data_get_forgot_password (GSignondSignonuiData *data,
- gboolean *forgot_password)
+/**
+ * gsignond_signonui_data_get_forgot_password:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for the forgot password string which is shown to the user as a link to
+ * reset the password or remind him of the password.
+ *
+ * Returns: (transfer none)
+ */
+const gchar*
+gsignond_signonui_data_get_forgot_password (GSignondSignonuiData *data)
{
- return gsignond_dictionary_get_boolean (data,
- SIGNONUI_KEY_FORGOT_PASSWORD,
- forgot_password);
+ return gsignond_dictionary_get_string (data,
+ SIGNONUI_KEY_FORGOT_PASSWORD);
}
+/**
+ * gsignond_signonui_data_set_forgot_password:
+ * @data: a #GSignondDictionary structure
+ * @forgot: the forgot password string
+ *
+ * A setter for the forgot password string, which is shown to the user as a link to
+ * reset the password or remind him of the password.
+ *
+ * Returns: (transfer none):
+ */
void
gsignond_signonui_data_set_forgot_password (GSignondSignonuiData *data,
- gboolean forgot)
+ const gchar* forgot)
{
- gsignond_dictionary_set_boolean (data, SIGNONUI_KEY_FORGOT_PASSWORD, forgot);
+ gsignond_dictionary_set_string (data, SIGNONUI_KEY_FORGOT_PASSWORD, forgot);
}
+/**
+ * gsignond_signonui_data_get_forgot_password_url:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for the forgot password URL, where the user can reset or request a
+ * reminder of the password.
+ *
+ * Returns: (transfer none)
+ */
const gchar*
gsignond_signonui_data_get_forgot_password_url (GSignondSignonuiData *data)
{
return gsignond_dictionary_get_string (data, SIGNONUI_KEY_FORGOT_PASSWORD_URL);
}
+/**
+ * gsignond_signonui_data_set_forgot_password_url:
+ * @data: a #GSignondDictionary structure
+ * @url: the forgot password URL
+ *
+ * A setter for the forgot password URL, where the user can reset or request a
+ * reminder of the password.
+ *
+ * Returns: (transfer none)
+ */
void
gsignond_signonui_data_set_forgot_password_url (GSignondSignonuiData *data,
const gchar *url)
@@ -140,12 +320,28 @@ gsignond_signonui_data_set_forgot_password_url (GSignondSignonuiData *data,
gsignond_dictionary_set_string (data, SIGNONUI_KEY_FORGOT_PASSWORD_URL, url);
}
+/**
+ * gsignond_signonui_data_get_message:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for the message which is show to the user in the signon UI dialog.
+ *
+ * Returns: (transfer none)
+ */
const gchar*
gsignond_signonui_data_get_message (GSignondSignonuiData *data)
{
return gsignond_dictionary_get_string (data, SIGNONUI_KEY_MESSAGE);
}
+/**
+ * gsignond_signonui_data_set_message:
+ * @data: a #GSignondDictionary structure
+ * @message: the message
+ *
+ * A setter for the message which is show to the user in the signon UI dialog.
+ *
+ */
void
gsignond_signonui_data_set_message (GSignondSignonuiData *data,
const gchar *message)
@@ -153,12 +349,28 @@ gsignond_signonui_data_set_message (GSignondSignonuiData *data,
gsignond_dictionary_set_string (data, SIGNONUI_KEY_MESSAGE, message);
}
+/**
+ * gsignond_signonui_data_get_open_url:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for the URL that should be opened by signon UI.
+ *
+ * Returns: (transfer none)
+ */
const gchar*
gsignond_signonui_data_get_open_url (GSignondSignonuiData *data)
{
return gsignond_dictionary_get_string (data, SIGNONUI_KEY_OPEN_URL);
}
+/**
+ * gsignond_signonui_data_set_open_url:
+ * @data: a #GSignondDictionary structure
+ * @url: the url to open
+ *
+ * A setter for the URL that should be opened by signon UI.
+ *
+ */
void
gsignond_signonui_data_set_open_url (GSignondSignonuiData *data,
const gchar *url)
@@ -166,12 +378,28 @@ gsignond_signonui_data_set_open_url (GSignondSignonuiData *data,
gsignond_dictionary_set_string (data, SIGNONUI_KEY_OPEN_URL, url);
}
+/**
+ * gsignond_signonui_data_get_password:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for the password string.
+ *
+ * Returns: (transfer none)
+ */
const gchar*
gsignond_signonui_data_get_password (GSignondSignonuiData *data)
{
return gsignond_dictionary_get_string (data, SIGNONUI_KEY_PASSWORD);
}
+/**
+ * gsignond_signonui_data_set_password:
+ * @data: a #GSignondDictionary structure
+ * @password: the password string
+ *
+ * A setter for the password string.
+ *
+ */
void
gsignond_signonui_data_set_password (GSignondSignonuiData *data,
const gchar *password)
@@ -179,6 +407,16 @@ gsignond_signonui_data_set_password (GSignondSignonuiData *data,
gsignond_dictionary_set_string (data, SIGNONUI_KEY_PASSWORD, password);
}
+/**
+ * gsignond_signonui_data_get_query_error:
+ * @data: a #GSignondDictionary structure
+ * @error: the error is written here
+ *
+ * A getter for the UI interaction error. Signon UI sets this to @SIGNONUI_ERROR_NONE if
+ * there were no errors.
+ *
+ * Returns: whether this property exists in the @data dictionary or not.
+ */
gboolean
gsignond_signonui_data_get_query_error (GSignondSignonuiData *data,
GSignondSignonuiError *error)
@@ -188,6 +426,15 @@ gsignond_signonui_data_get_query_error (GSignondSignonuiData *data,
error);
}
+/**
+ * gsignond_signonui_data_set_query_error:
+ * @data: a #GSignondDictionary structure
+ * @error: the error
+ *
+ * A setter for the UI interaction error. Signon UI sets this to @SIGNONUI_ERROR_NONE if
+ * there were no errors.
+ *
+ */
void
gsignond_signonui_data_set_query_error (GSignondSignonuiData *data,
GSignondSignonuiError error)
@@ -195,6 +442,16 @@ gsignond_signonui_data_set_query_error (GSignondSignonuiData *data,
gsignond_dictionary_set_uint32 (data, SIGNONUI_KEY_QUERY_ERROR_CODE, error);
}
+/**
+ * gsignond_signonui_data_get_query_password:
+ * @data: a #GSignondDictionary structure
+ * @query_password: the property is written here
+ *
+ * A getter for the query password property. It indicates whether the signon UI
+ * should ask the user for a password (and return it in the password property).
+ *
+ * Returns: whether this property exists in the @data dictionary or not.
+ */
gboolean
gsignond_signonui_data_get_query_password (GSignondSignonuiData *data,
gboolean *query_password)
@@ -204,6 +461,15 @@ gsignond_signonui_data_get_query_password (GSignondSignonuiData *data,
query_password);
}
+/**
+ * gsignond_signonui_data_set_query_password:
+ * @data: a #GSignondDictionary structure
+ * @query: the property value
+ *
+ * A setter for the query password property. It indicates whether the signon UI
+ * should ask the user for a password (and return it in the password property).
+ *
+ */
void
gsignond_signonui_data_set_query_password (GSignondSignonuiData *data,
gboolean query)
@@ -211,6 +477,16 @@ gsignond_signonui_data_set_query_password (GSignondSignonuiData *data,
gsignond_dictionary_set_boolean (data, SIGNONUI_KEY_QUERY_PASSWORD, query);
}
+/**
+ * gsignond_signonui_data_get_query_username:
+ * @data: a #GSignondDictionary structure
+ * @query_username: the property is written here
+ *
+ * A getter for the query username property. It indicates whether the signon UI
+ * should ask the user for a username (and return it in the username property).
+ *
+ * Returns: whether this property exists in the @data dictionary or not.
+ */
gboolean
gsignond_signonui_data_get_query_username (GSignondSignonuiData *data,
gboolean *query_username)
@@ -220,6 +496,15 @@ gsignond_signonui_data_get_query_username (GSignondSignonuiData *data,
query_username);
}
+/**
+ * gsignond_signonui_data_set_query_username:
+ * @data: a #GSignondDictionary structure
+ * @query: the property value
+ *
+ * A setter for the query username property. It indicates whether the signon UI
+ * should ask the user for a username (and return it in the username property).
+ *
+ */
void
gsignond_signonui_data_set_query_username (GSignondSignonuiData *data,
gboolean query)
@@ -227,6 +512,15 @@ gsignond_signonui_data_set_query_username (GSignondSignonuiData *data,
gsignond_dictionary_set_boolean (data, SIGNONUI_KEY_QUERY_USERNAME, query);
}
+/**
+ * gsignond_signonui_data_get_remember_password:
+ * @data: a #GSignondDictionary structure
+ * @remember_password: the property is written here
+ *
+ * A getter for whether the password should be remembered.
+ *
+ * Returns: whether this property exists in the @data dictionary or not.
+ */
gboolean
gsignond_signonui_data_get_remember_password (GSignondSignonuiData *data,
gboolean *remember_password)
@@ -236,6 +530,14 @@ gsignond_signonui_data_get_remember_password (GSignondSignonuiData *data,
remember_password);
}
+/**
+ * gsignond_signonui_data_set_remember_password:
+ * @data: a #GSignondDictionary structure
+ * @remember: the property value
+ *
+ * A setter for whether the password should be remembered.
+ *
+ */
void
gsignond_signonui_data_set_remember_password (GSignondSignonuiData *data,
gboolean remember)
@@ -243,12 +545,30 @@ gsignond_signonui_data_set_remember_password (GSignondSignonuiData *data,
gsignond_dictionary_set_boolean (data, SIGNONUI_KEY_REMEMBER_PASSWORD, remember);
}
+/**
+ * gsignond_signonui_data_get_request_id:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for the dialog request id. The id identifies the dialog so that it
+ * can be refreshed or updated.
+ *
+ * Returns: (transfer none)
+ */
const gchar*
gsignond_signonui_data_get_request_id (GSignondSignonuiData *data)
{
return gsignond_dictionary_get_string (data, SIGNONUI_KEY_REQUEST_ID);
}
+/**
+ * gsignond_signonui_data_set_request_id:
+ * @data: a #GSignondDictionary structure
+ * @id: request id
+ *
+ * A setter for the dialog request id. The id identifies the dialog so that it
+ * can be refreshed or updated.
+ *
+ */
void
gsignond_signonui_data_set_request_id (GSignondSignonuiData *data,
const gchar *id)
@@ -256,12 +576,30 @@ gsignond_signonui_data_set_request_id (GSignondSignonuiData *data,
gsignond_dictionary_set_string (data, SIGNONUI_KEY_REQUEST_ID, id);
}
+/**
+ * gsignond_signonui_data_get_test_reply:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for the test reply values. It's used only by the signon ui
+ * implementations to test themselves.
+ *
+ * Returns: (transfer none)
+ */
const gchar*
gsignond_signonui_data_get_test_reply (GSignondSignonuiData *data)
{
return gsignond_dictionary_get_string (data, SIGNONUI_KEY_TEST_REPLY_VALUES);
}
+/**
+ * gsignond_signonui_data_set_test_reply:
+ * @data: a #GSignondDictionary structure
+ * @reply: test reply values
+ *
+ * A setter for the test reply values. It's used only by the signon ui
+ * implementations to test themselves.
+ *
+ */
void
gsignond_signonui_data_set_test_reply (GSignondSignonuiData *data,
const gchar *reply)
@@ -269,12 +607,28 @@ gsignond_signonui_data_set_test_reply (GSignondSignonuiData *data,
gsignond_dictionary_set_string (data, SIGNONUI_KEY_TEST_REPLY_VALUES, reply);
}
+/**
+ * gsignond_signonui_data_get_title:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for the UI dialog title.
+ *
+ * Returns: (transfer none)
+ */
const gchar*
gsignond_signonui_data_get_title (GSignondSignonuiData *data)
{
return gsignond_dictionary_get_string (data, SIGNONUI_KEY_TITLE);
}
+/**
+ * gsignond_signonui_data_set_title:
+ * @data: a #GSignondDictionary structure
+ * @title: the title
+ *
+ * A setter for the UI dialog title.
+ *
+ */
void
gsignond_signonui_data_set_title (GSignondSignonuiData *data,
const gchar* title)
@@ -282,12 +636,34 @@ gsignond_signonui_data_set_title (GSignondSignonuiData *data,
gsignond_dictionary_set_string (data, SIGNONUI_KEY_TITLE, title);
}
+/**
+ * gsignond_signonui_data_get_url_response:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for the response URL. If the final URL was set in the request to the signon UI, and the signon UI
+ * detects that it has been reached, then the full final URL is returned using
+ * this property. This is used by redirection-based authentication such as OAauth.
+ *
+ * Returns: (transfer none)
+ */
const gchar*
gsignond_signonui_data_get_url_response (GSignondSignonuiData *data)
{
return gsignond_dictionary_get_string (data, SIGNONUI_KEY_URL_RESPONSE);
}
+/**
+ * gsignond_signonui_data_set_url_response:
+ * @data: a #GSignondDictionary structure
+ * @response: the response URL
+ *
+ * A getter for the response URL. If the final URL was set in the request to the
+ * signon UI, and the signon UI
+ * detects that it has been reached, then the full final URL is returned using
+ * this property. This is used by redirection-based authentication such as OAauth.
+ *
+ * Returns: (transfer none)
+ */
void
gsignond_signonui_data_set_url_response (GSignondSignonuiData *data,
const gchar *response)
@@ -295,12 +671,28 @@ gsignond_signonui_data_set_url_response (GSignondSignonuiData *data,
gsignond_dictionary_set_string (data, SIGNONUI_KEY_URL_RESPONSE, response);
}
+/**
+ * gsignond_signonui_data_get_username:
+ * @data: a #GSignondDictionary structure
+ *
+ * A getter for the username string.
+ *
+ * Returns: (transfer none)
+ */
const gchar*
gsignond_signonui_data_get_username (GSignondSignonuiData *data)
{
return gsignond_dictionary_get_string (data, SIGNONUI_KEY_USERNAME);
}
+/**
+ * gsignond_signonui_data_set_username:
+ * @data: a #GSignondDictionary structure
+ * @username: the username string
+ *
+ * A setter for the username string.
+ *
+ */
void
gsignond_signonui_data_set_username (GSignondSignonuiData *data,
const gchar *username)
diff --git a/src/common/gsignond-storage-manager.c b/src/common/gsignond-storage-manager.c
index 64e7d72..7df6c27 100644
--- a/src/common/gsignond-storage-manager.c
+++ b/src/common/gsignond-storage-manager.c
@@ -23,6 +23,7 @@
* 02110-1301 USA
*/
+#include <unistd.h>
#include <sys/stat.h>
#include <glib/gstdio.h>
@@ -31,6 +32,25 @@
#include "gsignond/gsignond-storage-manager.h"
#include "gsignond/gsignond-utils.h"
+/**
+ * SECTION:gsignond-storage-manager
+ * @short_description: manages encrypted disk storage for storing the secret database
+ * @include: gsignond/gsignond-plugin-interface.h
+ *
+ * #GSignondStorageManager manages encrypted disk storage for storing the
+ * databases. The default implementation maintains a simple per-user
+ * directory accessible only to root and gsignond group, but gSSO can be
+ * configured to use a custom extension that provides a subclassed
+ * implementation of #GSignondStorageManager
+ * (see #GSignondExtension for instructions and pointers to examples).
+ */
+/**
+ * GSignondStorageManager:
+ *
+ * Opaque #GSignondStorageManager data structure.
+ */
+
+
#define GSIGNOND_STORAGE_MANAGER_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
GSIGNOND_TYPE_STORAGE_MANAGER, \
@@ -57,17 +77,19 @@ _set_config (GSignondStorageManager *self, GSignondConfig *config)
g_assert (self->config == NULL);
self->config = config;
- const gchar *secure_dir = gsignond_config_get_string (
- self->config,
- GSIGNOND_CONFIG_GENERAL_SECURE_DIR);
- if (secure_dir)
- self->location = g_build_filename (secure_dir,
- "gsignond.secret",
+ gchar *user_dir = g_strdup_printf ("gsignond.%s", g_get_user_name ());
+ const gchar *storage_path = gsignond_config_get_string (
+ self->config,
+ GSIGNOND_CONFIG_GENERAL_STORAGE_PATH);
+ if (storage_path)
+ self->location = g_build_filename (storage_path,
+ user_dir,
NULL);
else
- self->location = g_build_filename (g_get_user_data_dir (),
- "gsignond.secret",
+ self->location = g_build_filename ("/var/db",
+ user_dir,
NULL);
+ g_free (user_dir);
DBG ("secure dir %s", self->location);
}
@@ -142,10 +164,28 @@ _initialize_storage (GSignondStorageManager *self)
g_return_val_if_fail (self != NULL, FALSE);
g_return_val_if_fail (self->location, FALSE);
- if (g_mkdir_with_parents (self->location, S_IRWXU))
- return FALSE;
+ if (g_access (self->location, R_OK) == 0)
+ return TRUE;
- return TRUE;
+ gboolean res = FALSE;
+
+ uid_t uid = getuid ();
+ if (seteuid (0))
+ WARN ("seteuid() failed");
+
+ if (g_mkdir_with_parents (self->location, S_IRWXU | S_IRWXG))
+ goto init_exit;
+ if (chown (self->location, 0, getegid ()))
+ WARN ("chown() failed");
+ if (chmod (self->location, S_IRWXU | S_IRWXG))
+ WARN ("chmod() failed");
+ res = TRUE;
+
+init_exit:
+ if (seteuid (uid))
+ WARN ("seteuid failed");
+
+ return res;
}
static gboolean
@@ -191,6 +231,18 @@ _filesystem_is_mounted (GSignondStorageManager *self)
return _storage_is_initialized (self);
}
+/**
+ * GSignondStorageManagerClass:
+ * @parent_class: parent class.
+ * @initialize_storage: an implementation of gsignond_storage_manager_initialize_storage()
+ * @delete_storage: an implementation of gsignond_storage_manager_delete_storage()
+ * @storage_is_initialized: an implementation of gsignond_storage_manager_storage_is_initialized()
+ * @mount_filesystem: an implementation of gsignond_storage_manager_mount_filesystem()
+ * @unmount_filesystem: an implementation of gsignond_storage_manager_unmount_filesystem()
+ * @filesystem_is_mounted: an implementation of gsignond_storage_manager_filesystem_is_mounted()
+ *
+ * #GSignondStorageManagerClass class containing pointers to class methods.
+ */
static void
gsignond_storage_manager_class_init (GSignondStorageManagerClass *klass)
{
@@ -232,8 +284,8 @@ gsignond_storage_manager_init (GSignondStorageManager *self)
* gsignond_storage_manager_initialize_storage:
* @self: object instance.
*
- * Initialize encryption storage. Initiali key should be set using
- * #gsignond_storage_manager_set_encryption_key before calling this.
+ * Initialize encryption storage. This means making sure that the
+ * necessary directories exist and are accessible.
*
* Returns: success?
*/
@@ -248,7 +300,8 @@ gsignond_storage_manager_initialize_storage (GSignondStorageManager *self)
* gsignond_storage_manager_delete_storage:
* @self: object instance.
*
- * Destroys all the encryption keys and wipes the storage.
+ * Destroys all the encryption keys and wipes the storage. gsignond_wipe_directory()
+ * is typically used for the latter.
*
* Returns: success?
*/
@@ -263,7 +316,7 @@ gsignond_storage_manager_delete_storage (GSignondStorageManager *self)
* gsignond_storage_manager_storage_is_initialized:
* @self: object instance.
*
- * Checks if the storage exists, and if possible if it has been initialized.
+ * Checks if the storage has been initialized.
*
* Returns: storage has been initialized?
*/
@@ -278,10 +331,14 @@ gsignond_storage_manager_storage_is_initialized (GSignondStorageManager *self)
* gsignond_storage_manager_mount_filesystem:
* @self: object instance.
*
- * Mounts an encrypted storage and returns filesystem path of the storage
- * mount point.
+ * Mounts an encrypted storage and returns the filesystem path of the storage
+ * mount point. This path will be used to access the secret database via
+ * #GSignondSecretStorage.
+ *
+ * The default implemenation does nothing, and immediately returns the path for the
+ * secret database.
*
- * Returns: (transfer none) path of the storage mount point.
+ * Returns: (transfer none): path of the storage mount point.
*/
const gchar *
gsignond_storage_manager_mount_filesystem (GSignondStorageManager *self)
@@ -294,7 +351,7 @@ gsignond_storage_manager_mount_filesystem (GSignondStorageManager *self)
* gsignond_storage_manager_unmount_filesystem:
* @self: object instance.
*
- * Unmounts a previously mounted storage filesystem.
+ * Unmounts a previously mounted encrypted storage filesystem.
*
* Returns: success?
*/
@@ -309,7 +366,7 @@ gsignond_storage_manager_unmount_filesystem (GSignondStorageManager *self)
* gsignond_storage_manager_filesystem_is_mounted:
* @self: object instance.
*
- * Checks if the filesystem is currently mounted.
+ * Checks if the encrypted storage filesystem is currently mounted.
*
* Returns: filesystem is currently mounted?
*/
diff --git a/src/common/gsignond-utils.c b/src/common/gsignond-utils.c
index 98d4065..df84032 100644
--- a/src/common/gsignond-utils.c
+++ b/src/common/gsignond-utils.c
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <string.h>
+#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
@@ -32,10 +33,36 @@
#include "gsignond/gsignond-utils.h"
#include "gsignond/gsignond-log.h"
+/**
+ * SECTION:gsignond-utils
+ * @title: Utility functions
+ * @short_description: miscellaneous utility functions
+ * @include: gsignond/gsignond-utils.h
+ *
+ * Miscellaneous utility functions are described below.
+ */
-static size_t pagesize = 0;
+typedef struct __nonce_ctx_t
+{
+ gboolean initialized;
+ guint32 serial;
+ guchar key[32];
+ guchar entropy[16];
+} _nonce_ctx_t;
+static size_t pagesize = 0;
+static _nonce_ctx_t _nonce_ctx = { 0, };
+G_LOCK_DEFINE_STATIC (_nonce_lock);
+/**
+ * gsignond_wipe_file:
+ * @filename: filename to wipe
+ *
+ * This function securely wipes the contents of the file, by overwriting it with
+ * 0's, then 1's, then random data. The file is then removed.
+ *
+ * Returns: TRUE if wiping and removal was successful.
+ */
gboolean
gsignond_wipe_file (const gchar *filename)
{
@@ -123,7 +150,16 @@ _rng_exit:
return retval;
}
-
+/**
+ * gsignond_wipe_directory:
+ * @dirname: directory to wipe
+ *
+ * This function securely wipes the contents of the directory by calling
+ * gsignond_wipe_file() on each file. It also removes links and empty directories but
+ * does not recursively wipe them.
+ *
+ * Returns: TRUE if wiping and removal was successful.
+ */
gboolean
gsignond_wipe_directory (const gchar *dirname)
{
@@ -161,3 +197,70 @@ _dir_exit:
return retval;
}
+static gboolean
+_init_nonce_gen ()
+{
+ if (G_LIKELY(_nonce_ctx.initialized))
+ return TRUE;
+
+ int fd;
+
+ fd = open ("/dev/urandom", O_RDONLY);
+ if (fd < 0)
+ goto init_exit;
+ if (read (fd, _nonce_ctx.key, sizeof (_nonce_ctx.key)) !=
+ sizeof (_nonce_ctx.key))
+ goto init_close;
+ if (read (fd, _nonce_ctx.entropy, sizeof(_nonce_ctx.entropy)) !=
+ sizeof (_nonce_ctx.entropy))
+ goto init_close;
+
+ _nonce_ctx.serial = 0;
+
+ _nonce_ctx.initialized = TRUE;
+
+init_close:
+ close (fd);
+
+init_exit:
+ return _nonce_ctx.initialized;
+}
+
+/**
+ * gsignond_generate_nonce:
+ *
+ * This function generates a random secure nonce using SHA1 HMAC.
+ *
+ * Returns: (transfer full): the nonce in lowercase hexadecimal format, 40 bytes long.
+ */
+gchar *
+gsignond_generate_nonce ()
+{
+ GHmac *hmac;
+ gchar *nonce = NULL;
+ struct timespec ts;
+
+ G_LOCK (_nonce_lock);
+
+ if (G_UNLIKELY (!_init_nonce_gen()))
+ goto nonce_exit;
+
+ hmac = g_hmac_new (G_CHECKSUM_SHA1,
+ _nonce_ctx.key, sizeof (_nonce_ctx.key));
+ g_hmac_update (hmac, _nonce_ctx.entropy, sizeof (_nonce_ctx.entropy));
+ _nonce_ctx.serial++;
+ g_hmac_update (hmac,
+ (const guchar *) &_nonce_ctx.serial,
+ sizeof (_nonce_ctx.serial));
+ if (clock_gettime (CLOCK_MONOTONIC, &ts) == 0)
+ g_hmac_update (hmac, (const guchar *) &ts, sizeof (ts));
+ memset (&ts, 0x00, sizeof(ts));
+ nonce = g_strdup (g_hmac_get_string (hmac));
+ g_hmac_unref (hmac);
+
+nonce_exit:
+ G_UNLOCK (_nonce_lock);
+
+ return nonce;
+}
+