Merge branch 'pierre-luc'

This commit is contained in:
Emmanuel Milou
2009-07-31 16:33:41 -04:00
18 changed files with 770 additions and 59 deletions

View File

@ -62,14 +62,15 @@ typedef enum
*
* To retrieve the Alias for example, use g_hash_table_lookup(a->properties, ACCOUNT_ALIAS).
*/
typedef struct {
gchar * accountID;
account_state_t state;
GHashTable * properties;
GPtrArray * credential_information;
} account_t;
/**
* This function initialize the account list.
*/

View File

@ -147,6 +147,12 @@ sflphone_hung_up( callable_obj_t * c)
#endif
}
static hashtable_free(gpointer key, gpointer value, gpointer user_data)
{
g_free(key);
g_free(value);
}
/** Internal to actions: Fill account list */
void
sflphone_fill_account_list(gboolean toolbarInitialized)
@ -165,6 +171,7 @@ sflphone_fill_account_list(gboolean toolbarInitialized)
{
account_t * a = g_new0(account_t,1);
a->accountID = g_strdup(*accountID);
a->credential_information = NULL;
account_list_add(a);
}
g_strfreev (array);
@ -177,6 +184,25 @@ sflphone_fill_account_list(gboolean toolbarInitialized)
if( details == NULL )
break;
a->properties = details;
/* As this function might be called numberous time, we should free the
* previously allocated space to avoid memory leaks.
*/
/* 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);
}
gchar * status = g_hash_table_lookup(details, "Status");
if(strcmp(status, "REGISTERED") == 0)

View File

@ -2,6 +2,7 @@
* Copyright (C) 2007-2008 Savoir-Faire Linux inc.
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
* Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>
* Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -48,6 +49,19 @@ GtkWidget * entryPassword;
GtkWidget * entryMailbox;
GtkWidget * entryResolveNameOnlyOnce;
GtkWidget * entryExpire;
GtkListStore * credentialStore;
GtkWidget * deleteCredButton;
GtkWidget * treeViewCredential;
GtkWidget * scrolledWindowCredential;
// Credentials
enum {
COLUMN_CREDENTIAL_REALM,
COLUMN_CREDENTIAL_USERNAME,
COLUMN_CREDENTIAL_PASSWORD,
COLUMN_CREDENTIAL_DATA,
COLUMN_CREDENTIAL_COUNT
};
/* Signal to entryProtocol 'changed' */
void
@ -66,6 +80,14 @@ is_iax_enabled(void)
return FALSE;
}
static void update_credential_cb(GtkWidget *widget, gpointer data UNUSED)
{
GtkTreeIter iter;
gtk_tree_model_get_iter_from_string ((GtkTreeModel *) credentialStore, &iter, "0");
gint column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "column"));
gtk_list_store_set (GTK_LIST_STORE (credentialStore), &iter, column, (gchar *) gtk_entry_get_text(GTK_ENTRY(widget)), -1);
}
static GtkWidget * createAccountTab(account_t **a)
{
GtkWidget * frame;
@ -181,7 +203,7 @@ static GtkWidget * createAccountTab(account_t **a)
gtk_table_attach ( GTK_TABLE( table ), entryHostname, 1, 2, 5, 6, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
label = gtk_label_new_with_mnemonic (_("_User name"));
gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 6, 7, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 6, 7, 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)
entryUsername = gtk_entry_new();
@ -194,12 +216,16 @@ static GtkWidget * createAccountTab(account_t **a)
gtk_label_set_mnemonic_widget (GTK_LABEL (label), entryUsername);
gtk_entry_set_text(GTK_ENTRY(entryUsername), curUsername);
gtk_table_attach ( GTK_TABLE( table ), entryUsername, 1, 2, 6, 7, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
g_signal_connect(G_OBJECT (entryUsername), "changed", G_CALLBACK (update_credential_cb), NULL);
g_object_set_data (G_OBJECT (entryUsername), "column", GINT_TO_POINTER (COLUMN_CREDENTIAL_USERNAME));
label = gtk_label_new_with_mnemonic (_("_Password"));
gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 7, 8, 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)
entryPassword = gtk_entry_new();
GtkSettings *settings = gtk_settings_get_default ();
g_object_set (G_OBJECT (settings), "gtk-entry-password-hint-timeout", 600, NULL);
gtk_entry_set_icon_from_stock (GTK_ENTRY (entryPassword), GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_DIALOG_AUTHENTICATION);
#else
entryPassword = sexy_icon_entry_new();
@ -210,7 +236,9 @@ static GtkWidget * createAccountTab(account_t **a)
gtk_label_set_mnemonic_widget (GTK_LABEL (label), entryPassword);
gtk_entry_set_text(GTK_ENTRY(entryPassword), curPassword);
gtk_table_attach ( GTK_TABLE( table ), entryPassword, 1, 2, 7, 8, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
g_signal_connect(G_OBJECT (entryPassword), "changed", G_CALLBACK (update_credential_cb), NULL);
g_object_set_data (G_OBJECT (entryPassword), "column", GINT_TO_POINTER (COLUMN_CREDENTIAL_PASSWORD));
label = gtk_label_new_with_mnemonic (_("_Voicemail number"));
gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 8, 9, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
gtk_misc_set_alignment(GTK_MISC (label), 0, 0.5);
@ -226,17 +254,160 @@ static GtkWidget * createAccountTab(account_t **a)
return frame;
}
static void fill_treeview_with_credential(GtkListStore * credentialStore, account_t * account)
{
GtkTreeIter iter;
gtk_list_store_clear(credentialStore);
gtk_list_store_append (credentialStore, &iter);
/* This is the default, undeletable credential */
if(g_hash_table_lookup(account->properties, ACCOUNT_AUTHENTICATION_USERNAME) == NULL) {
DEBUG("DEFAULT");
gtk_list_store_set(credentialStore, &iter,
COLUMN_CREDENTIAL_REALM, g_hash_table_lookup(account->properties, ACCOUNT_REALM),
COLUMN_CREDENTIAL_USERNAME, gtk_entry_get_text(GTK_ENTRY(entryUsername)),
COLUMN_CREDENTIAL_PASSWORD, gtk_entry_get_text(GTK_ENTRY(entryPassword)),
COLUMN_CREDENTIAL_DATA, account,
-1);
} else {
gtk_list_store_set(credentialStore, &iter,
COLUMN_CREDENTIAL_REALM, g_hash_table_lookup(account->properties, ACCOUNT_REALM),
COLUMN_CREDENTIAL_USERNAME, g_hash_table_lookup(account->properties, ACCOUNT_AUTHENTICATION_USERNAME),
COLUMN_CREDENTIAL_PASSWORD, gtk_entry_get_text(GTK_ENTRY(entryPassword)),
COLUMN_CREDENTIAL_DATA, account,
-1);
g_signal_handlers_disconnect_by_func (G_OBJECT(entryUsername), G_CALLBACK(update_credential_cb), NULL);
}
if(account->credential_information == NULL) {
DEBUG("No credential defined");
return;
}
unsigned int i;
for(i = 0; i < account->credential_information->len; i++)
{
GHashTable * element = g_ptr_array_index(account->credential_information, i);
gtk_list_store_append (credentialStore, &iter);
gtk_list_store_set(credentialStore, &iter,
COLUMN_CREDENTIAL_REALM, g_hash_table_lookup(element, ACCOUNT_REALM),
COLUMN_CREDENTIAL_USERNAME, g_hash_table_lookup(element, ACCOUNT_USERNAME),
COLUMN_CREDENTIAL_PASSWORD, g_hash_table_lookup(element, ACCOUNT_PASSWORD),
COLUMN_CREDENTIAL_DATA, element, // Pointer
-1);
}
}
static select_credential_cb(GtkTreeSelection *selection, GtkTreeModel *model)
{
GtkTreeIter iter;
GtkTreePath *path;
if(gtk_tree_selection_get_selected (selection, NULL, &iter)) {
path = gtk_tree_model_get_path (model, &iter);
if(gtk_tree_path_get_indices (path)[0] == 0) {
gtk_widget_set_sensitive(GTK_WIDGET(deleteCredButton), FALSE);
} else {
gtk_widget_set_sensitive(GTK_WIDGET(deleteCredButton), TRUE);
}
}
}
static void add_credential_cb (GtkWidget *button, gpointer data)
{
GtkTreeIter iter;
GtkTreeModel *model = (GtkTreeModel *)data;
GtkRequisition requisitionTreeView;
GtkRequisition oldRequisitionTreeView;
gtk_widget_size_request(GTK_WIDGET(treeViewCredential), &oldRequisitionTreeView);
gtk_list_store_append (GTK_LIST_STORE (model), &iter);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
COLUMN_CREDENTIAL_REALM, "*",
COLUMN_CREDENTIAL_USERNAME, _("Authentication"),
COLUMN_CREDENTIAL_PASSWORD, _("Secret"),
-1);
gtk_widget_size_request(GTK_WIDGET(treeViewCredential), &requisitionTreeView);
gtk_widget_set_size_request(GTK_WIDGET(scrolledWindowCredential), oldRequisitionTreeView.width, requisitionTreeView.height + 20);
}
static void delete_credential_cb(GtkWidget *button, gpointer data)
{
GtkTreeIter iter;
GtkTreeView *treeview = (GtkTreeView *)data;
GtkTreeModel *model = gtk_tree_view_get_model (treeview);
GtkTreeSelection *selection = gtk_tree_view_get_selection (treeview);
GtkRequisition requisitionTreeView;
GtkRequisition oldRequisitionTreeView;
gtk_widget_size_request(GTK_WIDGET(treeViewCredential), &oldRequisitionTreeView);
if (gtk_tree_selection_get_selected (selection, NULL, &iter))
{
GtkTreePath *path;
path = gtk_tree_model_get_path (model, &iter);
gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
gtk_tree_path_free (path);
}
gtk_widget_size_request(GTK_WIDGET(treeViewCredential), &requisitionTreeView);
gtk_widget_set_size_request(GTK_WIDGET(scrolledWindowCredential), oldRequisitionTreeView.width, requisitionTreeView.height + 20);
}
static void cell_edited_cb(GtkCellRendererText *renderer, gchar *path_desc, gchar *text, gpointer data)
{
GtkTreeModel *model = (GtkTreeModel *)data;
GtkTreePath *path = gtk_tree_path_new_from_string (path_desc);
GtkTreeIter iter;
gint column = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (renderer), "column"));
if(g_strcasecmp(path_desc, "0") == 0) {
if(g_strcasecmp(text, gtk_entry_get_text(GTK_ENTRY(entryUsername))) != 0) {
g_signal_handlers_disconnect_by_func (G_OBJECT(entryUsername), G_CALLBACK(update_credential_cb), NULL);
}
}
gtk_tree_model_get_iter (model, &iter, path);
gtk_list_store_set (GTK_LIST_STORE (model), &iter, column, text, -1);
gtk_tree_path_free (path);
}
static void editing_started_cb (GtkCellRenderer *cell, GtkCellEditable * editable, const gchar * path, gpointer data)
{
DEBUG("Editing started");
gtk_entry_set_visibility(GTK_ENTRY(editable), FALSE);
}
GtkWidget * createAdvancedTab(account_t **a)
{
GtkWidget * frame;
GtkWidget * table;
GtkWidget * ret;
GtkWidget * hbox;
GtkWidget * editButton;
GtkWidget * addButton;
GtkCellRenderer * renderer;
GtkTreeViewColumn * treeViewColumn;
GtkTreeSelection * treeSelection;
GtkRequisition requisitionTable;
GtkRequisition requisitionTreeView;
ret = gtk_vbox_new(FALSE, 10);
gtk_container_set_border_width(GTK_CONTAINER(ret), 10);
account_t * currentAccount;
// Default settings
gchar * curAccountResolveOnce = "FALSE";
gchar * curAccountExpire = "600";
currentAccount = *a;
currentAccount = *a;
// Load from SIP/IAX/Unknown ?
if(currentAccount) {
@ -244,14 +415,8 @@ GtkWidget * createAdvancedTab(account_t **a)
curAccountExpire = g_hash_table_lookup(currentAccount->properties, ACCOUNT_REGISTRATION_EXPIRE);
}
gnome_main_section_new (_("Advanced Settings"), &frame);
gtk_widget_show(frame);
table = gtk_table_new (2, 2, FALSE/* homogeneous */);
gtk_table_set_row_spacings( GTK_TABLE(table), 10);
gtk_table_set_col_spacings( GTK_TABLE(table), 10);
gtk_widget_show(table);
gtk_container_add( GTK_CONTAINER( frame) , table );
gnome_main_section_new_with_table (_("Registration Options"), &frame, &table, 2, 3);
gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
label = gtk_label_new_with_mnemonic (_("Registration _expire"));
gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 0, 1, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
@ -267,11 +432,137 @@ GtkWidget * createAdvancedTab(account_t **a)
gtk_table_attach ( GTK_TABLE( table ), entryResolveNameOnlyOnce, 0, 2, 1, 2, GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
gtk_widget_set_sensitive( GTK_WIDGET( entryResolveNameOnlyOnce ) , TRUE );
gtk_widget_show_all( table );
gtk_widget_show_all( table );
gtk_container_set_border_width (GTK_CONTAINER(table), 10);
*a = currentAccount;
return frame;
gtk_widget_size_request(GTK_WIDGET(table), &requisitionTable);
/* Credentials tree view */
gnome_main_section_new_with_table (_("Credential informations"), &frame, &table, 1, 1);
gtk_container_set_border_width (GTK_CONTAINER(table), 10);
gtk_table_set_row_spacings (GTK_TABLE(table), 10);
gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
scrolledWindowCredential = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindowCredential), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledWindowCredential), GTK_SHADOW_IN);
gtk_table_attach (GTK_TABLE(table), scrolledWindowCredential, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
credentialStore = gtk_list_store_new(COLUMN_CREDENTIAL_COUNT,
G_TYPE_STRING, // Realm
G_TYPE_STRING, // Username
G_TYPE_STRING, // Password
G_TYPE_POINTER // Pointer to the Object
);
treeViewCredential = gtk_tree_view_new_with_model(GTK_TREE_MODEL(credentialStore));
treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW (treeViewCredential));
g_signal_connect(G_OBJECT (treeSelection), "changed", G_CALLBACK (select_credential_cb), credentialStore);
renderer = gtk_cell_renderer_text_new();
g_object_set (renderer, "editable", TRUE, "editable-set", TRUE, NULL);
g_signal_connect(G_OBJECT (renderer), "edited", G_CALLBACK(cell_edited_cb), credentialStore);
g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (COLUMN_CREDENTIAL_REALM));
treeViewColumn = gtk_tree_view_column_new_with_attributes ("Realm",
renderer,
"markup", COLUMN_CREDENTIAL_REALM,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(treeViewCredential), treeViewColumn);
renderer = gtk_cell_renderer_text_new();
g_object_set (renderer, "editable", TRUE, "editable-set", TRUE, NULL);
g_signal_connect(G_OBJECT (renderer), "edited", G_CALLBACK(cell_edited_cb), credentialStore);
g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (COLUMN_CREDENTIAL_USERNAME));
treeViewColumn = gtk_tree_view_column_new_with_attributes (_("Authentication name"),
renderer,
"markup", COLUMN_CREDENTIAL_USERNAME,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(treeViewCredential), treeViewColumn);
renderer = gtk_cell_renderer_text_new();
g_object_set (renderer, "editable", TRUE, "editable-set", TRUE, NULL);
g_signal_connect(G_OBJECT (renderer), "edited", G_CALLBACK(cell_edited_cb), credentialStore);
g_signal_connect (renderer, "editing-started", G_CALLBACK (editing_started_cb), NULL);
g_object_set_data (G_OBJECT (renderer), "column", GINT_TO_POINTER (COLUMN_CREDENTIAL_PASSWORD));
treeViewColumn = gtk_tree_view_column_new_with_attributes (_("Password"),
renderer,
"markup", COLUMN_CREDENTIAL_PASSWORD,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW(treeViewCredential), treeViewColumn);
gtk_container_add(GTK_CONTAINER(scrolledWindowCredential), treeViewCredential);
fill_treeview_with_credential(credentialStore, *a);
/* Dynamically resize the window to fit the scrolled window */
gtk_widget_size_request(GTK_WIDGET(treeViewCredential), &requisitionTreeView);
gtk_widget_set_size_request(GTK_WIDGET(scrolledWindowCredential), requisitionTable.width, requisitionTreeView.height + 20);
/* Credential Buttons */
hbox = gtk_hbox_new(FALSE, 10);
gtk_table_attach (GTK_TABLE(table), hbox, 0, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
addButton = gtk_button_new_from_stock (GTK_STOCK_ADD);
g_signal_connect (addButton, "clicked", G_CALLBACK (add_credential_cb), credentialStore);
gtk_box_pack_start(GTK_BOX(hbox), addButton, FALSE, FALSE, 0);
deleteCredButton = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
g_signal_connect (deleteCredButton, "clicked", G_CALLBACK (delete_credential_cb), treeViewCredential);
gtk_box_pack_start(GTK_BOX(hbox), deleteCredButton, FALSE, FALSE, 0);
gtk_widget_show_all(ret);
return ret;
}
static GPtrArray * getNewCredential(account_t * account)
{
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;
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(account->properties, g_strdup(ACCOUNT_REALM), realm);
g_hash_table_insert(account->properties, g_strdup(ACCOUNT_AUTHENTICATION_USERNAME), username);
g_hash_table_insert(account->properties, g_strdup(ACCOUNT_PASSWORD), password);
valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(credentialStore), &iter);
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);
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_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;
}
void
@ -346,8 +637,8 @@ show_account_window (account_t * a)
g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(entryMailbox))));
g_hash_table_replace(currentAccount->properties,
g_strdup(ACCOUNT_REGISTRATION_EXPIRE),
g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(entryExpire))));
g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(entryExpire))));
if (strcmp(proto, "SIP") == 0) {
guint i, size;
account_t * account;
@ -376,13 +667,33 @@ show_account_window (account_t * a)
if(!flag)
{
g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_SIP_STUN_SERVER), (gchar*)"");
g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_SIP_STUN_ENABLED),
"FALSE");
g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_SIP_STUN_ENABLED), "FALSE");
}
config_window_set_stun_visible();
}
/* Set new credentials if any */
DEBUG("Setting credentials");
/* 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);
GPtrArray * credential = getNewCredential(a);
currentAccount->credential_information = credential;
if(currentAccount->credential_information != NULL) {
int i;
for(i = 0; i < currentAccount->credential_information->len; i++) {
dbus_set_credential(currentAccount, i);
}
dbus_set_number_of_credential(currentAccount, currentAccount->credential_information->len);
}
/** @todo Verify if it's the best condition to check */
if (currentAccount->accountID == NULL) {
dbus_add_account(currentAccount);
@ -390,7 +701,10 @@ show_account_window (account_t * a)
else {
dbus_set_account_details(currentAccount);
}
}
}
gtk_widget_destroy (GTK_WIDGET(dialog));
}

