gossip r2797 - in trunk: . data/glade libgossip src



Author: mr
Date: Sat May  3 11:02:49 2008
New Revision: 2797
URL: http://svn.gnome.org/viewvc/gossip?rev=2797&view=rev

Log:
	* libgossip/gossip-account-manager.c:
	* libgossip/gossip-account.[ch]:
	* libgossip/gossip-account.dtd: 
	* src/gossip-account-widget-jabber.c: Add properties for ignoring
	SSL certificate errors and using the OLD SSL connection port.

	* data/glade/main.glade:
	* libgossip/gossip-jabber-private.h:
	* libgossip/gossip-jabber-register.c:
	* libgossip/gossip-jabber.c: Support feeding back the certificate
	errors to the user in the UI and support using STARTTLS when
	connecting on the standard Jabber port.


Modified:
   trunk/ChangeLog
   trunk/data/glade/main.glade
   trunk/libgossip/gossip-account-manager.c
   trunk/libgossip/gossip-account.c
   trunk/libgossip/gossip-account.dtd
   trunk/libgossip/gossip-account.h
   trunk/libgossip/gossip-jabber-private.h
   trunk/libgossip/gossip-jabber-register.c
   trunk/libgossip/gossip-jabber.c
   trunk/src/gossip-account-widget-jabber.c

Modified: trunk/data/glade/main.glade
==============================================================================
--- trunk/data/glade/main.glade	(original)
+++ trunk/data/glade/main.glade	Sat May  3 11:02:49 2008
@@ -7068,8 +7068,9 @@
 	  <child>
 	    <widget class="GtkCheckButton" id="checkbutton_ssl">
 	      <property name="visible">True</property>
+	      <property name="tooltip" translatable="yes">Encrypt all data sent when communicating with the server</property>
 	      <property name="can_focus">True</property>
-	      <property name="label" translatable="yes">Use encryption (SS_L)</property>
+	      <property name="label" translatable="yes">_Use encryption</property>
 	      <property name="use_underline">True</property>
 	      <property name="relief">GTK_RELIEF_NORMAL</property>
 	      <property name="focus_on_click">True</property>
@@ -7163,7 +7164,7 @@
 	  <child>
 	    <widget class="GtkTable" id="table15">
 	      <property name="visible">True</property>
-	      <property name="n_rows">4</property>
+	      <property name="n_rows">6</property>
 	      <property name="n_columns">2</property>
 	      <property name="homogeneous">False</property>
 	      <property name="row_spacing">6</property>
@@ -7230,7 +7231,7 @@
 	      <child>
 		<widget class="GtkLabel" id="label_resource">
 		  <property name="visible">True</property>
-		  <property name="label" translatable="yes">Reso_urce:</property>
+		  <property name="label" translatable="yes">_Location:</property>
 		  <property name="use_underline">True</property>
 		  <property name="use_markup">False</property>
 		  <property name="justify">GTK_JUSTIFY_LEFT</property>
@@ -7340,6 +7341,52 @@
 		  <property name="y_options"></property>
 		</packing>
 	      </child>
+
+	      <child>
+		<widget class="GtkCheckButton" id="checkbutton_force_old_ssl">
+		  <property name="visible">True</property>
+		  <property name="tooltip" translatable="yes">This is a legacy option required for supporting older servers which use a different port (5223) to communicate securely. With newer encryption techniques, the same port (5222) can be used for both</property>
+		  <property name="can_focus">True</property>
+		  <property name="label" translatable="yes">_Force older secure connection method</property>
+		  <property name="use_underline">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <property name="active">False</property>
+		  <property name="inconsistent">False</property>
+		  <property name="draw_indicator">True</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">4</property>
+		  <property name="bottom_attach">5</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkCheckButton" id="checkbutton_ignore_ssl_errors">
+		  <property name="visible">True</property>
+		  <property name="tooltip" translatable="yes">When checked, any certification errors will stop the connection attempt. For example, if the server's certificate has expired or the server simply doesn't have one, it is considered unsafe and the connection attempt will stop.</property>
+		  <property name="can_focus">True</property>
+		  <property name="label" translatable="yes">I_gnore security warnings</property>
+		  <property name="use_underline">True</property>
+		  <property name="relief">GTK_RELIEF_NORMAL</property>
+		  <property name="focus_on_click">True</property>
+		  <property name="active">False</property>
+		  <property name="inconsistent">False</property>
+		  <property name="draw_indicator">True</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">5</property>
+		  <property name="bottom_attach">6</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
 	    </widget>
 	  </child>
 

Modified: trunk/libgossip/gossip-account-manager.c
==============================================================================
--- trunk/libgossip/gossip-account-manager.c	(original)
+++ trunk/libgossip/gossip-account-manager.c	Sat May  3 11:02:49 2008
@@ -487,6 +487,10 @@
 			gossip_account_set_use_ssl (account, strcmp (str, "yes") == 0);
 		} else if (strcmp (tag, "use_proxy") == 0) {
 			gossip_account_set_use_proxy (account, strcmp (str, "yes") == 0);
+		} else if (strcmp (tag, "force_old_ssl") == 0) {
+			gossip_account_set_force_old_ssl (account, strcmp (str, "yes") == 0);
+		} else if (strcmp (tag, "ignore_ssl_errors") == 0) {
+			gossip_account_set_ignore_ssl_errors (account, strcmp (str, "yes") == 0);
 		}
 
 		xmlFree (str);
