2
* Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
3
* Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
4
* Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>
5
* Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com>
6
* Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License as published by
10
* the Free Software Foundation; either version 3 of the License, or
11
* (at your option) any later version.
13
* This program is distributed in the hope that it will be useful,
14
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
* GNU General Public License for more details.
18
* You should have received a copy of the GNU General Public License
19
* along with this program; if not, write to the Free Software
20
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22
* Additional permission under GNU GPL version 3 section 7:
24
* If you modify this program, or any covered work, by linking or
25
* combining it with the OpenSSL project's OpenSSL library (or a
26
* modified version of that library), containing parts covered by the
27
* terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
28
* grants you additional permission to convey the resulting work.
29
* Corresponding Source for a non-source form of such a combination
30
* shall include the source code for the parts of OpenSSL used as well
31
* as that of the covered work.
34
#include <sys/socket.h>
35
#include <sys/ioctl.h>
37
#include <netinet/in.h>
44
#include "mainwindow.h"
45
#include "accountlist.h"
46
#include "audioconf.h"
47
#include "accountconfigdialog.h"
48
#include "zrtpadvanceddialog.h"
49
#include "tlsadvanceddialog.h"
50
#include "dbus/dbus.h"
56
* by storing these variables
57
* in a private structure.
60
static GtkWidget * entryAlias;
61
static GtkWidget * protocolComboBox;
62
static GtkWidget * entryUsername;
63
static GtkWidget * entryRouteSet;
64
static GtkWidget * entryHostname;
65
static GtkWidget * entryPassword;
66
static GtkWidget * entryMailbox;
67
static GtkWidget * entryUseragent;
68
static GtkWidget * entryResolveNameOnlyOnce;
69
static GtkWidget * expireSpinBox;
70
static GtkListStore * credentialStore;
71
static GtkWidget * deleteCredButton;
72
static GtkWidget * treeViewCredential;
73
static GtkWidget * advancedZrtpButton;
74
static GtkWidget * keyExchangeCombo;
75
static GtkWidget * useSipTlsCheckBox;
77
static GtkWidget * localAddressEntry;
78
static GtkWidget * publishedAddressEntry;
79
static GtkWidget * localAddressCombo;
80
static GtkWidget * useStunCheckBox;
81
static GtkWidget * sameAsLocalRadioButton;
82
static GtkWidget * publishedAddrRadioButton;
83
static GtkWidget * publishedPortSpinBox;
84
static GtkWidget * localPortSpinBox;
85
static GtkWidget * publishedAddressLabel;
86
static GtkWidget * publishedPortLabel;
87
static GtkWidget * stunServerLabel;
88
static GtkWidget * stunServerEntry;
89
static GtkWidget * enableTone;
90
static GtkWidget * fileChooser;
92
static GtkWidget * security_tab;
93
static GtkWidget * advanced_tab;
95
static GtkWidget * overrtp;
99
COLUMN_CREDENTIAL_REALM,
100
COLUMN_CREDENTIAL_USERNAME,
101
COLUMN_CREDENTIAL_PASSWORD,
102
COLUMN_CREDENTIAL_DATA,
103
COLUMN_CREDENTIAL_COUNT
107
* The same window is used with different configurations
108
* so we need to reset some data to prevent side-effects
113
protocolComboBox = NULL;
114
entryHostname = NULL;
115
entryUsername = NULL;
116
entryPassword = NULL;
117
entryUseragent = NULL;
122
* Display / Hide the password
124
static void show_password_cb(GtkWidget *widget UNUSED, gpointer data)
126
gtk_entry_set_visibility(GTK_ENTRY(data), !gtk_entry_get_visibility(GTK_ENTRY(data)));
129
/* Signal to protocolComboBox 'changed' */
130
void change_protocol_cb(account_t *currentAccount UNUSED)
132
gchar *protocol = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(protocolComboBox));
134
// Only if tabs are not NULL
135
if (security_tab && advanced_tab) {
136
if (g_strcasecmp(protocol, "IAX") == 0) {
137
gtk_widget_hide(security_tab);
138
gtk_widget_hide(advanced_tab);
140
gtk_widget_show(security_tab);
141
gtk_widget_show(advanced_tab);
149
select_dtmf_type(void)
151
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(overrtp)))
152
DEBUG("Selected DTMF over RTP");
154
DEBUG("Selected DTMF over SIP");
157
static GPtrArray* getNewCredential(void)
161
GPtrArray *credential_array = g_ptr_array_new();
165
for (valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(credentialStore), &iter) ;
167
valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(credentialStore), &iter)) {
172
gtk_tree_model_get(GTK_TREE_MODEL(credentialStore), &iter,
173
COLUMN_CREDENTIAL_REALM, &realm,
174
COLUMN_CREDENTIAL_USERNAME, &username,
175
COLUMN_CREDENTIAL_PASSWORD, &password,
178
DEBUG("Row %d: %s %s %s", row_count++, username, password, realm);
180
GHashTable * new_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
181
g_hash_table_insert(new_table, g_strdup(ACCOUNT_REALM), realm);
182
g_hash_table_insert(new_table, g_strdup(ACCOUNT_USERNAME), username);
183
g_hash_table_insert(new_table, g_strdup(ACCOUNT_PASSWORD), password);
185
g_ptr_array_add(credential_array, new_table);
188
return credential_array;
191
static void update_credential_cb(GtkWidget *widget, gpointer data UNUSED)
195
if (credentialStore && gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(credentialStore), &iter, "0")) {
196
gint column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "column"));
197
gtk_list_store_set(GTK_LIST_STORE(credentialStore), &iter, column,(gchar *) gtk_entry_get_text(GTK_ENTRY(widget)), -1);
201
static GtkWidget* create_basic_tab(account_t *currentAccount)
203
g_assert(currentAccount);
205
// Load from SIP/IAX/Unknown ?
206
gchar *curAccountType = g_hash_table_lookup(currentAccount->properties, ACCOUNT_TYPE);
207
gchar *curAlias = g_hash_table_lookup(currentAccount->properties, ACCOUNT_ALIAS);
208
gchar *curHostname = g_hash_table_lookup(currentAccount->properties, ACCOUNT_HOSTNAME);
215
if (g_strcmp0(curAccountType, "SIP") == 0) {
216
/* get password from credentials list */
217
if (currentAccount->credential_information) {
218
GHashTable * element = g_ptr_array_index(currentAccount->credential_information, 0);
219
curPassword = g_hash_table_lookup(element, ACCOUNT_PASSWORD);
223
curPassword = g_hash_table_lookup(currentAccount->properties, ACCOUNT_PASSWORD);
225
curUsername = g_hash_table_lookup(currentAccount->properties, ACCOUNT_USERNAME);
226
curRouteSet = g_hash_table_lookup(currentAccount->properties, ACCOUNT_ROUTE);
227
curMailbox = g_hash_table_lookup(currentAccount->properties, ACCOUNT_MAILBOX);
228
curMailbox = curMailbox != NULL ? curMailbox : "";
229
curUseragent = g_hash_table_lookup(currentAccount->properties, ACCOUNT_USERAGENT);
231
GtkWidget *frame = gnome_main_section_new(_("Account Parameters"));
232
gtk_widget_show(frame);
234
GtkWidget * table = NULL;
236
if (g_strcmp0(curAccountType, "SIP") == 0)
237
table = gtk_table_new(9, 2, FALSE/* homogeneous */);
238
else if (g_strcmp0(curAccountType, "IAX") == 0)
239
table = gtk_table_new(8, 2, FALSE);
241
ERROR("Unknown account type \"%s\"", curAccountType);
245
gtk_table_set_row_spacings(GTK_TABLE(table), 10);
246
gtk_table_set_col_spacings(GTK_TABLE(table), 10);
247
gtk_widget_show(table);
248
gtk_container_add(GTK_CONTAINER(frame) , table);
250
GtkWidget *label = gtk_label_new_with_mnemonic(_("_Alias"));
252
gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
253
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
254
entryAlias = gtk_entry_new();
255
gtk_label_set_mnemonic_widget(GTK_LABEL(label), entryAlias);
256
gtk_entry_set_text(GTK_ENTRY(entryAlias), curAlias);
257
gtk_table_attach(GTK_TABLE(table), entryAlias, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
260
label = gtk_label_new_with_mnemonic(_("_Protocol"));
261
gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
262
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
263
protocolComboBox = gtk_combo_box_text_new();
264
gtk_label_set_mnemonic_widget(GTK_LABEL(label), protocolComboBox);
265
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(protocolComboBox), "SIP");
267
if (dbus_is_iax2_enabled())
268
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(protocolComboBox), "IAX");
270
if (g_strcmp0(curAccountType, "SIP") == 0)
271
gtk_combo_box_set_active(GTK_COMBO_BOX(protocolComboBox),0);
272
else if (g_strcmp0(curAccountType, "IAX") == 0)
273
gtk_combo_box_set_active(GTK_COMBO_BOX(protocolComboBox),1);
275
DEBUG("Config: Error: Account protocol not valid");
276
/* Should never come here, add debug message. */
277
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(protocolComboBox), _("Unknown"));
278
gtk_combo_box_set_active(GTK_COMBO_BOX(protocolComboBox), 2);
281
gtk_table_attach(GTK_TABLE(table), protocolComboBox, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
283
/* Link signal 'changed' */
284
g_signal_connect(G_OBJECT(GTK_COMBO_BOX(protocolComboBox)), "changed",
285
G_CALLBACK(change_protocol_cb),
289
label = gtk_label_new_with_mnemonic(_("_Host name"));
290
gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
291
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
292
entryHostname = gtk_entry_new();
293
gtk_label_set_mnemonic_widget(GTK_LABEL(label), entryHostname);
294
gtk_entry_set_text(GTK_ENTRY(entryHostname), curHostname);
295
gtk_table_attach(GTK_TABLE(table), entryHostname, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
298
label = gtk_label_new_with_mnemonic(_("_User name"));
299
gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
300
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
301
entryUsername = gtk_entry_new();
302
gtk_entry_set_icon_from_pixbuf(GTK_ENTRY(entryUsername), GTK_ENTRY_ICON_PRIMARY, gdk_pixbuf_new_from_file(ICONS_DIR "/stock_person.svg", NULL));
303
gtk_label_set_mnemonic_widget(GTK_LABEL(label), entryUsername);
304
gtk_entry_set_text(GTK_ENTRY(entryUsername), curUsername);
305
gtk_table_attach(GTK_TABLE(table), entryUsername, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
307
if (g_strcmp0(curAccountType, "SIP") == 0) {
308
g_signal_connect(G_OBJECT(entryUsername), "changed", G_CALLBACK(update_credential_cb), NULL);
309
g_object_set_data(G_OBJECT(entryUsername), "column", GINT_TO_POINTER(COLUMN_CREDENTIAL_USERNAME));
313
label = gtk_label_new_with_mnemonic(_("_Password"));
314
gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row + 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
315
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
316
entryPassword = gtk_entry_new();
317
gtk_entry_set_icon_from_stock(GTK_ENTRY(entryPassword), GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_DIALOG_AUTHENTICATION);
318
gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE);
319
gtk_label_set_mnemonic_widget(GTK_LABEL(label), entryPassword);
320
gtk_entry_set_text(GTK_ENTRY(entryPassword), curPassword);
321
gtk_table_attach(GTK_TABLE(table), entryPassword, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
323
if (g_strcmp0(curAccountType, "SIP") == 0) {
324
g_signal_connect(G_OBJECT(entryPassword), "changed", G_CALLBACK(update_credential_cb), NULL);
325
g_object_set_data(G_OBJECT(entryPassword), "column", GINT_TO_POINTER(COLUMN_CREDENTIAL_PASSWORD));
329
GtkWidget *clearTextCheckbox = gtk_check_button_new_with_mnemonic(_("Show password"));
330
g_signal_connect(clearTextCheckbox, "toggled", G_CALLBACK(show_password_cb), entryPassword);
331
gtk_table_attach(GTK_TABLE(table), clearTextCheckbox, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
334
label = gtk_label_new_with_mnemonic(_("_Proxy"));
335
gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
336
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
337
entryRouteSet = gtk_entry_new();
338
gtk_label_set_mnemonic_widget(GTK_LABEL(label), entryRouteSet);
339
gtk_entry_set_text(GTK_ENTRY(entryRouteSet), curRouteSet);
340
gtk_table_attach(GTK_TABLE(table), entryRouteSet, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
343
label = gtk_label_new_with_mnemonic(_("_Voicemail number"));
344
gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
345
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
346
entryMailbox = gtk_entry_new();
347
gtk_label_set_mnemonic_widget(GTK_LABEL(label), entryMailbox);
348
gtk_entry_set_text(GTK_ENTRY(entryMailbox), curMailbox);
349
gtk_table_attach(GTK_TABLE(table), entryMailbox, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
352
label = gtk_label_new_with_mnemonic(_("_User-agent"));
353
gtk_table_attach(GTK_TABLE(table), label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
354
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
355
entryUseragent = gtk_entry_new();
356
gtk_label_set_mnemonic_widget(GTK_LABEL(label), entryUseragent);
357
gtk_entry_set_text(GTK_ENTRY(entryUseragent), curUseragent);
358
gtk_table_attach(GTK_TABLE(table), entryUseragent, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
360
gtk_widget_show_all(table);
361
gtk_container_set_border_width(GTK_CONTAINER(table), 10);
366
static void fill_treeview_with_credential(account_t * account)
369
gtk_list_store_clear(credentialStore);
371
if (!account->credential_information) {
372
account->credential_information = g_ptr_array_sized_new(1);
373
GHashTable * new_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
374
g_hash_table_insert(new_table, g_strdup(ACCOUNT_REALM), g_strdup("*"));
375
g_hash_table_insert(new_table, g_strdup(ACCOUNT_USERNAME), g_strdup(""));
376
g_hash_table_insert(new_table, g_strdup(ACCOUNT_PASSWORD), g_strdup(""));
377
g_ptr_array_add(account->credential_information, new_table);
380
for (unsigned i = 0; i < account->credential_information->len; i++) {
381
GHashTable * element = g_ptr_array_index(account->credential_information, i);
382
gtk_list_store_append(credentialStore, &iter);
383
gtk_list_store_set(credentialStore, &iter,
384
COLUMN_CREDENTIAL_REALM, g_hash_table_lookup(element, ACCOUNT_REALM),
385
COLUMN_CREDENTIAL_USERNAME, g_hash_table_lookup(element, ACCOUNT_USERNAME),
386
COLUMN_CREDENTIAL_PASSWORD, g_hash_table_lookup(element, ACCOUNT_PASSWORD),
387
COLUMN_CREDENTIAL_DATA, element, -1);
391
static void select_credential_cb(GtkTreeSelection *selection, GtkTreeModel *model)
395
if (gtk_tree_selection_get_selected(selection, NULL, &iter)) {
396
GtkTreePath *path = gtk_tree_model_get_path(model, &iter);
398
if (gtk_tree_path_get_indices(path)[0] == 0)
399
gtk_widget_set_sensitive(deleteCredButton, FALSE);
401
gtk_widget_set_sensitive(deleteCredButton, TRUE);
405
static void add_credential_cb(GtkWidget *button UNUSED, gpointer data)
408
GtkTreeModel *model =(GtkTreeModel *) data;
410
gtk_list_store_append(GTK_LIST_STORE(model), &iter);
411
gtk_list_store_set(GTK_LIST_STORE(model), &iter,
412
COLUMN_CREDENTIAL_REALM, "*",
413
COLUMN_CREDENTIAL_USERNAME, _("Authentication"),
414
COLUMN_CREDENTIAL_PASSWORD, _("Secret"), -1);
417
static void delete_credential_cb(GtkWidget *button UNUSED, gpointer data)
420
GtkTreeView *treeview =(GtkTreeView *) data;
421
GtkTreeModel *model = gtk_tree_view_get_model(treeview);
422
GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
424
if (gtk_tree_selection_get_selected(selection, NULL, &iter)) {
426
path = gtk_tree_model_get_path(model, &iter);
427
gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
429
gtk_tree_path_free(path);
434
static void cell_edited_cb(GtkCellRendererText *renderer, gchar *path_desc, gchar *text, gpointer data)
436
GtkTreeModel *model =(GtkTreeModel *) data;
437
GtkTreePath *path = gtk_tree_path_new_from_string(path_desc);
439
gint column = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(renderer), "column"));
440
DEBUG("path desc in cell_edited_cb: %s\n", text);
442
if ((g_strcasecmp(path_desc, "0") == 0) &&
443
g_strcasecmp(text, gtk_entry_get_text(GTK_ENTRY(entryUsername))) != 0)
444
g_signal_handlers_disconnect_by_func(G_OBJECT(entryUsername), G_CALLBACK(update_credential_cb), NULL);
447
gtk_tree_model_get_iter(model, &iter, path);
448
gtk_list_store_set(GTK_LIST_STORE(model), &iter, column, text, -1);
449
gtk_tree_path_free(path);
452
static void editing_started_cb(GtkCellRenderer *cell UNUSED, GtkCellEditable * editable, const gchar * path, gpointer data UNUSED)
454
DEBUG("Editing started");
455
DEBUG("path desc in editing_started_cb: %s\n", path);
457
// If we are dealing the first row
458
if (g_strcasecmp(path, "0") == 0)
459
gtk_entry_set_text(GTK_ENTRY(editable), gtk_entry_get_text(GTK_ENTRY(entryPassword)));
462
static void show_advanced_zrtp_options_cb(GtkWidget *widget UNUSED, gpointer data)
464
gchar *proto = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(keyExchangeCombo));
466
if (g_strcasecmp(proto, "ZRTP") == 0)
467
show_advanced_zrtp_options((GHashTable *) data);
469
show_advanced_sdes_options((GHashTable *) data);
475
static void show_advanced_tls_options_cb(GtkWidget *widget UNUSED, gpointer data)
477
show_advanced_tls_options((GHashTable *) data);
480
static void key_exchange_changed_cb(GtkWidget *widget UNUSED, gpointer data UNUSED)
482
gchar *active_text = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(keyExchangeCombo));
483
DEBUG("Key exchange changed %s", active_text);
485
gboolean set_sensitive = FALSE;
486
set_sensitive |= g_strcasecmp(active_text, "SDES") == 0;
487
set_sensitive |= g_strcasecmp(active_text, "ZRTP") == 0;
491
gtk_widget_set_sensitive(advancedZrtpButton, TRUE);
493
gtk_widget_set_sensitive(advancedZrtpButton, FALSE);
497
static void use_sip_tls_cb(GtkWidget *widget, gpointer data)
499
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
501
gtk_widget_set_sensitive(data, TRUE);
503
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(useStunCheckBox), FALSE);
504
gtk_widget_set_sensitive(useStunCheckBox, FALSE);
505
gtk_widget_set_sensitive(sameAsLocalRadioButton, TRUE);
506
gtk_widget_set_sensitive(publishedAddrRadioButton, TRUE);
507
gtk_widget_hide(stunServerLabel);
508
gtk_widget_hide(stunServerEntry);
510
if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sameAsLocalRadioButton))) {
511
gtk_widget_show(publishedAddressEntry);
512
gtk_widget_show(publishedPortSpinBox);
513
gtk_widget_show(publishedAddressLabel);
514
gtk_widget_show(publishedPortLabel);
517
gtk_widget_set_sensitive(data, FALSE);
518
gtk_widget_set_sensitive(useStunCheckBox, TRUE);
520
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(useStunCheckBox))) {
521
gtk_widget_set_sensitive(sameAsLocalRadioButton, FALSE);
522
gtk_widget_set_sensitive(publishedAddrRadioButton, FALSE);
523
gtk_widget_show(stunServerLabel);
524
gtk_widget_show(stunServerEntry);
525
gtk_widget_hide(publishedAddressEntry);
526
gtk_widget_hide(publishedPortSpinBox);
527
gtk_widget_hide(publishedAddressLabel);
528
gtk_widget_hide(publishedPortLabel);
530
gtk_widget_set_sensitive(sameAsLocalRadioButton, TRUE);
531
gtk_widget_set_sensitive(publishedAddrRadioButton, TRUE);
532
gtk_widget_hide(stunServerLabel);
533
gtk_widget_hide(stunServerEntry);
539
get_interface_addr_from_name(const gchar * const iface_name)
541
#define UC(b) (((int)b)&0xff)
545
if ((fd = socket(AF_INET, SOCK_DGRAM,0)) < 0)
546
DEBUG("getInterfaceAddrFromName error could not open socket\n");
549
memset(&ifr, 0, sizeof(struct ifreq));
551
strcpy(ifr.ifr_name, iface_name);
552
ifr.ifr_addr.sa_family = AF_INET;
554
if (ioctl(fd, SIOCGIFADDR, &ifr) < 0)
555
DEBUG("getInterfaceAddrFromName use default interface (0.0.0.0)\n");
558
struct sockaddr_in *saddr_in = (struct sockaddr_in *) &ifr.ifr_addr;
559
struct in_addr *addr_in = &(saddr_in->sin_addr);
561
char *tmp_addr = (char *) addr_in;
563
gchar *iface_addr = g_strdup_printf("%d.%d.%d.%d", UC(tmp_addr[0]),
564
UC(tmp_addr[1]), UC(tmp_addr[2]), UC(tmp_addr[3]));
571
static void local_interface_changed_cb(GtkWidget * widget UNUSED, gpointer data UNUSED)
573
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sameAsLocalRadioButton))) {
574
gchar *local_iface_name = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(localAddressCombo));
575
gchar *local_iface_addr = get_interface_addr_from_name(local_iface_name);
577
gtk_entry_set_text(GTK_ENTRY(localAddressEntry), local_iface_addr);
578
gtk_entry_set_text(GTK_ENTRY(publishedAddressEntry), local_iface_addr);
579
g_free(local_iface_addr);
580
g_free(local_iface_name);
584
static void set_published_addr_manually_cb(GtkWidget * widget, gpointer data UNUSED)
586
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
587
DEBUG("Config: Showing manual publishing options");
588
gtk_widget_show(publishedPortLabel);
589
gtk_widget_show(publishedPortSpinBox);
590
gtk_widget_show(publishedAddressLabel);
591
gtk_widget_show(publishedAddressEntry);
593
DEBUG("Config: Hiding manual publishing options");
594
gtk_widget_hide(publishedPortLabel);
595
gtk_widget_hide(publishedPortSpinBox);
596
gtk_widget_hide(publishedAddressLabel);
597
gtk_widget_hide(publishedAddressEntry);
601
static void use_stun_cb(GtkWidget *widget, gpointer data UNUSED)
603
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
604
DEBUG("Config: Showing stun options, hiding Local/Published info");
605
gtk_widget_show(stunServerLabel);
606
gtk_widget_show(stunServerEntry);
607
gtk_widget_set_sensitive(sameAsLocalRadioButton, FALSE);
608
gtk_widget_set_sensitive(publishedAddrRadioButton, FALSE);
610
gtk_widget_hide(publishedAddressLabel);
611
gtk_widget_hide(publishedPortLabel);
612
gtk_widget_hide(publishedAddressEntry);
613
gtk_widget_hide(publishedPortSpinBox);
615
DEBUG("Config: hiding stun options, showing Local/Published info");
616
gtk_widget_hide(stunServerLabel);
617
gtk_widget_hide(stunServerEntry);
618
gtk_widget_set_sensitive(sameAsLocalRadioButton, TRUE);
619
gtk_widget_set_sensitive(publishedAddrRadioButton, TRUE);
621
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(publishedAddrRadioButton))) {
622
gtk_widget_show(publishedAddressLabel);
623
gtk_widget_show(publishedPortLabel);
624
gtk_widget_show(publishedAddressEntry);
625
gtk_widget_show(publishedPortSpinBox);
633
static void same_as_local_cb(GtkWidget * widget, gpointer data UNUSED)
635
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
636
gchar *local_interface = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(localAddressCombo));
637
gchar *local_address = dbus_get_address_from_interface_name(local_interface);
639
gtk_entry_set_text(GTK_ENTRY(publishedAddressEntry), local_address);
641
const gchar * local_port = gtk_entry_get_text(GTK_ENTRY(localPortSpinBox));
642
gtk_spin_button_set_value(GTK_SPIN_BUTTON(publishedPortSpinBox), g_ascii_strtod(local_port, NULL));
643
g_free(local_interface);
649
GtkWidget* create_credential_widget(account_t *a)
652
GtkWidget *frame, *table, *scrolledWindowCredential, *addButton;
653
GtkCellRenderer * renderer;
654
GtkTreeViewColumn * treeViewColumn;
655
GtkTreeSelection * treeSelection;
657
/* Credentials tree view */
658
gnome_main_section_new_with_table(_("Credential"), &frame, &table, 1, 1);
659
gtk_container_set_border_width(GTK_CONTAINER(table), 10);
660
gtk_table_set_row_spacings(GTK_TABLE(table), 10);
662
scrolledWindowCredential = gtk_scrolled_window_new(NULL, NULL);
663
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledWindowCredential), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
664
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledWindowCredential), GTK_SHADOW_IN);
665
gtk_table_attach_defaults(GTK_TABLE(table), scrolledWindowCredential, 0, 1, 0, 1);
667
credentialStore = gtk_list_store_new(COLUMN_CREDENTIAL_COUNT,
668
G_TYPE_STRING, // Realm
669
G_TYPE_STRING, // Username
670
G_TYPE_STRING, // Password
671
G_TYPE_POINTER // Pointer to the Objectc
674
treeViewCredential = gtk_tree_view_new_with_model(GTK_TREE_MODEL(credentialStore));
675
treeSelection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeViewCredential));
676
g_signal_connect(G_OBJECT(treeSelection), "changed", G_CALLBACK(select_credential_cb), credentialStore);
678
renderer = gtk_cell_renderer_text_new();
679
g_object_set(renderer, "editable", TRUE, "editable-set", TRUE, NULL);
680
g_signal_connect(G_OBJECT(renderer), "edited", G_CALLBACK(cell_edited_cb), credentialStore);
681
g_object_set_data(G_OBJECT(renderer), "column", GINT_TO_POINTER(COLUMN_CREDENTIAL_REALM));
682
treeViewColumn = gtk_tree_view_column_new_with_attributes("Realm",
684
"markup", COLUMN_CREDENTIAL_REALM,
686
gtk_tree_view_append_column(GTK_TREE_VIEW(treeViewCredential), treeViewColumn);
688
renderer = gtk_cell_renderer_text_new();
689
g_object_set(renderer, "editable", TRUE, "editable-set", TRUE, NULL);
690
g_signal_connect(G_OBJECT(renderer), "edited", G_CALLBACK(cell_edited_cb), credentialStore);
691
g_object_set_data(G_OBJECT(renderer), "column", GINT_TO_POINTER(COLUMN_CREDENTIAL_USERNAME));
692
treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Authentication name"),
694
"markup", COLUMN_CREDENTIAL_USERNAME,
696
gtk_tree_view_append_column(GTK_TREE_VIEW(treeViewCredential), treeViewColumn);
698
renderer = gtk_cell_renderer_text_new();
699
g_object_set(renderer, "editable", TRUE, "editable-set", TRUE, NULL);
700
g_signal_connect(G_OBJECT(renderer), "edited", G_CALLBACK(cell_edited_cb), credentialStore);
701
g_signal_connect(renderer, "editing-started", G_CALLBACK(editing_started_cb), NULL);
702
g_object_set_data(G_OBJECT(renderer), "column", GINT_TO_POINTER(COLUMN_CREDENTIAL_PASSWORD));
703
treeViewColumn = gtk_tree_view_column_new_with_attributes(_("Password"),
705
"markup", COLUMN_CREDENTIAL_PASSWORD,
707
gtk_tree_view_append_column(GTK_TREE_VIEW(treeViewCredential), treeViewColumn);
709
gtk_container_add(GTK_CONTAINER(scrolledWindowCredential), treeViewCredential);
711
fill_treeview_with_credential(a);
713
/* Credential Buttons */
714
GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
715
gtk_table_attach_defaults(GTK_TABLE(table), hbox, 0, 3, 1, 2);
717
addButton = gtk_button_new_from_stock(GTK_STOCK_ADD);
718
g_signal_connect(addButton, "clicked", G_CALLBACK(add_credential_cb), credentialStore);
719
gtk_box_pack_start(GTK_BOX(hbox), addButton, FALSE, FALSE, 0);
721
deleteCredButton = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
722
g_signal_connect(deleteCredButton, "clicked", G_CALLBACK(delete_credential_cb), treeViewCredential);
723
gtk_box_pack_start(GTK_BOX(hbox), deleteCredButton, FALSE, FALSE, 0);
725
/* Dynamically resize the window to fit the scrolled window */
726
gtk_widget_set_size_request(scrolledWindowCredential, 400, 120);
732
GtkWidget* create_security_widget(account_t *a)
735
GtkWidget *frame, *table, *sipTlsAdvancedButton, *label;
736
gchar *curSRTPEnabled = NULL, *curKeyExchange = NULL, *curTLSEnabled = NULL;
738
// Load from SIP/IAX/Unknown ?
740
curKeyExchange = g_hash_table_lookup(a->properties, ACCOUNT_KEY_EXCHANGE);
742
if (curKeyExchange == NULL)
743
curKeyExchange = "none";
745
curSRTPEnabled = g_hash_table_lookup(a->properties, ACCOUNT_SRTP_ENABLED);
747
if (curSRTPEnabled == NULL)
748
curSRTPEnabled = "false";
750
curTLSEnabled = g_hash_table_lookup(a->properties, TLS_ENABLE);
752
if (curTLSEnabled == NULL)
753
curTLSEnabled = "false";
756
gnome_main_section_new_with_table(_("Security"), &frame, &table, 2, 3);
757
gtk_container_set_border_width(GTK_CONTAINER(table), 10);
758
gtk_table_set_row_spacings(GTK_TABLE(table), 10);
759
gtk_table_set_col_spacings(GTK_TABLE(table), 10);
762
sipTlsAdvancedButton = gtk_button_new_from_stock(GTK_STOCK_EDIT);
763
gtk_table_attach_defaults(GTK_TABLE(table), sipTlsAdvancedButton, 2, 3, 0, 1);
764
gtk_widget_set_sensitive(sipTlsAdvancedButton, FALSE);
765
g_signal_connect(G_OBJECT(sipTlsAdvancedButton), "clicked", G_CALLBACK(show_advanced_tls_options_cb),a->properties);
767
useSipTlsCheckBox = gtk_check_button_new_with_mnemonic(_("Use TLS transport(sips)"));
768
g_signal_connect(useSipTlsCheckBox, "toggled", G_CALLBACK(use_sip_tls_cb), sipTlsAdvancedButton);
769
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(useSipTlsCheckBox),(g_strcmp0(curTLSEnabled, "true") == 0) ? TRUE:FALSE);
770
gtk_table_attach_defaults(GTK_TABLE(table), useSipTlsCheckBox, 0, 2, 0, 1);
772
/* ZRTP subsection */
773
label = gtk_label_new_with_mnemonic(_("SRTP key exchange"));
774
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
775
keyExchangeCombo = gtk_combo_box_text_new();
776
gtk_label_set_mnemonic_widget(GTK_LABEL(label), keyExchangeCombo);
777
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(keyExchangeCombo), "ZRTP");
778
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(keyExchangeCombo), "SDES");
779
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(keyExchangeCombo), _("Disabled"));
781
advancedZrtpButton = gtk_button_new_from_stock(GTK_STOCK_PREFERENCES);
782
g_signal_connect(G_OBJECT(advancedZrtpButton), "clicked", G_CALLBACK(show_advanced_zrtp_options_cb),a->properties);
784
if (g_strcmp0(curSRTPEnabled, "false") == 0) {
785
gtk_combo_box_set_active(GTK_COMBO_BOX(keyExchangeCombo), 2);
786
gtk_widget_set_sensitive(advancedZrtpButton, FALSE);
788
if (g_strcmp0(curKeyExchange, ZRTP) == 0)
789
gtk_combo_box_set_active(GTK_COMBO_BOX(keyExchangeCombo),0);
790
else if (g_strcmp0(curKeyExchange, SDES) == 0)
791
gtk_combo_box_set_active(GTK_COMBO_BOX(keyExchangeCombo),1);
793
gtk_combo_box_set_active(GTK_COMBO_BOX(keyExchangeCombo), 2);
794
gtk_widget_set_sensitive(advancedZrtpButton, FALSE);
798
g_signal_connect(G_OBJECT(GTK_COMBO_BOX(keyExchangeCombo)), "changed", G_CALLBACK(key_exchange_changed_cb), a);
800
gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
801
gtk_table_attach_defaults(GTK_TABLE(table), keyExchangeCombo, 1, 2, 1, 2);
802
gtk_table_attach_defaults(GTK_TABLE(table), advancedZrtpButton, 2, 3, 1, 2);
804
gtk_widget_show_all(table);
810
GtkWidget * create_security_tab(account_t *a)
815
ret = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
816
gtk_container_set_border_width(GTK_CONTAINER(ret), 10);
819
frame = create_credential_widget(a);
820
gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
823
frame = create_security_widget(a);
824
gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0);
826
gtk_widget_show_all(ret);
831
static GtkWidget* create_registration_expire(account_t *a)
834
GtkWidget *table, *frame, *label;
836
gchar *resolve_once=NULL, *account_expire=NULL;
839
resolve_once = g_hash_table_lookup(a->properties, ACCOUNT_RESOLVE_ONCE);
840
account_expire = g_hash_table_lookup(a->properties, ACCOUNT_REGISTRATION_EXPIRE);
843
gnome_main_section_new_with_table(_("Registration"), &frame, &table, 2, 3);
844
gtk_container_set_border_width(GTK_CONTAINER(table), 10);
845
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
847
label = gtk_label_new_with_mnemonic(_("Registration expire"));
848
gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
849
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
850
expireSpinBox = gtk_spin_button_new_with_range(1, 65535, 1);
851
gtk_label_set_mnemonic_widget(GTK_LABEL(label), expireSpinBox);
852
gtk_spin_button_set_value(GTK_SPIN_BUTTON(expireSpinBox), g_ascii_strtod(account_expire, NULL));
853
gtk_table_attach_defaults(GTK_TABLE(table), expireSpinBox, 1, 2, 0, 1);
856
entryResolveNameOnlyOnce = gtk_check_button_new_with_mnemonic(_("_Comply with RFC 3263"));
857
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(entryResolveNameOnlyOnce),
858
g_strcasecmp(resolve_once,"false") == 0 ? TRUE: FALSE);
859
gtk_table_attach_defaults(GTK_TABLE(table), entryResolveNameOnlyOnce, 0, 2, 1, 2);
860
gtk_widget_set_sensitive(entryResolveNameOnlyOnce , TRUE);
865
GtkWidget* create_network(account_t *a)
867
GtkWidget *table, *frame, *label;
868
gchar *local_interface = NULL;
869
gchar *local_port = NULL;
872
local_interface = g_hash_table_lookup(a->properties, LOCAL_INTERFACE);
873
local_port = g_hash_table_lookup(a->properties, LOCAL_PORT);
876
gnome_main_section_new_with_table(_("Network Interface"), &frame, &table, 2, 3);
877
gtk_container_set_border_width(GTK_CONTAINER(table), 10);
878
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
881
* Retreive the list of IP interface from the
882
* the daemon and build the combo box.
884
localAddressCombo = gtk_combo_box_text_new();
887
label = gtk_label_new_with_mnemonic(_("Local address"));
888
gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
889
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
891
gchar **iface_list = dbus_get_all_ip_interface_by_name();
894
for (gchar **iface = iface_list; iface && *iface; iface++, idx++) {
896
gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(localAddressCombo), NULL, *iface);
897
if (g_strcmp0(*iface, local_interface) == 0)
898
gtk_combo_box_set_active(GTK_COMBO_BOX(localAddressCombo), idx);
900
if (!local_interface)
901
gtk_combo_box_set_active(GTK_COMBO_BOX(localAddressCombo), 0);
904
gtk_label_set_mnemonic_widget(GTK_LABEL(label), localAddressCombo);
905
gtk_table_attach(GTK_TABLE(table), localAddressCombo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
907
// Fill the text entry with the ip address of local interface selected
908
localAddressEntry = gtk_entry_new();
909
gchar *local_iface_name = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(localAddressCombo));
910
gchar *local_iface_addr = get_interface_addr_from_name(local_iface_name);
911
g_free(local_iface_name);
912
gtk_entry_set_text(GTK_ENTRY(localAddressEntry), local_iface_addr);
913
g_free(local_iface_addr);
914
gtk_widget_set_sensitive(localAddressEntry, FALSE);
915
gtk_table_attach(GTK_TABLE(table), localAddressEntry, 2, 3, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
918
label = gtk_label_new_with_mnemonic(_("Local port"));
919
gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
920
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
921
localPortSpinBox = gtk_spin_button_new_with_range(1, 65535, 1);
922
gtk_label_set_mnemonic_widget(GTK_LABEL(label), localPortSpinBox);
923
gtk_spin_button_set_value(GTK_SPIN_BUTTON(localPortSpinBox), g_ascii_strtod(local_port, NULL));
925
gtk_table_attach_defaults(GTK_TABLE(table), localPortSpinBox, 1, 2, 1, 2);
930
GtkWidget* create_published_address(account_t *a)
933
GtkWidget *table, *frame;
934
gchar *use_tls =NULL;
935
gchar *published_address = NULL;
936
gchar *published_port = NULL;
937
gchar *stun_enable = NULL;
938
gchar *stun_server = NULL;
939
gchar *published_sameas_local = NULL;
941
// Get the user configuration
944
use_tls = g_hash_table_lookup(a->properties, TLS_ENABLE);
945
published_sameas_local = g_hash_table_lookup(a->properties, PUBLISHED_SAMEAS_LOCAL);
947
if (g_strcasecmp(published_sameas_local, "true") == 0) {
948
published_address = dbus_get_address_from_interface_name(g_hash_table_lookup(a->properties, LOCAL_INTERFACE));
949
published_port = g_hash_table_lookup(a->properties, LOCAL_PORT);
951
published_address = g_hash_table_lookup(a->properties, PUBLISHED_ADDRESS);
952
published_port = g_hash_table_lookup(a->properties, PUBLISHED_PORT);
955
stun_enable = g_hash_table_lookup(a->properties, ACCOUNT_SIP_STUN_ENABLED);
956
stun_server = g_hash_table_lookup(a->properties, ACCOUNT_SIP_STUN_SERVER);
957
published_sameas_local = g_hash_table_lookup(a->properties, PUBLISHED_SAMEAS_LOCAL);
960
gnome_main_section_new_with_table(_("Published address"), &frame, &table, 2, 3);
961
gtk_container_set_border_width(GTK_CONTAINER(table), 10);
962
gtk_table_set_row_spacings(GTK_TABLE(table), 5);
964
useStunCheckBox = gtk_check_button_new_with_mnemonic(_("Using STUN"));
965
gtk_table_attach_defaults(GTK_TABLE(table), useStunCheckBox, 0, 1, 0, 1);
966
g_signal_connect(useStunCheckBox, "toggled", G_CALLBACK(use_stun_cb), a);
967
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(useStunCheckBox),
968
g_strcasecmp(stun_enable, "true") == 0 ? TRUE: FALSE);
969
gtk_widget_set_sensitive(useStunCheckBox,
970
g_strcasecmp(use_tls, "true") == 0 ? FALSE: TRUE);
972
stunServerLabel = gtk_label_new_with_mnemonic(_("STUN server URL"));
973
gtk_table_attach_defaults(GTK_TABLE(table), stunServerLabel, 0, 1, 1, 2);
974
gtk_misc_set_alignment(GTK_MISC(stunServerLabel), 0, 0.5);
975
stunServerEntry = gtk_entry_new();
976
gtk_label_set_mnemonic_widget(GTK_LABEL(stunServerLabel), stunServerEntry);
977
gtk_entry_set_text(GTK_ENTRY(stunServerEntry), stun_server);
978
gtk_table_attach_defaults(GTK_TABLE(table), stunServerEntry, 1, 2, 1, 2);
980
sameAsLocalRadioButton = gtk_radio_button_new_with_mnemonic_from_widget(NULL, _("Same as local parameters"));
981
gtk_table_attach_defaults(GTK_TABLE(table), sameAsLocalRadioButton, 0, 2, 3, 4);
983
publishedAddrRadioButton = gtk_radio_button_new_with_mnemonic_from_widget(GTK_RADIO_BUTTON(sameAsLocalRadioButton), _("Set published address and port:"));
984
gtk_table_attach_defaults(GTK_TABLE(table), publishedAddrRadioButton, 0, 2, 4, 5);
986
if (g_strcasecmp(published_sameas_local, "true") == 0) {
987
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sameAsLocalRadioButton), TRUE);
988
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(publishedAddrRadioButton), FALSE);
990
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sameAsLocalRadioButton), FALSE);
991
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(publishedAddrRadioButton), TRUE);
994
publishedAddressLabel = gtk_label_new_with_mnemonic(_("Published address"));
995
gtk_table_attach_defaults(GTK_TABLE(table), publishedAddressLabel, 0, 1, 5, 6);
996
gtk_misc_set_alignment(GTK_MISC(publishedAddressLabel), 0, 0.5);
997
publishedAddressEntry = gtk_entry_new();
998
gtk_label_set_mnemonic_widget(GTK_LABEL(publishedAddressLabel), publishedAddressEntry);
1000
gtk_entry_set_text(GTK_ENTRY(publishedAddressEntry), published_address);
1001
gtk_table_attach_defaults(GTK_TABLE(table), publishedAddressEntry, 1, 2, 5, 6);
1003
publishedPortLabel = gtk_label_new_with_mnemonic(_("Published port"));
1004
gtk_table_attach_defaults(GTK_TABLE(table), publishedPortLabel, 0, 1, 6, 7);
1005
gtk_misc_set_alignment(GTK_MISC(publishedPortLabel), 0, 0.5);
1006
publishedPortSpinBox = gtk_spin_button_new_with_range(1, 65535, 1);
1007
gtk_label_set_mnemonic_widget(GTK_LABEL(publishedPortLabel), publishedPortSpinBox);
1008
gtk_spin_button_set_value(GTK_SPIN_BUTTON(publishedPortSpinBox), g_ascii_strtod(published_port, NULL));
1010
gtk_table_attach_defaults(GTK_TABLE(table), publishedPortSpinBox, 1, 2, 6, 7);
1012
// This will trigger a signal, and the above two
1013
// widgets need to be instanciated before that.
1014
g_signal_connect(localAddressCombo, "changed", G_CALLBACK(local_interface_changed_cb), localAddressCombo);
1017
g_signal_connect(sameAsLocalRadioButton, "toggled", G_CALLBACK(same_as_local_cb), sameAsLocalRadioButton);
1018
g_signal_connect(publishedAddrRadioButton, "toggled", G_CALLBACK(set_published_addr_manually_cb), publishedAddrRadioButton);
1020
set_published_addr_manually_cb(publishedAddrRadioButton, NULL);
1025
GtkWidget* create_advanced_tab(account_t *a)
1028
// Build the advanced tab, to appear on the account configuration panel
1029
DEBUG("Config: Build advanced tab");
1031
GtkWidget *vbox, *frame;
1033
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
1035
gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
1037
frame = create_registration_expire(a);
1038
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
1040
frame = create_network(a);
1041
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
1043
frame = create_published_address(a);
1044
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
1046
gtk_widget_show_all(vbox);
1048
use_stun_cb(useStunCheckBox, NULL);
1050
set_published_addr_manually_cb(publishedAddrRadioButton, NULL);
1055
void ringtone_enabled(GtkWidget *widget UNUSED, gpointer data, const gchar *accountID UNUSED)
1057
/* toggle sensitivity */
1058
gtk_widget_set_sensitive(data, !gtk_widget_is_sensitive(data));
1062
static GtkWidget* create_audiocodecs_configuration(account_t *currentAccount)
1064
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
1065
gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
1067
GtkWidget *box = audiocodecs_box(currentAccount);
1069
// Box for the audiocodecs
1070
GtkWidget *audiocodecs = gnome_main_section_new(_("Audio"));
1071
gtk_box_pack_start(GTK_BOX(vbox), audiocodecs, FALSE, FALSE, 0);
1072
gtk_widget_set_size_request(audiocodecs, -1, 200);
1073
gtk_widget_show(audiocodecs);
1074
gtk_container_add(GTK_CONTAINER(audiocodecs), box);
1076
// Add DTMF type selection for SIP account only
1077
gpointer p = g_hash_table_lookup(currentAccount->properties, ACCOUNT_TYPE);
1081
if (g_strcmp0(p, "SIP") == 0) {
1084
gnome_main_section_new_with_table(_("DTMF"), &dtmf, &table, 1, 2);
1085
gtk_box_pack_start(GTK_BOX(vbox), dtmf, FALSE, FALSE, 0);
1086
gtk_widget_show(dtmf);
1088
const gchar * const currentDtmfType = g_hash_table_lookup(currentAccount->properties, ACCOUNT_DTMF_TYPE);
1090
gboolean dtmf_are_rtp = TRUE;
1092
if (g_strcasecmp(currentDtmfType, OVERRTP) != 0)
1093
dtmf_are_rtp = FALSE;
1095
overrtp = gtk_radio_button_new_with_label(NULL, _("RTP"));
1096
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(overrtp), dtmf_are_rtp);
1097
gtk_table_attach(GTK_TABLE(table), overrtp, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
1099
GtkWidget *sipinfo = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(overrtp), _("SIP"));
1100
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(sipinfo), !dtmf_are_rtp);
1101
g_signal_connect(G_OBJECT(sipinfo), "clicked", G_CALLBACK(select_dtmf_type), NULL);
1102
gtk_table_attach(GTK_TABLE(table), sipinfo, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
1105
// Box for the ringtones
1107
gnome_main_section_new_with_table(_("Ringtones"), &frame, &table, 1, 2);
1108
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
1110
fileChooser = gtk_file_chooser_button_new(_("Choose a ringtone"), GTK_FILE_CHOOSER_ACTION_OPEN);
1112
p = g_hash_table_lookup(currentAccount->properties, CONFIG_RINGTONE_ENABLED);
1113
gboolean ringtoneEnabled =(g_strcmp0(p, "true") == 0) ? TRUE : FALSE;
1115
enableTone = gtk_check_button_new_with_mnemonic(_("_Enable ringtones"));
1116
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(enableTone), ringtoneEnabled);
1117
g_signal_connect(G_OBJECT(enableTone) , "clicked" , G_CALLBACK(ringtone_enabled), fileChooser);
1118
gtk_table_attach(GTK_TABLE(table), enableTone, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
1120
// file chooser button
1121
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fileChooser) , g_get_home_dir());
1122
p = g_hash_table_lookup(currentAccount->properties, CONFIG_RINGTONE_PATH);
1123
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(fileChooser) , p);
1124
gtk_widget_set_sensitive(fileChooser, ringtoneEnabled);
1126
GtkFileFilter *filter = gtk_file_filter_new();
1127
gtk_file_filter_set_name(filter, _("Audio Files"));
1128
gtk_file_filter_add_pattern(filter, "*.wav");
1129
gtk_file_filter_add_pattern(filter, "*.ul");
1130
gtk_file_filter_add_pattern(filter, "*.au");
1132
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(fileChooser) , filter);
1133
gtk_table_attach(GTK_TABLE(table), fileChooser, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
1135
gtk_widget_show_all(vbox);
1140
GtkWidget* create_direct_ip_calls_tab(account_t *a)
1142
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
1143
gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
1145
gchar *description = g_markup_printf_escaped(_("This profile is used when "
1146
"you want to reach a remote peer simply by typing a sip URI "
1147
"such as <b>sip:remotepeer</b>. The settings you define here "
1148
"will also be used if no account can be matched to an incoming"
1149
" or outgoing call."));
1150
GtkWidget *label = gtk_label_new(NULL);
1151
gtk_label_set_markup(GTK_LABEL(label), description);
1152
gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
1153
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
1155
gtk_widget_set_size_request(label, 350, -1);
1156
gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
1158
GtkWidget *frame = create_network(a);
1159
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
1161
frame = create_security_widget(a);
1162
gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
1164
gtk_widget_show_all(vbox);
1168
void show_account_window(account_t * currentAccount)
1173
if (currentAccount == NULL) {
1174
DEBUG("Config: Fetching default values for new account");
1175
currentAccount = g_new0(account_t, 1);
1176
currentAccount->properties = dbus_get_account_details(NULL);
1177
currentAccount->accountID = g_strdup("new"); //FIXME : replace with NULL for new accounts
1178
currentAccount->credential_information = NULL;
1179
sflphone_fill_codec_list_per_account(currentAccount);
1182
GtkWidget *dialog = gtk_dialog_new_with_buttons(_("Account settings"),
1183
GTK_WINDOW(get_main_window()),
1184
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
1186
GTK_RESPONSE_CANCEL,
1188
GTK_RESPONSE_ACCEPT,
1191
gtk_container_set_border_width(GTK_CONTAINER(dialog), 0);
1193
GtkWidget *notebook = gtk_notebook_new();
1194
gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), notebook, TRUE, TRUE, 0);
1195
gtk_container_set_border_width(GTK_CONTAINER(notebook), 10);
1196
gtk_widget_show(notebook);
1198
// We do not need the global settings for the IP2IP account
1199
if (g_strcasecmp(currentAccount->accountID, IP2IP) != 0) {
1200
/* General Settings */
1201
GtkWidget *basic_tab = create_basic_tab(currentAccount);
1202
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), basic_tab, gtk_label_new(_("Basic")));
1203
gtk_notebook_page_num(GTK_NOTEBOOK(notebook), basic_tab);
1207
GtkWidget *audiocodecs_tab = create_audiocodecs_configuration(currentAccount);
1208
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), audiocodecs_tab, gtk_label_new(_("Audio")));
1209
gtk_notebook_page_num(GTK_NOTEBOOK(notebook), audiocodecs_tab);
1211
// Get current protocol for this account protocol
1212
gchar *currentProtocol;
1214
if (protocolComboBox)
1215
currentProtocol = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(protocolComboBox));
1217
currentProtocol = g_strdup("SIP");
1219
// Do not need advanced or security one for the IP2IP account
1220
if (g_strcasecmp(currentAccount->accountID, IP2IP) != 0) {
1223
advanced_tab = create_advanced_tab(currentAccount);
1224
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), advanced_tab, gtk_label_new(_("Advanced")));
1225
gtk_notebook_page_num(GTK_NOTEBOOK(notebook), advanced_tab);
1228
security_tab = create_security_tab(currentAccount);
1229
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), security_tab, gtk_label_new(_("Security")));
1230
gtk_notebook_page_num(GTK_NOTEBOOK(notebook),security_tab);
1233
/* Custom tab for the IP to IP profile */
1234
GtkWidget *ip_tab = create_direct_ip_calls_tab(currentAccount);
1235
gtk_notebook_prepend_page(GTK_NOTEBOOK(notebook), ip_tab, gtk_label_new(_("Network")));
1236
gtk_notebook_page_num(GTK_NOTEBOOK(notebook), ip_tab);
1239
// Emit signal to hide advanced and security tabs in case of IAX
1240
if (protocolComboBox)
1241
g_signal_emit_by_name(protocolComboBox, "changed", NULL);
1243
gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook) , 0);
1248
gint response = gtk_dialog_run(GTK_DIALOG(dialog));
1250
// Update protocol in case it changed
1253
if (protocolComboBox)
1254
proto = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(protocolComboBox));
1256
proto = g_strdup("SIP");
1258
// If cancel button is pressed
1259
if (response == GTK_RESPONSE_CANCEL) {
1260
gtk_widget_destroy(dialog);
1265
// If accept button is
1266
if (g_strcasecmp(currentAccount->accountID, IP2IP) != 0) {
1268
g_hash_table_replace(currentAccount->properties,
1269
g_strdup(ACCOUNT_ALIAS),
1270
g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(entryAlias))));
1271
g_hash_table_replace(currentAccount->properties,
1272
g_strdup(ACCOUNT_TYPE),
1274
g_hash_table_replace(currentAccount->properties,
1275
g_strdup(ACCOUNT_HOSTNAME),
1276
g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(entryHostname))));
1277
g_hash_table_replace(currentAccount->properties,
1278
g_strdup(ACCOUNT_USERNAME),
1279
g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(entryUsername))));
1280
g_hash_table_replace(currentAccount->properties,
1281
g_strdup(ACCOUNT_PASSWORD),
1282
g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(entryPassword))));
1283
g_hash_table_replace(currentAccount->properties,
1284
g_strdup(ACCOUNT_MAILBOX),
1285
g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(entryMailbox))));
1288
if (g_strcmp0(proto, "SIP") == 0) {
1289
if (g_strcasecmp(currentAccount->accountID, IP2IP) != 0) {
1291
g_hash_table_replace(currentAccount->properties,
1292
g_strdup(ACCOUNT_RESOLVE_ONCE),
1293
g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(entryResolveNameOnlyOnce)) ? "false": "true"));
1295
g_hash_table_replace(currentAccount->properties,
1296
g_strdup(ACCOUNT_REGISTRATION_EXPIRE),
1297
g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(expireSpinBox))));
1300
// TODO: uncomment this code and implement route
1301
g_hash_table_replace(currentAccount->properties,
1302
g_strdup(ACCOUNT_ROUTE),
1303
g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(entryRouteSet))));
1306
g_hash_table_replace(currentAccount->properties,
1307
g_strdup(ACCOUNT_USERAGENT),
1308
g_strdup(gtk_entry_get_text(GTK_ENTRY(entryUseragent))));
1310
g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_SIP_STUN_ENABLED),
1311
g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(useStunCheckBox)) ? "true":"false"));
1313
g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_SIP_STUN_SERVER),
1314
g_strdup(gtk_entry_get_text(GTK_ENTRY(stunServerEntry))));
1316
g_hash_table_replace(currentAccount->properties, g_strdup(PUBLISHED_SAMEAS_LOCAL), g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sameAsLocalRadioButton)) ? "true":"false"));
1318
if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(sameAsLocalRadioButton))) {
1319
g_hash_table_replace(currentAccount->properties,
1320
g_strdup(PUBLISHED_PORT),
1321
g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(publishedPortSpinBox))));
1323
g_hash_table_replace(currentAccount->properties,
1324
g_strdup(PUBLISHED_ADDRESS),
1325
g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(publishedAddressEntry))));
1327
g_hash_table_replace(currentAccount->properties,
1328
g_strdup(PUBLISHED_PORT),
1329
g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(localPortSpinBox))));
1330
gchar *local_interface = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(localAddressCombo));
1332
gchar *published_address = dbus_get_address_from_interface_name(local_interface);
1333
g_free(local_interface);
1335
g_hash_table_replace(currentAccount->properties,
1336
g_strdup(PUBLISHED_ADDRESS),
1341
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(overrtp))) {
1342
DEBUG("Config: Set dtmf over rtp");
1343
g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_DTMF_TYPE), g_strdup(OVERRTP));
1345
DEBUG("Config: Set dtmf over sip");
1346
g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_DTMF_TYPE), g_strdup(SIPINFO));
1349
gchar* keyExchange = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(keyExchangeCombo));
1351
if (g_strcasecmp(keyExchange, "ZRTP") == 0) {
1352
g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_SRTP_ENABLED), g_strdup("true"));
1353
g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_KEY_EXCHANGE), g_strdup(ZRTP));
1354
} else if (g_strcasecmp(keyExchange, "SDES") == 0) {
1355
g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_SRTP_ENABLED), g_strdup("true"));
1356
g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_KEY_EXCHANGE), g_strdup(SDES));
1358
g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_SRTP_ENABLED), g_strdup("false"));
1359
g_hash_table_replace(currentAccount->properties, g_strdup(ACCOUNT_KEY_EXCHANGE), g_strdup(""));
1362
g_free(keyExchange);
1364
g_hash_table_replace(currentAccount->properties, g_strdup(TLS_ENABLE),
1365
g_strdup(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(useSipTlsCheckBox)) ? "true":"false"));
1367
gboolean toneEnabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(enableTone));
1368
g_hash_table_replace(currentAccount->properties,
1369
g_strdup(CONFIG_RINGTONE_ENABLED),
1370
g_strdup(toneEnabled ? "true" : "false"));
1372
g_hash_table_replace(currentAccount->properties,
1373
g_strdup(CONFIG_RINGTONE_PATH),
1374
g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(fileChooser))));
1376
g_hash_table_replace(currentAccount->properties,
1377
g_strdup(LOCAL_INTERFACE),
1378
gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(localAddressCombo)));
1380
g_hash_table_replace(currentAccount->properties,
1381
g_strdup(LOCAL_PORT),
1382
g_strdup(gtk_entry_get_text(GTK_ENTRY(localPortSpinBox))));
1386
/** @todo Verify if it's the best condition to check */
1387
if (g_strcasecmp(currentAccount->accountID, "new") == 0)
1388
dbus_add_account(currentAccount);
1390
dbus_set_account_details(currentAccount);
1392
if (g_strcmp0(currentProtocol, "SIP") == 0) {
1393
/* Set new credentials if any */
1394
DEBUG("Config: Setting credentials");
1396
if (g_strcasecmp(currentAccount->accountID, IP2IP) != 0) {
1397
DEBUG("Config: Get new credentials");
1398
currentAccount->credential_information = getNewCredential();
1400
if (currentAccount->credential_information)
1401
dbus_set_credentials(currentAccount);
1405
// propagate changes to the daemon
1406
codec_list_update_to_daemon(currentAccount);
1408
gtk_widget_destroy(dialog);
1409
g_free(currentProtocol);