View File

@ -236,7 +236,7 @@ select_account(GtkTreeSelection *selection, GtkTreeModel *model)
gtk_widget_set_sensitive(GTK_WIDGET(accountMoveUpButton), TRUE);
gtk_widget_set_sensitive(GTK_WIDGET(accountMoveDownButton), TRUE);
}
DEBUG("select");
DEBUG("Selecting account in account window");
}
static void

View File

@ -14,6 +14,32 @@
<arg type="s" name="accountID" direction="in"/>
<arg type="a{ss}" name="details" direction="in"/>
</method>
<method name="setNumberOfCredential">
<arg type="s" name="accountID" direction="in"/>
<arg type="i" name="number" direction="in"/>
</method>
<method name="deleteAllCredential">
<arg type="s" name="accountID" direction="in"/>
</method>
<method name="setCredential">
<arg type="s" name="accountID" direction="in"/>
<arg type="i" name="index" direction="in"/>
<arg type="a{ss}" name="credentialInformation" direction="in"/>
</method>
<method name="getCredential">
<arg type="s" name="accountID" direction="in"/>
<arg type="i" name="index" direction="in"/>
<arg type="a{ss}" name="credentialInformation" direction="out"/>
</method>
<method name="getNumberOfCredential">
<arg type="s" name="accountID" direction="in"/>
<arg type="i" name="numberOfCredential" direction="out"/>
</method>
<method name="addAccount">
<annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="MapStringString"/>