@@ -651,6 +655,8 @@
 		xmlNewChild (node, NULL, "auto_connect", gossip_account_get_auto_connect (account) ? "yes" : "no");
 		xmlNewChild (node, NULL, "use_ssl", gossip_account_get_use_ssl (account) ? "yes" : "no");
 		xmlNewChild (node, NULL, "use_proxy", gossip_account_get_use_proxy (account) ? "yes" : "no");
+		xmlNewChild (node, NULL, "force_old_ssl", gossip_account_get_force_old_ssl (account) ? "yes" : "no");
+		xmlNewChild (node, NULL, "ignore_ssl_errors", gossip_account_get_ignore_ssl_errors (account) ? "yes" : "no");
 
 		g_free (port);
 	}

Modified: trunk/libgossip/gossip-account.c
==============================================================================
--- trunk/libgossip/gossip-account.c	(original)
+++ trunk/libgossip/gossip-account.c	Sat May  3 11:02:49 2008
@@ -49,16 +49,18 @@
 typedef struct _GossipAccountPriv GossipAccountPriv;
 
 struct _GossipAccountPriv {
-	gchar             *name;
-	gchar             *id;
-	gchar             *password;
-	gchar             *password_tmp;
-	gchar             *resource;
-	gchar             *server;
-	guint16            port;
-	gboolean           auto_connect;
-	gboolean           use_ssl;
-	gboolean           use_proxy;
+	gchar    *name;
+	gchar    *id;
+	gchar    *password;
+	gchar    *password_tmp;
+	gchar    *resource;
+	gchar    *server;
+	guint16   port;
+	gboolean  auto_connect;
+	gboolean  use_ssl;
+	gboolean  use_proxy;
+	gboolean  force_old_ssl;
+	gboolean  ignore_ssl_errors;
 };
 
 static void gossip_account_class_init (GossipAccountClass *klass);
@@ -84,7 +86,9 @@
 	PROP_PORT,
 	PROP_AUTO_CONNECT,
 	PROP_USE_SSL,
-	PROP_USE_PROXY
+	PROP_USE_PROXY,
+	PROP_FORCE_OLD_SSL,
+	PROP_IGNORE_SSL_ERRORS
 };
 
 G_DEFINE_TYPE (GossipAccount, gossip_account, G_TYPE_OBJECT);
@@ -161,27 +165,43 @@
 
 	g_object_class_install_property (object_class,
 					 PROP_AUTO_CONNECT,
-					 g_param_spec_boolean ("auto_connect",
+					 g_param_spec_boolean ("auto-connect",
 							       "Account Auto Connect",
 							       "Connect on startup",
 							       TRUE,
-							       G_PARAM_READWRITE));
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
 	g_object_class_install_property (object_class,
 					 PROP_USE_SSL,
-					 g_param_spec_boolean ("use_ssl",
+					 g_param_spec_boolean ("use-ssl",
 							       "Account Uses SSL",
 							       "Identifies if the connection uses secure methods",
-							       FALSE,
-							       G_PARAM_READWRITE));
+							       TRUE,
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 	
 	g_object_class_install_property (object_class,
 					 PROP_USE_PROXY,
-					 g_param_spec_boolean ("use_proxy",
+					 g_param_spec_boolean ("use-proxy",
 							       "Account Uses Proxy",
 							       "Identifies if the connection uses the environment proxy",
 							       FALSE,
 							       G_PARAM_READWRITE));
+
+	g_object_class_install_property (object_class,
+					 PROP_FORCE_OLD_SSL,
+					 g_param_spec_boolean ("force-old-ssl",
+							       "Force Old SSL",
+							       "Connect to a different port for SSL, don't use STARTTLS",
+							       FALSE,
+							       G_PARAM_READWRITE));
+
+	g_object_class_install_property (object_class,
+					 PROP_IGNORE_SSL_ERRORS,
+					 g_param_spec_boolean ("ignore-ssl-errors",
+							       "Ignore SSL Errors",
+							       "If certificates are untrusted, expired, not found, etc, ignore it and just continue.",
+							       TRUE,
+							       G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 	
 	g_type_class_add_private (object_class, sizeof (GossipAccountPriv));
 }
@@ -189,23 +209,6 @@
 static void
 gossip_account_init (GossipAccount *account)
 {
-	GossipAccountPriv *priv;
-
-	priv = GET_PRIV (account);
-
-	priv->name         = NULL;
-
-	priv->id           = NULL;
-	priv->password     = NULL;
-	priv->password_tmp = NULL;
-	priv->resource     = NULL;
-	priv->server       = NULL;
-	priv->port         = 0;
-
-	priv->auto_connect = TRUE;
-
-	priv->use_ssl      = FALSE;
-	priv->use_proxy    = FALSE;
 }
 
 static void
@@ -270,6 +273,12 @@
 	case PROP_USE_PROXY:
 		g_value_set_boolean (value, priv->use_proxy);
 		break;
+	case PROP_FORCE_OLD_SSL:
+		g_value_set_boolean (value, priv->force_old_ssl);
+		break;
+	case PROP_IGNORE_SSL_ERRORS:
+		g_value_set_boolean (value, priv->ignore_ssl_errors);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 		break;
@@ -327,6 +336,14 @@
 		gossip_account_set_use_proxy (GOSSIP_ACCOUNT (object),
 					    g_value_get_boolean (value));
 		break;
+	case PROP_FORCE_OLD_SSL:
+		gossip_account_set_force_old_ssl (GOSSIP_ACCOUNT (object),
+						  g_value_get_boolean (value));
+		break;
+	case PROP_IGNORE_SSL_ERRORS:
+		gossip_account_set_ignore_ssl_errors (GOSSIP_ACCOUNT (object),
+						      g_value_get_boolean (value));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
 		break;
@@ -549,6 +566,28 @@
 	return priv->use_proxy;
 }
 
+gboolean
+gossip_account_get_force_old_ssl (GossipAccount *account)
+{
+	GossipAccountPriv *priv;
+
+	g_return_val_if_fail (GOSSIP_IS_ACCOUNT (account), FALSE);
+
+	priv = GET_PRIV (account);
+	return priv->force_old_ssl;
+}
+
+gboolean
+gossip_account_get_ignore_ssl_errors (GossipAccount *account)
+{
+	GossipAccountPriv *priv;
+
+	g_return_val_if_fail (GOSSIP_IS_ACCOUNT (account), TRUE);
+
+	priv = GET_PRIV (account);
+	return priv->ignore_ssl_errors;
+}
+
 void 
 gossip_account_set_name (GossipAccount *account,
 			 const gchar   *name)
@@ -751,7 +790,7 @@
 	priv = GET_PRIV (account);
 	priv->auto_connect = auto_connect;
 
-	g_object_notify (G_OBJECT (account), "auto_connect");
+	g_object_notify (G_OBJECT (account), "auto-connect");
 }
 
 void
@@ -765,7 +804,7 @@
 	priv = GET_PRIV (account);
 	priv->use_ssl = use_ssl;
 
-	g_object_notify (G_OBJECT (account), "use_ssl");
+	g_object_notify (G_OBJECT (account), "use-ssl");
 }
 
 void
@@ -779,7 +818,35 @@
 	priv = GET_PRIV (account);
 	priv->use_proxy = use_proxy;
 
-	g_object_notify (G_OBJECT (account), "use_proxy");
+	g_object_notify (G_OBJECT (account), "use-proxy");
+}
+
+void
+gossip_account_set_force_old_ssl (GossipAccount *account,
+				  gboolean       force_old_ssl)
+{
+	GossipAccountPriv *priv;
+
+	g_return_if_fail (GOSSIP_IS_ACCOUNT (account));
+
+	priv = GET_PRIV (account);
+	priv->force_old_ssl = force_old_ssl;
+
+	g_object_notify (G_OBJECT (account), "force-old-ssl");
+}
+
+void
+gossip_account_set_ignore_ssl_errors (GossipAccount *account,
+				      gboolean       ignore_ssl_errors)
+{
+	GossipAccountPriv *priv;
+
+	g_return_if_fail (GOSSIP_IS_ACCOUNT (account));
+
+	priv = GET_PRIV (account);
+	priv->ignore_ssl_errors = ignore_ssl_errors;
+
+	g_object_notify (G_OBJECT (account), "ignore-ssl-errors");
 }
 
 guint

