changeset 12167:5851a9219bc7

[gaim-migrate @ 14468] Some SILC fixes from Pekka for whiteboard support, preferences, and documentation. Let's hear a big thanks to Pekka for keeping up with this stuff! Enclosed patch fixes couple crashbugs from the SILC whiteboard code, fixes the preferences (which are not used anymore in Gaim) by eliminating some of the old preferences and moving some of the preferences to account options, and introduces Create SILC Key Pair protocol action which can be used to generate new SILC key pair from Gaim. committer: Tailor Script <tailor@pidgin.im>
author Ethan Blanton <elb@pidgin.im>
date Sun, 20 Nov 2005 00:59:36 +0000
parents d6417efb990c
children dd7392cce819
files src/protocols/silc/README src/protocols/silc/TODO src/protocols/silc/buddy.c src/protocols/silc/chat.c src/protocols/silc/ops.c src/protocols/silc/silc.c src/protocols/silc/wb.c
diffstat 7 files changed, 276 insertions(+), 107 deletions(-) [+]
line wrap: on
line diff
--- a/src/protocols/silc/README	Sat Nov 19 18:09:51 2005 +0000
+++ b/src/protocols/silc/README	Sun Nov 20 00:59:36 2005 +0000
@@ -9,7 +9,7 @@
 To include the SILC into Gaim, one needs to first compile and install 
 the SILC Toolkit.  It is done as follows:
 
-	./configure --enable-shared --without-silcd --without-irssi
+	./configure --enable-shared
 	make
 	make install
 
@@ -18,7 +18,11 @@
 /usr/local/silc directory.
 
 Once the Toolkit is installed one needs to tell for the Gaim ./configure
-script where the SILC Toolkit is located.  It is done as follows:
+script where the SILC Toolkit is located.  It is done as simply as:
+
+	./configure
+
+if pkg-config is installed in your system.  If it is isn't it's done as:
 
 	./configure --with-silc-libs=/path/to/silc/lib
 		    --with-silc-includes=/path/to/silc/include
--- a/src/protocols/silc/TODO	Sat Nov 19 18:09:51 2005 +0000
+++ b/src/protocols/silc/TODO	Sun Nov 20 00:59:36 2005 +0000
@@ -1,6 +1,11 @@
 Features TODO (maybe)
 =====================
 
+Sending images
+	- PROTO_IM_IMAGES flag support.  We need easy way to map the
+	  image filenames to their MIME types to do this.
+	- Sending images to channel too, if Gaim allows it.
+
 Preferences
 	- Add joined channels to buddy list automatically (during
 	  session)
--- a/src/protocols/silc/buddy.c	Sat Nov 19 18:09:51 2005 +0000
+++ b/src/protocols/silc/buddy.c	Sun Nov 20 00:59:36 2005 +0000
@@ -1109,8 +1109,9 @@
 	GaimRequestFields *fields;
 	GaimRequestFieldGroup *g;
 	GaimRequestField *f;
-	char tmp[512];
+	char tmp[512], tmp2[128];
 	int i;
+	char *fingerprint;
 
 	fields = gaim_request_fields_new();
 	g = gaim_request_field_group_new(NULL);
@@ -1120,11 +1121,19 @@
 	gaim_request_fields_add_group(fields, g);
 
 	for (i = 0; i < clients_count; i++) {
-		g_snprintf(tmp, sizeof(tmp), "%s - %s (%s@%s)",
+		fingerprint = NULL;
+		if (clients[i]->fingerprint) {
+			fingerprint = silc_fingerprint(clients[i]->fingerprint,
+						       clients[i]->fingerprint_len);
+			g_snprintf(tmp2, sizeof(tmp2), "\n%s", fingerprint);
+		}
+		g_snprintf(tmp, sizeof(tmp), "%s - %s (%s@%s)%s",
 			   clients[i]->realname, clients[i]->nickname,
 			   clients[i]->username, clients[i]->hostname ?
-			   clients[i]->hostname : "");
+			   clients[i]->hostname : "",
+			   fingerprint ? tmp2 : "");
 		gaim_request_field_list_add(f, tmp, clients[i]);
+		silc_free(fingerprint);
 	}
 
 	gaim_request_fields(r->client->application, _("Add Buddy"),
@@ -1615,12 +1624,13 @@
 		m = g_list_append(m, act);
 	}
 