View File

@ -559,6 +559,100 @@ GHashTable* dbus_account_details(gchar * accountID)
}
}
void
dbus_set_credential(account_t *a, int index)
{
DEBUG("Sending credential %d to server", index);
GError *error = NULL;
GHashTable * credential = g_ptr_array_index(a->credential_information, index);
if(credential == NULL) {
DEBUG("Credential %d was deleted", index);
} else {
org_sflphone_SFLphone_ConfigurationManager_set_credential (
configurationManagerProxy,
a->accountID,
index,
credential,
&error);
}
if (error) {
ERROR ("Failed to call set_account_details() on ConfigurationManager: %s",
error->message);
g_error_free (error);
}
}
void
dbus_set_number_of_credential(account_t *a, int number)
{
DEBUG("Sending number of credential %d to server", number);
GError *error = NULL;
org_sflphone_SFLphone_ConfigurationManager_set_number_of_credential( configurationManagerProxy, a->accountID, number, &error);
if (error) {
ERROR ("Failed to call set_account_details() on ConfigurationManager: %s",
error->message);
g_error_free (error);
}
}
void
dbus_delete_all_credential(account_t *a)
{
DEBUG("Deleting all credentials\n");
GError *error = NULL;
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)
{
GError *error = NULL;
int number = 0;
DEBUG("Getting number of credential for account %s", 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);
}
g_error_free (error);
return 0;
} else {
DEBUG("%d credential(s) found for account %s", number, accountID);
return number;
}
}
GHashTable* dbus_get_credential(gchar * accountID, int index)
{
GError *error = NULL;
GHashTable * details;
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;
}
}
void
dbus_send_register ( gchar* accountID , const guint expire)
{

View File

@ -106,6 +106,51 @@ GHashTable * dbus_account_details(gchar * accountID);
*/
void dbus_set_account_details(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 index for the credential to update
*/
void dbus_set_credential(account_t *a, int index);
/**
* 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
* @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 number of credential that
* is being used.
* @param a The account id
*/
void dbus_set_number_of_credential(account_t *a, int number);
/**
* 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);
/**
* ConfigurationManager - Send registration request
* @param accountID The account to register/unregister

View File

@ -56,6 +56,8 @@
#define ACCOUNT_HOSTNAME "hostname"
#define ACCOUNT_USERNAME "username"
#define ACCOUNT_PASSWORD "password"
#define ACCOUNT_AUTHENTICATION_USERNAME "authenticationUsername"
#define ACCOUNT_REALM "realm"
/**
* Global logger

View File

@ -60,10 +60,13 @@ typedef enum RegistrationState {
#define CONFIG_ACCOUNT_ENABLE "Account.enable"
#define CONFIG_ACCOUNT_RESOLVE_ONCE "Account.resolveOnce"
#define CONFIG_ACCOUNT_REGISTRATION_EXPIRE "Account.expire"
#define CONFIG_CREDENTIAL_NUMBER "Credential.count"
#define HOSTNAME "hostname"
#define USERNAME "username"
#define AUTHENTICATION_USERNAME "authenticationUsername"
#define PASSWORD "password"
#define REALM "realm"
// SIP specific parameters
#define SIP_PROXY "SIP.proxy"

View File

@ -15,6 +15,32 @@
<arg type="a{ss}" name="details" direction="in"/>
</method>
<method name="setCredential">
<arg type="s" name="accountID" direction="in"/>
<arg type="i" name="index" direction="in"/>
<arg type="a{ss}" name="credentialInformation" direction="in"/>
</method>
<method name="setNumberOfCredential">
<arg type="s" name="accountID" direction="in"/>
<arg type="i" name="number" direction="in"/>
</method>
<method name="deleteAllCredential">
<arg type="s" name="accountID" direction="in"/>
</method>
<method name="getCredential">
<arg type="s" name="accountID" direction="in"/>
<arg type="i" name="index" direction="in"/>
<arg type="a{ss}" name="credentialInformation" direction="out"/>
</method>
<method name="getNumberOfCredential">
<arg type="s" name="accountID" direction="in"/>
<arg type="i" name="numberOfCredential" direction="out"/>
</method>
<method name="addAccount">
<annotation name="com.trolltech.QtDBus.QtTypeName.In0" value="MapStringString"/>
<arg type="a{ss}" name="details" direction="in"/>

View File

@ -41,6 +41,97 @@ ConfigurationManager::getAccountDetails (const std::string& accountID)
return Manager::instance().getAccountDetails (accountID);
}
std::map< std::string, std::string >
ConfigurationManager::getCredential (const std::string& accountID, const int32_t& index)
{
_debug ("ConfigurationManager::getCredential number %i for accountID %s\n", index, accountID.c_str());
std::string credentialIndex;
std::stringstream streamOut;
streamOut << index;
credentialIndex = streamOut.str();
std::string section = std::string("Credential") + std::string(":") + accountID + std::string(":") + credentialIndex;
std::map<std::string, std::string> credentialInformation;
std::string username = Manager::instance().getConfigString(section, USERNAME);
std::string password = Manager::instance().getConfigString(section, PASSWORD);
std::string realm = Manager::instance().getConfigString(section, REALM);
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;
}
int32_t
ConfigurationManager::getNumberOfCredential (const std::string& accountID)
{
_debug ("ConfigurationManager::getNumberOfCredential\n");
return Manager::instance().getConfigInt (accountID, CONFIG_CREDENTIAL_NUMBER);
}
void
ConfigurationManager::setNumberOfCredential (const std::string& accountID, const int32_t& number)
{
Manager::instance().setConfig (accountID, CONFIG_CREDENTIAL_NUMBER, number);
}
void
ConfigurationManager::setCredential (const std::string& accountID, const int32_t& index,
const std::map< std::string, std::string >& details)
{
_debug ("ConfigurationManager::setCredential received\n");
std::map<std::string, std::string>::iterator it;
std::map<std::string, std::string> credentialInformation = details;
std::string credentialIndex;
std::stringstream streamOut;
streamOut << index;
credentialIndex = streamOut.str();
std::string section = "Credential" + std::string(":") + accountID + std::string(":") + credentialIndex;
_debug("Setting credential in section %s\n", section.c_str());
it = credentialInformation.find(USERNAME);
if(it == credentialInformation.end()) {
Manager::instance().setConfig (section, USERNAME, EMPTY_FIELD);
} else {
Manager::instance().setConfig (section, USERNAME, it->second);
}
_debug("Username: %s\n", it->second.c_str());
it = credentialInformation.find(PASSWORD);
if(it == credentialInformation.end()) {
Manager::instance().setConfig (section, PASSWORD, EMPTY_FIELD);
} else {
Manager::instance().setConfig (section, PASSWORD, it->second);
}
_debug("Password: %s\n", it->second.c_str());
it = credentialInformation.find(REALM);
if(it == credentialInformation.end()) {
Manager::instance().setConfig (section, REALM, EMPTY_FIELD);
} else {
Manager::instance().setConfig (section, REALM, it->second);
}
_debug("Realm: %s\n", it->second.c_str());
}
void
ConfigurationManager::deleteAllCredential (const std::string& accountID)
{
_debug ("ConfigurationManager::deleteAllCredential received\n");
Manager::instance().deleteAllCredential (accountID);
}
void
ConfigurationManager::setAccountDetails (const std::string& accountID,
const std::map< std::string, std::string >& details)

View File

@ -43,9 +43,15 @@ public:
void setAccountDetails( const std::string& accountID, const std::map< std::string, std::string >& details );
std::string addAccount( const std::map< std::string, std::string >& details );
void removeAccount( const std::string& accoundID );
void deleteAllCredential (const std::string& accountID);
std::vector< std::string > getAccountList( );
void sendRegister( const std::string& accoundID , const int32_t& expire );
std::map< std::string, std::string > getCredential (const std::string& accountID, const int32_t& index);
int32_t getNumberOfCredential (const std::string& accountID);
void setCredential (const std::string& accountID, const int32_t& index, const std::map< std::string, std::string >& details);
void setNumberOfCredential (const std::string& accountID, const int32_t& number);
std::vector< std::string > getCodecList( );
std::vector< std::string > getCodecDetails( const int32_t& payload );
std::vector< std::string > getActiveCodecList( );

View File

@ -2492,6 +2492,8 @@ std::map< std::string, std::string > ManagerImpl::getAccountDetails (const Accou
a.insert (std::pair<std::string, std::string> (USERNAME, getConfigString (accountID, USERNAME)));
a.insert (std::pair<std::string, std::string> (PASSWORD, getConfigString (accountID, PASSWORD)));
a.insert (std::pair<std::string, std::string> (HOSTNAME, getConfigString (accountID, HOSTNAME)));
a.insert (std::pair<std::string, std::string> (REALM, getConfigString (accountID, REALM)));
a.insert (std::pair<std::string, std::string> (AUTHENTICATION_USERNAME, getConfigString (accountID, AUTHENTICATION_USERNAME)));
a.insert (std::pair<std::string, std::string> (CONFIG_ACCOUNT_MAILBOX, getConfigString (accountID, CONFIG_ACCOUNT_MAILBOX)));
if (getConfigString (accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE).empty()) {
@ -2538,13 +2540,18 @@ void ManagerImpl::setAccountDetails (const std::string& accountID, const std::ma
( (iter = map_cpy.find (HOSTNAME)) == map_cpy.end ()) ? setConfig (accountID, HOSTNAME, EMPTY_FIELD)
: setConfig (accountID, HOSTNAME, iter->second);
( (iter = map_cpy.find (REALM)) == map_cpy.end ()) ? setConfig (accountID, REALM, std::string("*"))
: setConfig (accountID, REALM, iter->second);
( (iter = map_cpy.find (CONFIG_ACCOUNT_MAILBOX)) == map_cpy.end ()) ? setConfig (accountID, CONFIG_ACCOUNT_MAILBOX, EMPTY_FIELD)
: setConfig (accountID, CONFIG_ACCOUNT_MAILBOX, iter->second);
( (iter = map_cpy.find (CONFIG_ACCOUNT_REGISTRATION_EXPIRE)) == map_cpy.end ()) ? setConfig (accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE, DFT_EXPIRE_VALUE)
: setConfig (accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE, iter->second);
( (iter = map_cpy.find (AUTHENTICATION_USERNAME)) == map_cpy.end ()) ? setConfig (accountID, AUTHENTICATION_USERNAME, EMPTY_FIELD)
: setConfig (accountID, AUTHENTICATION_USERNAME, iter->second);
saveConfig();
acc = getAccount (accountID);
@ -2638,6 +2645,25 @@ ManagerImpl::addAccount (const std::map< std::string, std::string >& details)
return newAccountID;
}
void
ManagerImpl::deleteAllCredential(const AccountID& accountID)
{
int numberOfCredential = getConfigInt (accountID, CONFIG_CREDENTIAL_NUMBER);
int i;
for(i = 0; i < numberOfCredential; i++) {
std::string credentialIndex;
std::stringstream streamOut;
streamOut << i;
credentialIndex = streamOut.str();
std::string section = "Credential" + std::string(":") + accountID + std::string(":") + credentialIndex;
_config.removeSection (section);
}
setConfig (accountID, CONFIG_CREDENTIAL_NUMBER, 0);
}
void
ManagerImpl::removeAccount (const AccountID& accountID)
{
@ -2745,7 +2771,7 @@ ManagerImpl::loadAccountMap()
while (iter != sections.end()) {
// Check if it starts with "Account:" (SIP and IAX pour le moment)
if ( (int) (iter->find ("Account:")) == -1) {
if ( (int) (iter->find ("Account:")) != 0) {
iter++;
continue;
}
@ -2786,7 +2812,7 @@ ManagerImpl::unloadAccountMap()
while (iter != _accountMap.end()) {
_debug ("-> Deleting account %s\n", iter->first.c_str());
_debug ("-> Unloading account %s\n", iter->first.c_str());
delete iter->second;
iter->second = 0;

View File

@ -342,6 +342,13 @@ class ManagerImpl {
*/
void removeAccount(const AccountID& accountID);
/**
* Deletes all credentials defined for an account
* @param accountID The account unique ID
*/
void deleteAllCredential(const AccountID& accountID);
/**
* Get the list of codecs we supports, not ordered
* @return The list of the codecs
@ -897,7 +904,7 @@ class ManagerImpl {
* Initialize audiodriver
*/
bool initAudioDriver(void);
private:
/**

View File

@ -47,7 +47,7 @@ SIPAccount::~SIPAccount()
dynamic_cast<SIPVoIPLink*> (_link)->decrementClients();
/* Delete accounts-related information */
_regc = NULL;
delete _cred;
free(_cred);
_cred = NULL;
}
@ -61,11 +61,59 @@ int SIPAccount::registerVoIPLink()
if (Manager::instance().getConfigString (_accountID, HOSTNAME).length() >= PJ_MAX_HOSTNAME) {
return !SUCCESS;
}
setHostname (Manager::instance().getConfigString (_accountID, HOSTNAME));
setUsername (Manager::instance().getConfigString (_accountID, USERNAME));
setPassword (Manager::instance().getConfigString (_accountID, PASSWORD));
_authenticationUsername = Manager::instance().getConfigString (_accountID, AUTHENTICATION_USERNAME);
_realm = Manager::instance().getConfigString (_accountID, REALM);
int credentialCount = 0;
credentialCount = Manager::instance().getConfigInt (_accountID, CONFIG_CREDENTIAL_NUMBER);
credentialCount += 1;
pjsip_cred_info * cred_info = (pjsip_cred_info *) malloc(sizeof(pjsip_cred_info)*(credentialCount));
if (cred_info == NULL) {
_debug("Failed to set cred_info for account %s\n", _accountID.c_str());
return !SUCCESS;
}
pj_bzero (cred_info, sizeof(pjsip_cred_info)*credentialCount);
if (!_authenticationUsername.empty()) {
cred_info[0].username = pj_str(strdup(_authenticationUsername.c_str()));
} else {
cred_info[0].username = pj_str(strdup(_username.c_str()));
}
cred_info[0].data = pj_str(strdup(_password.c_str()));
cred_info[0].realm = pj_str(strdup(_realm.c_str()));
cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
cred_info[0].scheme = pj_str("digest");
int i;
for (i = 1; i < credentialCount; i++) {
std::string credentialIndex;
std::stringstream streamOut;
streamOut << i - 1;
credentialIndex = streamOut.str();
std::string section = std::string("Credential") + std::string(":") + _accountID + std::string(":") + credentialIndex;
std::string username = Manager::instance().getConfigString(section, USERNAME);
std::string password = Manager::instance().getConfigString(section, PASSWORD);
std::string realm = Manager::instance().getConfigString(section, REALM);
cred_info[i].username = pj_str(strdup(username.c_str()));
cred_info[i].data = pj_str(strdup(password.c_str()));
cred_info[i].realm = pj_str(strdup(realm.c_str()));
cred_info[i].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
cred_info[i].scheme = pj_str("digest");
_debug("Setting credential %d realm = %s passwd = %s username = %s data_type = %d\n", i, realm.c_str(), password.c_str(), username.c_str(), cred_info[i].data_type);
}
_credentialCount = credentialCount;
_cred = cred_info;
_resolveOnce = Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_RESOLVE_ONCE) == "1" ? true : false;
if (Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE).empty()) {
@ -73,7 +121,7 @@ int SIPAccount::registerVoIPLink()
} else {
_registrationExpire = Manager::instance().getConfigString (_accountID, CONFIG_ACCOUNT_REGISTRATION_EXPIRE);
}
/* Start registration */
status = _link->sendRegister (_accountID);