Modified: trunk/libgossip/gossip-account.dtd
==============================================================================
--- trunk/libgossip/gossip-account.dtd	(original)
+++ trunk/libgossip/gossip-account.dtd	Sat May  3 11:02:49 2008
@@ -9,7 +9,7 @@
 <!ELEMENT default (#PCDATA)>
 
 <!ELEMENT account 
-    (name,id,(resource?),(password?),(server?),(port?),(auto_connect?),(use_ssl?),(use_proxy?))>
+    (name,id,(resource?),(password?),(server?),(port?),(auto_connect?),(use_ssl?),(use_proxy?),(force_old_ssl?),(ignore_ssl_errors?))>
 
 <!ELEMENT name (#PCDATA)>
 <!ELEMENT id (#PCDATA)>
@@ -20,3 +20,5 @@
 <!ELEMENT auto_connect (#PCDATA)>
 <!ELEMENT use_ssl (#PCDATA)>
 <!ELEMENT use_proxy (#PCDATA)>
+<!ELEMENT force_old_ssl (#PCDATA)>
+<!ELEMENT ignore_ssl_errors (#PCDATA)>

Modified: trunk/libgossip/gossip-account.h
==============================================================================
--- trunk/libgossip/gossip-account.h	(original)
+++ trunk/libgossip/gossip-account.h	Sat May  3 11:02:49 2008
@@ -55,53 +55,56 @@
 	GOSSIP_ACCOUNT_TYPE_COUNT
 } GossipAccountType;
 
-GType             gossip_account_get_type             (void) G_GNUC_CONST;
-
-const gchar *     gossip_account_get_name             (GossipAccount     *account);
-const gchar *     gossip_account_get_id               (GossipAccount     *account);
-const gchar *     gossip_account_get_password         (GossipAccount     *account);
-const gchar *     gossip_account_get_password_tmp     (GossipAccount     *account);
-const gchar *     gossip_account_get_resource         (GossipAccount     *account);
-const gchar *     gossip_account_get_server           (GossipAccount     *account);
-guint16           gossip_account_get_port             (GossipAccount     *account);
-gboolean          gossip_account_get_auto_connect     (GossipAccount     *account);
-gboolean          gossip_account_get_use_ssl          (GossipAccount     *account);
-gboolean          gossip_account_get_use_proxy        (GossipAccount     *account);
-
-void              gossip_account_set_id               (GossipAccount     *account,
-						       const gchar       *id);
-void              gossip_account_set_name             (GossipAccount     *account,
-						       const gchar       *name);
-void              gossip_account_set_password         (GossipAccount     *account,
-						       const gchar       *password);
-void              gossip_account_set_password_tmp     (GossipAccount     *account,
-						       const gchar       *password);
-void              gossip_account_set_resource         (GossipAccount     *account,
-						       const gchar       *resource);
-void              gossip_account_set_server           (GossipAccount     *account,
-						       const gchar       *server);
-void              gossip_account_set_port             (GossipAccount     *account,
-						       guint16            port);
-void              gossip_account_set_auto_connect     (GossipAccount     *account,
-						       gboolean           auto_connect);
-void              gossip_account_set_use_ssl          (GossipAccount     *account,
-						       gboolean           use_ssl);
-void              gossip_account_set_use_proxy        (GossipAccount     *account,
-						       gboolean           use_proxy);
-
-guint             gossip_account_hash                 (gconstpointer      key);
-gboolean          gossip_account_equal                (gconstpointer      a,
-						       gconstpointer      b);
+GType             gossip_account_get_type              (void) G_GNUC_CONST;
+const gchar *     gossip_account_get_name              (GossipAccount     *account);
+const gchar *     gossip_account_get_id                (GossipAccount     *account);
+const gchar *     gossip_account_get_password          (GossipAccount     *account);
+const gchar *     gossip_account_get_password_tmp      (GossipAccount     *account);
+const gchar *     gossip_account_get_resource          (GossipAccount     *account);
+const gchar *     gossip_account_get_server            (GossipAccount     *account);
+guint16           gossip_account_get_port              (GossipAccount     *account);
+gboolean          gossip_account_get_auto_connect      (GossipAccount     *account);
+gboolean          gossip_account_get_use_ssl           (GossipAccount     *account);
+gboolean          gossip_account_get_use_proxy         (GossipAccount     *account);
+gboolean          gossip_account_get_force_old_ssl     (GossipAccount     *account);
+gboolean          gossip_account_get_ignore_ssl_errors (GossipAccount     *account);
+void              gossip_account_set_id                (GossipAccount     *account,
+							const gchar       *id);
+void              gossip_account_set_name              (GossipAccount     *account,
+							const gchar       *name);
+void              gossip_account_set_password          (GossipAccount     *account,
+							const gchar       *password);
+void              gossip_account_set_password_tmp      (GossipAccount     *account,
+							const gchar       *password);
+void              gossip_account_set_resource          (GossipAccount     *account,
+							const gchar       *resource);
+void              gossip_account_set_server            (GossipAccount     *account,
+							const gchar       *server);
+void              gossip_account_set_port              (GossipAccount     *account,
+							guint16            port);
+void              gossip_account_set_auto_connect      (GossipAccount     *account,
+							gboolean           auto_connect);
+void              gossip_account_set_use_ssl           (GossipAccount     *account,
+							gboolean           use_ssl);
+void              gossip_account_set_use_proxy         (GossipAccount     *account,
+							gboolean           use_proxy);
+void              gossip_account_set_force_old_ssl     (GossipAccount     *account,
+							gboolean           force_old_ssl);
+void              gossip_account_set_ignore_ssl_errors (GossipAccount     *account,
+							gboolean           ignore_ssl_errors);
+guint             gossip_account_hash                  (gconstpointer      key);
+gboolean          gossip_account_equal                 (gconstpointer      a,
+							gconstpointer      b);
 
 /* Utils */
-const gchar *     gossip_account_type_to_string       (GossipAccountType  type);
-GossipAccountType gossip_account_string_to_type       (const gchar       *str);
-GdkPixbuf *       gossip_account_type_create_pixbuf   (GossipAccountType  type,
-						       GtkIconSize        icon_size);
-GdkPixbuf *       gossip_account_create_pixbuf        (GossipAccount     *account,
-						       GtkIconSize        icon_size);
-GdkPixbuf *       gossip_account_status_create_pixbuf (GossipAccount     *account,
-						       GtkIconSize        icon_size,
-						       gboolean           online);
+const gchar *     gossip_account_type_to_string        (GossipAccountType  type);
+GossipAccountType gossip_account_string_to_type        (const gchar       *str);
+GdkPixbuf *       gossip_account_type_create_pixbuf    (GossipAccountType  type,
+							GtkIconSize        icon_size);
+GdkPixbuf *       gossip_account_create_pixbuf         (GossipAccount     *account,
+							GtkIconSize        icon_size);
+GdkPixbuf *       gossip_account_status_create_pixbuf  (GossipAccount     *account,
+							GtkIconSize        icon_size,
+							gboolean           online);
 
 #endif /* __GOSSIP_ACCOUNT_H__ */

Modified: trunk/libgossip/gossip-jabber-private.h
==============================================================================
--- trunk/libgossip/gossip-jabber-private.h	(original)
+++ trunk/libgossip/gossip-jabber-private.h	Sat May  3 11:02:49 2008
@@ -28,8 +28,10 @@
 
 G_BEGIN_DECLS
 
-LmConnection *   gossip_jabber_new_connection (GossipAccount *account);
+LmConnection *   gossip_jabber_new_connection (GossipJabber  *jabber,
+					       GossipAccount *account);
 gboolean         gossip_jabber_set_connection (LmConnection  *connection,
+					       GossipJabber  *jabber,
 					       GossipAccount *account);
 LmConnection *   gossip_jabber_get_connection (GossipJabber  *jabber);
 GossipJabberFTs *gossip_jabber_get_fts        (GossipJabber  *jabber);

Modified: trunk/libgossip/gossip-jabber-register.c
==============================================================================
--- trunk/libgossip/gossip-jabber-register.c	(original)
+++ trunk/libgossip/gossip-jabber-register.c	Sat May  3 11:02:49 2008
@@ -90,7 +90,7 @@
 	
 	rd = g_new0 (RegisterData, 1);
 
-	rd->connection = gossip_jabber_new_connection (account);
+	rd->connection = gossip_jabber_new_connection (jabber, account);
 	if (!rd->connection) {
 		g_free (rd);
 		return NULL;

Modified: trunk/libgossip/gossip-jabber.c
==============================================================================
--- trunk/libgossip/gossip-jabber.c	(original)
+++ trunk/libgossip/gossip-jabber.c	Sat May  3 11:02:49 2008
@@ -83,6 +83,8 @@
 
 struct _GossipJabberPriv {
 	LmConnection          *connection;
+	LmSSLStatus            ssl_status;
+	gboolean               ssl_disconnection;
 
 	GossipContact         *contact;
 	GossipAccount         *account;
@@ -523,8 +525,6 @@
 				"resource", computer_name,
 				"port", port, 
 				"use_ssl", gossip_jabber_is_ssl_supported (),
-				"auto_connect", TRUE,
-				"use_proxy", FALSE,
 				NULL);
 
 	gossip_jid_unref (jid);
@@ -575,7 +575,7 @@
 
 	server = gossip_account_get_server (priv->account);
 
-	priv->connection = gossip_jabber_new_connection (account);
+	priv->connection = gossip_jabber_new_connection (jabber, account);
 
 	/* setup the connection to send keep alive messages every 30 seconds */
 	lm_connection_set_keep_alive_rate (priv->connection, 30);
@@ -636,6 +636,7 @@
 	gossip_debug (DEBUG_DOMAIN, "Refreshing connection details");
 
 	gossip_jabber_set_connection (priv->connection, 
+				      jabber,
 				      priv->account);
 
 	/* Update connection details and own contact information */
@@ -671,6 +672,13 @@
 	 */
 	priv->disconnect_request = FALSE;
 
+	/* This is important. If we just got disconnected because of
+	 * an invalid certificate, we need to reset this in case
+	 * things have changed since then.
+	 */
+	priv->ssl_status = LM_SSL_STATUS_NO_CERT_FOUND;
+	priv->ssl_disconnection = FALSE;
+
 	/* Set up new presence information */
 	if (priv->presence) {
 		g_object_unref (priv->presence);
@@ -797,6 +805,76 @@
 	return TRUE;
 }
 
+static const gchar *
+jabber_ssl_status_to_string (LmSSLStatus status)
+{
+	switch (status) {
+	case LM_SSL_STATUS_NO_CERT_FOUND:
+		return _("No certificate found");
+	case LM_SSL_STATUS_UNTRUSTED_CERT:
+		return _("Untrusted certificate");
+	case LM_SSL_STATUS_CERT_EXPIRED:
+		return _("Certificate expired");
+	case LM_SSL_STATUS_CERT_NOT_ACTIVATED:
+		return _("Certificate not activated");
+	case LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH:
+		return _("Certificate host mismatch");
+	case LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH:
+		return _("Certificate fingerprint mismatch");
+	case LM_SSL_STATUS_GENERIC_ERROR:
+		return _("Unknown security error occurred");
+	default:
+		break;
+	}
+
+	return _("Unknown error");
+}
+
+static LmSSLResponse
+jabber_ssl_status_cb (LmConnection  *connection,
+		      LmSSLStatus    status,
+		      GossipJabber  *jabber)
+{
+	GossipJabberPriv *priv;
+	GossipAccount    *account;
+	const gchar      *str;
+
+	priv = GET_PRIV (jabber);
+
+	str = jabber_ssl_status_to_string (status);
+	gossip_debug (DEBUG_DOMAIN, "%s", str);
+
+	priv->ssl_status = status;
+
+	account = gossip_jabber_get_account (jabber);
+
+	if (gossip_account_get_ignore_ssl_errors (account)) {
+		priv->ssl_disconnection = FALSE;
+		return LM_SSL_RESPONSE_CONTINUE;
+	} else {
+		priv->ssl_disconnection = TRUE;
+
+		/* FIXME: Not sure if this is a LM bug, but, we don't
+		 * disconnect properly in this situation when using
+		 * STARTTLS - so we force a disconnect
+		 */
+		if (!gossip_account_get_force_old_ssl (account)) {
+			GError      *error;
+			const gchar *str;
+
+			gossip_jabber_logout (jabber);
+
+			/* This code is duplicated because of this bug */
+			str = jabber_ssl_status_to_string (priv->ssl_status);
+			error = gossip_jabber_error_create (priv->ssl_status, str);
+			g_signal_emit_by_name (jabber, "error", account, error);
+			g_error_free (error);
+		}
+
+		return LM_SSL_RESPONSE_STOP;
+	}
+}
+
 static void
 jabber_connected_cb (LmConnection *connection,
 		     gboolean      result,
@@ -828,7 +906,21 @@
 	if (result == FALSE) {
 		gossip_debug (DEBUG_DOMAIN, "Cleaning up connection, disconnecting...");
 		gossip_jabber_logout (jabber);
-		gossip_jabber_error (jabber, GOSSIP_JABBER_NO_CONNECTION);
+
+		if (priv->ssl_disconnection) {
+			GossipAccount *account;
+			GError        *error;
+			const gchar   *str;
+
+			account = gossip_jabber_get_account (jabber);
+			str = jabber_ssl_status_to_string (priv->ssl_status);
+			error = gossip_jabber_error_create (priv->ssl_status, str);
+			g_signal_emit_by_name (jabber, "error", account, error);
+			g_error_free (error);
+		} else {
+			gossip_jabber_error (jabber, GOSSIP_JABBER_NO_CONNECTION);
+		}
+
 		return;
 	}
 
@@ -1004,45 +1096,6 @@
 	g_signal_emit_by_name (jabber, "disconnected", priv->account, gossip_reason);
 }
 
-static LmSSLResponse
-jabber_ssl_status_cb (LmConnection *connection,
-		      LmSSLStatus   status,
-		      GossipJabber *jabber)
-{
-	const gchar *str = "";
-
-	switch (status) {
-	case LM_SSL_STATUS_NO_CERT_FOUND:
-		str = "No certificate found";
-		break;
-	case LM_SSL_STATUS_UNTRUSTED_CERT:
-		str = "Untrusted certificate";
-		break;
-	case LM_SSL_STATUS_CERT_EXPIRED:
-		str = "Certificate expired";
-		break;
-	case LM_SSL_STATUS_CERT_NOT_ACTIVATED:
-		str = "Certificate not activated";
-		break;
-	case LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH:
-		str = "Certificate host mismatch";
-		break;
-	case LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH:
-		str = "Certificate fingerprint mismatch";
-		break;
-	case LM_SSL_STATUS_GENERIC_ERROR:
-		str = "Generic error";
-		break;
-	default:
-		str = "Unknown error:";
-		break;
-	}
-
-	gossip_debug (DEBUG_DOMAIN, "%s", str);
-
-	return LM_SSL_RESPONSE_CONTINUE;
-}
-
 static LmHandlerResult
 jabber_change_password_message_handler (LmMessageHandler      *handler,
 					LmConnection          *connection,
@@ -3397,6 +3450,7 @@
 
 gboolean
 gossip_jabber_set_connection (LmConnection  *connection, 
+			      GossipJabber  *jabber,
 			      GossipAccount *account)
 {
 	GossipJID    *jid;
@@ -3406,35 +3460,62 @@
 	gboolean      use_proxy = FALSE;
 
 	g_return_val_if_fail (connection != NULL, FALSE);
+	g_return_val_if_fail (GOSSIP_IS_JABBER (jabber), FALSE);
 	g_return_val_if_fail (GOSSIP_IS_ACCOUNT (account), FALSE);
 
+	gossip_debug (DEBUG_DOMAIN,
+		      "Setting connection details for account:'%s'", 
+		      gossip_account_get_name (account));
+
 	id = gossip_account_get_id (account);
 	if (id) {
+		gossip_debug (DEBUG_DOMAIN, "- ID:'%s'", id);
 		jid = gossip_jid_new (id);
 		lm_connection_set_jid (connection, gossip_jid_get_without_resource (jid));
 		gossip_jid_unref (jid);
 	}
 
+
 	server = gossip_account_get_server (account);
 	if (server) {
+		gossip_debug (DEBUG_DOMAIN, "- Server:'%s'", server);
 		lm_connection_set_server (connection, server);
 	}
 
 	port = gossip_account_get_port (account);
+	gossip_debug (DEBUG_DOMAIN, "- Port:%d", port);
 	lm_connection_set_port (connection, port);
 
-	if (gossip_account_get_use_ssl (account)) {
+	/* So here, we do the following:
+	 * Either: 
+	 * - If we should use old school SSL, set up simple SSL
+	 * OR: 
+	 * - Attempt to use STARTTLS.
+	 * - Require STARTTLS ONLY if the user requires security.
+	 * - Ignore SSL errors if we don't require security.
+	 */
+	if (gossip_account_get_force_old_ssl (account)) {
 		LmSSL *ssl;
 
-		gossip_debug (DEBUG_DOMAIN, "Using SSL");
-
-		ssl = lm_ssl_new (NULL,
-				  (LmSSLFunction) jabber_ssl_status_cb,
-				  NULL, NULL);
+		gossip_debug (DEBUG_DOMAIN, "- Using OLD SSL method for connection");
 
+		ssl = lm_ssl_new (NULL, 
+				  (LmSSLFunction) jabber_ssl_status_cb, 
+				  jabber, 
+				  NULL);
 		lm_connection_set_ssl (connection, ssl);
-		lm_connection_set_port (connection, port);
+		lm_ssl_unref (ssl);
+	} else {
+		LmSSL    *ssl;
+
+		gossip_debug (DEBUG_DOMAIN, "- Using STARTTLS method for connection");
 
+		ssl = lm_ssl_new (NULL, 
+				  (LmSSLFunction) jabber_ssl_status_cb, 
+				  jabber, 
+				  NULL);
+		lm_connection_set_ssl (connection, ssl);
+		lm_ssl_use_starttls (ssl, TRUE, gossip_account_get_use_ssl (account));
 		lm_ssl_unref (ssl);
 	}
 
@@ -3457,13 +3538,16 @@
 
 		if (use_proxy) {
 			LmProxy  *proxy;
-			
+
+			gossip_debug (DEBUG_DOMAIN, "- Proxy server:'%s', port:%d", host, port);
+	
 			proxy = lm_proxy_new_with_server (LM_PROXY_TYPE_HTTP,
 							  host, 
 							  (guint) port);
 			lm_connection_set_proxy (connection, proxy);
 			
 			if (use_auth) {
+				gossip_debug (DEBUG_DOMAIN, "- Proxy auth username:'%s'", username);
 				lm_proxy_set_username (proxy, username);
 				lm_proxy_set_password (proxy, password);
 			}
@@ -3485,7 +3569,8 @@
 }
 
 LmConnection *
-gossip_jabber_new_connection (GossipAccount *account)
+gossip_jabber_new_connection (GossipJabber  *jabber,
+			      GossipAccount *account)
 {
 	LmConnection *connection;
 	const gchar  *server;
@@ -3494,7 +3579,7 @@
 
 	server = gossip_account_get_server (account);
 	connection = lm_connection_new (server);
-	gossip_jabber_set_connection (connection, account);
+ 	gossip_jabber_set_connection (connection, jabber, account);
 
 	return connection;
 }

Modified: trunk/src/gossip-account-widget-jabber.c
==============================================================================
--- trunk/src/gossip-account-widget-jabber.c	(original)
+++ trunk/src/gossip-account-widget-jabber.c	Sat May  3 11:02:49 2008
@@ -72,8 +72,10 @@
 	GtkWidget     *entry_port;
 
 	GtkWidget     *checkbutton_ssl;
-	GtkWidget     *checkbutton_proxy;
 	GtkWidget     *checkbutton_auto_connect;
+	GtkWidget     *checkbutton_proxy;
+	GtkWidget     *checkbutton_force_old_ssl;
+	GtkWidget     *checkbutton_ignore_ssl_errors;
 
 	gboolean       registering;
 	gboolean       changing_password;
@@ -173,8 +175,10 @@
 				       "entry_server", &priv->entry_server,
 				       "entry_port", &priv->entry_port,
 				       "checkbutton_ssl", &priv->checkbutton_ssl,
-				       "checkbutton_proxy", &priv->checkbutton_proxy,
 				       "checkbutton_auto_connect", &priv->checkbutton_auto_connect,
+				       "checkbutton_proxy", &priv->checkbutton_proxy,
+				       "checkbutton_force_old_ssl", &priv->checkbutton_force_old_ssl,
+				       "checkbutton_ignore_ssl_errors", &priv->checkbutton_ignore_ssl_errors,
 				       NULL);
 
 	gossip_glade_connect (glade, 
@@ -203,10 +207,16 @@
 	g_signal_connect (priv->checkbutton_ssl, "toggled", 
 			  G_CALLBACK (account_widget_jabber_checkbutton_toggled_cb),
 			  settings);
+	g_signal_connect (priv->checkbutton_auto_connect, "toggled", 
+			  G_CALLBACK (account_widget_jabber_checkbutton_toggled_cb),
+			  settings);
 	g_signal_connect (priv->checkbutton_proxy, "toggled", 
 			  G_CALLBACK (account_widget_jabber_checkbutton_toggled_cb),
 			  settings);
-	g_signal_connect (priv->checkbutton_auto_connect, "toggled", 
+	g_signal_connect (priv->checkbutton_force_old_ssl, "toggled", 
+			  G_CALLBACK (account_widget_jabber_checkbutton_toggled_cb),
+			  settings);
+	g_signal_connect (priv->checkbutton_ignore_ssl_errors, "toggled", 
 			  G_CALLBACK (account_widget_jabber_checkbutton_toggled_cb),
 			  settings);
 
@@ -550,6 +560,7 @@
 		guint16        port_without_ssl;
 		guint16        port;
 		gboolean       use_ssl;
+		gboolean       force_old_ssl;
 		gboolean       changed = FALSE;
 
 		port_with_ssl = gossip_jabber_get_default_port (TRUE);
@@ -558,11 +569,19 @@
 		port = gossip_account_get_port (priv->account);
 
 		use_ssl = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton));
+		force_old_ssl = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->checkbutton_force_old_ssl));
 
-		if (use_ssl) {
-			if (port == port_without_ssl) {
-				port = port_with_ssl;
-				changed = TRUE;
+		if (force_old_ssl) {
+			if (use_ssl) {
+				if (port == port_without_ssl) {
+					port = port_with_ssl;
+					changed = TRUE;
+				}
+			} else {
+				if (port == port_with_ssl) {
+					port = port_without_ssl;
+					changed = TRUE;
+				}
 			}
 		} else {
 			if (port == port_with_ssl) {
@@ -581,16 +600,76 @@
 			gtk_entry_set_text (GTK_ENTRY (priv->entry_port), port_str);
 			g_free (port_str);
 		}
-	} else if (checkbutton == priv->checkbutton_proxy) {
-		gboolean use_proxy;
 
-		use_proxy = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton));
-		gossip_account_set_use_proxy (priv->account, use_proxy);
+		/* So if we use STARTTLS we don't worry if we get SSL
+		 * errors since we might not use it and may fallback.
+		 */ 
+		if (!use_ssl) {
+			gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbutton_ignore_ssl_errors), TRUE);
+		}
+
+		gtk_widget_set_sensitive (priv->checkbutton_force_old_ssl, use_ssl);
+		gtk_widget_set_sensitive (priv->checkbutton_ignore_ssl_errors, use_ssl);
 	} else if (checkbutton == priv->checkbutton_auto_connect) {
 		gboolean auto_connect;
 
 		auto_connect = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton));
 		gossip_account_set_auto_connect (priv->account, auto_connect);
+	} else if (checkbutton == priv->checkbutton_proxy) {
+		gboolean use_proxy;
+
+		use_proxy = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton));
+		gossip_account_set_use_proxy (priv->account, use_proxy);
+	} else if (checkbutton == priv->checkbutton_force_old_ssl) {
+		guint16        port_with_ssl;
+		guint16        port_without_ssl;
+		guint16        port;
+		gboolean       use_ssl;
+		gboolean       force_old_ssl;
+		gboolean       changed = FALSE;
+
+		port_with_ssl = gossip_jabber_get_default_port (TRUE);
+		port_without_ssl = gossip_jabber_get_default_port (FALSE);
+
+		port = gossip_account_get_port (priv->account);
+		
+		force_old_ssl = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton));
+		use_ssl = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->checkbutton_ssl));
+
+		if (force_old_ssl) {
+			if (use_ssl) {
+				if (port == port_without_ssl) {
+					port = port_with_ssl;
+					changed = TRUE;
+				}
+			} else {
+				if (port == port_with_ssl) {
+					port = port_without_ssl;
+					changed = TRUE;
+				}
+			}
+		} else {
+			if (port == port_with_ssl) {
+				port = port_without_ssl;
+				changed = TRUE;
+			}
+		}
+
+		gossip_account_set_force_old_ssl (priv->account, force_old_ssl);
+		gossip_account_set_port (priv->account, port);
+
+		if (changed) {
+			gchar *port_str;
+
+			port_str = g_strdup_printf ("%d", port);
+			gtk_entry_set_text (GTK_ENTRY (priv->entry_port), port_str);
+			g_free (port_str);
+		}
+	} else if (checkbutton == priv->checkbutton_ignore_ssl_errors) {
+		gboolean ignore_ssl_errors;
+
+		ignore_ssl_errors = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton));
+		gossip_account_set_ignore_ssl_errors (priv->account, ignore_ssl_errors);
 	}
 
 	gossip_debug (DEBUG_DOMAIN, "Checkbutton toggled, saving accounts...");