-	wb = silc_calloc(1, sizeof(*wb));
-	wb->sg = sg;
-	wb->client_entry = client_entry;
-	act = gaim_blist_node_action_new(_("Draw On Whiteboard"),
-	                                 silcgaim_buddy_wb, (void *)wb, NULL);
-	m = g_list_append(m, act);
-
+	if (client_entry) {
+		wb = silc_calloc(1, sizeof(*wb));
+		wb->sg = sg;
+		wb->client_entry = client_entry;
+		act = gaim_blist_node_action_new(_("Draw On Whiteboard"),
+		                                 silcgaim_buddy_wb, (void *)wb, NULL);
+		m = g_list_append(m, act);
+	}
 	return m;
 }
--- a/src/protocols/silc/chat.c	Sat Nov 19 18:09:51 2005 +0000
+++ b/src/protocols/silc/chat.c	Sun Nov 20 00:59:36 2005 +0000
@@ -1271,7 +1271,7 @@
 	const char *msg2;
 	char *tmp;
 	gboolean found = FALSE;
-	gboolean sign = gaim_prefs_get_bool("/plugins/prpl/silc/sign_chat");
+	gboolean sign = gaim_account_get_bool(sg->account, "sign-verify", FALSE);
 
 	if (!msg || !conn)
 		return 0;
--- a/src/protocols/silc/ops.c	Sat Nov 19 18:09:51 2005 +0000
+++ b/src/protocols/silc/ops.c	Sun Nov 20 00:59:36 2005 +0000
@@ -76,7 +76,7 @@
 		return;
 
 	if (flags & SILC_MESSAGE_FLAG_SIGNED &&
-	    gaim_prefs_get_bool("/plugins/prpl/silc/verify_chat")) {
+	    gaim_account_get_bool(sg->account, "sign-verify", FALSE)) {
 		/* XXX */
 	}
 
@@ -94,7 +94,8 @@
 			return;
 
 		if (!strcmp(type, "application/x-wb") &&
-		    !strcmp(enc, "binary"))
+		    !strcmp(enc, "binary") &&
+		    !gaim_account_get_bool(sg->account, "block-wb", FALSE))
 			silcgaim_wb_receive_ch(client, conn, sender, channel,
 					       payload, flags, data, data_len);
 
@@ -171,7 +172,7 @@
 								sender->nickname, sg->account);
 
 	if (flags & SILC_MESSAGE_FLAG_SIGNED &&
-	    gaim_prefs_get_bool("/plugins/prpl/silc/verify_im")) {
+	    gaim_account_get_bool(sg->account, "sign-verify", FALSE)) {
 		/* XXX */
 	}
 
@@ -189,7 +190,8 @@
 			return;
 
 		if (!strcmp(type, "application/x-wb") &&
-		    !strcmp(enc, "binary"))
+		    !strcmp(enc, "binary") &&
+		    !gaim_account_get_bool(sg->account, "block-wb", FALSE))
 			silcgaim_wb_receive(client, conn, sender, payload,
 					    flags, data, data_len);
 
--- a/src/protocols/silc/silc.c	Sat Nov 19 18:09:51 2005 +0000
+++ b/src/protocols/silc/silc.c	Sun Nov 20 00:59:36 2005 +0000
@@ -316,7 +316,8 @@
 							(char *)gaim_account_get_string(account, "private-key", prd),
 				(gc->password == NULL) ? "" : gc->password, &client->pkcs,
 				&client->public_key, &client->private_key)) {
-		gaim_connection_error(gc, ("Could not load SILC key pair"));
+		g_snprintf(pkd, sizeof(pkd), ("Could not load SILC key pair: %s"), strerror(errno));
+		gaim_connection_error(gc, pkd);
 		return;
 	}
 
@@ -512,7 +513,7 @@
 	if (f)
 		val = gaim_request_field_string_get_value(f);
 	if (val && *val) {
-		gaim_prefs_set_string("/plugins/prpl/silc/vcard", val);
+		gaim_account_set_string(sg->account, "vcard", val);
 		tmp = silc_file_readfile(val, &tmp_len);
 		if (tmp) {
 			tmp[tmp_len] = 0;
@@ -524,6 +525,8 @@
 		}
 		silc_vcard_free(&vcard);
 		silc_free(tmp);
+	} else {
+		gaim_account_set_string(sg->account, "vcard", "");
 	}
 
 #ifdef HAVE_SYS_UTSNAME_H
@@ -696,7 +699,7 @@
 
 	g = gaim_request_field_group_new(NULL);
 	f = gaim_request_field_string_new("vcard", _("Your VCard File"),
-					  gaim_prefs_get_string("/plugins/prpl/silc/vcard"),
+					  gaim_account_get_string(sg->account, "vcard", ""),
 					  FALSE);
 	gaim_request_field_group_add_field(g, f);
 #ifdef _WIN32