View File

@ -70,10 +70,17 @@ class SIPAccount : public Account
inline void setCredInfo(pjsip_cred_info *cred) {_cred = cred;}
inline pjsip_cred_info *getCredInfo() {return _cred;}
inline void setContact(const std::string &contact) {_contact = contact;}
inline std::string getContact() {return _contact;}
inline std::string& getAuthenticationUsername(void) { return _authenticationUsername; }
inline void setAuthenticationUsername(const std::string& username) { _authenticationUsername = username; }
inline bool isResolveOnce(void) { return _resolveOnce; }
inline std::string& getRegistrationExpire(void) { return _registrationExpire; }
bool fullMatch(const std::string& username, const std::string& hostname);
bool userMatch(const std::string& username);
bool hostnameMatch(const std::string& hostname);
@ -81,13 +88,12 @@ class SIPAccount : public Account
pjsip_regc* getRegistrationInfo( void ) { return _regc; }
void setRegistrationInfo( pjsip_regc *regc ) { _regc = regc; }
inline int getCredentialCount(void) { return _credentialCount; }
/* Registration flag */
bool isRegister() {return _bRegister;}
void setRegister(bool result) {_bRegister = result;}
inline bool isResolveOnce(void) { return _resolveOnce; }
inline std::string& getRegistrationExpire(void) { return _registrationExpire; }
void setRegister(bool result) {_bRegister = result;}
private:
/**
@ -105,14 +111,20 @@ class SIPAccount : public Account
*/
bool _bRegister;
bool _resolveOnce;
/*
* SIP address
*/
std::string _contact;
bool _resolveOnce;
std::string _registrationExpire;
std::string _authenticationUsername;
std::string _realm;
int _credentialCount;
};
#endif

View File

@ -484,26 +484,10 @@ int SIPVoIPLink::sendRegister (AccountID id)
}
pjsip_cred_info *cred = account->getCredInfo();
if (!cred)
cred = new pjsip_cred_info();
pj_bzero (cred, sizeof (pjsip_cred_info));
pj_strdup2 (_pool, &cred->username, username.data());
cred->data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
pj_strdup2 (_pool, &cred->data, password.data());
pj_strdup2 (_pool, &cred->realm, "*");
pj_strdup2 (_pool, &cred->scheme, "digest");
pjsip_regc_set_credentials (regc, 1, cred);
account->setCredInfo (cred);
int credential_count = account->getCredentialCount();
_debug("setting %d credentials\n", credential_count);
pjsip_regc_set_credentials (regc, credential_count, cred);
// Add User-Agent Header
pj_list_init (&hdr_list);

View File

@ -42,7 +42,7 @@ class AudioRtp;
#define RANDOM_SIP_PORT rand() % 64000 + 1024
// To set the verbosity. From 0 (min) to 6 (max)
#define PJ_LOG_LEVEL 0
#define PJ_LOG_LEVEL 0
/**
* @file sipvoiplink.h