Commit d0bc7f3b authored by Rafaël Carré's avatar Rafaël Carré
Browse files

* #6560 : actually use, store, restore, transmit SIP credentials

The SIP credentials are transmitted (between client and daemon) and
(un)serialized (in the config file) as a list of items holding:
    - realm
    - username
    - password

The password associated to the SIP account will be removed as it is
redundant with the first item of the list.
idem for the authentication username.
parent 0bb73290
......@@ -340,20 +340,7 @@ void sflphone_fill_account_list (void)
a->properties = details;
/* Fill the actual array of credentials */
int number_of_credential = dbus_get_number_of_credential (a->accountID);
if (number_of_credential) {
a->credential_information = g_ptr_array_new();
} else {
a->credential_information = NULL;
}
int credential_index;
for (credential_index = 0; credential_index < number_of_credential; credential_index++) {
GHashTable * credential_information = dbus_get_credential (a->accountID, credential_index);
g_ptr_array_add (a->credential_information, credential_information);
}
dbus_get_credentials (a);
gchar * status = g_hash_table_lookup (details, REGISTRATION_STATUS);
......
......@@ -69,7 +69,6 @@ GtkWidget * entryID;
GtkWidget * entryAlias;
GtkWidget * protocolComboBox;
GtkWidget * entryUsername;
GtkWidget * entryAuthenticationUsername;
GtkWidget * entryRouteSet;
GtkWidget * entryHostname;
GtkWidget * entryPassword;
......@@ -132,7 +131,6 @@ static void reset()
protocolComboBox = NULL;
entryHostname = NULL;
entryUsername = NULL;
entryAuthenticationUsername = NULL;
entryPassword = NULL;
entryUseragent = NULL;
entryMailbox = NULL;
......@@ -193,62 +191,35 @@ select_dtmf_type (void)
}
static GPtrArray* getNewCredential (GHashTable * properties)
static GPtrArray* getNewCredential (void)
{
GtkTreeIter iter;
gboolean valid;
gint row_count = 0;
valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (credentialStore), &iter);
GPtrArray *credential_array = g_ptr_array_new ();
gchar *username;
gchar *realm;
gchar *password;
GHashTable * new_table;
if (valid == FALSE) {
DEBUG ("Gtk tree model iter is not valid");
return NULL;
}
gtk_tree_model_get (GTK_TREE_MODEL (credentialStore), &iter,
COLUMN_CREDENTIAL_REALM, &realm,
COLUMN_CREDENTIAL_USERNAME, &username,
COLUMN_CREDENTIAL_PASSWORD, &password,
-1);
g_hash_table_insert (properties, g_strdup (ACCOUNT_REALM), realm);
g_hash_table_insert(properties, g_strdup(ACCOUNT_AUTHENTICATION_USERNAME), username);
// Do not change the password if nothing has been changed by the user
if (g_strcasecmp (password, PW_HIDDEN) != 0)
g_hash_table_insert (properties, g_strdup (ACCOUNT_PASSWORD), password);
valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (credentialStore), &iter);
gboolean valid;
for (valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (credentialStore), &iter) ;
valid ;
valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (credentialStore), &iter)
) {
gchar *username;
gchar *realm;
gchar *password;
while (valid) {
gtk_tree_model_get (GTK_TREE_MODEL (credentialStore), &iter,
COLUMN_CREDENTIAL_REALM, &realm,
COLUMN_CREDENTIAL_USERNAME, &username,
COLUMN_CREDENTIAL_PASSWORD, &password,
-1);
DEBUG ("Row %d: %s %s %s", row_count, username, password, realm);
DEBUG ("Row %d: %s %s %s", row_count++, username, password, realm);
new_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
GHashTable * new_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
g_hash_table_insert (new_table, g_strdup (ACCOUNT_REALM), realm);
g_hash_table_insert (new_table, g_strdup (ACCOUNT_AUTHENTICATION_USERNAME), username);
g_hash_table_insert (new_table, g_strdup (ACCOUNT_USERNAME), username);
g_hash_table_insert (new_table, g_strdup (ACCOUNT_PASSWORD), password);
g_ptr_array_add (credential_array, new_table);
row_count ++;
valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (credentialStore), &iter);
}
return credential_array;
......@@ -283,7 +254,6 @@ static GtkWidget* create_basic_tab (account_t **a)
gchar *curAccountType = "SIP";
gchar *curAlias = "";
gchar *curUsername = "";
gchar *curAuthenticationUsername = "";
gchar *curHostname = "";
gchar *curPassword = "";
/* TODO: add curProxy, and add boxes for Proxy support */
......@@ -304,7 +274,6 @@ static GtkWidget* create_basic_tab (account_t **a)
curHostname = g_hash_table_lookup (currentAccount->properties, ACCOUNT_HOSTNAME);
curPassword = g_hash_table_lookup (currentAccount->properties, ACCOUNT_PASSWORD);
curUsername = g_hash_table_lookup (currentAccount->properties, ACCOUNT_USERNAME);
curAuthenticationUsername = g_hash_table_lookup (currentAccount->properties, ACCOUNT_AUTHENTICATION_USERNAME);
curRouteSet = g_hash_table_lookup(currentAccount->properties, ACCOUNT_ROUTE);
curMailbox = g_hash_table_lookup (currentAccount->properties, ACCOUNT_MAILBOX);
curMailbox = curMailbox != NULL ? curMailbox : "";
......@@ -392,27 +361,6 @@ static GtkWidget* create_basic_tab (account_t **a)
g_object_set_data (G_OBJECT (entryUsername), "column", GINT_TO_POINTER (COLUMN_CREDENTIAL_USERNAME));
}
row++;
label = gtk_label_new_with_mnemonic (_ ("_Authentication User name"));
gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
#if GTK_CHECK_VERSION(2,16,0)
entryAuthenticationUsername = gtk_entry_new();
gtk_entry_set_icon_from_pixbuf (GTK_ENTRY (entryAuthenticationUsername), GTK_ENTRY_ICON_PRIMARY, gdk_pixbuf_new_from_file (ICONS_DIR "/stock_person.svg", NULL));
#else
entryAuthenticationUsername = sexy_icon_entry_new();
image = gtk_image_new_from_file (ICONS_DIR "/stock_person.svg");
sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (entryAuthenticationUsername), SEXY_ICON_ENTRY_PRIMARY , GTK_IMAGE (image));
#endif
gtk_label_set_mnemonic_widget (GTK_LABEL (label), entryAuthenticationUsername);
gtk_entry_set_text (GTK_ENTRY (entryAuthenticationUsername), curAuthenticationUsername);
gtk_table_attach (GTK_TABLE (table), entryAuthenticationUsername, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
if (strcmp (curAccountType, "SIP") == 0) {
g_signal_connect (G_OBJECT (entryAuthenticationUsername), "changed", G_CALLBACK (update_credential_cb), NULL);
g_object_set_data (G_OBJECT (entryAuthenticationUsername), "column", GINT_TO_POINTER (COLUMN_CREDENTIAL_USERNAME));
}
row++;
label = gtk_label_new_with_mnemonic (_ ("_Password"));
gtk_table_attach (GTK_TABLE (table), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
......@@ -1442,9 +1390,6 @@ void show_account_window (account_t * a)
g_hash_table_replace (currentAccount->properties,
g_strdup (ACCOUNT_USERNAME),
g_strdup ( (gchar *) gtk_entry_get_text (GTK_ENTRY (entryUsername))));
g_hash_table_replace (currentAccount->properties,
g_strdup (ACCOUNT_AUTHENTICATION_USERNAME),
g_strdup ( (gchar *) gtk_entry_get_text (GTK_ENTRY (entryAuthenticationUsername))));
g_hash_table_replace (currentAccount->properties,
g_strdup (ACCOUNT_PASSWORD),
g_strdup ( (gchar *) gtk_entry_get_text (GTK_ENTRY (entryPassword))));
......@@ -1562,26 +1507,10 @@ void show_account_window (account_t * a)
DEBUG ("Config: Setting credentials");
if (g_strcasecmp (currentAccount->accountID, IP2IP) != 0) {
/* This hack is necessary because of the way the
* configuration file is made (.ini at that time).
* and deleting account per account is too much
* of a trouble.
*/
dbus_delete_all_credential (currentAccount);
DEBUG ("Config: Get new credentials");
GPtrArray * credential = getNewCredential (currentAccount->properties);
currentAccount->credential_information = credential;
if (currentAccount->credential_information != NULL) {
guint i;
for (i = 0; i < currentAccount->credential_information->len; i++) {
DEBUG ("Create new credential");
dbus_set_credential (currentAccount, i);
}
}
currentAccount->credential_information = getNewCredential ();
if (currentAccount->credential_information)
dbus_set_credentials (currentAccount);
}
}
......
......@@ -27,7 +27,6 @@
<li>USERNAME: The username (or extension) of the account</li>
<li>PASSWORD: The password associated to the account</li>
<li>REALM</li>
<li>AUTHENTICATION_USERNAME</li>
<li>CONFIG_ACCOUNT_MAILBOX: Number to dial to access the voicemail box</li>
<li>CONFIG_ACCOUNT_REGISTRATION_EXPIRE: SIP header expiration value (Default: 1600)</li>
<li>LOCAL_INTERFACE: The network interface (Default: eth0)</li>
......@@ -83,7 +82,7 @@
</arg>
</method>
<method name="setCredential" tp:name-for-bindings="setCredential">
<method name="setCredentials" tp:name-for-bindings="setCredentials">
<tp:docstring>
</tp:docstring>
<annotation name="com.trolltech.QtDBus.QtTypeName.In2" value="MapStringString"/>
......@@ -91,20 +90,7 @@
<tp:docstring>
</tp:docstring>
</arg>
<arg type="i" name="index" direction="in">
<tp:docstring>
</tp:docstring>
</arg>
<arg type="a{ss}" name="credentialInformation" direction="in" tp:type="String_String_Map">
<tp:docstring>
</tp:docstring>
</arg>
</method>
<method name="deleteAllCredential" tp:name-for-bindings="deleteAllCredential">
<tp:docstring>
</tp:docstring>
<arg type="s" name="accountID" direction="in">
<arg type="aa{ss}" name="credentialInformation" direction="in" tp:type="String_String_Map">
<tp:docstring>
</tp:docstring>
</arg>
......@@ -160,7 +146,7 @@
</arg>
</method>
<method name="getCredential" tp:name-for-bindings="getCredential">
<method name="getCredentials" tp:name-for-bindings="getCredentials">
<tp:docstring>
</tp:docstring>
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/>
......@@ -168,24 +154,7 @@
<tp:docstring>
</tp:docstring>
</arg>
<arg type="i" name="index" direction="in">
<tp:docstring>
</tp:docstring>
</arg>
<arg type="a{ss}" name="credentialInformation" direction="out">
<tp:docstring>
</tp:docstring>
</arg>
</method>
<method name="getNumberOfCredential" tp:name-for-bindings="getNumberOfCredential">
<tp:docstring>
</tp:docstring>
<arg type="s" name="accountID" direction="in">
<tp:docstring>
</tp:docstring>
</arg>
<arg type="i" name="numberOfCredential" direction="out">
<arg type="aa{ss}" name="credentialInformation" direction="out">
<tp:docstring>
</tp:docstring>
</arg>
......
......@@ -1185,20 +1185,13 @@ dbus_get_account_details (gchar * accountID)
}
void
dbus_set_credential (account_t *a, int index)
dbus_set_credentials (account_t *a)
{
GError *error = NULL;
DEBUG ("DBUS: Sending credential %d to server", index);
GHashTable * credential = g_ptr_array_index (a->credential_information, index);
DEBUG ("DBUS: Sending credentials to server");
if (credential == NULL) {
DEBUG ("Credential %d was deleted", index);
} else {
org_sflphone_SFLphone_ConfigurationManager_set_credential (
configurationManagerProxy, a->accountID, index, credential, &error);
}
org_sflphone_SFLphone_ConfigurationManager_set_credentials (
configurationManagerProxy, a->accountID, a->credential_information, &error);
if (error) {
ERROR ("Failed to call set_credential() on ConfigurationManager: %s",
......@@ -1208,69 +1201,23 @@ dbus_set_credential (account_t *a, int index)
}
void
dbus_delete_all_credential (account_t *a)
{
GError *error = NULL;
DEBUG ("DBUS: Deleting all credentials");
org_sflphone_SFLphone_ConfigurationManager_delete_all_credential (
configurationManagerProxy, a->accountID, &error);
if (error) {
ERROR ("Failed to call deleteAllCredential on ConfigurationManager: %s",
error->message);
g_error_free (error);
}
}
int
dbus_get_number_of_credential (gchar * accountID)
dbus_get_credentials (account_t *a)
{
GError *error = NULL;
int number = 0;
DEBUG ("DBUS: Getting number of credential for account %s", accountID);
DEBUG("DBUS: Get credential for account %s", a->accountID);
if (!org_sflphone_SFLphone_ConfigurationManager_get_number_of_credential (
configurationManagerProxy, accountID, &number, &error)) {
if (error->domain == DBUS_GERROR && error->code
== DBUS_GERROR_REMOTE_EXCEPTION) {
ERROR ("Caught remote method (get_account_details) exception %s: %s", dbus_g_error_get_name (error), error->message);
} else {
ERROR ("Error while calling get_account_details: %s", error->message);
}
if (org_sflphone_SFLphone_ConfigurationManager_get_credentials (
configurationManagerProxy, a->accountID, &a->credential_information, &error))
return;
g_error_free (error);
return 0;
if (error->domain == DBUS_GERROR && error->code
== DBUS_GERROR_REMOTE_EXCEPTION) {
ERROR ("Caught remote method (get_account_details) exception %s: %s", dbus_g_error_get_name (error), error->message);
} else {
DEBUG ("%d credential(s) found for account %s", number, accountID);
return number;
ERROR ("Error while calling get_account_details: %s", error->message);
}
}
GHashTable*
dbus_get_credential (gchar * accountID, int index)
{
GError *error = NULL;
GHashTable * details;
DEBUG("DBUS: Get credential for account %s", accountID);
if (!org_sflphone_SFLphone_ConfigurationManager_get_credential (
configurationManagerProxy, accountID, index, &details, &error)) {
if (error->domain == DBUS_GERROR && error->code
== DBUS_GERROR_REMOTE_EXCEPTION) {
ERROR ("Caught remote method (get_account_details) exception %s: %s", dbus_g_error_get_name (error), error->message);
} else {
ERROR ("Error while calling get_account_details: %s", error->message);
}
g_error_free (error);
return NULL;
} else {
return details;
}
g_error_free (error);
}
GHashTable*
......
......@@ -128,41 +128,21 @@ void dbus_set_account_details (account_t *a);
/**
* ConfigurationManager - Set the additional credential information
* of a specific account, for a specific credential index.
* of a specific account.
* This function will add the new section on the server side
* if it cannot be found.
* @param a The account to update
* @param index The index for the credential to update
*/
void dbus_set_credential (account_t *a, int index);
void dbus_set_credentials (account_t *a);
/**
* ConfigurationManager - Set the additional credential information
* of a specific account, for a specific credential index.
* of a specific account.
* This function will add the new section on the server side
* if it cannot be found.
* @param a The account to update
* @return int The number of credentials specified
*/
int dbus_get_number_of_credential (gchar * accountID);
/**
* ConfigurationManager - Delete all credentials defined for
* a given account.
* @param a The account id
*/
void dbus_delete_all_credential (account_t *a);
/**
* ConfigurationManager - Set the additional credential information
* of a specific account, for a specific credential index.
* This function will add the new section on the server side
* if it cannot be found.
* @param a The account to update
* @param index The credential index
* @return GHashTable* The credential at index "index" for the given account
*/
GHashTable* dbus_get_credential (gchar * accountID, int index);
void dbus_get_credentials (account_t *a);
/**
* ConfigurationManager - Get the details for the ip2ip profile
......
......@@ -79,7 +79,6 @@
#define ACCOUNT_USERNAME "username"
#define ACCOUNT_ROUTE "routeset"
#define ACCOUNT_PASSWORD "password"
#define ACCOUNT_AUTHENTICATION_USERNAME "authenticationUsername"
#define ACCOUNT_REALM "realm"
#define ACCOUNT_KEY_EXCHANGE "SRTP.keyExchange"
#define ACCOUNT_SRTP_ENABLED "SRTP.enable"
......
......@@ -80,7 +80,6 @@ typedef enum RegistrationState {
#define HOSTNAME "hostname"
#define USERNAME "username"
#define ROUTESET "routeset"
#define AUTHENTICATION_USERNAME "authenticationUsername"
#define PASSWORD "password"
#define REALM "realm"
#define DEFAULT_REALM "*"
......
......@@ -27,7 +27,6 @@
<li>USERNAME: The username (or extension) of the account</li>
<li>PASSWORD: The password associated to the account</li>
<li>REALM</li>
<li>AUTHENTICATION_USERNAME</li>
<li>CONFIG_ACCOUNT_MAILBOX: Number to dial to access the voicemail box</li>
<li>CONFIG_ACCOUNT_REGISTRATION_EXPIRE: SIP header expiration value (Default: 1600)</li>
<li>LOCAL_INTERFACE: The network interface (Default: eth0)</li>
......@@ -83,7 +82,7 @@
</arg>
</method>
<method name="setCredential" tp:name-for-bindings="setCredential">
<method name="setCredentials" tp:name-for-bindings="setCredentials">
<tp:docstring>
</tp:docstring>
<annotation name="com.trolltech.QtDBus.QtTypeName.In2" value="MapStringString"/>
......@@ -91,20 +90,7 @@
<tp:docstring>
</tp:docstring>
</arg>
<arg type="i" name="index" direction="in">
<tp:docstring>
</tp:docstring>
</arg>
<arg type="a{ss}" name="credentialInformation" direction="in" tp:type="String_String_Map">
<tp:docstring>
</tp:docstring>
</arg>
</method>
<method name="deleteAllCredential" tp:name-for-bindings="deleteAllCredential">
<tp:docstring>
</tp:docstring>
<arg type="s" name="accountID" direction="in">
<arg type="aa{ss}" name="credentialInformation" direction="in" tp:type="String_String_Map">
<tp:docstring>
</tp:docstring>
</arg>
......@@ -160,7 +146,7 @@
</arg>
</method>
<method name="getCredential" tp:name-for-bindings="getCredential">
<method name="getCredentials" tp:name-for-bindings="getCredentials">
<tp:docstring>
</tp:docstring>
<annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="MapStringString"/>
......@@ -168,24 +154,7 @@
<tp:docstring>
</tp:docstring>
</arg>
<arg type="i" name="index" direction="in">
<tp:docstring>
</tp:docstring>
</arg>
<arg type="a{ss}" name="credentialInformation" direction="out">
<tp:docstring>
</tp:docstring>
</arg>
</method>
<method name="getNumberOfCredential" tp:name-for-bindings="getNumberOfCredential">
<tp:docstring>
</tp:docstring>
<arg type="s" name="accountID" direction="in">
<tp:docstring>
</tp:docstring>
</arg>
<arg type="i" name="numberOfCredential" direction="out">
<arg type="aa{ss}" name="credentialInformation" direction="out">
<tp:docstring>
</tp:docstring>
</arg>
......
......@@ -289,68 +289,28 @@ void ConfigurationManager::setTlsSettings (const std::map<std::string, std::stri
}
std::map<std::string, std::string> ConfigurationManager::getCredential (
const std::string& accountID, const int32_t& index)
std::vector<std::map<std::string, std::string> > ConfigurationManager::getCredentials (
const std::string& accountID)
{
Account *account = Manager::instance().getAccount (accountID);
std::vector<std::map<std::string, std::string> > credentialInformation;
std::map<std::string, std::string> credentialInformation;
if (account->getType() != "SIP")
if (!account || account->getType() != "SIP")
return credentialInformation;
SIPAccount *sipaccount = (SIPAccount *) account;
if (index == 0) {
std::string username = sipaccount->getUsername();
std::string password = sipaccount->getPassword();
std::string realm = sipaccount->getRealm();
credentialInformation.insert (std::pair<std::string, std::string> (USERNAME, username));
credentialInformation.insert (std::pair<std::string, std::string> (PASSWORD, password));
credentialInformation.insert (std::pair<std::string, std::string> (REALM, realm));
} else {
// TODO: implement for extra credentials
std::string username = sipaccount->getUsername();
std::string password = sipaccount->getPassword();
std::string realm = sipaccount->getRealm();
credentialInformation.insert (std::pair<std::string, std::string> (USERNAME, username));
credentialInformation.insert (std::pair<std::string, std::string> (PASSWORD, password));
credentialInformation.insert (std::pair<std::string, std::string> (REALM, realm));
}
return credentialInformation;
return sipaccount->getCredentials();
}
int32_t ConfigurationManager::getNumberOfCredential (
const std::string& accountID)
void ConfigurationManager::setCredentials (const std::string& accountID,
const std::vector<std::map<std::string, std::string> >& details)
{
Account *account = Manager::instance().getAccount (accountID);
if (!account)
return 0;
if (account->getType() == "SIP") {
SIPAccount *sipaccount = static_cast<SIPAccount *> (account);
return sipaccount->getCredentialCount();
} else
return 0;
}
void ConfigurationManager::setCredential (const std::string& accountID,
const int32_t& index, const std::map<std::string, std::string>& details)
{
Manager::instance().setCredential (accountID, index, details);
}
void ConfigurationManager::deleteAllCredential (const std::string& accountID)
{
Manager::instance().deleteAllCredential (accountID);
if (account && account->getType() == "SIP") {
SIPAccount *sipaccount = (SIPAccount *) account;
sipaccount->setCredentials(details);
}
}
void ConfigurationManager::setAccountDetails (const std::string& accountID,
......
......@@ -73,9 +73,9 @@ class ConfigurationManager
std::