@@ -707,7 +710,6 @@
 	gaim_request_field_group_add_field(g, f);
 	gaim_request_fields_add_group(fields, g);
 
-
 	gaim_request_fields(gc, _("User Online Status Attributes"),
 			    _("User Online Status Attributes"),
 			    _("You can let other users see your online status information "
@@ -762,6 +764,171 @@
 }
 
 static void
+silcgaim_create_keypair_cancel(GaimConnection *gc, GaimRequestFields *fields)
+{
+	/* Nothing */
+}
+
+static void
+silcgaim_create_keypair_cb(GaimConnection *gc, GaimRequestFields *fields)
+{
+	SilcGaim sg = gc->proto_data;
+	GaimRequestField *f;
+	const char *val, *pkfile = NULL, *prfile = NULL;
+	const char *pass1 = NULL, *pass2 = NULL, *un = NULL, *hn = NULL;
+	const char *rn = NULL, *e = NULL, *o = NULL, *c = NULL;
+	char *identifier;
+	int keylen = SILCGAIM_DEF_PKCS_LEN;
+	SilcPublicKey public_key;
+
+	sg = gc->proto_data;
+	if (!sg)
+		return;
+
+	val = NULL;
+	f = gaim_request_fields_get_field(fields, "pass1");
+	if (f)
+		val = gaim_request_field_string_get_value(f);
+	if (val && *val)
+		pass1 = val;
+	else
+		pass1 = "";
+	val = NULL;
+	f = gaim_request_fields_get_field(fields, "pass2");
+	if (f)
+		val = gaim_request_field_string_get_value(f);
+	if (val && *val)
+		pass2 = val;
+	else
+		pass2 = "";
+
+	if (strcmp(pass1, pass2)) {
+		gaim_notify_error(
+		     gc, _("Create New SILC Key Pair"), _("Passphrases do not match"), NULL);
+		return;
+	}
+
+	val = NULL;
+	f = gaim_request_fields_get_field(fields, "key");
+	if (f)
+		val = gaim_request_field_string_get_value(f);
+	if (val && *val)
+		keylen = atoi(val);
+	f = gaim_request_fields_get_field(fields, "pkfile");
+	if (f)
+		pkfile = gaim_request_field_string_get_value(f);
+	f = gaim_request_fields_get_field(fields, "prfile");
+	if (f)
+		prfile = gaim_request_field_string_get_value(f);
+
+	f = gaim_request_fields_get_field(fields, "un");
+	if (f)
+		un = gaim_request_field_string_get_value(f);
+	f = gaim_request_fields_get_field(fields, "hn");
+	if (f)
+		hn = gaim_request_field_string_get_value(f);
+	f = gaim_request_fields_get_field(fields, "rn");
+	if (f)
+		rn = gaim_request_field_string_get_value(f);
+	f = gaim_request_fields_get_field(fields, "e");
+	if (f)
+		e = gaim_request_field_string_get_value(f);
+	f = gaim_request_fields_get_field(fields, "o");
+	if (f)
+		o = gaim_request_field_string_get_value(f);
+	f = gaim_request_fields_get_field(fields, "c");
+	if (f)
+		c = gaim_request_field_string_get_value(f);
+
+	identifier = silc_pkcs_encode_identifier((char *)un, (char *)hn, 
+						 (char *)rn, (char *)e, (char *)o, (char *)c);
+
+	/* Create the key pair */
+	if (!silc_create_key_pair(SILCGAIM_DEF_PKCS, keylen, pkfile, prfile,
+				  identifier, pass1, NULL, &public_key, NULL, 
+				  FALSE)) {
+		gaim_notify_error(
+		     gc, _("Create New SILC Key Pair"), _("Key Pair Generation failed"), NULL);
+		return;
+	}
+
+	silcgaim_show_public_key(sg, NULL, public_key, NULL, NULL);
+
+	silc_pkcs_public_key_free(public_key);
+	silc_free(identifier);
+}
+
+static void
+silcgaim_create_keypair(GaimPluginAction *action)
+{
+	GaimConnection *gc = (GaimConnection *) action->context;
+	SilcGaim sg = gc->proto_data;
+	GaimRequestFields *fields;
+	GaimRequestFieldGroup *g;
+	GaimRequestField *f;
+	const char *username, *realname;
+	char *hostname, **u;
+	char tmp[256], pkd[256], pkd2[256], prd[256], prd2[256];
+
+	username = gaim_account_get_username(sg->account);
+	u = g_strsplit(username, "@", 2);
+	username = u[0];
+	realname = gaim_account_get_user_info(sg->account);
+	hostname = silc_net_localhost();
+	g_snprintf(tmp, sizeof(tmp), "%s@%s", username, hostname);
+
+	g_snprintf(pkd2, sizeof(pkd2), "%s" G_DIR_SEPARATOR_S"public_key.pub", silcgaim_silcdir());
+	g_snprintf(prd2, sizeof(prd2), "%s" G_DIR_SEPARATOR_S"private_key.prv", silcgaim_silcdir());
+	g_snprintf(pkd, sizeof(pkd) - 1, "%s",
+		   gaim_account_get_string(gc->account, "public-key", pkd2));
+	g_snprintf(prd, sizeof(prd) - 1, "%s",
+		   gaim_account_get_string(gc->account, "private-key", prd2));
+
+	fields = gaim_request_fields_new();
+
+	g = gaim_request_field_group_new(NULL);
+	f = gaim_request_field_string_new("key", _("Key Length"), "2048", FALSE);
+	gaim_request_field_group_add_field(g, f);
+	f = gaim_request_field_string_new("pkfile", _("Public Key File"), pkd, FALSE);
+	gaim_request_field_group_add_field(g, f);
+	f = gaim_request_field_string_new("prfile", _("Private Key File"), prd, FALSE);
+	gaim_request_field_group_add_field(g, f);
+	gaim_request_fields_add_group(fields, g);
+
+	g = gaim_request_field_group_new(NULL);
+	f = gaim_request_field_string_new("un", _("Username"), username ? username : "", FALSE);
+	gaim_request_field_group_add_field(g, f);
+	f = gaim_request_field_string_new("hn", _("Hostname"), hostname ? hostname : "", FALSE);
+	gaim_request_field_group_add_field(g, f);
+	f = gaim_request_field_string_new("rn", _("Real Name"), realname ? realname : "", FALSE);
+	gaim_request_field_group_add_field(g, f);
+	f = gaim_request_field_string_new("e", _("Email"), tmp, FALSE);
+	gaim_request_field_group_add_field(g, f);
+	f = gaim_request_field_string_new("o", _("Organization"), "", FALSE);
+	gaim_request_field_group_add_field(g, f);
+	f = gaim_request_field_string_new("c", _("Country"), "", FALSE);
+	gaim_request_field_group_add_field(g, f);
+	gaim_request_fields_add_group(fields, g);
+
+	g = gaim_request_field_group_new(NULL);
+	f = gaim_request_field_string_new("pass1", _("Passphrase"), "", FALSE);
+	gaim_request_field_string_set_masked(f, TRUE);
+	gaim_request_field_group_add_field(g, f);
+	f = gaim_request_field_string_new("pass2", _("Re-type Passphrase"), "", FALSE);
+	gaim_request_field_string_set_masked(f, TRUE);
+	gaim_request_field_group_add_field(g, f);
+	gaim_request_fields_add_group(fields, g);
+
+	gaim_request_fields(gc, _("Create New SILC Key Pair"),
+			    _("Create New SILC Key Pair"), NULL, fields,
+			    _("Generate Key Pair"), G_CALLBACK(silcgaim_create_keypair_cb),
+			    _("Cancel"), G_CALLBACK(silcgaim_create_keypair_cancel), gc);
+
+	g_strfreev(u);
+	silc_free(hostname);
+}
+
+static void
 silcgaim_change_pass(GaimPluginAction *action)
 {
 	GaimConnection *gc = (GaimConnection *) action->context;
@@ -811,6 +978,10 @@
 			silcgaim_view_motd);
 	list = g_list_append(list, act);
 
+	act = gaim_plugin_action_new(_("Create SILC Key Pair..."),
+			silcgaim_create_keypair);
+	list = g_list_append(list, act);
+
 	act = gaim_plugin_action_new(_("Change Password..."),
 			silcgaim_change_pass);
 	list = g_list_append(list, act);
@@ -901,7 +1072,7 @@
 	SilcUInt32 clients_count, mflags;
 	char *nickname;
 	int ret;
-	gboolean sign = gaim_prefs_get_bool("/plugins/prpl/silc/sign_im");
+	gboolean sign = gaim_account_get_bool(sg->account, "sign-verify", FALSE);
 
 	if (!who || !msg)
 		return 0;
@@ -1443,48 +1614,6 @@
 #endif
 }
 
