diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c
index c8943cc7a..0310ec633 100644
--- a/coreapi/linphonecall.c
+++ b/coreapi/linphonecall.c
@@ -108,6 +108,7 @@ void propagate_encryption_changed(LinphoneCall *call){
LinphoneCore *lc=call->core;
if (!linphone_call_are_all_streams_encrypted(call)) {
ms_message("Some streams are not encrypted");
+ call->current_params.media_encryption=LinphoneMediaEncryptionNone;
if (lc->vtable.call_encryption_changed)
lc->vtable.call_encryption_changed(call->core, call, FALSE, call->auth_token);
} else {
@@ -168,6 +169,21 @@ static void linphone_call_audiostream_auth_token_ready(void *data, const char* a
ms_message("Authentication token is %s (%s)", auth_token, verified?"verified":"unverified");
}
+void linphone_call_set_authentication_token_verified(LinphoneCall *call, bool_t verified){
+ if (call->audiostream==NULL){
+ ms_error("linphone_call_set_authentication_token_verified(): No audio stream");
+ }
+ if (call->audiostream->ortpZrtpContext==NULL){
+ ms_error("linphone_call_set_authentication_token_verified(): No zrtp context.");
+ }
+ if (!call->auth_token_verified && verified){
+ ortp_zrtp_sas_verified(call->audiostream->ortpZrtpContext);
+ }else if (call->auth_token_verified && !verified){
+ ortp_zrtp_sas_reset_verified(call->audiostream->ortpZrtpContext);
+ }
+ call->auth_token_verified=verified;
+ propagate_encryption_changed(call);
+}
static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandwidth_limit){
MSList *l=NULL;
diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h
index e52a0b5f9..047e6792b 100644
--- a/coreapi/linphonecore.h
+++ b/coreapi/linphonecore.h
@@ -269,6 +269,7 @@ float linphone_call_get_current_quality(LinphoneCall *call);
float linphone_call_get_average_quality(LinphoneCall *call);
const char* linphone_call_get_authentication_token(LinphoneCall *call);
bool_t linphone_call_get_authentication_token_verified(LinphoneCall *call);
+void linphone_call_set_authentication_token_verified(LinphoneCall *call, bool_t verified);
void linphone_call_send_vfu_request(LinphoneCall *call);
void *linphone_call_get_user_pointer(LinphoneCall *call);
void linphone_call_set_user_pointer(LinphoneCall *call, void *user_pointer);
diff --git a/gtk/incall_view.c b/gtk/incall_view.c
index af216f208..1dc9d47e4 100644
--- a/gtk/incall_view.c
+++ b/gtk/incall_view.c
@@ -426,14 +426,26 @@ void linphone_gtk_in_call_view_enable_audio_view(LinphoneCall *call, gboolean va
}
}
-static void linphone_gtk_in_call_view_show_encryption(LinphoneCall *call){
+void linphone_gtk_auth_token_verified_clicked(GtkButton *button){
+ LinphoneCall *call=linphone_gtk_get_currently_displayed_call(NULL);
+ if (call){
+ linphone_call_set_authentication_token_verified(call,!linphone_call_get_authentication_token_verified(call));
+ }
+}
+
+void linphone_gtk_in_call_view_show_encryption(LinphoneCall *call){
GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call);
GtkWidget *encryption_box=linphone_gtk_get_widget(callview,"encryption_box");
GtkWidget *label=linphone_gtk_get_widget(callview,"encryption_label");
+ GtkWidget *status_icon=linphone_gtk_get_widget(callview,"encryption_status_icon");
+ GtkWidget *verify_button=linphone_gtk_get_widget(callview,"encryption_verify_button");
LinphoneMediaEncryption me=linphone_call_params_get_media_encryption(linphone_call_get_current_params(call));
+ bool_t verified=linphone_call_get_authentication_token_verified(call);
switch(me){
case LinphoneMediaEncryptionSRTP:
gtk_label_set_markup(GTK_LABEL(label),_("Secured by SRTP"));
+ gtk_widget_hide(status_icon);
+ gtk_widget_hide(verify_button);
gtk_widget_show_all(encryption_box);
break;
case LinphoneMediaEncryptionZRTP:
@@ -441,6 +453,10 @@ static void linphone_gtk_in_call_view_show_encryption(LinphoneCall *call){
gchar *text=g_strdup_printf(_("Secured by ZRTP - [auth token: %s]"),linphone_call_get_authentication_token(call));
gtk_label_set_markup(GTK_LABEL(label),text);
g_free(text);
+ gtk_image_set_from_stock(GTK_IMAGE(status_icon),
+ verified ? GTK_STOCK_APPLY : GTK_STOCK_DIALOG_WARNING,GTK_ICON_SIZE_MENU);
+ gtk_button_set_label(GTK_BUTTON(verify_button),
+ verified ? _("Set unverified") : _("Set verified"));
gtk_widget_show_all(encryption_box);
}
break;
diff --git a/gtk/linphone.h b/gtk/linphone.h
index 63564c72f..57b562038 100644
--- a/gtk/linphone.h
+++ b/gtk/linphone.h
@@ -112,6 +112,7 @@ void linphone_gtk_enable_conference_button(LinphoneCore *lc, gboolean value);
void linphone_gtk_set_in_conference(LinphoneCall *call);
void linphone_gtk_unset_from_conference(LinphoneCall *call);
void linphone_gtk_terminate_conference_participant(LinphoneCall *call);
+void linphone_gtk_in_call_view_show_encryption(LinphoneCall *call);
typedef float (*get_volume_t)(void *data);
void linphone_gtk_init_audio_meter(GtkWidget *w, get_volume_t get_volume, void *data);
diff --git a/gtk/main.c b/gtk/main.c
index 1eec9173a..e24fb24cc 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -61,6 +61,7 @@ static void linphone_gtk_display_warning(LinphoneCore *lc, const char *warning);
static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const char *url);
static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl);
static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cs, const char *msg);
+static void linphone_gtk_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t enabled, const char *token);
static gboolean linphone_gtk_auto_answer(LinphoneCall *call);
static void linphone_gtk_status_icon_set_blinking(gboolean val);
@@ -125,34 +126,35 @@ static GOptionEntry linphone_options[]={
#ifndef WIN32
#define CONFIG_FILE ".linphonerc"
+#define SECRETS_FILE ".linphone-zidcache"
#else
#define CONFIG_FILE "linphonerc"
+#define SECRETS_FILE "linphone-zidcache"
#endif
-
-static char _config_file[1024];
-
-
-const char *linphone_gtk_get_config_file(){
+char *linphone_gtk_get_config_file(const char *filename){
+ const int path_max=1024;
+ char *config_file=g_malloc0(path_max);
+ if (filename==NULL) filename=CONFIG_FILE;
/*try accessing a local file first if exists*/
if (access(CONFIG_FILE,F_OK)==0){
- snprintf(_config_file,sizeof(_config_file),"%s",CONFIG_FILE);
+ snprintf(config_file,path_max,"%s",CONFIG_FILE);
}else{
#ifdef WIN32
const char *appdata=getenv("APPDATA");
if (appdata){
- snprintf(_config_file,sizeof(_config_file),"%s\\%s",appdata,LINPHONE_CONFIG_DIR);
- CreateDirectory(_config_file,NULL);
- snprintf(_config_file,sizeof(_config_file),"%s\\%s",appdata,LINPHONE_CONFIG_DIR "\\" CONFIG_FILE);
+ snprintf(config_file,path_max,"%s\\%s",appdata,LINPHONE_CONFIG_DIR);
+ CreateDirectory(config_file,NULL);
+ snprintf(config_file,path_max,"%s\\%s\\%s",appdata,LINPHONE_CONFIG_DIR,filename);
}
#else
const char *home=getenv("HOME");
if (home==NULL) home=".";
- snprintf(_config_file,sizeof(_config_file),"%s/%s",home,CONFIG_FILE);
+ snprintf(config_file,path_max,"%s/%s",home,filename);
#endif
}
- return _config_file;
+ return config_file;
}
@@ -206,6 +208,7 @@ static const char *linphone_gtk_get_factory_config_file(){
static void linphone_gtk_init_liblinphone(const char *config_file,
const char *factory_config_file) {
LinphoneCoreVTable vtable={0};
+ gchar *secrets_file=linphone_gtk_get_config_file(SECRETS_FILE);
vtable.call_state_changed=linphone_gtk_call_state_changed;
vtable.registration_state_changed=linphone_gtk_registration_state_changed;
@@ -220,10 +223,13 @@ static void linphone_gtk_init_liblinphone(const char *config_file,
vtable.text_received=linphone_gtk_text_received;
vtable.refer_received=linphone_gtk_refer_received;
vtable.buddy_info_updated=linphone_gtk_buddy_info_updated;
+ vtable.call_encryption_changed=linphone_gtk_call_encryption_changed;
linphone_core_set_user_agent("Linphone", LINPHONE_VERSION);
the_core=linphone_core_new(&vtable,config_file,factory_config_file,NULL);
linphone_core_set_waiting_callback(the_core,linphone_gtk_wait,NULL);
+ linphone_core_set_zrtp_secrets_file(the_core,secrets_file);
+ g_free(secrets_file);
}
@@ -1058,6 +1064,10 @@ static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call
linphone_gtk_update_call_buttons (call);
}
+static void linphone_gtk_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t enabled, const char *token){
+ linphone_gtk_in_call_view_show_encryption(call);
+}
+
static void update_registration_status(LinphoneProxyConfig *cfg, LinphoneRegistrationState rs){
GtkComboBox *box=GTK_COMBO_BOX(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"identities"));
GtkTreeModel *model=gtk_combo_box_get_model(box);
@@ -1591,7 +1601,7 @@ int main(int argc, char *argv[]){
#ifdef ENABLE_NLS
void *p;
#endif
- const char *config_file;
+ char *config_file;
const char *factory_config_file;
const char *lang;
GtkSettings *settings;
@@ -1603,7 +1613,7 @@ int main(int argc, char *argv[]){
progpath = strdup(argv[0]);
- config_file=linphone_gtk_get_config_file();
+ config_file=linphone_gtk_get_config_file(NULL);
#ifdef WIN32
diff --git a/gtk/main.ui b/gtk/main.ui
index 1a3784f3b..925492386 100644
--- a/gtk/main.ui
+++ b/gtk/main.ui
@@ -141,6 +141,18 @@
0
+
+
+
+ False
+ False
+ 1
+
+
-
+
+
+ False
+ False
+ 3
+