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 + + + True + False + gtk-apply + + + False + False + 1 + + True @@ -150,11 +162,23 @@ True True - 1 + 2 - + + button + True + True + True + False + + + + False + False + 3 +