-static GaimPluginPrefFrame *
-silcgaim_pref_frame(GaimPlugin *plugin)
-{
-	GaimPluginPrefFrame *frame;
-	GaimPluginPref *ppref;
-
-	frame = gaim_plugin_pref_frame_new();
-
-	ppref = gaim_plugin_pref_new_with_label(_("Instant Messages"));
-	gaim_plugin_pref_frame_add(frame, ppref);
-
-	ppref = gaim_plugin_pref_new_with_name_and_label(
-			    "/plugins/prpl/silc/sign_im",
-			    _("Digitally sign all IM messages"));
-	gaim_plugin_pref_frame_add(frame, ppref);
-
-	ppref = gaim_plugin_pref_new_with_name_and_label(
-			    "/plugins/prpl/silc/verify_im",
-			    _("Verify all IM message signatures"));
-	gaim_plugin_pref_frame_add(frame, ppref);
-
-	ppref = gaim_plugin_pref_new_with_label(_("Channel Messages"));
-	gaim_plugin_pref_frame_add(frame, ppref);
-
-	ppref = gaim_plugin_pref_new_with_name_and_label(
-			    "/plugins/prpl/silc/sign_chat",
-			    _("Digitally sign all channel messages"));
-	gaim_plugin_pref_frame_add(frame, ppref);
-
-	ppref = gaim_plugin_pref_new_with_name_and_label(
-			    "/plugins/prpl/silc/verify_chat",
-			    _("Verify all channel message signatures"));
-	gaim_plugin_pref_frame_add(frame, ppref);
-
-	return frame;
-}
-
-static GaimPluginUiInfo prefs_info =
-{
-	silcgaim_pref_frame,
-};
-
 static GaimWhiteboardPrplOps silcgaim_wb_ops =
 {
 	silcgaim_wb_start,
@@ -1588,7 +1717,7 @@
 
 	NULL,                                             /**< ui_info        */
 	&prpl_info,                                       /**< extra_info     */
-	&prefs_info,                                      /**< prefs_info     */
+	NULL,                                             /**< prefs_info     */
 	silcgaim_actions
 };
 
@@ -1635,14 +1764,17 @@
 	option = gaim_account_option_bool_new(_("Reject online status attribute requests"),
 					      "reject-attrs", FALSE);
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
+	option = gaim_account_option_bool_new(_("Block messages to whiteboard"),
+					      "block-wb", FALSE);
+	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
+	option = gaim_account_option_bool_new(_("Automatically open whiteboard"),
+					      "open-wb", FALSE);
+	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
+	option = gaim_account_option_bool_new(_("Digitally sign and verify all messages"),
+					      "sign-verify", FALSE);
+	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, option);
 
-	/* Preferences */
-	gaim_prefs_add_none("/plugins/prpl/silc");
-	gaim_prefs_add_bool("/plugins/prpl/silc/sign_im", FALSE);
-	gaim_prefs_add_bool("/plugins/prpl/silc/verify_im", FALSE);
-	gaim_prefs_add_bool("/plugins/prpl/silc/sign_chat", FALSE);
-	gaim_prefs_add_bool("/plugins/prpl/silc/verify_chat", FALSE);
-	gaim_prefs_add_string("/plugins/prpl/silc/vcard", "");
+	gaim_prefs_remove("/plugins/prpl/silc");
 
 	silcgaim_register_commands();
 
--- a/src/protocols/silc/wb.c	Sat Nov 19 18:09:51 2005 +0000
+++ b/src/protocols/silc/wb.c	Sun Nov 20 00:59:36 2005 +0000
@@ -111,25 +111,26 @@
 	conn = sg->conn;
 	wb = gaim_whiteboard_get_session(sg->account, client_entry->nickname);
 	if (!wb)
-		wb = gaim_whiteboard_create(sg->account, client_entry->nickname,
-					    0);
+		wb = gaim_whiteboard_create(sg->account, client_entry->nickname, 0);
 	if (!wb)
 		return NULL;
 
