# HG changeset patch # User Ethan Blanton # Date 1132448376 0 # Node ID 5851a9219bc73f8ded27e7e8abba6212dc25ad0a # Parent d6417efb990cce28bc9bd641b87dd524d7f60743 [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 diff -r d6417efb990c -r 5851a9219bc7 src/protocols/silc/README --- 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 diff -r d6417efb990c -r 5851a9219bc7 src/protocols/silc/TODO --- 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) diff -r d6417efb990c -r 5851a9219bc7 src/protocols/silc/buddy.c --- 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; } diff -r d6417efb990c -r 5851a9219bc7 src/protocols/silc/chat.c --- 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; diff -r d6417efb990c -r 5851a9219bc7 src/protocols/silc/ops.c --- 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); diff -r d6417efb990c -r 5851a9219bc7 src/protocols/silc/silc.c --- 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(); diff -r d6417efb990c -r 5851a9219bc7 src/protocols/silc/wb.c --- 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)