This commit is contained in:
parent
55385c5356
commit
46aac301c8
|
@ -35,7 +35,6 @@ to the Jabber network.</property>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkFrame" id="frame33">
|
<widget class="GtkFrame" id="frame33">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label_xalign">0</property>
|
|
||||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkAlignment" id="alignment68">
|
<widget class="GtkAlignment" id="alignment68">
|
||||||
|
@ -99,9 +98,6 @@ to the Jabber network.</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkLabel" id="label259">
|
<widget class="GtkLabel" id="label259">
|
||||||
|
@ -109,7 +105,6 @@ to the Jabber network.</property>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -144,61 +139,64 @@ to the Jabber network.</property>
|
||||||
<placeholder/>
|
<placeholder/>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkLabel" id="jid_label">
|
<widget class="GtkEntry" id="username_entry">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="xalign">0</property>
|
<property name="has_focus">True</property>
|
||||||
<property name="use_markup">True</property>
|
|
||||||
<property name="selectable">True</property>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="right_attach">3</property>
|
|
||||||
<property name="top_attach">3</property>
|
|
||||||
<property name="bottom_attach">4</property>
|
|
||||||
<property name="x_options">GTK_FILL</property>
|
|
||||||
<property name="y_options"></property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkLabel" id="label258">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="label" translatable="yes">Your JID:</property>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="top_attach">3</property>
|
|
||||||
<property name="bottom_attach">4</property>
|
|
||||||
<property name="x_options">GTK_FILL</property>
|
|
||||||
<property name="y_options"></property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkLabel" id="label262">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="label" translatable="yes">_Username:</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="mnemonic_widget">username_entry</property>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="x_options">GTK_FILL</property>
|
|
||||||
<property name="y_options"></property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkEntry" id="password_entry">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="visibility">False</property>
|
|
||||||
<property name="invisible_char">*</property>
|
<property name="invisible_char">*</property>
|
||||||
<property name="activates_default">True</property>
|
<signal name="changed" handler="on_username_entry_changed"/>
|
||||||
|
<signal name="key_press_event" handler="on_username_entry_key_press_event"/>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">1</property>
|
<property name="left_attach">1</property>
|
||||||
<property name="right_attach">2</property>
|
<property name="right_attach">2</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label267">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">_Server:</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
<property name="bottom_attach">2</property>
|
||||||
|
<property name="x_options">GTK_FILL</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkComboBoxEntry" id="server_comboboxentry">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<signal name="changed" handler="on_server_comboboxentry_changed"/>
|
||||||
|
<child internal-child="entry">
|
||||||
|
<widget class="GtkEntry" id="comboboxentry-entry1">
|
||||||
|
</widget>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="right_attach">2</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
<property name="bottom_attach">2</property>
|
||||||
|
<property name="x_options">GTK_FILL</property>
|
||||||
|
<property name="y_options">GTK_FILL</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label263">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">_Password:</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="mnemonic_widget">password_entry</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
<property name="top_attach">2</property>
|
<property name="top_attach">2</property>
|
||||||
<property name="bottom_attach">3</property>
|
<property name="bottom_attach">3</property>
|
||||||
|
<property name="x_options">GTK_FILL</property>
|
||||||
<property name="y_options"></property>
|
<property name="y_options"></property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -225,64 +223,61 @@ to the Jabber network.</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkLabel" id="label263">
|
<widget class="GtkEntry" id="password_entry">
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="label" translatable="yes">_Password:</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="mnemonic_widget">password_entry</property>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="top_attach">2</property>
|
|
||||||
<property name="bottom_attach">3</property>
|
|
||||||
<property name="x_options">GTK_FILL</property>
|
|
||||||
<property name="y_options"></property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkComboBoxEntry" id="server_comboboxentry">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<signal name="changed" handler="on_server_comboboxentry_changed"/>
|
|
||||||
<child internal-child="entry">
|
|
||||||
<widget class="GtkEntry" id="comboboxentry-entry1">
|
|
||||||
</widget>
|
|
||||||
</child>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="right_attach">2</property>
|
|
||||||
<property name="top_attach">1</property>
|
|
||||||
<property name="bottom_attach">2</property>
|
|
||||||
<property name="x_options">GTK_FILL</property>
|
|
||||||
<property name="y_options">GTK_FILL</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkLabel" id="label267">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="label" translatable="yes">_Server:</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="top_attach">1</property>
|
|
||||||
<property name="bottom_attach">2</property>
|
|
||||||
<property name="x_options">GTK_FILL</property>
|
|
||||||
<property name="y_options"></property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkEntry" id="username_entry">
|
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="has_focus">True</property>
|
<property name="visibility">False</property>
|
||||||
<property name="invisible_char">*</property>
|
<property name="invisible_char">*</property>
|
||||||
<signal name="changed" handler="on_username_entry_changed"/>
|
<property name="activates_default">True</property>
|
||||||
<signal name="key_press_event" handler="on_username_entry_key_press_event"/>
|
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="left_attach">1</property>
|
<property name="left_attach">1</property>
|
||||||
<property name="right_attach">2</property>
|
<property name="right_attach">2</property>
|
||||||
|
<property name="top_attach">2</property>
|
||||||
|
<property name="bottom_attach">3</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label262">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">_Username:</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="mnemonic_widget">username_entry</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="x_options">GTK_FILL</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label258">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">Your JID:</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="top_attach">3</property>
|
||||||
|
<property name="bottom_attach">4</property>
|
||||||
|
<property name="x_options">GTK_FILL</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="jid_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="use_markup">True</property>
|
||||||
|
<property name="selectable">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="right_attach">3</property>
|
||||||
|
<property name="top_attach">3</property>
|
||||||
|
<property name="bottom_attach">4</property>
|
||||||
|
<property name="x_options">GTK_FILL</property>
|
||||||
<property name="y_options"></property>
|
<property name="y_options"></property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -294,7 +289,6 @@ to the Jabber network.</property>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -304,7 +298,6 @@ to the Jabber network.</property>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="position">1</property>
|
<property name="position">1</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -388,6 +381,62 @@ to the Jabber network.</property>
|
||||||
<property name="n_columns">3</property>
|
<property name="n_columns">3</property>
|
||||||
<property name="column_spacing">5</property>
|
<property name="column_spacing">5</property>
|
||||||
<property name="row_spacing">5</property>
|
<property name="row_spacing">5</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label381">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="xalign">0</property>
|
||||||
|
<property name="label" translatable="yes">Prox_y:</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="x_options">GTK_FILL</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkComboBox" id="proxies_combobox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="items">None</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">1</property>
|
||||||
|
<property name="right_attach">2</property>
|
||||||
|
<property name="y_options">GTK_FILL</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkButton" id="manage_proxies_button">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="label" translatable="yes">Manage...</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
|
<signal name="clicked" handler="on_manage_proxies_button_clicked"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="left_attach">2</property>
|
||||||
|
<property name="right_attach">3</property>
|
||||||
|
<property name="x_options"></property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkCheckButton" id="custom_host_port_checkbutton">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="label" translatable="yes">Use custom hostname/port</property>
|
||||||
|
<property name="use_underline">True</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
<signal name="toggled" handler="on_custom_host_port_checkbutton_toggled"/>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="right_attach">3</property>
|
||||||
|
<property name="top_attach">1</property>
|
||||||
|
<property name="bottom_attach">2</property>
|
||||||
|
<property name="y_options"></property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkHBox" id="custom_host_hbox">
|
<widget class="GtkHBox" id="custom_host_hbox">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
@ -450,62 +499,6 @@ to the Jabber network.</property>
|
||||||
<property name="y_options">GTK_FILL</property>
|
<property name="y_options">GTK_FILL</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
|
||||||
<widget class="GtkCheckButton" id="custom_host_port_checkbutton">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="label" translatable="yes">Use custom hostname/port</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="response_id">0</property>
|
|
||||||
<property name="draw_indicator">True</property>
|
|
||||||
<signal name="toggled" handler="on_custom_host_port_checkbutton_toggled"/>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="right_attach">3</property>
|
|
||||||
<property name="top_attach">1</property>
|
|
||||||
<property name="bottom_attach">2</property>
|
|
||||||
<property name="y_options"></property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkButton" id="manage_proxies_button">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="can_focus">True</property>
|
|
||||||
<property name="label" translatable="yes">Manage...</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="response_id">0</property>
|
|
||||||
<signal name="clicked" handler="on_manage_proxies_button_clicked"/>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">2</property>
|
|
||||||
<property name="right_attach">3</property>
|
|
||||||
<property name="x_options"></property>
|
|
||||||
<property name="y_options"></property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkComboBox" id="proxies_combobox">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="items">None</property>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="left_attach">1</property>
|
|
||||||
<property name="right_attach">2</property>
|
|
||||||
<property name="y_options">GTK_FILL</property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
<child>
|
|
||||||
<widget class="GtkLabel" id="label381">
|
|
||||||
<property name="visible">True</property>
|
|
||||||
<property name="xalign">0</property>
|
|
||||||
<property name="label" translatable="yes">Prox_y:</property>
|
|
||||||
<property name="use_underline">True</property>
|
|
||||||
</widget>
|
|
||||||
<packing>
|
|
||||||
<property name="x_options">GTK_FILL</property>
|
|
||||||
<property name="y_options"></property>
|
|
||||||
</packing>
|
|
||||||
</child>
|
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -526,7 +519,6 @@ to the Jabber network.</property>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">2</property>
|
<property name="position">2</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -536,7 +528,69 @@ to the Jabber network.</property>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="position">2</property>
|
<property name="position">2</property>
|
||||||
<property name="tab_expand">False</property>
|
<property name="tab_fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkVBox" id="ssl_vbox">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkHBox" id="hbox1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkImage" id="image1">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||||
|
<property name="stock">gtk-dialog-warning</property>
|
||||||
|
<property name="icon_size">5</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="expand">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="ssl_label">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkCheckButton" id="ssl_checkbutton">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
<property name="can_focus">True</property>
|
||||||
|
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||||
|
<property name="label" translatable="yes">Add this certificate to the list of trusted certificates.
|
||||||
|
SHA1 fingerprint of the certificate:
|
||||||
|
</property>
|
||||||
|
<property name="response_id">0</property>
|
||||||
|
<property name="draw_indicator">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="fill">False</property>
|
||||||
|
<property name="position">1</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="position">3</property>
|
||||||
|
</packing>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<widget class="GtkLabel" id="label482">
|
||||||
|
<property name="visible">True</property>
|
||||||
|
</widget>
|
||||||
|
<packing>
|
||||||
|
<property name="type">tab</property>
|
||||||
|
<property name="position">3</property>
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -548,8 +602,7 @@ to the Jabber network.</property>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">3</property>
|
<property name="position">4</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -558,8 +611,7 @@ to the Jabber network.</property>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="position">3</property>
|
<property name="position">4</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -592,8 +644,7 @@ Please wait...</property>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">4</property>
|
<property name="position">5</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -602,8 +653,7 @@ Please wait...</property>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="position">4</property>
|
<property name="position">5</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
@ -671,8 +721,7 @@ Please wait...</property>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">5</property>
|
<property name="position">6</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
<child>
|
<child>
|
||||||
|
@ -681,8 +730,7 @@ Please wait...</property>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="type">tab</property>
|
<property name="type">tab</property>
|
||||||
<property name="position">5</property>
|
<property name="position">6</property>
|
||||||
<property name="tab_expand">False</property>
|
|
||||||
<property name="tab_fill">False</property>
|
<property name="tab_fill">False</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
|
|
@ -275,6 +275,7 @@ class Config:
|
||||||
'keyid': [ opt_str, '', '', True ],
|
'keyid': [ opt_str, '', '', True ],
|
||||||
'keyname': [ opt_str, '', '', True ],
|
'keyname': [ opt_str, '', '', True ],
|
||||||
'usessl': [ opt_bool, False, '', True ],
|
'usessl': [ opt_bool, False, '', True ],
|
||||||
|
'ssl_fingerprint_sha1': [ opt_str, '', '', True ],
|
||||||
'use_srv': [ opt_bool, True, '', True ],
|
'use_srv': [ opt_bool, True, '', True ],
|
||||||
'use_custom_host': [ opt_bool, False, '', True ],
|
'use_custom_host': [ opt_bool, False, '', True ],
|
||||||
'custom_port': [ opt_int, 5222, '', True ],
|
'custom_port': [ opt_int, 5222, '', True ],
|
||||||
|
|
|
@ -79,9 +79,9 @@ class ConfigPaths:
|
||||||
|
|
||||||
# LOG is deprecated
|
# LOG is deprecated
|
||||||
k = ( 'LOG', 'LOG_DB', 'VCARD', 'AVATAR', 'MY_EMOTS',
|
k = ( 'LOG', 'LOG_DB', 'VCARD', 'AVATAR', 'MY_EMOTS',
|
||||||
'MY_ICONSETS' )
|
'MY_ICONSETS', 'MY_CACERTS')
|
||||||
v = (u'logs', u'logs.db', u'vcards', u'avatars', u'emoticons',
|
v = (u'logs', u'logs.db', u'vcards', u'avatars', u'emoticons',
|
||||||
u'iconsets')
|
u'iconsets', u'cacerts.pem')
|
||||||
|
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
v = map(lambda x: x.capitalize(), v)
|
v = map(lambda x: x.capitalize(), v)
|
||||||
|
|
|
@ -58,39 +58,39 @@ log = logging.getLogger('gajim.c.connection')
|
||||||
|
|
||||||
import gtkgui_helpers
|
import gtkgui_helpers
|
||||||
|
|
||||||
ssl_error = {
|
ssl_error = {
|
||||||
2: "Unable to get issuer certificate",
|
2: _("Unable to get issuer certificate"),
|
||||||
3: "Unable to get certificate CRL",
|
3: _("Unable to get certificate CRL"),
|
||||||
4: "Unable to decrypt certificate's signature",
|
4: _("Unable to decrypt certificate's signature"),
|
||||||
5: "Unable to decrypt CRL's signature",
|
5: _("Unable to decrypt CRL's signature"),
|
||||||
6: "Unable to decode issuer public key",
|
6: _("Unable to decode issuer public key"),
|
||||||
7: "Certificate signature failure",
|
7: _("Certificate signature failure"),
|
||||||
8: "CRL signature failure",
|
8: _("CRL signature failure"),
|
||||||
9: "Certificate is not yet valid",
|
9: _("Certificate is not yet valid"),
|
||||||
10: "Certificate has expired",
|
10: _("Certificate has expired"),
|
||||||
11: "CRL is not yet valid",
|
11: _("CRL is not yet valid"),
|
||||||
12: "CRL has expired",
|
12: _("CRL has expired"),
|
||||||
13: "Format error in certificate's notBefore field",
|
13: _("Format error in certificate's notBefore field"),
|
||||||
14: "Format error in certificate's notAfter field",
|
14: _("Format error in certificate's notAfter field"),
|
||||||
15: "Format error in CRL's lastUpdate field",
|
15: _("Format error in CRL's lastUpdate field"),
|
||||||
16: "Format error in CRL's nextUpdate field",
|
16: _("Format error in CRL's nextUpdate field"),
|
||||||
17: "Out of memory",
|
17: _("Out of memory"),
|
||||||
18: "Self signed certificate in certificate chain",
|
18: _("Self signed certificate in certificate chain"),
|
||||||
19: "Unable to get local issuer certificate",
|
19: _("Unable to get local issuer certificate"),
|
||||||
20: "Unable to verify the first certificate",
|
20: _("Unable to verify the first certificate"),
|
||||||
21: "Unable to verify the first certificate",
|
21: _("Unable to verify the first certificate"),
|
||||||
22: "Certificate chain too long",
|
22: _("Certificate chain too long"),
|
||||||
23: "Certificate revoked",
|
23: _("Certificate revoked"),
|
||||||
24: "Invalid CA certificate",
|
24: _("Invalid CA certificate"),
|
||||||
25: "Path length constraint exceeded",
|
25: _("Path length constraint exceeded"),
|
||||||
26: "Unsupported certificate purpose",
|
26: _("Unsupported certificate purpose"),
|
||||||
27: "Certificate not trusted",
|
27: _("Certificate not trusted"),
|
||||||
28: "Certificate rejected",
|
28: _("Certificate rejected"),
|
||||||
29: "Subject issuer mismatch",
|
29: _("Subject issuer mismatch"),
|
||||||
30: "Authority and subject key identifier mismatch",
|
30: _("Authority and subject key identifier mismatch"),
|
||||||
31: "Authority and issuer serial number mismatch",
|
31: _("Authority and issuer serial number mismatch"),
|
||||||
32: "Key usage does not include certificate signing",
|
32: _("Key usage does not include certificate signing"),
|
||||||
50: "Application verification failure"
|
50: _("Application verification failure")
|
||||||
}
|
}
|
||||||
class Connection(ConnectionHandlers):
|
class Connection(ConnectionHandlers):
|
||||||
'''Connection class'''
|
'''Connection class'''
|
||||||
|
@ -128,7 +128,7 @@ class Connection(ConnectionHandlers):
|
||||||
self.last_history_line = {}
|
self.last_history_line = {}
|
||||||
self.password = passwords.get_password(name)
|
self.password = passwords.get_password(name)
|
||||||
self.server_resource = gajim.config.get_per('accounts', name, 'resource')
|
self.server_resource = gajim.config.get_per('accounts', name, 'resource')
|
||||||
# All valid resource substitution strings should be added to this hash.
|
# All valid resource substitution strings should be added to this hash.
|
||||||
if self.server_resource:
|
if self.server_resource:
|
||||||
self.server_resource = Template(self.server_resource).safe_substitute({
|
self.server_resource = Template(self.server_resource).safe_substitute({
|
||||||
'hostname': socket.gethostname()
|
'hostname': socket.gethostname()
|
||||||
|
@ -183,7 +183,7 @@ class Connection(ConnectionHandlers):
|
||||||
# reconnect succeeded
|
# reconnect succeeded
|
||||||
self.time_to_reconnect = None
|
self.time_to_reconnect = None
|
||||||
self.retrycount = 0
|
self.retrycount = 0
|
||||||
|
|
||||||
# We are doing disconnect at so many places, better use one function in all
|
# We are doing disconnect at so many places, better use one function in all
|
||||||
def disconnect(self, on_purpose=False):
|
def disconnect(self, on_purpose=False):
|
||||||
self.on_purpose = on_purpose
|
self.on_purpose = on_purpose
|
||||||
|
@ -196,7 +196,7 @@ class Connection(ConnectionHandlers):
|
||||||
self.connection.disconnect()
|
self.connection.disconnect()
|
||||||
self.last_connection = None
|
self.last_connection = None
|
||||||
self.connection = None
|
self.connection = None
|
||||||
|
|
||||||
def _disconnectedReconnCB(self):
|
def _disconnectedReconnCB(self):
|
||||||
'''Called when we are disconnected'''
|
'''Called when we are disconnected'''
|
||||||
log.debug('disconnectedReconnCB')
|
log.debug('disconnectedReconnCB')
|
||||||
|
@ -238,7 +238,7 @@ class Connection(ConnectionHandlers):
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
self.on_purpose = False
|
self.on_purpose = False
|
||||||
# END disconenctedReconnCB
|
# END disconenctedReconnCB
|
||||||
|
|
||||||
def _connection_lost(self):
|
def _connection_lost(self):
|
||||||
self.disconnect(on_purpose = False)
|
self.disconnect(on_purpose = False)
|
||||||
self.dispatch('STATUS', 'offline')
|
self.dispatch('STATUS', 'offline')
|
||||||
|
@ -295,12 +295,29 @@ class Connection(ConnectionHandlers):
|
||||||
self._hostname, self.new_account_form,
|
self._hostname, self.new_account_form,
|
||||||
_on_register_result)
|
_on_register_result)
|
||||||
return
|
return
|
||||||
else:
|
try:
|
||||||
self.dispatch('NEW_ACC_CONNECTED', (conf, is_form))
|
errnum = self.connection.Connection.ssl_errnum
|
||||||
self.connection.UnregisterDisconnectHandler(
|
except AttributeError:
|
||||||
self._on_new_account)
|
errnum = -1 # we don't have an errnum
|
||||||
self.disconnect(on_purpose=True)
|
ssl_msg = ''
|
||||||
return
|
if errnum > 0:
|
||||||
|
if errnum in ssl_error:
|
||||||
|
ssl_msg = ssl_error[errnum]
|
||||||
|
else:
|
||||||
|
ssl_msg = _('Unknown SSL error: %d') % errnum
|
||||||
|
ssl_cert = ''
|
||||||
|
if hasattr(self.connection.Connection, 'ssl_cert_pem'):
|
||||||
|
ssl_cert = self.connection.Connection.ssl_cert_pem
|
||||||
|
ssl_fingerprint = ''
|
||||||
|
if hasattr(self.connection.Connection, 'ssl_fingerprint_sha1'):
|
||||||
|
ssl_fingerprint = \
|
||||||
|
self.connection.Connection.ssl_fingerprint_sha1
|
||||||
|
self.dispatch('NEW_ACC_CONNECTED', (conf, is_form, ssl_msg,
|
||||||
|
ssl_cert, ssl_fingerprint))
|
||||||
|
self.connection.UnregisterDisconnectHandler(
|
||||||
|
self._on_new_account)
|
||||||
|
self.disconnect(on_purpose=True)
|
||||||
|
return
|
||||||
if not data[1]: # wrong answer
|
if not data[1]: # wrong answer
|
||||||
self.dispatch('ERROR', (_('Invalid answer'),
|
self.dispatch('ERROR', (_('Invalid answer'),
|
||||||
_('Transport %s answered wrongly to register request: %s') % \
|
_('Transport %s answered wrongly to register request: %s') % \
|
||||||
|
@ -519,7 +536,6 @@ class Connection(ConnectionHandlers):
|
||||||
con.RegisterDisconnectHandler(self._disconnectedReconnCB)
|
con.RegisterDisconnectHandler(self._disconnectedReconnCB)
|
||||||
log.debug(_('Connected to server %s:%s with %s') % (self._current_host['host'],
|
log.debug(_('Connected to server %s:%s with %s') % (self._current_host['host'],
|
||||||
self._current_host['port'], con_type))
|
self._current_host['port'], con_type))
|
||||||
self._register_handlers(con, con_type)
|
|
||||||
|
|
||||||
name = gajim.config.get_per('accounts', self.name, 'name')
|
name = gajim.config.get_per('accounts', self.name, 'name')
|
||||||
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
|
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
|
||||||
|
@ -529,14 +545,31 @@ class Connection(ConnectionHandlers):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
errnum = -1 # we don't have an errnum
|
errnum = -1 # we don't have an errnum
|
||||||
if errnum > 0:
|
if errnum > 0:
|
||||||
# FIXME: tell the user that the certificat is untrusted, and ask him what to do
|
text = _('The authenticity of the %s certificate could be invalid.') %\
|
||||||
try:
|
hostname
|
||||||
log.warning("The authenticity of the "+hostname+" certificate could be invalid.\nSSL Error: "+ssl_error[errnum])
|
if errnum in ssl_error:
|
||||||
except KeyError:
|
text += _('\nSSL Error: %s') % ssl_error[errnum]
|
||||||
log.warning("Unknown SSL error: %d" % errnum)
|
else:
|
||||||
|
text += _('\nUnknown SSL error: %d') % errnum
|
||||||
|
self.dispatch('SSL_ERROR', (text, con.Connection.ssl_cert_pem,
|
||||||
|
con.Connection.ssl_fingerprint_sha1))
|
||||||
|
return True
|
||||||
|
if hasattr(con.Connection, 'ssl_fingerprint_sha1'):
|
||||||
|
saved_fingerprint = gajim.config.get_per('accounts', self.name, 'ssl_fingerprint_sha1')
|
||||||
|
if saved_fingerprint:
|
||||||
|
# Check sha1 fingerprint
|
||||||
|
if con.Connection.ssl_fingerprint_sha1 != saved_fingerprint:
|
||||||
|
self.dispatch('FINGERPRINT_ERROR',
|
||||||
|
(con.Connection.ssl_fingerprint_sha1,))
|
||||||
|
return True
|
||||||
|
self._register_handlers(con, con_type)
|
||||||
con.auth(name, self.password, self.server_resource, 1, self.__on_auth)
|
con.auth(name, self.password, self.server_resource, 1, self.__on_auth)
|
||||||
|
|
||||||
return True
|
|
||||||
|
def ssl_certificate_accepted(self):
|
||||||
|
name = gajim.config.get_per('accounts', self.name, 'name')
|
||||||
|
self._register_handlers(self.connection, 'ssl')
|
||||||
|
self.connection.auth(name, self.password, self.server_resource, 1, self.__on_auth)
|
||||||
|
|
||||||
def _register_handlers(self, con, con_type):
|
def _register_handlers(self, con, con_type):
|
||||||
self.peerhost = con.get_peerhost()
|
self.peerhost = con.get_peerhost()
|
||||||
|
@ -585,8 +618,8 @@ class Connection(ConnectionHandlers):
|
||||||
|
|
||||||
def quit(self, kill_core):
|
def quit(self, kill_core):
|
||||||
if kill_core and gajim.account_is_connected(self.name):
|
if kill_core and gajim.account_is_connected(self.name):
|
||||||
self.disconnect(on_purpose = True)
|
self.disconnect(on_purpose=True)
|
||||||
|
|
||||||
def get_privacy_lists(self):
|
def get_privacy_lists(self):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
|
@ -612,7 +645,7 @@ class Connection(ConnectionHandlers):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
common.xmpp.features_nb.getActiveAndDefaultPrivacyLists(self.connection)
|
common.xmpp.features_nb.getActiveAndDefaultPrivacyLists(self.connection)
|
||||||
|
|
||||||
def del_privacy_list(self, privacy_list):
|
def del_privacy_list(self, privacy_list):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
|
@ -626,17 +659,17 @@ class Connection(ConnectionHandlers):
|
||||||
'again.') % privacy_list))
|
'again.') % privacy_list))
|
||||||
common.xmpp.features_nb.delPrivacyList(self.connection, privacy_list,
|
common.xmpp.features_nb.delPrivacyList(self.connection, privacy_list,
|
||||||
_on_del_privacy_list_result)
|
_on_del_privacy_list_result)
|
||||||
|
|
||||||
def get_privacy_list(self, title):
|
def get_privacy_list(self, title):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
common.xmpp.features_nb.getPrivacyList(self.connection, title)
|
common.xmpp.features_nb.getPrivacyList(self.connection, title)
|
||||||
|
|
||||||
def set_privacy_list(self, listname, tags):
|
def set_privacy_list(self, listname, tags):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
common.xmpp.features_nb.setPrivacyList(self.connection, listname, tags)
|
common.xmpp.features_nb.setPrivacyList(self.connection, listname, tags)
|
||||||
|
|
||||||
def set_active_list(self, listname):
|
def set_active_list(self, listname):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
|
@ -646,7 +679,7 @@ class Connection(ConnectionHandlers):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
common.xmpp.features_nb.setDefaultPrivacyList(self.connection, listname)
|
common.xmpp.features_nb.setDefaultPrivacyList(self.connection, listname)
|
||||||
|
|
||||||
def build_privacy_rule(self, name, action):
|
def build_privacy_rule(self, name, action):
|
||||||
'''Build a Privacy rule stanza for invisibility'''
|
'''Build a Privacy rule stanza for invisibility'''
|
||||||
iq = common.xmpp.Iq('set', common.xmpp.NS_PRIVACY, xmlns = '')
|
iq = common.xmpp.Iq('set', common.xmpp.NS_PRIVACY, xmlns = '')
|
||||||
|
@ -699,7 +732,7 @@ class Connection(ConnectionHandlers):
|
||||||
|
|
||||||
#Get bookmarks from private namespace
|
#Get bookmarks from private namespace
|
||||||
self.get_bookmarks()
|
self.get_bookmarks()
|
||||||
|
|
||||||
#Get annotations
|
#Get annotations
|
||||||
self.get_annotations()
|
self.get_annotations()
|
||||||
|
|
||||||
|
@ -798,7 +831,7 @@ class Connection(ConnectionHandlers):
|
||||||
# set old_show to requested 'show' in case we need to
|
# set old_show to requested 'show' in case we need to
|
||||||
# recconect before we auth to server
|
# recconect before we auth to server
|
||||||
self.old_show = show
|
self.old_show = show
|
||||||
self.on_purpose = False
|
self.on_purpose = False
|
||||||
self.server_resource = gajim.config.get_per('accounts', self.name,
|
self.server_resource = gajim.config.get_per('accounts', self.name,
|
||||||
'resource')
|
'resource')
|
||||||
# All valid resource substitution strings should be added to this hash.
|
# All valid resource substitution strings should be added to this hash.
|
||||||
|
@ -941,8 +974,8 @@ class Connection(ConnectionHandlers):
|
||||||
msg_id = ''
|
msg_id = ''
|
||||||
chatstate_node.setTagData('id', msg_id)
|
chatstate_node.setTagData('id', msg_id)
|
||||||
# when msgtxt, requests JEP-0022 composing notification
|
# when msgtxt, requests JEP-0022 composing notification
|
||||||
if chatstate is 'composing' or msgtxt:
|
if chatstate is 'composing' or msgtxt:
|
||||||
chatstate_node.addChild(name = 'composing')
|
chatstate_node.addChild(name = 'composing')
|
||||||
|
|
||||||
if forward_from:
|
if forward_from:
|
||||||
addresses = msg_iq.addChild('addresses',
|
addresses = msg_iq.addChild('addresses',
|
||||||
|
@ -983,7 +1016,7 @@ class Connection(ConnectionHandlers):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
self.connection.send(stanza)
|
self.connection.send(stanza)
|
||||||
|
|
||||||
def ack_subscribed(self, jid):
|
def ack_subscribed(self, jid):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
|
@ -1280,7 +1313,7 @@ class Connection(ConnectionHandlers):
|
||||||
self.connection.send(p)
|
self.connection.send(p)
|
||||||
|
|
||||||
# last date/time in history to avoid duplicate
|
# last date/time in history to avoid duplicate
|
||||||
if not self.last_history_line.has_key(room_jid):
|
if not self.last_history_line.has_key(room_jid):
|
||||||
# Not in memory, get it from DB
|
# Not in memory, get it from DB
|
||||||
last_log = None
|
last_log = None
|
||||||
no_log_for = gajim.config.get_per('accounts', self.name, 'no_log_for')\
|
no_log_for = gajim.config.get_per('accounts', self.name, 'no_log_for')\
|
||||||
|
@ -1343,7 +1376,7 @@ class Connection(ConnectionHandlers):
|
||||||
# send instantly so when we go offline, status is sent to gc before we
|
# send instantly so when we go offline, status is sent to gc before we
|
||||||
# disconnect from jabber server
|
# disconnect from jabber server
|
||||||
self.connection.send(p)
|
self.connection.send(p)
|
||||||
# Save the time we quit to avoid duplicate logs AND be faster than
|
# Save the time we quit to avoid duplicate logs AND be faster than
|
||||||
# get that date from DB
|
# get that date from DB
|
||||||
self.last_history_line[jid] = time_time()
|
self.last_history_line[jid] = time_time()
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,7 @@ VCARD_PATH = gajimpaths['VCARD']
|
||||||
AVATAR_PATH = gajimpaths['AVATAR']
|
AVATAR_PATH = gajimpaths['AVATAR']
|
||||||
MY_EMOTS_PATH = gajimpaths['MY_EMOTS']
|
MY_EMOTS_PATH = gajimpaths['MY_EMOTS']
|
||||||
MY_ICONSETS_PATH = gajimpaths['MY_ICONSETS']
|
MY_ICONSETS_PATH = gajimpaths['MY_ICONSETS']
|
||||||
|
MY_CACERTS = gajimpaths['MY_CACERTS']
|
||||||
TMP = gajimpaths['TMP']
|
TMP = gajimpaths['TMP']
|
||||||
DATA_DIR = gajimpaths['DATA']
|
DATA_DIR = gajimpaths['DATA']
|
||||||
HOME_DIR = gajimpaths['HOME']
|
HOME_DIR = gajimpaths['HOME']
|
||||||
|
|
|
@ -745,10 +745,34 @@ class NonBlockingTLS(PlugIn):
|
||||||
#tcpsock._sslContext = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
|
#tcpsock._sslContext = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
|
||||||
tcpsock.ssl_errnum = 0
|
tcpsock.ssl_errnum = 0
|
||||||
tcpsock._sslContext.set_verify(OpenSSL.SSL.VERIFY_PEER, self._ssl_verify_callback)
|
tcpsock._sslContext.set_verify(OpenSSL.SSL.VERIFY_PEER, self._ssl_verify_callback)
|
||||||
|
cacerts = os.path.join(gajim.DATA_DIR, 'other', 'cacerts.pem')
|
||||||
try:
|
try:
|
||||||
tcpsock._sslContext.load_verify_locations(os.path.join(gajim.DATA_DIR, 'other', 'cacerts.pem'))
|
tcpsock._sslContext.load_verify_locations(cacerts)
|
||||||
except:
|
except:
|
||||||
log.warning(_("Unable to load SSL certificats from file %s" % os.path.abspath(os.path.join(gajim.DATA_DIR,'other','ca.crt'))))
|
log.warning('Unable to load SSL certificats from file %s' % \
|
||||||
|
os.path.abspath(cacerts))
|
||||||
|
# load users certs
|
||||||
|
if os.path.isfile(gajim.MY_CACERTS):
|
||||||
|
store = tcpsock._sslContext.get_cert_store()
|
||||||
|
f = open(gajim.MY_CACERTS)
|
||||||
|
lines = f.readlines()
|
||||||
|
i = 0
|
||||||
|
begin = -1
|
||||||
|
for line in lines:
|
||||||
|
if 'BEGIN CERTIFICATE' in line:
|
||||||
|
begin = i
|
||||||
|
continue
|
||||||
|
elif 'END CERTIFICATE' in line and begin > -1:
|
||||||
|
cert = ''.join(lines[begin:i+2])
|
||||||
|
try:
|
||||||
|
X509cert = OpenSSL.crypto.load_certificate(
|
||||||
|
OpenSSL.crypto.FILETYPE_PEM, cert)
|
||||||
|
store.add_cert(X509cert)
|
||||||
|
except:
|
||||||
|
log.warning('Unable to load a certificate from file %s' % \
|
||||||
|
gajim.MY_CACERTS)
|
||||||
|
begin = -1
|
||||||
|
i += 1
|
||||||
tcpsock._sslObj = OpenSSL.SSL.Connection(tcpsock._sslContext, tcpsock._sock)
|
tcpsock._sslObj = OpenSSL.SSL.Connection(tcpsock._sslContext, tcpsock._sock)
|
||||||
tcpsock._sslObj.set_connect_state() # set to client mode
|
tcpsock._sslObj.set_connect_state() # set to client mode
|
||||||
|
|
||||||
|
@ -788,9 +812,12 @@ class NonBlockingTLS(PlugIn):
|
||||||
def _ssl_verify_callback(self, sslconn, cert, errnum, depth, ok):
|
def _ssl_verify_callback(self, sslconn, cert, errnum, depth, ok):
|
||||||
# Exceptions can't propagate up through this callback, so print them here.
|
# Exceptions can't propagate up through this callback, so print them here.
|
||||||
try:
|
try:
|
||||||
|
self._owner.Connection.ssl_fingerprint_sha1 = cert.digest('sha1')
|
||||||
if errnum == 0:
|
if errnum == 0:
|
||||||
return True
|
return True
|
||||||
self._owner.Connection.ssl_errnum = errnum
|
self._owner.Connection.ssl_errnum = errnum
|
||||||
|
self._owner.Connection.ssl_cert_pem = OpenSSL.crypto.dump_certificate(
|
||||||
|
OpenSSL.crypto.FILETYPE_PEM, cert)
|
||||||
return True
|
return True
|
||||||
except:
|
except:
|
||||||
log.error("Exception caught in _ssl_info_callback:", exc_info=True)
|
log.error("Exception caught in _ssl_info_callback:", exc_info=True)
|
||||||
|
|
|
@ -2977,7 +2977,7 @@ class AccountCreationWizardWindow:
|
||||||
|
|
||||||
def on_wizard_window_destroy(self, widget):
|
def on_wizard_window_destroy(self, widget):
|
||||||
page = self.notebook.get_current_page()
|
page = self.notebook.get_current_page()
|
||||||
if page > 2 and page < 5 and self.account in gajim.connections:
|
if page in (4, 5) and self.account in gajim.connections:
|
||||||
# connection instance is saved in gajim.connections and we canceled the
|
# connection instance is saved in gajim.connections and we canceled the
|
||||||
# addition of the account
|
# addition of the account
|
||||||
del gajim.connections[self.account]
|
del gajim.connections[self.account]
|
||||||
|
@ -2994,15 +2994,19 @@ class AccountCreationWizardWindow:
|
||||||
self.window.destroy()
|
self.window.destroy()
|
||||||
|
|
||||||
def on_back_button_clicked(self, widget):
|
def on_back_button_clicked(self, widget):
|
||||||
if self.notebook.get_current_page() in (1, 2):
|
cur_page = self.notebook.get_current_page()
|
||||||
|
if cur_page in (1, 2):
|
||||||
self.notebook.set_current_page(0)
|
self.notebook.set_current_page(0)
|
||||||
self.back_button.set_sensitive(False)
|
self.back_button.set_sensitive(False)
|
||||||
elif self.notebook.get_current_page() == 3:
|
elif cur_page == 3:
|
||||||
|
self.xml.get_widget('form_vbox').remove(self.data_form_widget)
|
||||||
|
self.notebook.set_current_page(2) # show server page
|
||||||
|
elif cur_page == 4:
|
||||||
if self.account in gajim.connections:
|
if self.account in gajim.connections:
|
||||||
del gajim.connections[self.account]
|
del gajim.connections[self.account]
|
||||||
self.notebook.set_current_page(2)
|
self.notebook.set_current_page(2)
|
||||||
self.xml.get_widget('form_vbox').remove(self.data_form_widget)
|
self.xml.get_widget('form_vbox').remove(self.data_form_widget)
|
||||||
elif self.notebook.get_current_page() == 5: # finish page
|
elif cur_page == 6: # finish page
|
||||||
self.forward_button.show()
|
self.forward_button.show()
|
||||||
if self.modify:
|
if self.modify:
|
||||||
self.notebook.set_current_page(1) # Go to parameters page
|
self.notebook.set_current_page(1) # Go to parameters page
|
||||||
|
@ -3085,7 +3089,7 @@ class AccountCreationWizardWindow:
|
||||||
self.go_online_checkbutton.show()
|
self.go_online_checkbutton.show()
|
||||||
img = self.xml.get_widget('finish_image')
|
img = self.xml.get_widget('finish_image')
|
||||||
img.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_DIALOG)
|
img.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_DIALOG)
|
||||||
self.notebook.set_current_page(5) # show finish page
|
self.notebook.set_current_page(6) # show finish page
|
||||||
self.show_vcard_checkbutton.set_active(False)
|
self.show_vcard_checkbutton.set_active(False)
|
||||||
elif cur_page == 2:
|
elif cur_page == 2:
|
||||||
# We are creating a new account
|
# We are creating a new account
|
||||||
|
@ -3124,7 +3128,7 @@ class AccountCreationWizardWindow:
|
||||||
config['custom_host'] = self.xml.get_widget(
|
config['custom_host'] = self.xml.get_widget(
|
||||||
'custom_host_entry').get_text().decode('utf-8')
|
'custom_host_entry').get_text().decode('utf-8')
|
||||||
|
|
||||||
self.notebook.set_current_page(4) # show creating page
|
self.notebook.set_current_page(5) # show creating page
|
||||||
self.back_button.hide()
|
self.back_button.hide()
|
||||||
self.forward_button.hide()
|
self.forward_button.hide()
|
||||||
self.update_progressbar_timeout_id = gobject.timeout_add(100,
|
self.update_progressbar_timeout_id = gobject.timeout_add(100,
|
||||||
|
@ -3134,6 +3138,18 @@ class AccountCreationWizardWindow:
|
||||||
con.new_account(self.account, config)
|
con.new_account(self.account, config)
|
||||||
gajim.connections[self.account] = con
|
gajim.connections[self.account] = con
|
||||||
elif cur_page == 3:
|
elif cur_page == 3:
|
||||||
|
checked = self.xml.get_widget('ssl_checkbutton').get_active()
|
||||||
|
if checked:
|
||||||
|
hostname = gajim.connections[self.account].new_account_info[
|
||||||
|
'hostname']
|
||||||
|
f = open(gajim.MY_CACERTS, 'a')
|
||||||
|
f.write(hostname + '\n')
|
||||||
|
f.write(self.ssl_cert + '\n\n')
|
||||||
|
f.close()
|
||||||
|
gajim.connections[self.account].new_account_info[
|
||||||
|
'ssl_fingerprint_sha1'] = self.ssl_fingerprint
|
||||||
|
self.notebook.set_current_page(4) # show fom page
|
||||||
|
elif cur_page == 4:
|
||||||
if self.is_form:
|
if self.is_form:
|
||||||
form = self.data_form_widget.data_form
|
form = self.data_form_widget.data_form
|
||||||
else:
|
else:
|
||||||
|
@ -3142,7 +3158,7 @@ class AccountCreationWizardWindow:
|
||||||
self.is_form)
|
self.is_form)
|
||||||
self.xml.get_widget('form_vbox').remove(self.data_form_widget)
|
self.xml.get_widget('form_vbox').remove(self.data_form_widget)
|
||||||
self.xml.get_widget('progressbar_label').set_markup('<b>Account is being created</b>\n\nPlease wait...')
|
self.xml.get_widget('progressbar_label').set_markup('<b>Account is being created</b>\n\nPlease wait...')
|
||||||
self.notebook.set_current_page(4) # show creating page
|
self.notebook.set_current_page(5) # show creating page
|
||||||
self.back_button.hide()
|
self.back_button.hide()
|
||||||
self.forward_button.hide()
|
self.forward_button.hide()
|
||||||
self.update_progressbar_timeout_id = gobject.timeout_add(100,
|
self.update_progressbar_timeout_id = gobject.timeout_add(100,
|
||||||
|
@ -3172,13 +3188,13 @@ class AccountCreationWizardWindow:
|
||||||
self.progressbar.pulse()
|
self.progressbar.pulse()
|
||||||
return True # loop forever
|
return True # loop forever
|
||||||
|
|
||||||
def new_acc_connected(self, form, is_form):
|
def new_acc_connected(self, form, is_form, ssl_msg, ssl_cert,
|
||||||
|
ssl_fingerprint):
|
||||||
'''connection to server succeded, present the form to the user.'''
|
'''connection to server succeded, present the form to the user.'''
|
||||||
if self.update_progressbar_timeout_id is not None:
|
if self.update_progressbar_timeout_id is not None:
|
||||||
gobject.source_remove(self.update_progressbar_timeout_id)
|
gobject.source_remove(self.update_progressbar_timeout_id)
|
||||||
self.back_button.show()
|
self.back_button.show()
|
||||||
self.forward_button.show()
|
self.forward_button.show()
|
||||||
self.notebook.set_current_page(3) # show form page
|
|
||||||
self.is_form = is_form
|
self.is_form = is_form
|
||||||
if is_form:
|
if is_form:
|
||||||
dataform = dataforms.ExtendForm(node = form)
|
dataform = dataforms.ExtendForm(node = form)
|
||||||
|
@ -3187,6 +3203,21 @@ class AccountCreationWizardWindow:
|
||||||
self.data_form_widget = FakeDataForm(form)
|
self.data_form_widget = FakeDataForm(form)
|
||||||
self.data_form_widget.show_all()
|
self.data_form_widget.show_all()
|
||||||
self.xml.get_widget('form_vbox').pack_start(self.data_form_widget)
|
self.xml.get_widget('form_vbox').pack_start(self.data_form_widget)
|
||||||
|
self.ssl_fingerprint = ssl_fingerprint
|
||||||
|
self.ssl_cert = ssl_cert
|
||||||
|
if ssl_msg:
|
||||||
|
# An SSL warning occured, show it
|
||||||
|
hostname = gajim.connections[self.account].new_account_info['hostname']
|
||||||
|
self.xml.get_widget('ssl_label').set_markup(_('<b>Security Warning</b>'
|
||||||
|
'\n\nThe authenticity of the %s SSL certificate could be invalid.\n'
|
||||||
|
'SSL Error: %s\n'
|
||||||
|
'Do you still want to connect to this server?') % (hostname,
|
||||||
|
ssl_msg))
|
||||||
|
text = _('Add this certificate to the list of trusted certificates.\nSHA1 fingerprint of the certificate:\n%s') % ssl_fingerprint
|
||||||
|
self.xml.get_widget('ssl_checkbutton').set_label(text)
|
||||||
|
self.notebook.set_current_page(3) # show SSL page
|
||||||
|
else:
|
||||||
|
self.notebook.set_current_page(4) # show form page
|
||||||
|
|
||||||
def new_acc_not_connected(self, reason):
|
def new_acc_not_connected(self, reason):
|
||||||
'''Account creation failed: connection to server failed'''
|
'''Account creation failed: connection to server failed'''
|
||||||
|
@ -3202,7 +3233,7 @@ class AccountCreationWizardWindow:
|
||||||
finish_text = '<big><b>%s</b></big>\n\n%s' % (
|
finish_text = '<big><b>%s</b></big>\n\n%s' % (
|
||||||
_('An error occurred during account creation') , reason)
|
_('An error occurred during account creation') , reason)
|
||||||
self.finish_label.set_markup(finish_text)
|
self.finish_label.set_markup(finish_text)
|
||||||
self.notebook.set_current_page(5) # show finish page
|
self.notebook.set_current_page(6) # show finish page
|
||||||
|
|
||||||
def acc_is_ok(self, config):
|
def acc_is_ok(self, config):
|
||||||
'''Account creation succeeded'''
|
'''Account creation succeeded'''
|
||||||
|
@ -3225,7 +3256,7 @@ class AccountCreationWizardWindow:
|
||||||
'button, or later by choosing the Accounts menuitem under the Edit '
|
'button, or later by choosing the Accounts menuitem under the Edit '
|
||||||
'menu from the main window.'))
|
'menu from the main window.'))
|
||||||
self.finish_label.set_markup(finish_text)
|
self.finish_label.set_markup(finish_text)
|
||||||
self.notebook.set_current_page(5) # show finish page
|
self.notebook.set_current_page(6) # show finish page
|
||||||
|
|
||||||
if self.update_progressbar_timeout_id is not None:
|
if self.update_progressbar_timeout_id is not None:
|
||||||
gobject.source_remove(self.update_progressbar_timeout_id)
|
gobject.source_remove(self.update_progressbar_timeout_id)
|
||||||
|
@ -3242,7 +3273,7 @@ class AccountCreationWizardWindow:
|
||||||
finish_text = '<big><b>%s</b></big>\n\n%s' % (_('An error occurred during '
|
finish_text = '<big><b>%s</b></big>\n\n%s' % (_('An error occurred during '
|
||||||
'account creation') , reason)
|
'account creation') , reason)
|
||||||
self.finish_label.set_markup(finish_text)
|
self.finish_label.set_markup(finish_text)
|
||||||
self.notebook.set_current_page(5) # show finish page
|
self.notebook.set_current_page(6) # show finish page
|
||||||
|
|
||||||
if self.update_progressbar_timeout_id is not None:
|
if self.update_progressbar_timeout_id is not None:
|
||||||
gobject.source_remove(self.update_progressbar_timeout_id)
|
gobject.source_remove(self.update_progressbar_timeout_id)
|
||||||
|
|
46
src/gajim.py
46
src/gajim.py
|
@ -998,10 +998,11 @@ class Interface:
|
||||||
return
|
return
|
||||||
|
|
||||||
def handle_event_new_acc_connected(self, account, array):
|
def handle_event_new_acc_connected(self, account, array):
|
||||||
#('NEW_ACC_CONNECTED', account, (infos, is_form))
|
#('NEW_ACC_CONNECTED', account, (infos, is_form, ssl_msg, ssl_cert,
|
||||||
|
# ssl_fingerprint))
|
||||||
if self.instances.has_key('account_creation_wizard'):
|
if self.instances.has_key('account_creation_wizard'):
|
||||||
self.instances['account_creation_wizard'].new_acc_connected(array[0],
|
self.instances['account_creation_wizard'].new_acc_connected(array[0],
|
||||||
array[1])
|
array[1], array[2], array[3], array[4])
|
||||||
|
|
||||||
def handle_event_new_acc_not_connected(self, account, array):
|
def handle_event_new_acc_not_connected(self, account, array):
|
||||||
#('NEW_ACC_NOT_CONNECTED', account, (reason))
|
#('NEW_ACC_NOT_CONNECTED', account, (reason))
|
||||||
|
@ -2160,6 +2161,45 @@ class Interface:
|
||||||
instance = data[1]
|
instance = data[1]
|
||||||
instance.unique_room_id_error(data[0])
|
instance.unique_room_id_error(data[0])
|
||||||
|
|
||||||
|
def handle_event_ssl_error(self, account, data):
|
||||||
|
# ('SSL_ERROR', account, (text, cert, sha1_fingerprint))
|
||||||
|
server = gajim.config.get_per('accounts', account, 'hostname')
|
||||||
|
def on_ok(is_checked):
|
||||||
|
if is_checked:
|
||||||
|
f = open(gajim.MY_CACERTS, 'a')
|
||||||
|
f.write(server + '\n')
|
||||||
|
f.write(data[1] + '\n\n')
|
||||||
|
f.close()
|
||||||
|
gajim.config.set_per('accounts', account, 'ssl_fingerprint_sha1',
|
||||||
|
data[2])
|
||||||
|
gajim.connections[account].ssl_certificate_accepted()
|
||||||
|
def on_cancel():
|
||||||
|
gajim.connections[account].disconnect(on_purpose=True)
|
||||||
|
self.handle_event_status(account, 'offline')
|
||||||
|
pritext = _('Error verifying SSL certificate')
|
||||||
|
sectext = _('There was an error verifying the SSL certificate of your jabber server: %(error)s\nDo you still want to connect to this server?') % {'error': data[0]}
|
||||||
|
checktext = _('Add this certificate to the list of trusted certificates.\nSHA1 fingerprint of the certificate:\n%s') % data[2]
|
||||||
|
dialogs.ConfirmationDialogCheck(pritext, sectext, checktext,
|
||||||
|
on_response_ok=on_ok, on_response_cancel=on_cancel)
|
||||||
|
|
||||||
|
def handle_event_fingerprint_error(self, account, data):
|
||||||
|
# ('FINGERPRINT_ERROR', account, (fingerprint,))
|
||||||
|
def on_yes(widget):
|
||||||
|
dialog.destroy()
|
||||||
|
gajim.config.set_per('accounts', account, 'ssl_fingerprint_sha1',
|
||||||
|
data[0])
|
||||||
|
gajim.connections[account].ssl_certificate_accepted()
|
||||||
|
def on_no(widget):
|
||||||
|
dialog.destroy()
|
||||||
|
gajim.connections[account].disconnect(on_purpose=True)
|
||||||
|
self.handle_event_status(account, 'offline')
|
||||||
|
pritext = _('SSL certificate error')
|
||||||
|
sectext = _('It seems SSL certificate has changed or your connection is '
|
||||||
|
'being hacked. Do you still want to connect and update the fingerprint'
|
||||||
|
'of the certificate?')
|
||||||
|
dialog = dialogs.YesNoDialog(pritext, sectext, on_response_yes=on_yes,
|
||||||
|
on_response_no=on_no)
|
||||||
|
|
||||||
def read_sleepy(self):
|
def read_sleepy(self):
|
||||||
'''Check idle status and change that status if needed'''
|
'''Check idle status and change that status if needed'''
|
||||||
if not self.sleeper.poll():
|
if not self.sleeper.poll():
|
||||||
|
@ -2497,6 +2537,8 @@ class Interface:
|
||||||
'UNIQUE_ROOM_ID_SUPPORTED': self.handle_event_unique_room_id_supported,
|
'UNIQUE_ROOM_ID_SUPPORTED': self.handle_event_unique_room_id_supported,
|
||||||
'SESSION_NEG': self.handle_session_negotiation,
|
'SESSION_NEG': self.handle_session_negotiation,
|
||||||
'GPG_PASSWORD_REQUIRED': self.handle_event_gpg_password_required,
|
'GPG_PASSWORD_REQUIRED': self.handle_event_gpg_password_required,
|
||||||
|
'SSL_ERROR': self.handle_event_ssl_error,
|
||||||
|
'FINGERPRINT_ERROR': self.handle_event_fingerprint_error,
|
||||||
}
|
}
|
||||||
gajim.handlers = self.handlers
|
gajim.handlers = self.handlers
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue