DBus server: implement keyring support in dbus server (MB#3602)
Use gnome-keyring to store and retrieve passwords in dbus server by default when dbus server is compiled with gnome-keyring library. For storing passwords, if failed in gnome-keyring, an error will be thrown, which aborts flushing properties. For retrieving passwords, firstly find them in the gnome-keyring. If it is not found, dbus server then send InfoRequest signal to dbus clients to ask for passwords. See MB#6376.
This commit is contained in:
parent
f73c895b65
commit
1dd1323f39
2 changed files with 100 additions and 2 deletions
|
@ -146,9 +146,9 @@ syncevo_dbus_server_SOURCES = \
|
|||
nodist_syncevo_dbus_server_SOURCES = \
|
||||
../test/test.cpp
|
||||
|
||||
syncevo_dbus_server_LDADD = gdbus/libgdbus.la $(CORE_LDADD)
|
||||
syncevo_dbus_server_LDADD = gdbus/libgdbus.la $(CORE_LDADD) $(KEYRING_LIBS)
|
||||
syncevo_dbus_server_CPPFLAGS = -DHAVE_CONFIG_H -I$(srcdir)/gdbus $(AM_CPPFLAGS)
|
||||
syncevo_dbus_server_CXXFLAGS = $(SYNCEVOLUTION_CXXFLAGS) $(CORE_CXXFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) $(LIBSOUP_CFLAGS)
|
||||
syncevo_dbus_server_CXXFLAGS = $(SYNCEVOLUTION_CXXFLAGS) $(CORE_CXXFLAGS) $(GLIB_CFLAGS) $(DBUS_CFLAGS) $(LIBSOUP_CFLAGS) $(KEYRING_CFLAGS)
|
||||
syncevo_dbus_server_LDFLAGS = $(CORE_LD_FLAGS) $(LIBSOUP_LIBS)
|
||||
syncevo_dbus_server_DEPENDENCIES = gdbus/libgdbus.la $(EXTRA_LTLIBRARIES) $(CORE_DEP) $(SYNTHESIS_DEP)
|
||||
endif
|
||||
|
|
|
@ -51,6 +51,11 @@
|
|||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include <glib-object.h>
|
||||
#ifdef USE_GNOME_KEYRING
|
||||
extern "C" {
|
||||
#include <gnome-keyring.h>
|
||||
}
|
||||
#endif
|
||||
|
||||
class DBusMessage;
|
||||
static DBusMessage *SyncEvoHandleException(DBusMessage *msg);
|
||||
|
@ -603,6 +608,17 @@ protected:
|
|||
virtual bool checkForSuspend();
|
||||
virtual bool checkForAbort();
|
||||
virtual int sleep(int intervals);
|
||||
|
||||
/**
|
||||
* Implement askPassword and savePassword to retrieve
|
||||
* or save password in DBusSync.
|
||||
*/
|
||||
string askPassword(const string &passwordName,
|
||||
const string &descr,
|
||||
const ConfigPasswordKey &key);
|
||||
bool savePassword(const string &passwordName,
|
||||
const string &password,
|
||||
const ConfigPasswordKey &key);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1451,6 +1467,88 @@ int DBusSync::sleep(int intervals)
|
|||
}
|
||||
}
|
||||
|
||||
inline const char *passwdStr(const std::string &str)
|
||||
{
|
||||
return str.empty() ? NULL : str.c_str();
|
||||
}
|
||||
|
||||
string DBusSync::askPassword(const string &passwordName,
|
||||
const string &descr,
|
||||
const ConfigPasswordKey &key)
|
||||
{
|
||||
string password;
|
||||
#ifdef USE_GNOME_KEYRING
|
||||
/** here we use server sync url without protocol prefix and
|
||||
* user account name as the key in the keyring */
|
||||
/* It is possible to let CmdlineSyncClient decide which of fields in ConfigPasswordKey it would use
|
||||
* but currently only use passed key instead */
|
||||
GnomeKeyringResult result;
|
||||
GList* list;
|
||||
|
||||
result = gnome_keyring_find_network_password_sync(passwdStr(key.user),
|
||||
passwdStr(key.domain),
|
||||
passwdStr(key.server),
|
||||
passwdStr(key.object),
|
||||
passwdStr(key.protocol),
|
||||
passwdStr(key.authtype),
|
||||
key.port,
|
||||
&list);
|
||||
|
||||
/** if find password stored in gnome keyring */
|
||||
if(result == GNOME_KEYRING_RESULT_OK && list && list->data ) {
|
||||
GnomeKeyringNetworkPasswordData *key_data;
|
||||
key_data = (GnomeKeyringNetworkPasswordData*)list->data;
|
||||
password = key_data->password;
|
||||
gnome_keyring_network_password_list_free(list);
|
||||
return password;
|
||||
}
|
||||
//if not found, then ask user to interactively input password
|
||||
#endif
|
||||
/** if not built with gnome_keyring support, directly ask dbus clients to
|
||||
* input password */
|
||||
// TODO: send InfoRequest signal to dbus clients
|
||||
// m_session.infoRequest()
|
||||
return password;
|
||||
}
|
||||
|
||||
bool DBusSync::savePassword(const string &passwordName,
|
||||
const string &password,
|
||||
const ConfigPasswordKey &key)
|
||||
{
|
||||
#ifdef USE_GNOME_KEYRING
|
||||
/* It is possible to let CmdlineSyncClient decide which of fields in ConfigPasswordKey it would use
|
||||
* but currently only use passed key instead */
|
||||
guint32 itemId;
|
||||
GnomeKeyringResult result;
|
||||
// write password to keyring
|
||||
result = gnome_keyring_set_network_password_sync(NULL,
|
||||
passwdStr(key.user),
|
||||
passwdStr(key.domain),
|
||||
passwdStr(key.server),
|
||||
passwdStr(key.object),
|
||||
passwdStr(key.protocol),
|
||||
passwdStr(key.authtype),
|
||||
key.port,
|
||||
password.c_str(),
|
||||
&itemId);
|
||||
/* if set operation is failed */
|
||||
if(result != GNOME_KEYRING_RESULT_OK) {
|
||||
#ifdef GNOME_KEYRING_220
|
||||
SyncContext::throwError("Try to save " + passwordName + " in gnome-keyring but get an error. " + gnome_keyring_result_to_message(result));
|
||||
#else
|
||||
/** if gnome-keyring version is below 2.20, it doesn't support 'gnome_keyring_result_to_message'. */
|
||||
stringstream value;
|
||||
value << (int)result;
|
||||
SyncContext::throwError("Try to save " + passwordName + " in gnome-keyring but get an error. The gnome-keyring error code is " + value.str() + ".");
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
/** if no support of gnome-keyring, don't save anything */
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************** Session implementation ***********************/
|
||||
|
||||
void Session::detach(const Caller_t &caller)
|
||||
|
|
Loading…
Reference in a new issue