im.pidgin.pidgin: 913a42db844168ecf35d9c14fa1ff42dbfdd1411
elb at pidgin.im
elb at pidgin.im
Sun Oct 28 20:25:50 EDT 2007
-----------------------------------------------------------------
Revision: 913a42db844168ecf35d9c14fa1ff42dbfdd1411
Ancestor: 7a1372c412c0973889e7ec68a02c91d6b0f5ec72
Author: elb at pidgin.im
Date: 2007-10-29T00:19:53
Branch: im.pidgin.pidgin
Modified files:
libpurple/protocols/silc/chat.c
libpurple/protocols/silc/ops.c libpurple/protocols/silc/pk.c
libpurple/protocols/silc/silc.c
libpurple/protocols/silc/silcpurple.h
libpurple/protocols/silc/util.c
libpurple/protocols/silc/wb.c
ChangeLog:
Patch from Pekka Riikone to fix various SILC issues.
Fixes: #3103
-------------- next part --------------
============================================================
--- libpurple/protocols/silc/chat.c 1ae8b183d4f656fe89a006ddd488d46043bc53c6
+++ libpurple/protocols/silc/chat.c 0146868e917dfab3a6b6792ae57b00381ef8a94e
@@ -160,15 +160,17 @@ silcpurple_chat_getinfo(PurpleConnection
unsigned char *pk;
SilcUInt32 pk_len;
pk = silc_pkcs_public_key_encode(channel->founder_key, &pk_len);
- fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
+ if (pk) {
+ fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
+ babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
- g_string_append_printf(s, _("<br><b>Founder Key Fingerprint:</b><br>%s"), fingerprint);
- g_string_append_printf(s, _("<br><b>Founder Key Babbleprint:</b><br>%s"), babbleprint);
+ g_string_append_printf(s, _("<br><b>Founder Key Fingerprint:</b><br>%s"), fingerprint);
+ g_string_append_printf(s, _("<br><b>Founder Key Babbleprint:</b><br>%s"), babbleprint);
- silc_free(fingerprint);
- silc_free(babbleprint);
- silc_free(pk);
+ silc_free(fingerprint);
+ silc_free(babbleprint);
+ silc_free(pk);
+ }
}
buf = g_string_free(s, FALSE);
@@ -460,6 +462,8 @@ void silcpurple_chat_chauth_show(SilcPur
silc_dlist_start(channel_pubkeys);
while ((public_key = silc_dlist_get(channel_pubkeys))) {
pk = silc_pkcs_public_key_encode(public_key, &pk_len);
+ if (!pk)
+ continue;
fingerprint = silc_hash_fingerprint(NULL, pk + 4, pk_len - 4);
babbleprint = silc_hash_babbleprint(NULL, pk + 4, pk_len - 4);
@@ -1013,9 +1017,6 @@ void silcpurple_chat_join(PurpleConnecti
SilcClient client = sg->client;
SilcClientConnection conn = sg->conn;
const char *channel, *passphrase, *parentch;
-#if 0
- PurpleChat *chat;
-#endif
if (!conn)
return;
@@ -1071,22 +1072,6 @@ void silcpurple_chat_join(PurpleConnecti
return;
}
-#if 0
- /* If the channel is not on buddy list, automatically add it there. */
- chat = purple_blist_find_chat(sg->account, channel);
- if (!chat) {
- data = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, g_free);
- g_hash_table_replace(data, g_strdup("channel"),
- g_strdup(channel));
- if (passphrase)
- g_hash_table_replace(data, g_strdup("passphrase"),
- g_strdup(passphrase));
- chat = purple_chat_new(sg->account, NULL, data);
- purple_blist_add_chat(chat, NULL, NULL);
- }
-#endif
-
/* XXX We should have other properties here as well:
1. whether to try to authenticate to the channel
1a. with default key,
@@ -1320,7 +1305,7 @@ int silcpurple_chat_send(PurpleConnectio
ret =
silc_client_send_channel_message(client, conn,
channel, key,
- flags, NULL,
+ flags, sg->sha1hash,
buf->data,
silc_buffer_len(buf));
silc_mime_partial_free(list);
@@ -1334,7 +1319,8 @@ int silcpurple_chat_send(PurpleConnectio
/* Send channel message */
ret = silc_client_send_channel_message(client, conn, channel, key,
- flags, NULL, (unsigned char *)msg2,
+ flags, sg->sha1hash,
+ (unsigned char *)msg2,
strlen(msg2));
if (ret) {
serv_got_chat_in(gc, id, purple_connection_get_display_name(gc), 0, msg,
============================================================
--- libpurple/protocols/silc/ops.c 51cf0f7468c5ce01aca69a36dd1eebda6a186f66
+++ libpurple/protocols/silc/ops.c 19f5e64698139b4a8b9fa8b2dc43b606b41799ff
@@ -1274,13 +1274,15 @@ silc_command_reply(SilcClient client, Si
unsigned char *pk;
SilcUInt32 pk_len;
pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len);
- fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
- purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint);
- purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint);
- silc_free(fingerprint);
- silc_free(babbleprint);
- silc_free(pk);
+ if (pk) {
+ fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
+ babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
+ purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint);
+ purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint);
+ silc_free(fingerprint);
+ silc_free(babbleprint);
+ silc_free(pk);
+ }
}
#if 0 /* XXX for now, let's not show attrs here */
@@ -1346,13 +1348,15 @@ silc_command_reply(SilcClient client, Si
unsigned char *pk;
SilcUInt32 pk_len;
pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len);
- fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
- babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
- purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint);
- purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint);
- silc_free(fingerprint);
- silc_free(babbleprint);
- silc_free(pk);
+ if (pk) {
+ fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
+ babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
+ purple_notify_user_info_add_pair(user_info, _("Public Key Fingerprint"), fingerprint);
+ purple_notify_user_info_add_pair(user_info, _("Public Key Babbleprint"), babbleprint);
+ silc_free(fingerprint);
+ silc_free(babbleprint);
+ silc_free(pk);
+ }
}
purple_notify_userinfo(gc, nickname, user_info, NULL, NULL);
============================================================
--- libpurple/protocols/silc/pk.c a67b620a11231b9b218c27471db5765efed1a124
+++ libpurple/protocols/silc/pk.c d51e1c49b31e88f5a0d34afb6f4cc4b0170c9eb2
@@ -158,6 +158,11 @@ void silcpurple_verify_public_key(SilcCl
NULL, &hostname, &ip, &port);
pk = silc_pkcs_public_key_encode(public_key, &pk_len);
+ if (!pk) {
+ if (completion)
+ completion(FALSE, context);
+ return;
+ }
if (conn_type == SILC_CONN_SERVER ||
conn_type == SILC_CONN_ROUTER) {
============================================================
--- libpurple/protocols/silc/silc.c 8d0a3d182b1aab7a03c61b577fd46db1440505ad
+++ libpurple/protocols/silc/silc.c a63295343f9000e46be8e4dc0cb986b2ce511802
@@ -128,6 +128,7 @@ silcpurple_keepalive(PurpleConnection *g
NULL, 0);
}
+#if __SILC_TOOLKIT_VERSION < SILC_VERSION(1,1,1)
static gboolean
silcpurple_scheduler(gpointer *context)
{
@@ -135,8 +136,107 @@ silcpurple_scheduler(gpointer *context)
silc_client_run_one(client);
return TRUE;
}
+#else
+typedef struct {
+ SilcPurple sg;
+ SilcUInt32 fd;
+ guint tag;
+} *SilcPurpleTask;
+/* A timeout occurred. Call SILC scheduler. */
+
+static gboolean
+silcpurple_scheduler_timeout(gpointer context)
+{
+ SilcPurpleTask task = (SilcPurpleTask)context;
+ silc_client_run_one(task->sg->client);
+ silc_dlist_del(task->sg->tasks, task);
+ silc_free(task);
+ return FALSE;
+}
+
+/* An fd task event occurred. Call SILC scheduler. */
+
static void
+silcpurple_scheduler_fd(gpointer data, gint fd, PurpleInputCondition cond)
+{
+ SilcClient client = (SilcClient)data;
+ silc_client_run_one(client);
+}
+
+/* SILC Scheduler notify callback. This is called whenever task is added to
+ or deleted from SILC scheduler. It's also called when fd task events
+ change. Here we add same tasks to glib's main loop. */
+
+static void
+silcpurple_scheduler(SilcSchedule schedule,
+ SilcBool added, SilcTask task,
+ SilcBool fd_task, SilcUInt32 fd,
+ SilcTaskEvent event,
+ long seconds, long useconds,
+ void *context)
+{
+ SilcClient client = (SilcClient)context;
+ PurpleConnection *gc = client->application;
+ SilcPurple sg = gc->proto_data;
+ SilcPurpleTask ptask = NULL;
+
+ if (added) {
+ if (fd_task) {
+ /* Add fd or change fd events */
+ PurpleInputCondition e = 0;
+
+ silc_dlist_start(sg->tasks);
+ while ((ptask = silc_dlist_get(sg->tasks)))
+ if (ptask->fd == fd) {
+ purple_input_remove(ptask->tag);
+ break;
+ }
+
+ if (event & SILC_TASK_READ)
+ e |= PURPLE_INPUT_READ;
+ if (event & SILC_TASK_WRITE)
+ e |= PURPLE_INPUT_WRITE;
+
+ if (e) {
+ if (!ptask) {
+ ptask = silc_calloc(1, sizeof(*ptask));
+ ptask->fd = fd;
+ silc_dlist_add(sg->tasks, ptask);
+ }
+ ptask->tag = purple_input_add(fd, e, silcpurple_scheduler_fd,
+ client);
+ } else if (ptask) {
+ silc_dlist_del(sg->tasks, ptask);
+ silc_free(ptask);
+ }
+ } else {
+ /* Add timeout */
+ ptask = silc_calloc(1, sizeof(*ptask));
+ ptask->sg = sg;
+ ptask->tag = purple_timeout_add((seconds * 1000) +
+ (useconds / 1000),
+ silcpurple_scheduler_timeout,
+ ptask);
+ silc_dlist_add(sg->tasks, ptask);
+ }
+ } else {
+ if (fd_task) {
+ /* Remove fd */
+ silc_dlist_start(sg->tasks);
+ while ((ptask = silc_dlist_get(sg->tasks)))
+ if (ptask->fd == fd) {
+ purple_input_remove(ptask->tag);
+ silc_dlist_del(sg->tasks, ptask);
+ silc_free(ptask);
+ break;
+ }
+ }
+ }
+}
+#endif /* __SILC_TOOLKIT_VERSION */
+
+static void
silcpurple_connect_cb(SilcClient client, SilcClientConnection conn,
SilcClientConnectionStatus status, SilcStatus error,
const char *message, void *context)
@@ -316,6 +416,8 @@ silcpurple_login_connected(gpointer data
return;
}
+ silc_hash_alloc("sha1", &sg->sha1hash);
+
/* Wrap socket to TCP stream */
silc_socket_tcp_stream_create(source, TRUE, FALSE,
sg->client->schedule,
@@ -324,21 +426,11 @@ static void silcpurple_running(SilcClien
static void silcpurple_running(SilcClient client, void *context)
{
- PurpleAccount *account = context;
- PurpleConnection *gc = account->gc;
- SilcPurple sg;
+ SilcPurple sg = context;
+ PurpleConnection *gc = sg->gc;
+ PurpleAccount *account = purple_connection_get_account(gc);
char pkd[256], prd[256];
- sg = silc_calloc(1, sizeof(*sg));
- if (!sg)
- return;
- memset(sg, 0, sizeof(*sg));
- sg->client = client;
- sg->gc = gc;
- sg->account = account;
- sg->scheduler = SILC_PTR_TO_32(gc->proto_data);
- gc->proto_data = sg;
-
/* Progress */
purple_connection_update_progress(gc, _("Connecting to SILC Server"), 1, 5);
@@ -375,10 +467,10 @@ silcpurple_login(PurpleAccount *account)
{
SilcClient client;
PurpleConnection *gc;
+ SilcPurple sg;
SilcClientParams params;
const char *cipher, *hmac;
char *username, *hostname, *realname, **up;
- guint scheduler;
int i;
gc = account->gc;
@@ -431,11 +523,21 @@ silcpurple_login(PurpleAccount *account)
break;
}
+ sg = silc_calloc(1, sizeof(*sg));
+ if (!sg)
+ return;
+ sg->client = client;
+ sg->gc = gc;
+ sg->account = account;
+ gc->proto_data = sg;
+
/* Init SILC client */
if (!silc_client_init(client, username, hostname, realname,
- silcpurple_running, account)) {
+ silcpurple_running, sg)) {
gc->wants_to_die = TRUE;
purple_connection_error(gc, _("Cannot initialize SILC protocol"));
+ gc->proto_data = NULL;
+ silc_free(sg);
return;
}
@@ -443,20 +545,32 @@ silcpurple_login(PurpleAccount *account)
if (!silcpurple_check_silc_dir(gc)) {
gc->wants_to_die = TRUE;
purple_connection_error(gc, _("Error loading SILC key pair"));
+ gc->proto_data = NULL;
+ silc_free(sg);
return;
}
+#if __SILC_TOOLKIT_VERSION < SILC_VERSION(1,1,1)
/* Schedule SILC using Glib's event loop */
- scheduler = purple_timeout_add(300, (GSourceFunc)silcpurple_scheduler, client);
- gc->proto_data = SILC_32_TO_PTR(scheduler);
+ sg->scheduler = purple_timeout_add(300, (GSourceFunc)silcpurple_scheduler, client);
+#else
+ /* Run SILC scheduler */
+ sg->tasks = silc_dlist_init();
+ silc_schedule_set_notify(client->schedule, silcpurple_scheduler,
+ client);
+ silc_client_run_one(client);
+#endif /* __SILC_TOOLKIT_VERSION */
}
static int
silcpurple_close_final(gpointer *context)
{
SilcPurple sg = (SilcPurple)context;
+
silc_client_stop(sg->client, NULL, NULL);
silc_client_free(sg->client);
+ if (sg->sha1hash)
+ silc_hash_free(sg->sha1hash);
if (sg->mimeass)
silc_mime_assembler_free(sg->mimeass);
silc_free(sg);
@@ -467,16 +581,33 @@ silcpurple_close(PurpleConnection *gc)
silcpurple_close(PurpleConnection *gc)
{
SilcPurple sg = gc->proto_data;
+#if __SILC_TOOLKIT_VERSION >= SILC_VERSION(1,1,1)
+ SilcPurpleTask task;
+#endif /* __SILC_TOOLKIT_VERSION */
g_return_if_fail(sg != NULL);
/* Send QUIT */
silc_client_command_call(sg->client, sg->conn, NULL,
- "QUIT", "Download Pidgin: " PURPLE_WEBSITE, NULL);
+ "QUIT", "Download Pidgin: " PURPLE_WEBSITE,
+ NULL);
if (sg->conn)
silc_client_close_connection(sg->client, sg->conn);
+#if __SILC_TOOLKIT_VERSION >= SILC_VERSION(1,1,1)
+ if (sg->conn)
+ silc_client_run_one(sg->client);
+ silc_schedule_set_notify(sg->client->schedule, NULL, NULL);
+
+ silc_dlist_start(sg->tasks);
+ while ((task = silc_dlist_get(sg->tasks))) {
+ purple_input_remove(task->tag);
+ silc_free(task);
+ }
+ silc_dlist_uninit(sg->tasks);
+#endif /* __SILC_TOOLKIT_VERSION */
+
purple_timeout_remove(sg->scheduler);
purple_timeout_add(1, (GSourceFunc)silcpurple_close_final, sg);
}
@@ -1155,7 +1286,7 @@ silcpurple_send_im_resolved(SilcClient c
silc_dlist_start(list);
while ((buf = silc_dlist_get(list)) != SILC_LIST_END)
silc_client_send_private_message(client, conn,
- client_entry, im->flags, NULL,
+ client_entry, im->flags, sg->sha1hash,
buf->data,
silc_buffer_len(buf));
silc_mime_partial_free(list);
@@ -1167,7 +1298,7 @@ silcpurple_send_im_resolved(SilcClient c
/* Send the message */
silc_client_send_private_message(client, conn, client_entry, im->flags,
- NULL, (unsigned char *)im->message, im->message_len);
+ sg->sha1hash, (unsigned char *)im->message, im->message_len);
purple_conv_im_write(PURPLE_CONV_IM(convo), conn->local_entry->nickname,
im->message, 0, time(NULL));
goto out;
@@ -1259,7 +1390,7 @@ silcpurple_send_im(PurpleConnection *gc,
while ((buf = silc_dlist_get(list)) != SILC_LIST_END)
ret =
silc_client_send_private_message(client, conn,
- client_entry, mflags, NULL,
+ client_entry, mflags, sg->sha1hash,
buf->data,
silc_buffer_len(buf));
silc_mime_partial_free(list);
@@ -1271,7 +1402,7 @@ silcpurple_send_im(PurpleConnection *gc,
/* Send private message directly */
ret = silc_client_send_private_message(client, conn, client_entry,
- mflags, NULL,
+ mflags, sg->sha1hash,
(unsigned char *)msg,
strlen(msg));
============================================================
--- libpurple/protocols/silc/silcpurple.h 83a974c5ca39f14d643ad5b512d67742e0ef7e75
+++ libpurple/protocols/silc/silcpurple.h ff90e27accf4434be9ae415a7db51d128ac48491
@@ -35,6 +35,9 @@
#include "server.h"
#include "util.h"
+#undef SILC_VERSION
+#define SILC_VERSION(a, b, c) (((a) << 24) + ((b) << 16) + ((c) << 8))
+
/* Default public and private key file names */
#define SILCPURPLE_PUBLIC_KEY_NAME "public_key.pub"
#define SILCPURPLE_PRIVATE_KEY_NAME "private_key.prv"
@@ -68,7 +71,9 @@ typedef struct SilcPurpleStruct {
SilcClientConnection conn;
SilcPublicKey public_key;
SilcPrivateKey private_key;
+ SilcHash sha1hash;
+ SilcDList tasks;
guint scheduler;
PurpleConnection *gc;
PurpleAccount *account;
============================================================
--- libpurple/protocols/silc/util.c dc180615f15f1f5b3128810202d21d5a06061a7b
+++ libpurple/protocols/silc/util.c dd1c3ee1af03d94f6a285aed1a767a97acc5aee8
@@ -347,8 +347,12 @@ void silcpurple_show_public_key(SilcPurp
key_len = silc_pkcs_public_key_get_len(public_key);
pk = silc_pkcs_public_key_encode(public_key, &pk_len);
+ if (!pk)
+ return;
fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
+ if (!fingerprint || !babbleprint)
+ return;
s = g_string_new("");
if (ident->realname)
============================================================
--- libpurple/protocols/silc/wb.c 3b6037e180d10ec387bccf2935367dd4f5e7d584
+++ libpurple/protocols/silc/wb.c e49a89f73238ae0e0af8ea065f376763d5428cd4
@@ -254,10 +254,10 @@ silcpurple_wb_request(SilcClient client,
static void
silcpurple_wb_request(SilcClient client, const unsigned char *message,
- SilcUInt32 message_len, SilcClientEntry sender,
- SilcChannelEntry channel)
+ SilcUInt32 message_len, SilcClientEntry sender,
+ SilcChannelEntry channel)
{
- char tmp[128];
+ char tmp[256];
SilcPurpleWbRequest req;
PurpleConnection *gc;
SilcPurple sg;
@@ -274,20 +274,24 @@ silcpurple_wb_request(SilcClient client,
else
wb = silcpurple_wb_init_ch(sg, channel);
- silcpurple_wb_parse(wb->proto_data, wb, (unsigned char *)message,
- message_len);
+ silcpurple_wb_parse(wb->proto_data, wb,
+ (unsigned char *)message,
+ message_len);
return;
}
+ /* Close any previous unaccepted requests */
+ purple_request_close_with_handle(sender);
+
if (!channel) {
g_snprintf(tmp, sizeof(tmp),
- _("%s sent message to whiteboard. Would you like "
- "to open the whiteboard?"), sender->nickname);
+ _("%s sent message to whiteboard. Would you like "
+ "to open the whiteboard?"), sender->nickname);
} else {
g_snprintf(tmp, sizeof(tmp),
- _("%s sent message to whiteboard on %s channel. "
- "Would you like to open the whiteboard?"),
- sender->nickname, channel->channel_name);
+ _("%s sent message to whiteboard on %s channel. "
+ "Would you like to open the whiteboard?"),
+ sender->nickname, channel->channel_name);
}
req = silc_calloc(1, sizeof(*req));
@@ -299,10 +303,10 @@ silcpurple_wb_request(SilcClient client,
req->channel = channel;
req->sg = sg;
- purple_request_action(gc, _("Whiteboard"), tmp, NULL, 1,
- sg->account, sender->nickname, NULL, req, 2,
- _("Yes"), G_CALLBACK(silcpurple_wb_request_cb),
- _("No"), G_CALLBACK(silcpurple_wb_request_cb));
+ purple_request_action(sender, _("Whiteboard"), tmp, NULL, 1,
+ sg->account, sender->nickname, NULL, req, 2,
+ _("Yes"), G_CALLBACK(silcpurple_wb_request_cb),
+ _("No"), G_CALLBACK(silcpurple_wb_request_cb));
}
/* Process incoming whiteboard message */
More information about the Commits
mailing list