-	wbs = silc_calloc(1, sizeof(*wbs));
-	if (!wbs)
-		return NULL;
-	wbs->type = 0;
-	wbs->u.client = client_entry;
-	wbs->width = SILCGAIM_WB_WIDTH;
-	wbs->height = SILCGAIM_WB_HEIGHT;
-	wbs->brush_size = SILCGAIM_WB_BRUSH_SMALL;
-	wbs->brush_color = SILCGAIM_WB_COLOR_BLACK;
-	wb->proto_data = wbs;
+	if (!wb->proto_data) {
+		wbs = silc_calloc(1, sizeof(*wbs));
+		if (!wbs)
+			return NULL;
+		wbs->type = 0;
+		wbs->u.client = client_entry;
+		wbs->width = SILCGAIM_WB_WIDTH;
+		wbs->height = SILCGAIM_WB_HEIGHT;
+		wbs->brush_size = SILCGAIM_WB_BRUSH_SMALL;
+		wbs->brush_color = SILCGAIM_WB_COLOR_BLACK;
+		wb->proto_data = wbs;
 
-	/* Start the whiteboard */
-	gaim_whiteboard_start(wb);
-	gaim_whiteboard_clear(wb);
+		/* Start the whiteboard */
+		gaim_whiteboard_start(wb);
+		gaim_whiteboard_clear(wb);
+	}
 
 	return wb;
 }
@@ -141,25 +142,26 @@
 
 	wb = gaim_whiteboard_get_session(sg->account, channel->channel_name);
 	if (!wb)
-		wb = gaim_whiteboard_create(sg->account, channel->channel_name,
-					    0);
+		wb = gaim_whiteboard_create(sg->account, channel->channel_name, 0);
 	if (!wb)
 		return NULL;
 
-	wbs = silc_calloc(1, sizeof(*wbs));
-	if (!wbs)
-		return NULL;
-	wbs->type = 1;
-	wbs->u.channel = channel;
-	wbs->width = SILCGAIM_WB_WIDTH;
-	wbs->height = SILCGAIM_WB_HEIGHT;
-	wbs->brush_size = SILCGAIM_WB_BRUSH_SMALL;
-	wbs->brush_color = SILCGAIM_WB_COLOR_BLACK;
-	wb->proto_data = wbs;
+	if (!wb->proto_data) {
+		wbs = silc_calloc(1, sizeof(*wbs));
+		if (!wbs)
+			return NULL;
+		wbs->type = 1;
+		wbs->u.channel = channel;
+		wbs->width = SILCGAIM_WB_WIDTH;
+		wbs->height = SILCGAIM_WB_HEIGHT;
+		wbs->brush_size = SILCGAIM_WB_BRUSH_SMALL;
+		wbs->brush_color = SILCGAIM_WB_COLOR_BLACK;
+		wb->proto_data = wbs;
 
-	/* Start the whiteboard */
-	gaim_whiteboard_start(wb);
-	gaim_whiteboard_clear(wb);
+		/* Start the whiteboard */
+		gaim_whiteboard_start(wb);
+		gaim_whiteboard_clear(wb);
+	}
 
 	return wb;
 }
@@ -260,6 +262,23 @@
 	GaimConnection *gc;
 	SilcGaim sg;
 
+	gc = client->application;
+        sg = gc->proto_data;
+
+	/* Open whiteboard automatically if requested */
+	if (gaim_account_get_bool(sg->account, "open-wb", FALSE)) {
+		GaimWhiteboard *wb;
+
+		if (!channel)
+			wb = silcgaim_wb_init(sg, sender);
+		else
+			wb = silcgaim_wb_init_ch(sg, channel);
+
+		silcgaim_wb_parse(wb->proto_data, wb, (unsigned char *)message,
+				  message_len);
+		return;
+	}
+
 	if (!channel) {
 		g_snprintf(tmp, sizeof(tmp),
 			_("%s sent message to whiteboard. Would you like "
@@ -271,9 +290,6 @@
 			sender->nickname, channel->channel_name);
 	}
 
-	gc = client->application;
-        sg = gc->proto_data;
-
 	req = silc_calloc(1, sizeof(*req));
 	if (!req)
 		return;
@@ -394,7 +410,7 @@
 						 SILC_MESSAGE_FLAG_DATA,
 						 packet->head, len, TRUE);
 	} else if (wbs->type == 1) {
-		/* Channel message */
+		/* Channel message. Channel private keys are not supported. */
 		silc_client_send_channel_message(sg->client, sg->conn,
 						 wbs->u.channel, NULL,
 						 SILC_MESSAGE_FLAG_DATA,
@@ -433,7 +449,7 @@
 			height;
 
 	/* Update whiteboard */
-	gaim_whiteboard_set_dimensions(wb, width, height);
+	gaim_whiteboard_set_dimensions(wb, wbs->width, wbs->height);
 }
 
 void silcgaim_wb_get_brush(GaimWhiteboard *wb, int *size, int *color)