@@ -845,8 +924,10 @@
 	const gchar                   *server;
 	const gchar                   *password;
 	gboolean                       use_ssl;
-	gboolean                       use_proxy;
 	gboolean                       auto_connect;
+	gboolean                       use_proxy;
+	gboolean                       force_old_ssl;
+	gboolean                       ignore_ssl_errors;
 	gboolean                       is_connected;
 
 	priv = GET_PRIV (settings);
@@ -859,34 +940,54 @@
 	server = gossip_account_get_server (priv->account);
 	port = gossip_account_get_port (priv->account);
 	use_ssl = gossip_account_get_use_ssl (priv->account);
-	use_proxy = gossip_account_get_use_proxy (priv->account);
 	auto_connect = gossip_account_get_auto_connect (priv->account);
+	use_proxy = gossip_account_get_use_proxy (priv->account);
+	force_old_ssl = gossip_account_get_force_old_ssl (priv->account);
+	ignore_ssl_errors = gossip_account_get_ignore_ssl_errors (priv->account);
 
 	/* Set up checkbuttons, but block signals first */
 	g_signal_handlers_block_by_func (priv->checkbutton_ssl, 
 					 account_widget_jabber_checkbutton_toggled_cb,
 					 settings);
+	g_signal_handlers_block_by_func (priv->checkbutton_auto_connect, 
+					 account_widget_jabber_checkbutton_toggled_cb,
+					 settings);
 	g_signal_handlers_block_by_func (priv->checkbutton_proxy, 
 					 account_widget_jabber_checkbutton_toggled_cb,
 					 settings);
-	g_signal_handlers_block_by_func (priv->checkbutton_auto_connect, 
+	g_signal_handlers_block_by_func (priv->checkbutton_force_old_ssl, 
+					 account_widget_jabber_checkbutton_toggled_cb,
+					 settings);
+	g_signal_handlers_block_by_func (priv->checkbutton_ignore_ssl_errors, 
 					 account_widget_jabber_checkbutton_toggled_cb,
 					 settings);
 	if (gossip_jabber_is_ssl_supported ()) {
 		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbutton_ssl), use_ssl);
+		gtk_widget_set_sensitive (priv->checkbutton_ssl, TRUE);
+		gtk_widget_set_sensitive (priv->checkbutton_force_old_ssl, use_ssl);
+		gtk_widget_set_sensitive (priv->checkbutton_ignore_ssl_errors, use_ssl);
 	} else {
 		gtk_widget_set_sensitive (priv->checkbutton_ssl, FALSE);
+		gtk_widget_set_sensitive (priv->checkbutton_force_old_ssl, FALSE);
+		gtk_widget_set_sensitive (priv->checkbutton_ignore_ssl_errors, FALSE);
 	}
 
-	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbutton_proxy), use_proxy);
 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbutton_auto_connect), auto_connect);
+ 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbutton_force_old_ssl), force_old_ssl);
+ 	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbutton_ignore_ssl_errors), ignore_ssl_errors);
 
-	g_signal_handlers_unblock_by_func (priv->checkbutton_ssl, 
+	g_signal_handlers_unblock_by_func (priv->checkbutton_ignore_ssl_errors, 
+					   account_widget_jabber_checkbutton_toggled_cb,
+					   settings);
+	g_signal_handlers_unblock_by_func (priv->checkbutton_force_old_ssl, 
 					   account_widget_jabber_checkbutton_toggled_cb,
 					   settings);
 	g_signal_handlers_unblock_by_func (priv->checkbutton_proxy, 
 					   account_widget_jabber_checkbutton_toggled_cb,
 					   settings);
+	g_signal_handlers_unblock_by_func (priv->checkbutton_ssl, 
+					   account_widget_jabber_checkbutton_toggled_cb,
+					   settings);
 	g_signal_handlers_unblock_by_func (priv->checkbutton_auto_connect, 
 					   account_widget_jabber_checkbutton_toggled_cb,
 					   settings);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]