Wed, 16 Nov 2005 06:07:42 +0000
[gaim-migrate @ 14411]
sf patch #1357831, from Sadrul Habib Chowdhury
Looks like this was my bug (me being KingAnt). Sorry!
The description from Sadrul:
This is a simple fix for the following "ShowStopperBug"
(from the kwiki):
==========
buddy shows as online when offline
* I(luke) played with this some today. when my
lschiere SILC account signs on, lschiere(aim) appears
on my LSchiere2 buddy list as though signing on. As far
as the gaim UI is concerned, there is no SILC buddy in
that contact. as LSchiere (aim) is my account, I am
quite sure that it is not online, plus attempting to IM
it yeilds the same result.
==========
committer: Mark Doliner <markdoliner@pidgin.im>
| 8849 | 1 | /* |
| 2 | ||
| 3 | silcgaim_buddy.c | |
| 4 | ||
| 5 | Author: Pekka Riikonen <priikone@silcnet.org> | |
| 6 | ||
| 7 | Copyright (C) 2004 Pekka Riikonen | |
| 8 | ||
| 9 | This program is free software; you can redistribute it and/or modify | |
| 10 | it under the terms of the GNU General Public License as published by | |
| 11 | the Free Software Foundation; version 2 of the License. | |
| 12 | ||
| 13 | This program is distributed in the hope that it will be useful, | |
| 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 16 | GNU General Public License for more details. | |
| 17 | ||
| 18 | */ | |
| 19 | ||
| 20 | #include "silcincludes.h" | |
| 21 | #include "silcclient.h" | |
| 22 | #include "silcgaim.h" | |
|
12058
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
23 | #include "wb.h" |
| 8849 | 24 | |
| 25 | /***************************** Key Agreement *********************************/ | |
| 26 | ||
| 27 | static void | |
| 9060 | 28 | silcgaim_buddy_keyagr(GaimBlistNode *node, gpointer data); |
| 29 | ||
| 30 | static void | |
| 31 | silcgaim_buddy_keyagr_do(GaimConnection *gc, const char *name, | |
| 32 | gboolean force_local); | |
| 8849 | 33 | |
| 34 | typedef struct { | |
| 35 | char *nick; | |
| 36 | GaimConnection *gc; | |
| 37 | } *SilcGaimResolve; | |
| 38 | ||
| 39 | static void | |
| 40 | silcgaim_buddy_keyagr_resolved(SilcClient client, | |
| 41 | SilcClientConnection conn, | |
| 42 | SilcClientEntry *clients, | |
| 43 | SilcUInt32 clients_count, | |
| 44 | void *context) | |
| 45 | { | |
| 46 | GaimConnection *gc = client->application; | |
| 47 | SilcGaimResolve r = context; | |
| 48 | char tmp[256]; | |
| 49 | ||
| 50 | if (!clients) { | |
| 51 | g_snprintf(tmp, sizeof(tmp), | |
| 52 | _("User %s is not present in the network"), r->nick); | |
| 53 | gaim_notify_error(gc, _("Key Agreement"), | |
| 54 | _("Cannot perform the key agreement"), tmp); | |
| 55 | silc_free(r->nick); | |
| 56 | silc_free(r); | |
| 57 | return; | |
| 58 | } | |
| 59 | ||
| 9060 | 60 | silcgaim_buddy_keyagr_do(gc, r->nick, FALSE); |
| 8849 | 61 | silc_free(r->nick); |
| 62 | silc_free(r); | |
| 63 | } | |
| 64 | ||
| 65 | typedef struct { | |
| 66 | gboolean responder; | |
| 67 | } *SilcGaimKeyAgr; | |
| 68 | ||
| 69 | static void | |
| 70 | silcgaim_buddy_keyagr_cb(SilcClient client, | |
| 71 | SilcClientConnection conn, | |
| 72 | SilcClientEntry client_entry, | |
| 73 | SilcKeyAgreementStatus status, | |
| 74 | SilcSKEKeyMaterial *key, | |
| 75 | void *context) | |
| 76 | { | |
| 77 | GaimConnection *gc = client->application; | |
| 78 | SilcGaim sg = gc->proto_data; | |
| 79 | SilcGaimKeyAgr a = context; | |
| 80 | ||
| 81 | if (!sg->conn) | |
| 82 | return; | |
| 83 | ||
| 84 | switch (status) { | |
| 85 | case SILC_KEY_AGREEMENT_OK: | |
| 86 | { | |
| 87 | GaimConversation *convo; | |
| 88 | char tmp[128]; | |
| 89 | ||
| 90 | /* Set the private key for this client */ | |
| 91 | silc_client_del_private_message_key(client, conn, client_entry); | |
| 92 | silc_client_add_private_message_key_ske(client, conn, client_entry, | |
| 93 | NULL, NULL, key, a->responder); | |
| 94 | silc_ske_free_key_material(key); | |
| 95 | ||
| 11586 | 96 | |
| 8849 | 97 | /* Open IM window */ |
|
11338
1a3663ac9b05
[gaim-migrate @ 13551]
Mark Doliner <markdoliner@pidgin.im>
parents:
11201
diff
changeset
|
98 | convo = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, |
|
10246
aa5bff72f94c
[gaim-migrate @ 11386]
Mark Doliner <markdoliner@pidgin.im>
parents:
10232
diff
changeset
|
99 | client_entry->nickname, sg->account); |
| 11586 | 100 | if (convo) { |
| 101 | /* we don't have windows in the core anymore...but we may want to | |
| 102 | * provide some method for asking the UI to show the window | |
| 8849 | 103 | gaim_conv_window_show(gaim_conversation_get_window(convo)); |
| 11586 | 104 | */ |
| 105 | } else { | |
|
11338
1a3663ac9b05
[gaim-migrate @ 13551]
Mark Doliner <markdoliner@pidgin.im>
parents:
11201
diff
changeset
|
106 | convo = gaim_conversation_new(GAIM_CONV_TYPE_IM, sg->account, |
| 8849 | 107 | client_entry->nickname); |
| 11586 | 108 | } |
| 8849 | 109 | g_snprintf(tmp, sizeof(tmp), "%s [private key]", client_entry->nickname); |
| 110 | gaim_conversation_set_title(convo, tmp); | |
| 111 | } | |
| 112 | break; | |
| 113 | ||
| 114 | case SILC_KEY_AGREEMENT_ERROR: | |
| 115 | gaim_notify_error(gc, _("Key Agreement"), | |
| 116 | _("Error occurred during key agreement"), NULL); | |
| 117 | break; | |
| 118 | ||
| 119 | case SILC_KEY_AGREEMENT_FAILURE: | |
| 120 | gaim_notify_error(gc, _("Key Agreement"), _("Key Agreement failed"), NULL); | |
| 121 | break; | |
| 122 | ||
| 123 | case SILC_KEY_AGREEMENT_TIMEOUT: | |
| 124 | gaim_notify_error(gc, _("Key Agreement"), | |
| 125 | _("Timeout during key agreement"), NULL); | |
| 126 | break; | |
| 127 | ||
| 128 | case SILC_KEY_AGREEMENT_ABORTED: | |
| 129 | gaim_notify_error(gc, _("Key Agreement"), | |
| 130 | _("Key agreement was aborted"), NULL); | |
| 131 | break; | |
| 132 | ||
| 133 | case SILC_KEY_AGREEMENT_ALREADY_STARTED: | |
| 134 | gaim_notify_error(gc, _("Key Agreement"), | |
| 135 | _("Key agreement is already started"), NULL); | |
| 136 | break; | |
| 137 | ||
| 138 | case SILC_KEY_AGREEMENT_SELF_DENIED: | |
| 139 | gaim_notify_error(gc, _("Key Agreement"), | |
| 140 | _("Key agreement cannot be started with yourself"), | |
| 141 | NULL); | |
| 142 | break; | |
| 143 | ||
| 144 | default: | |
| 145 | break; | |
| 146 | } | |
| 147 | ||
| 148 | silc_free(a); | |
| 149 | } | |
| 150 | ||
| 151 | static void | |
| 152 | silcgaim_buddy_keyagr_do(GaimConnection *gc, const char *name, | |
| 153 | gboolean force_local) | |
| 154 | { | |
| 155 | SilcGaim sg = gc->proto_data; | |
| 156 | SilcClientEntry *clients; | |
| 157 | SilcUInt32 clients_count; | |
| 8910 | 158 | char *local_ip = NULL, *remote_ip = NULL; |
| 8849 | 159 | gboolean local = TRUE; |
| 160 | char *nickname; | |
| 161 | SilcGaimKeyAgr a; | |
| 162 | ||
| 163 | if (!sg->conn || !name) | |
| 164 | return; | |
| 165 | ||
| 166 | if (!silc_parse_userfqdn(name, &nickname, NULL)) | |
| 167 | return; | |
| 168 | ||
| 169 | /* Find client entry */ | |
| 170 | clients = silc_client_get_clients_local(sg->client, sg->conn, nickname, name, | |
| 171 | &clients_count); | |
| 172 | if (!clients) { | |
| 173 | /* Resolve unknown user */ | |
| 174 | SilcGaimResolve r = silc_calloc(1, sizeof(*r)); | |
| 175 | if (!r) | |
| 176 | return; | |
| 177 | r->nick = g_strdup(name); | |
| 178 | r->gc = gc; | |
| 179 | silc_client_get_clients(sg->client, sg->conn, nickname, NULL, | |
| 180 | silcgaim_buddy_keyagr_resolved, r); | |
| 181 | silc_free(nickname); | |
| 182 | return; | |
| 183 | } | |
| 184 | ||
| 185 | /* Resolve the local IP from the outgoing socket connection. We resolve | |
| 186 | it to check whether we have a private range IP address or public IP | |
| 187 | address. If we have public then we will assume that we are not behind | |
| 188 | NAT and will provide automatically the point of connection to the | |
| 189 | agreement. If we have private range address we assume that we are | |
| 190 | behind NAT and we let the responder provide the point of connection. | |
| 191 | ||
| 192 | The algorithm also checks the remote IP address of server connection. | |
| 193 | If it is private range address and we have private range address we | |
| 194 | assume that we are chatting in LAN and will provide the point of | |
| 195 | connection. | |
| 196 | ||
| 197 | Naturally this algorithm does not always get things right. */ | |
| 198 | ||
| 199 | if (silc_net_check_local_by_sock(sg->conn->sock->sock, NULL, &local_ip)) { | |
| 200 | /* Check if the IP is private */ | |
| 201 | if (!force_local && silcgaim_ip_is_private(local_ip)) { | |
| 202 | local = FALSE; | |
| 203 | ||
| 204 | /* Local IP is private, resolve the remote server IP to see whether | |
| 205 | we are talking to Internet or just on LAN. */ | |
| 206 | if (silc_net_check_host_by_sock(sg->conn->sock->sock, NULL, | |
| 207 | &remote_ip)) | |
| 208 | if (silcgaim_ip_is_private(remote_ip)) | |
| 209 | /* We assume we are in LAN. Let's provide | |
| 210 | the connection point. */ | |
| 211 | local = TRUE; | |
| 212 | } | |
| 213 | } | |
| 214 | ||
| 215 | if (force_local) | |
| 216 | local = TRUE; | |
| 217 | ||
| 218 | if (local && !local_ip) | |
| 219 | local_ip = silc_net_localip(); | |
| 220 | ||
| 221 | a = silc_calloc(1, sizeof(*a)); | |
| 222 | if (!a) | |
| 223 | return; | |
| 224 | a->responder = local; | |
| 225 | ||
| 226 | /* Send the key agreement request */ | |
| 227 | silc_client_send_key_agreement(sg->client, sg->conn, clients[0], | |
| 228 | local ? local_ip : NULL, NULL, 0, 60, | |
| 229 | silcgaim_buddy_keyagr_cb, a); | |
| 230 | ||
| 231 | silc_free(local_ip); | |
| 232 | silc_free(remote_ip); | |
| 233 | silc_free(clients); | |
| 234 | } | |
| 235 | ||
| 236 | typedef struct { | |
| 237 | SilcClient client; | |
| 238 | SilcClientConnection conn; | |
| 239 | SilcClientID client_id; | |
| 240 | char *hostname; | |
| 241 | SilcUInt16 port; | |
| 242 | } *SilcGaimKeyAgrAsk; | |
| 243 | ||
| 244 | static void | |
| 245 | silcgaim_buddy_keyagr_request_cb(SilcGaimKeyAgrAsk a, gint id) | |
| 246 | { | |
| 247 | SilcGaimKeyAgr ai; | |
| 248 | SilcClientEntry client_entry; | |
| 249 | ||
| 250 | if (id != 1) | |
| 251 | goto out; | |
| 252 | ||
| 253 | /* Get the client entry. */ | |
| 254 | client_entry = silc_client_get_client_by_id(a->client, a->conn, | |
| 255 | &a->client_id); | |
| 256 | if (!client_entry) { | |
| 257 | gaim_notify_error(a->client->application, _("Key Agreement"), | |
| 258 | _("The remote user is not present in the network any more"), | |
| 259 | NULL); | |
| 260 | goto out; | |
| 261 | } | |
| 262 | ||
| 263 | /* If the hostname was provided by the requestor perform the key agreement | |
| 264 | now. Otherwise, we will send him a request to connect to us. */ | |
| 265 | if (a->hostname) { | |
| 266 | ai = silc_calloc(1, sizeof(*ai)); | |
| 267 | if (!ai) | |
| 268 | goto out; | |
| 269 | ai->responder = FALSE; | |
| 270 | silc_client_perform_key_agreement(a->client, a->conn, client_entry, | |
| 271 | a->hostname, a->port, | |
| 272 | silcgaim_buddy_keyagr_cb, ai); | |
| 273 | } else { | |
| 274 | /* Send request. Force us as the point of connection since requestor | |
| 275 | did not provide the point of connection. */ | |
| 276 | silcgaim_buddy_keyagr_do(a->client->application, | |
| 277 | client_entry->nickname, TRUE); | |
| 278 | } | |
| 279 | ||
| 280 | out: | |
| 281 | silc_free(a->hostname); | |
| 282 | silc_free(a); | |
| 283 | } | |
| 284 | ||
| 285 | void silcgaim_buddy_keyagr_request(SilcClient client, | |
| 286 | SilcClientConnection conn, | |
| 287 | SilcClientEntry client_entry, | |
| 288 | const char *hostname, SilcUInt16 port) | |
| 289 | { | |
| 290 | char tmp[128], tmp2[128]; | |
| 291 | SilcGaimKeyAgrAsk a; | |
| 292 | ||
| 293 | g_snprintf(tmp, sizeof(tmp), | |
| 294 | _("Key agreement request received from %s. Would you like to " | |
| 295 | "perform the key agreement?"), client_entry->nickname); | |
| 296 | if (hostname) | |
| 297 | g_snprintf(tmp2, sizeof(tmp2), | |
| 298 | _("The remote user is waiting key agreement on:\n" | |
| 299 | "Remote host: %s\nRemote port: %d"), hostname, port); | |
| 300 | ||
| 301 | a = silc_calloc(1, sizeof(*a)); | |
| 302 | if (!a) | |
| 303 | return; | |
| 304 | a->client = client; | |
| 305 | a->conn = conn; | |
| 306 | a->client_id = *client_entry->id; | |
| 307 | if (hostname) | |
| 308 | a->hostname = strdup(hostname); | |
| 309 | a->port = port; | |
| 310 | ||
|
11201
f8fed1f48ca3
[gaim-migrate @ 13329]
Mark Doliner <markdoliner@pidgin.im>
parents:
11165
diff
changeset
|
311 | gaim_request_action(client->application, _("Key Agreement Request"), tmp, |
| 8849 | 312 | hostname ? tmp2 : NULL, 1, a, 2, |
| 313 | _("Yes"), G_CALLBACK(silcgaim_buddy_keyagr_request_cb), | |
| 314 | _("No"), G_CALLBACK(silcgaim_buddy_keyagr_request_cb)); | |
| 315 | } | |
| 316 | ||
| 317 | static void | |
| 9060 | 318 | silcgaim_buddy_keyagr(GaimBlistNode *node, gpointer data) |
| 8849 | 319 | { |
|
9133
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
320 | GaimBuddy *buddy; |
| 9060 | 321 | |
| 322 | buddy = (GaimBuddy *)node; | |
| 323 | silcgaim_buddy_keyagr_do(buddy->account->gc, buddy->name, FALSE); | |
| 8849 | 324 | } |
| 325 | ||
| 326 | ||
| 327 | /**************************** Static IM Key **********************************/ | |
| 328 | ||
| 329 | static void | |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
330 | silcgaim_buddy_resetkey(GaimBlistNode *node, gpointer data) |
| 8849 | 331 | { |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
332 | GaimBuddy *b; |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
333 | GaimConnection *gc; |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
334 | SilcGaim sg; |
| 8849 | 335 | char *nickname; |
| 336 | SilcClientEntry *clients; | |
| 337 | SilcUInt32 clients_count; | |
| 338 | ||
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
339 | g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
340 | |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
341 | b = (GaimBuddy *) node; |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
342 | gc = gaim_account_get_connection(b->account); |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
343 | sg = gc->proto_data; |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
344 | |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
345 | if (!silc_parse_userfqdn(b->name, &nickname, NULL)) |
| 8849 | 346 | return; |
| 347 | ||
| 348 | /* Find client entry */ | |
| 349 | clients = silc_client_get_clients_local(sg->client, sg->conn, | |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
350 | nickname, b->name, |
| 8849 | 351 | &clients_count); |
| 352 | if (!clients) { | |
| 353 | silc_free(nickname); | |
| 354 | return; | |
| 355 | } | |
| 356 | ||
| 357 | clients[0]->prv_resp = FALSE; | |
| 358 | silc_client_del_private_message_key(sg->client, sg->conn, | |
| 359 | clients[0]); | |
| 360 | silc_free(clients); | |
| 361 | silc_free(nickname); | |
| 362 | } | |
| 363 | ||
| 364 | typedef struct { | |
| 365 | SilcClient client; | |
| 366 | SilcClientConnection conn; | |
| 367 | SilcClientID client_id; | |
| 368 | } *SilcGaimPrivkey; | |
| 369 | ||
| 370 | static void | |
| 371 | silcgaim_buddy_privkey(GaimConnection *gc, const char *name); | |
| 372 | ||
| 373 | static void | |
| 374 | silcgaim_buddy_privkey_cb(SilcGaimPrivkey p, const char *passphrase) | |
| 375 | { | |
| 376 | SilcClientEntry client_entry; | |
| 377 | ||
| 378 | if (!passphrase || !(*passphrase)) { | |
| 379 | silc_free(p); | |
| 380 | return; | |
| 381 | } | |
| 382 | ||
| 383 | /* Get the client entry. */ | |
| 384 | client_entry = silc_client_get_client_by_id(p->client, p->conn, | |
| 385 | &p->client_id); | |
| 386 | if (!client_entry) { | |
| 387 | gaim_notify_error(p->client->application, _("IM With Password"), | |
| 388 | _("The remote user is not present in the network any more"), | |
| 389 | NULL); | |
| 390 | silc_free(p); | |
| 391 | return; | |
| 392 | } | |
| 393 | ||
| 394 | /* Set the private message key */ | |
| 395 | silc_client_del_private_message_key(p->client, p->conn, | |
| 396 | client_entry); | |
| 397 | silc_client_add_private_message_key(p->client, p->conn, | |
| 398 | client_entry, NULL, NULL, | |
| 399 | (unsigned char *)passphrase, | |
| 400 | strlen(passphrase), FALSE, | |
| 401 | client_entry->prv_resp); | |
| 402 | if (!client_entry->prv_resp) | |
| 403 | silc_client_send_private_message_key_request(p->client, | |
| 404 | p->conn, | |
| 405 | client_entry); | |
| 406 | silc_free(p); | |
| 407 | } | |
| 408 | ||
| 409 | static void | |
| 410 | silcgaim_buddy_privkey_resolved(SilcClient client, | |
| 411 | SilcClientConnection conn, | |
| 412 | SilcClientEntry *clients, | |
| 413 | SilcUInt32 clients_count, | |
| 414 | void *context) | |
| 415 | { | |
| 416 | char tmp[256]; | |
| 417 | ||
| 418 | if (!clients) { | |
| 419 | g_snprintf(tmp, sizeof(tmp), | |
| 420 | _("User %s is not present in the network"), | |
| 421 | (const char *)context); | |
| 422 | gaim_notify_error(client->application, _("IM With Password"), | |
| 423 | _("Cannot set IM key"), tmp); | |
| 424 | g_free(context); | |
| 425 | return; | |
| 426 | } | |
| 427 | ||
| 428 | silcgaim_buddy_privkey(client->application, context); | |
| 429 | silc_free(context); | |
| 430 | } | |
| 431 | ||
| 432 | static void | |
| 9038 | 433 | silcgaim_buddy_privkey(GaimConnection *gc, const char *name) |
| 8849 | 434 | { |
| 9038 | 435 | SilcGaim sg = gc->proto_data; |
| 8849 | 436 | char *nickname; |
| 437 | SilcGaimPrivkey p; | |
| 438 | SilcClientEntry *clients; | |
| 439 | SilcUInt32 clients_count; | |
| 440 | ||
| 9038 | 441 | if (!name) |
| 442 | return; | |
| 443 | if (!silc_parse_userfqdn(name, &nickname, NULL)) | |
| 8849 | 444 | return; |
| 445 | ||
| 446 | /* Find client entry */ | |
| 447 | clients = silc_client_get_clients_local(sg->client, sg->conn, | |
| 9038 | 448 | nickname, name, |
| 8849 | 449 | &clients_count); |
| 450 | if (!clients) { | |
| 451 | silc_client_get_clients(sg->client, sg->conn, nickname, NULL, | |
| 452 | silcgaim_buddy_privkey_resolved, | |
| 9038 | 453 | g_strdup(name)); |
| 8849 | 454 | silc_free(nickname); |
| 455 | return; | |
| 456 | } | |
| 457 | ||
| 458 | p = silc_calloc(1, sizeof(*p)); | |
| 459 | if (!p) | |
| 460 | return; | |
| 461 | p->client = sg->client; | |
| 462 | p->conn = sg->conn; | |
| 463 | p->client_id = *clients[0]->id; | |
|
11201
f8fed1f48ca3
[gaim-migrate @ 13329]
Mark Doliner <markdoliner@pidgin.im>
parents:
11165
diff
changeset
|
464 | gaim_request_input(gc, _("IM With Password"), NULL, |
| 8849 | 465 | _("Set IM Password"), NULL, FALSE, TRUE, NULL, |
| 466 | _("OK"), G_CALLBACK(silcgaim_buddy_privkey_cb), | |
| 467 | _("Cancel"), G_CALLBACK(silcgaim_buddy_privkey_cb), | |
| 468 | p); | |
| 469 | ||
| 470 | silc_free(clients); | |
| 471 | silc_free(nickname); | |
| 472 | } | |
| 473 | ||
| 9038 | 474 | static void |
| 475 | silcgaim_buddy_privkey_menu(GaimBlistNode *node, gpointer data) | |
| 476 | { | |
| 477 | GaimBuddy *buddy; | |
| 478 | GaimConnection *gc; | |
| 479 | ||
| 480 | g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); | |
| 481 | ||
| 482 | buddy = (GaimBuddy *) node; | |
| 483 | gc = gaim_account_get_connection(buddy->account); | |
| 484 | ||
| 485 | silcgaim_buddy_privkey(gc, buddy->name); | |
| 486 | } | |
| 487 | ||
| 8849 | 488 | |
| 489 | /**************************** Get Public Key *********************************/ | |
| 490 | ||
| 491 | typedef struct { | |
| 492 | SilcClient client; | |
| 493 | SilcClientConnection conn; | |
| 494 | SilcClientID client_id; | |
| 495 | } *SilcGaimBuddyGetkey; | |
| 496 | ||
| 497 | static void | |
| 498 | silcgaim_buddy_getkey(GaimConnection *gc, const char *name); | |
| 499 | ||
| 500 | static void | |
| 501 | silcgaim_buddy_getkey_cb(SilcGaimBuddyGetkey g, | |
| 502 | SilcClientCommandReplyContext cmd) | |
| 503 | { | |
| 504 | SilcClientEntry client_entry; | |
| 505 | unsigned char *pk; | |
| 506 | SilcUInt32 pk_len; | |
| 507 | ||
| 508 | /* Get the client entry. */ | |
| 509 | client_entry = silc_client_get_client_by_id(g->client, g->conn, | |
| 510 | &g->client_id); | |
| 511 | if (!client_entry) { | |
| 512 | gaim_notify_error(g->client->application, _("Get Public Key"), | |
| 513 | _("The remote user is not present in the network any more"), | |
| 514 | NULL); | |
| 515 | silc_free(g); | |
| 516 | return; | |
| 517 | } | |
| 518 | ||
| 519 | if (!client_entry->public_key) { | |
| 520 | silc_free(g); | |
| 521 | return; | |
| 522 | } | |
| 523 | ||
| 524 | /* Now verify the public key */ | |
| 525 | pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len); | |
| 526 | silcgaim_verify_public_key(g->client, g->conn, client_entry->nickname, | |
| 527 | SILC_SOCKET_TYPE_CLIENT, | |
| 528 | pk, pk_len, SILC_SKE_PK_TYPE_SILC, | |
| 529 | NULL, NULL); | |
| 530 | silc_free(pk); | |
| 531 | silc_free(g); | |
| 532 | } | |
| 533 | ||
| 534 | static void | |
| 535 | silcgaim_buddy_getkey_resolved(SilcClient client, | |
| 536 | SilcClientConnection conn, | |
| 537 | SilcClientEntry *clients, | |
| 538 | SilcUInt32 clients_count, | |
| 539 | void *context) | |
| 540 | { | |
| 541 | char tmp[256]; | |
| 542 | ||
| 543 | if (!clients) { | |
| 544 | g_snprintf(tmp, sizeof(tmp), | |
| 545 | _("User %s is not present in the network"), | |
| 546 | (const char *)context); | |
| 547 | gaim_notify_error(client->application, _("Get Public Key"), | |
| 548 | _("Cannot fetch the public key"), tmp); | |
| 549 | g_free(context); | |
| 550 | return; | |
| 551 | } | |
| 552 | ||
| 553 | silcgaim_buddy_getkey(client->application, context); | |
| 554 | silc_free(context); | |
| 555 | } | |
| 556 | ||
| 557 | static void | |
| 9038 | 558 | silcgaim_buddy_getkey(GaimConnection *gc, const char *name) |
| 8849 | 559 | { |
| 9038 | 560 | SilcGaim sg = gc->proto_data; |
| 561 | SilcClient client = sg->client; | |
| 562 | SilcClientConnection conn = sg->conn; | |
| 8849 | 563 | SilcClientEntry *clients; |
| 564 | SilcUInt32 clients_count; | |
| 565 | SilcGaimBuddyGetkey g; | |
| 566 | char *nickname; | |
| 567 | ||
| 9038 | 568 | if (!name) |
| 569 | return; | |
| 8849 | 570 | |
| 9038 | 571 | if (!silc_parse_userfqdn(name, &nickname, NULL)) |
| 8849 | 572 | return; |
| 573 | ||
| 574 | /* Find client entry */ | |
| 9038 | 575 | clients = silc_client_get_clients_local(client, conn, nickname, name, |
| 576 | &clients_count); | |
| 8849 | 577 | if (!clients) { |
| 578 | silc_client_get_clients(client, conn, nickname, NULL, | |
| 579 | silcgaim_buddy_getkey_resolved, | |
| 9038 | 580 | g_strdup(name)); |
| 8849 | 581 | silc_free(nickname); |
| 582 | return; | |
| 583 | } | |
| 584 | ||
| 585 | /* Call GETKEY */ | |
| 586 | g = silc_calloc(1, sizeof(*g)); | |
| 587 | if (!g) | |
| 588 | return; | |
| 589 | g->client = client; | |
| 590 | g->conn = conn; | |
| 591 | g->client_id = *clients[0]->id; | |
| 592 | silc_client_command_call(client, conn, NULL, "GETKEY", | |
| 593 | clients[0]->nickname, NULL); | |
| 594 | silc_client_command_pending(conn, SILC_COMMAND_GETKEY, | |
| 595 | conn->cmd_ident, | |
| 596 | (SilcCommandCb)silcgaim_buddy_getkey_cb, g); | |
| 597 | silc_free(clients); | |
| 598 | silc_free(nickname); | |
| 599 | } | |
| 600 | ||
| 601 | static void | |
| 9038 | 602 | silcgaim_buddy_getkey_menu(GaimBlistNode *node, gpointer data) |
| 603 | { | |
| 604 | GaimBuddy *buddy; | |
| 605 | GaimConnection *gc; | |
| 606 | ||
| 607 | g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); | |
| 608 | ||
| 609 | buddy = (GaimBuddy *) node; | |
| 610 | gc = gaim_account_get_connection(buddy->account); | |
| 611 | ||
| 612 | silcgaim_buddy_privkey(gc, buddy->name); | |
| 613 | ||
| 614 | } | |
| 615 | ||
| 616 | static void | |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
617 | silcgaim_buddy_showkey(GaimBlistNode *node, gpointer data) |
| 8849 | 618 | { |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
619 | GaimBuddy *b; |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
620 | GaimConnection *gc; |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
621 | SilcGaim sg; |
| 8849 | 622 | SilcPublicKey public_key; |
| 623 | const char *pkfile; | |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
624 | |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
625 | g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); |
| 8849 | 626 | |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
627 | b = (GaimBuddy *) node; |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
628 | gc = gaim_account_get_connection(b->account); |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
629 | sg = gc->proto_data; |
| 8849 | 630 | |
| 9038 | 631 | pkfile = gaim_blist_node_get_string(node, "public-key"); |
| 8849 | 632 | if (!silc_pkcs_load_public_key(pkfile, &public_key, SILC_PKCS_FILE_PEM) && |
| 633 | !silc_pkcs_load_public_key(pkfile, &public_key, SILC_PKCS_FILE_BIN)) { | |
| 634 | gaim_notify_error(gc, | |
| 635 | _("Show Public Key"), | |
| 636 | _("Could not load public key"), NULL); | |
| 637 | return; | |
| 638 | } | |
| 639 | ||
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
640 | silcgaim_show_public_key(sg, b->name, public_key, NULL, NULL); |
| 8849 | 641 | silc_pkcs_public_key_free(public_key); |
| 642 | } | |
| 643 | ||
| 644 | ||
| 645 | /**************************** Buddy routines *********************************/ | |
| 646 | ||
| 647 | /* The buddies are implemented by using the WHOIS and WATCH commands that | |
| 648 | can be used to search users by their public key. Since nicknames aren't | |
| 649 | unique in SILC we cannot trust the buddy list using their nickname. We | |
| 650 | associate public keys to buddies and use those to search and watch | |
| 651 | in the network. | |
| 652 | ||
| 653 | The problem is that Gaim does not return GaimBuddy contexts to the | |
| 654 | callbacks but the buddy names. Naturally, this is not going to work | |
| 655 | with SILC. But, for now, we have to do what we can... */ | |
| 656 | ||
| 657 | typedef struct { | |
| 658 | SilcClient client; | |
| 659 | SilcClientConnection conn; | |
| 660 | SilcClientID client_id; | |
| 661 | GaimBuddy *b; | |
| 662 | unsigned char *offline_pk; | |
| 663 | SilcUInt32 offline_pk_len; | |
| 664 | unsigned int offline : 1; | |
| 665 | unsigned int pubkey_search : 1; | |
| 666 | unsigned int init : 1; | |
| 667 | } *SilcGaimBuddyRes; | |
| 668 | ||
| 669 | static void | |
| 670 | silcgaim_add_buddy_ask_pk_cb(SilcGaimBuddyRes r, gint id); | |
| 671 | static void | |
| 672 | silcgaim_add_buddy_resolved(SilcClient client, | |
| 673 | SilcClientConnection conn, | |
| 674 | SilcClientEntry *clients, | |
| 675 | SilcUInt32 clients_count, | |
| 676 | void *context); | |
| 677 | ||
| 678 | void silcgaim_get_info(GaimConnection *gc, const char *who) | |
| 679 | { | |
| 680 | SilcGaim sg = gc->proto_data; | |
| 681 | SilcClient client = sg->client; | |
| 682 | SilcClientConnection conn = sg->conn; | |
| 683 | SilcClientEntry client_entry; | |
| 684 | GaimBuddy *b; | |
| 685 | const char *filename, *nick = who; | |
| 686 | char tmp[256]; | |
| 687 | ||
| 688 | if (!who) | |
| 689 | return; | |
| 690 | if (strlen(who) > 1 && who[0] == '@') | |
| 691 | nick = who + 1; | |
| 692 | if (strlen(who) > 1 && who[0] == '*') | |
| 693 | nick = who + 1; | |
| 694 | if (strlen(who) > 2 && who[0] == '*' && who[1] == '@') | |
| 695 | nick = who + 2; | |
| 696 | ||
| 697 | b = gaim_find_buddy(gc->account, nick); | |
| 698 | if (b) { | |
| 699 | /* See if we have this buddy's public key. If we do use that | |
| 700 | to search the details. */ | |
| 701 | filename = gaim_blist_node_get_string((GaimBlistNode *)b, "public-key"); | |
| 702 | if (filename) { | |
| 703 | /* Call WHOIS. The user info is displayed in the WHOIS | |
| 704 | command reply. */ | |
| 705 | silc_client_command_call(client, conn, NULL, "WHOIS", | |
| 706 | "-details", "-pubkey", filename, NULL); | |
| 707 | return; | |
| 708 | } | |
| 709 | ||
| 710 | if (!b->proto_data) { | |
| 711 | g_snprintf(tmp, sizeof(tmp), | |
| 712 | _("User %s is not present in the network"), b->name); | |
| 713 | gaim_notify_error(gc, _("User Information"), | |
| 714 | _("Cannot get user information"), tmp); | |
| 715 | return; | |
| 716 | } | |
| 717 | ||
| 718 | client_entry = silc_client_get_client_by_id(client, conn, b->proto_data); | |
| 719 | if (client_entry) { | |
| 720 | /* Call WHOIS. The user info is displayed in the WHOIS | |
| 721 | command reply. */ | |
| 722 | silc_client_command_call(client, conn, NULL, "WHOIS", | |
| 723 | client_entry->nickname, "-details", NULL); | |
| 724 | } | |
| 725 | } else { | |
| 726 | /* Call WHOIS just with nickname. */ | |
| 727 | silc_client_command_call(client, conn, NULL, "WHOIS", nick, NULL); | |
| 728 | } | |
| 729 | } | |
| 730 | ||
| 731 | static void | |
| 732 | silcgaim_add_buddy_pk_no(SilcGaimBuddyRes r) | |
| 733 | { | |
| 734 | char tmp[512]; | |
| 735 | g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not trusted"), | |
| 736 | r->b->name); | |
| 737 | gaim_notify_error(r->client->application, _("Add Buddy"), tmp, | |
| 8910 | 738 | _("You cannot receive buddy notifications until you " |
| 739 | "import his/her public key. You can use the Get Public Key " | |
| 8849 | 740 | "command to get the public key.")); |
|
10050
78e480f768f2
[gaim-migrate @ 11011]
Dave West <kat@users.sourceforge.net>
parents:
10029
diff
changeset
|
741 | gaim_prpl_got_user_status(gaim_buddy_get_account(r->b), gaim_buddy_get_name(r->b), SILCGAIM_STATUS_ID_OFFLINE, NULL); |
| 8849 | 742 | } |
| 743 | ||
| 744 | static void | |
| 745 | silcgaim_add_buddy_save(bool success, void *context) | |
| 746 | { | |
| 747 | SilcGaimBuddyRes r = context; | |
| 748 | GaimBuddy *b = r->b; | |
| 749 | SilcClient client = r->client; | |
| 750 | SilcClientEntry client_entry; | |
| 751 | SilcAttributePayload attr; | |
| 752 | SilcAttribute attribute; | |
| 753 | SilcVCardStruct vcard; | |
| 754 | SilcAttributeObjMime message, extension; | |
| 755 | SilcAttributeObjPk serverpk, usersign, serversign; | |
| 756 | gboolean usign_success = TRUE, ssign_success = TRUE; | |
|
11165
770e5d7940a0
[gaim-migrate @ 13266]
Mark Doliner <markdoliner@pidgin.im>
parents:
10869
diff
changeset
|
757 | char filename[512], filename2[512], *fingerprint = NULL, *tmp; |
| 8849 | 758 | SilcUInt32 len; |
| 759 | int i; | |
| 760 | ||
| 761 | if (!success) { | |
| 762 | /* The user did not trust the public key. */ | |
| 763 | silcgaim_add_buddy_pk_no(r); | |
| 764 | silc_free(r); | |
| 765 | return; | |
| 766 | } | |
| 767 | ||
| 768 | if (r->offline) { | |
| 769 | /* User is offline. Associate the imported public key with | |
| 770 | this user. */ | |
| 771 | fingerprint = silc_hash_fingerprint(NULL, r->offline_pk, | |
| 772 | r->offline_pk_len); | |
| 773 | for (i = 0; i < strlen(fingerprint); i++) | |
| 774 | if (fingerprint[i] == ' ') | |
| 775 | fingerprint[i] = '_'; | |
| 776 | g_snprintf(filename, sizeof(filename) - 1, | |
| 777 | "%s" G_DIR_SEPARATOR_S "clientkeys" G_DIR_SEPARATOR_S "clientkey_%s.pub", | |
| 778 | silcgaim_silcdir(), fingerprint); | |
| 779 | gaim_blist_node_set_string((GaimBlistNode *)b, "public-key", filename); | |
|
10050
78e480f768f2
[gaim-migrate @ 11011]
Dave West <kat@users.sourceforge.net>
parents:
10029
diff
changeset
|
780 | gaim_prpl_got_user_status(gaim_buddy_get_account(r->b), gaim_buddy_get_name(r->b), SILCGAIM_STATUS_ID_OFFLINE, NULL); |
| 8849 | 781 | silc_free(fingerprint); |
| 782 | silc_free(r->offline_pk); | |
| 783 | silc_free(r); | |
| 784 | return; | |
| 785 | } | |
| 786 | ||
| 787 | /* Get the client entry. */ | |
| 788 | client_entry = silc_client_get_client_by_id(r->client, r->conn, | |
| 789 | &r->client_id); | |
| 790 | if (!client_entry) { | |
| 791 | silc_free(r); | |
| 792 | return; | |
| 793 | } | |
| 794 | ||
| 795 | memset(&vcard, 0, sizeof(vcard)); | |
| 796 | memset(&message, 0, sizeof(message)); | |
| 797 | memset(&extension, 0, sizeof(extension)); | |
| 798 | memset(&serverpk, 0, sizeof(serverpk)); | |
| 799 | memset(&usersign, 0, sizeof(usersign)); | |
| 800 | memset(&serversign, 0, sizeof(serversign)); | |
| 801 | ||
| 802 | /* Now that we have the public key and we trust it now we | |
| 803 | save the attributes of the buddy and update its status. */ | |
| 804 | ||
|
9133
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
805 | if (client_entry->attrs) { |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
806 | silc_dlist_start(client_entry->attrs); |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
807 | while ((attr = silc_dlist_get(client_entry->attrs)) |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
808 | != SILC_LIST_END) { |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
809 | attribute = silc_attribute_get_attribute(attr); |
| 8849 | 810 | |
|
9133
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
811 | switch (attribute) { |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
812 | case SILC_ATTRIBUTE_USER_INFO: |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
813 | if (!silc_attribute_get_object(attr, (void *)&vcard, |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
814 | sizeof(vcard))) |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
815 | continue; |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
816 | break; |
| 8849 | 817 | |
|
9133
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
818 | case SILC_ATTRIBUTE_STATUS_MESSAGE: |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
819 | if (!silc_attribute_get_object(attr, (void *)&message, |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
820 | sizeof(message))) |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
821 | continue; |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
822 | break; |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
823 | |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
824 | case SILC_ATTRIBUTE_EXTENSION: |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
825 | if (!silc_attribute_get_object(attr, (void *)&extension, |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
826 | sizeof(extension))) |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
827 | continue; |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
828 | break; |
| 8849 | 829 | |
|
9133
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
830 | case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY: |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
831 | if (serverpk.type) |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
832 | continue; |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
833 | if (!silc_attribute_get_object(attr, (void *)&serverpk, |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
834 | sizeof(serverpk))) |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
835 | continue; |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
836 | break; |
| 8849 | 837 | |
|
9133
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
838 | case SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE: |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
839 | if (usersign.data) |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
840 | continue; |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
841 | if (!silc_attribute_get_object(attr, (void *)&usersign, |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
842 | sizeof(usersign))) |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
843 | continue; |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
844 | break; |
| 8849 | 845 | |
|
9133
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
846 | case SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE: |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
847 | if (serversign.data) |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
848 | continue; |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
849 | if (!silc_attribute_get_object(attr, (void *)&serversign, |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
850 | sizeof(serversign))) |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
851 | continue; |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
852 | break; |
| 8849 | 853 | |
|
9133
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
854 | default: |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
855 | break; |
|
bc33b12619d4
[gaim-migrate @ 9915]
Pekka Riikonen <priikone@silcnet.org>
parents:
9060
diff
changeset
|
856 | } |
| 8849 | 857 | } |
| 858 | } | |
| 859 | ||
| 860 | /* Verify the attribute signatures */ | |
| 861 | ||
| 862 | if (usersign.data) { | |
| 863 | SilcPKCS pkcs; | |
| 864 | unsigned char *verifyd; | |
| 865 | SilcUInt32 verify_len; | |
| 866 | ||
|
11488
d422a70bed74
[gaim-migrate @ 13730]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
11338
diff
changeset
|
867 | silc_pkcs_alloc((unsigned char*)"rsa", &pkcs); |
| 8849 | 868 | verifyd = silc_attribute_get_verify_data(client_entry->attrs, |
| 869 | FALSE, &verify_len); | |
| 870 | if (verifyd && silc_pkcs_public_key_set(pkcs, client_entry->public_key)){ | |
| 871 | if (!silc_pkcs_verify_with_hash(pkcs, client->sha1hash, | |
| 872 | usersign.data, | |
| 873 | usersign.data_len, | |
| 874 | verifyd, verify_len)) | |
| 875 | usign_success = FALSE; | |
| 876 | } | |
| 877 | silc_free(verifyd); | |
| 878 | } | |
| 879 | ||
| 880 | if (serversign.data && !strcmp(serverpk.type, "silc-rsa")) { | |
| 881 | SilcPublicKey public_key; | |
| 882 | SilcPKCS pkcs; | |
| 883 | unsigned char *verifyd; | |
| 884 | SilcUInt32 verify_len; | |
| 885 | ||
| 886 | if (silc_pkcs_public_key_decode(serverpk.data, serverpk.data_len, | |
| 887 | &public_key)) { | |
|
11488
d422a70bed74
[gaim-migrate @ 13730]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
11338
diff
changeset
|
888 | silc_pkcs_alloc((unsigned char *)"rsa", &pkcs); |
| 8849 | 889 | verifyd = silc_attribute_get_verify_data(client_entry->attrs, |
| 890 | TRUE, &verify_len); | |
| 891 | if (verifyd && silc_pkcs_public_key_set(pkcs, public_key)) { | |
| 892 | if (!silc_pkcs_verify_with_hash(pkcs, client->sha1hash, | |
| 893 | serversign.data, | |
| 894 | serversign.data_len, | |
| 895 | verifyd, verify_len)) | |
| 896 | ssign_success = FALSE; | |
| 897 | } | |
| 898 | silc_pkcs_public_key_free(public_key); | |
| 899 | silc_free(verifyd); | |
| 900 | } | |
| 901 | } | |
| 902 | ||
| 903 | fingerprint = silc_fingerprint(client_entry->fingerprint, | |
| 904 | client_entry->fingerprint_len); | |
| 905 | for (i = 0; i < strlen(fingerprint); i++) | |
| 906 | if (fingerprint[i] == ' ') | |
| 907 | fingerprint[i] = '_'; | |
| 908 | ||
| 909 | if (usign_success || ssign_success) { | |
| 910 | struct passwd *pw; | |
| 911 | struct stat st; | |
| 912 | ||
| 913 | memset(filename2, 0, sizeof(filename2)); | |
| 914 | ||
| 915 | /* Filename for dir */ | |
| 916 | tmp = fingerprint + strlen(fingerprint) - 9; | |
| 917 | g_snprintf(filename, sizeof(filename) - 1, | |
| 918 | "%s" G_DIR_SEPARATOR_S "friends" G_DIR_SEPARATOR_S "%s", | |
| 919 | silcgaim_silcdir(), tmp); | |
| 920 | ||
| 921 | pw = getpwuid(getuid()); | |
| 922 | if (!pw) | |
| 923 | return; | |
| 924 | ||
| 925 | /* Create dir if it doesn't exist */ | |
|
10589
4e10236e06d4
[gaim-migrate @ 11994]
Daniel Atallah <datallah@pidgin.im>
parents:
10341
diff
changeset
|
926 | if ((g_stat(filename, &st)) == -1) { |
| 8849 | 927 | if (errno == ENOENT) { |
| 928 | if (pw->pw_uid == geteuid()) | |
|
10589
4e10236e06d4
[gaim-migrate @ 11994]
Daniel Atallah <datallah@pidgin.im>
parents:
10341
diff
changeset
|
929 | g_mkdir(filename, 0755); |
| 8849 | 930 | } |
| 931 | } | |
| 932 | ||
| 933 | /* Save VCard */ | |
| 934 | g_snprintf(filename2, sizeof(filename2) - 1, | |
| 935 | "%s" G_DIR_SEPARATOR_S "vcard", filename); | |
| 936 | if (vcard.full_name) { | |
|
11488
d422a70bed74
[gaim-migrate @ 13730]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
11338
diff
changeset
|
937 | tmp = (char *)silc_vcard_encode(&vcard, &len); |
| 8849 | 938 | silc_file_writefile(filename2, tmp, len); |
| 939 | silc_free(tmp); | |
| 940 | } | |
| 941 | ||
| 942 | /* Save status message */ | |
| 943 | if (message.mime) { | |
| 944 | memset(filename2, 0, sizeof(filename2)); | |
| 945 | g_snprintf(filename2, sizeof(filename2) - 1, | |
| 946 | "%s" G_DIR_SEPARATOR_S "status_message.mime", | |
| 947 | filename); | |
|
11488
d422a70bed74
[gaim-migrate @ 13730]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
11338
diff
changeset
|
948 | silc_file_writefile(filename2, (char *)message.mime, |
| 8849 | 949 | message.mime_len); |
| 950 | } | |
| 951 | ||
| 952 | /* Save extension data */ | |
| 953 | if (extension.mime) { | |
| 954 | memset(filename2, 0, sizeof(filename2)); | |
| 955 | g_snprintf(filename2, sizeof(filename2) - 1, | |
| 956 | "%s" G_DIR_SEPARATOR_S "extension.mime", | |
| 957 | filename); | |
|
11488
d422a70bed74
[gaim-migrate @ 13730]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
11338
diff
changeset
|
958 | silc_file_writefile(filename2, (char *)extension.mime, |
| 8849 | 959 | extension.mime_len); |
| 960 | } | |
| 961 | } | |
| 962 | ||
| 963 | /* Save the public key path to buddy properties, as it is used | |
| 964 | to identify the buddy in the network (and not the nickname). */ | |
| 965 | memset(filename, 0, sizeof(filename)); | |
| 966 | g_snprintf(filename, sizeof(filename) - 1, | |
| 967 | "%s" G_DIR_SEPARATOR_S "clientkeys" G_DIR_SEPARATOR_S "clientkey_%s.pub", | |
| 968 | silcgaim_silcdir(), fingerprint); | |
| 969 | gaim_blist_node_set_string((GaimBlistNode *)b, "public-key", filename); | |
| 970 | ||
|
10050
78e480f768f2
[gaim-migrate @ 11011]
Dave West <kat@users.sourceforge.net>
parents:
10029
diff
changeset
|
971 | /* Update online status */ |
|
11522
c2a0d620f903
[gaim-migrate @ 13770]
Mark Doliner <markdoliner@pidgin.im>
parents:
11488
diff
changeset
|
972 | gaim_prpl_got_user_status(gaim_buddy_get_account(r->b), gaim_buddy_get_name(r->b), SILCGAIM_STATUS_ID_AVAILABLE, NULL); |
| 8849 | 973 | |
| 974 | /* Finally, start watching this user so we receive its status | |
| 975 | changes from the server */ | |
| 976 | g_snprintf(filename2, sizeof(filename2) - 1, "+%s", filename); | |
| 977 | silc_client_command_call(r->client, r->conn, NULL, "WATCH", "-pubkey", | |
| 978 | filename2, NULL); | |
| 979 | ||
| 980 | silc_free(fingerprint); | |
| 981 | silc_free(r); | |
| 982 | } | |
| 983 | ||
| 984 | static void | |
| 985 | silcgaim_add_buddy_ask_import(void *user_data, const char *name) | |
| 986 | { | |
| 987 | SilcGaimBuddyRes r = (SilcGaimBuddyRes)user_data; | |
| 988 | SilcPublicKey public_key; | |
| 989 | ||
| 990 | /* Load the public key */ | |
| 991 | if (!silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_PEM) && | |
| 992 | !silc_pkcs_load_public_key(name, &public_key, SILC_PKCS_FILE_BIN)) { | |
| 993 | silcgaim_add_buddy_ask_pk_cb(r, 0); | |
| 994 | gaim_notify_error(r->client->application, | |
| 995 | _("Add Buddy"), _("Could not load public key"), NULL); | |
| 996 | return; | |
| 997 | } | |
| 998 | ||
| 999 | /* Now verify the public key */ | |
| 1000 | r->offline_pk = silc_pkcs_public_key_encode(public_key, &r->offline_pk_len); | |
| 1001 | silcgaim_verify_public_key(r->client, r->conn, r->b->name, | |
| 1002 | SILC_SOCKET_TYPE_CLIENT, | |
| 1003 | r->offline_pk, r->offline_pk_len, | |
| 1004 | SILC_SKE_PK_TYPE_SILC, | |
| 1005 | silcgaim_add_buddy_save, r); | |
| 1006 | } | |
| 1007 | ||
| 1008 | static void | |
| 1009 | silcgaim_add_buddy_ask_pk_cancel(void *user_data, const char *name) | |
| 1010 | { | |
| 1011 | SilcGaimBuddyRes r = (SilcGaimBuddyRes)user_data; | |
| 1012 | ||
| 1013 | /* The user did not import public key. The buddy is unusable. */ | |
| 1014 | silcgaim_add_buddy_pk_no(r); | |
| 1015 | silc_free(r); | |
| 1016 | } | |
| 1017 | ||
| 1018 | static void | |
| 1019 | silcgaim_add_buddy_ask_pk_cb(SilcGaimBuddyRes r, gint id) | |
| 1020 | { | |
| 1021 | if (id != 0) { | |
| 1022 | /* The user did not import public key. The buddy is unusable. */ | |
| 1023 | silcgaim_add_buddy_pk_no(r); | |
| 1024 | silc_free(r); | |
| 1025 | return; | |
| 1026 | } | |
| 1027 | ||
| 1028 | /* Open file selector to select the public key. */ | |
|
11201
f8fed1f48ca3
[gaim-migrate @ 13329]
Mark Doliner <markdoliner@pidgin.im>
parents:
11165
diff
changeset
|
1029 | gaim_request_file(r->client->application, _("Open..."), NULL, FALSE, |
| 8849 | 1030 | G_CALLBACK(silcgaim_add_buddy_ask_import), |
| 1031 | G_CALLBACK(silcgaim_add_buddy_ask_pk_cancel), r); | |
| 1032 | } | |
| 1033 | ||
| 1034 | static void | |
| 1035 | silcgaim_add_buddy_ask_pk(SilcGaimBuddyRes r) | |
| 1036 | { | |
| 1037 | char tmp[512]; | |
| 1038 | g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not present in the network"), | |
| 1039 | r->b->name); | |
|
11201
f8fed1f48ca3
[gaim-migrate @ 13329]
Mark Doliner <markdoliner@pidgin.im>
parents:
11165
diff
changeset
|
1040 | gaim_request_action(r->client->application, _("Add Buddy"), tmp, |
| 8910 | 1041 | _("To add the buddy you must import his/her public key. " |
| 8849 | 1042 | "Press Import to import a public key."), 0, r, 2, |
| 1043 | _("Cancel"), G_CALLBACK(silcgaim_add_buddy_ask_pk_cb), | |
| 1044 | _("Import..."), G_CALLBACK(silcgaim_add_buddy_ask_pk_cb)); | |
| 1045 | } | |
| 1046 | ||
| 1047 | static void | |
| 1048 | silcgaim_add_buddy_getkey_cb(SilcGaimBuddyRes r, | |
| 1049 | SilcClientCommandReplyContext cmd) | |
| 1050 | { | |
| 1051 | SilcClientEntry client_entry; | |
| 1052 | unsigned char *pk; | |
| 1053 | SilcUInt32 pk_len; | |
| 1054 | ||
| 1055 | /* Get the client entry. */ | |
| 1056 | client_entry = silc_client_get_client_by_id(r->client, r->conn, | |
| 1057 | &r->client_id); | |
| 1058 | if (!client_entry || !client_entry->public_key) { | |
| 1059 | /* The buddy is offline/nonexistent. We will require user | |
| 1060 | to associate a public key with the buddy or the buddy | |
| 1061 | cannot be added. */ | |
| 1062 | r->offline = TRUE; | |
| 1063 | silcgaim_add_buddy_ask_pk(r); | |
| 1064 | return; | |
| 1065 | } | |
| 1066 | ||
| 1067 | /* Now verify the public key */ | |
| 1068 | pk = silc_pkcs_public_key_encode(client_entry->public_key, &pk_len); | |
| 1069 | silcgaim_verify_public_key(r->client, r->conn, client_entry->nickname, | |
| 1070 | SILC_SOCKET_TYPE_CLIENT, | |
| 1071 | pk, pk_len, SILC_SKE_PK_TYPE_SILC, | |
| 1072 | silcgaim_add_buddy_save, r); | |
| 1073 | silc_free(pk); | |
| 1074 | } | |
| 1075 | ||
| 1076 | static void | |
| 1077 | silcgaim_add_buddy_select_cb(SilcGaimBuddyRes r, GaimRequestFields *fields) | |
| 1078 | { | |
| 1079 | GaimRequestField *f; | |
| 1080 | const GList *list; | |
| 1081 | SilcClientEntry client_entry; | |
| 1082 | ||
| 1083 | f = gaim_request_fields_get_field(fields, "list"); | |
| 1084 | list = gaim_request_field_list_get_selected(f); | |
| 1085 | if (!list) { | |
| 1086 | /* The user did not select any user. */ | |
| 1087 | silcgaim_add_buddy_pk_no(r); | |
| 1088 | silc_free(r); | |
| 1089 | return; | |
| 1090 | } | |
| 1091 | ||
| 1092 | client_entry = gaim_request_field_list_get_data(f, list->data); | |
| 1093 | silcgaim_add_buddy_resolved(r->client, r->conn, &client_entry, 1, r); | |
| 1094 | } | |
| 1095 | ||
| 1096 | static void | |
| 1097 | silcgaim_add_buddy_select_cancel(SilcGaimBuddyRes r, GaimRequestFields *fields) | |
| 1098 | { | |
| 1099 | /* The user did not select any user. */ | |
| 1100 | silcgaim_add_buddy_pk_no(r); | |
| 1101 | silc_free(r); | |
| 1102 | } | |
| 1103 | ||
| 1104 | static void | |
| 1105 | silcgaim_add_buddy_select(SilcGaimBuddyRes r, | |
| 1106 | SilcClientEntry *clients, | |
| 1107 | SilcUInt32 clients_count) | |
| 1108 | { | |
| 1109 | GaimRequestFields *fields; | |
| 1110 | GaimRequestFieldGroup *g; | |
| 1111 | GaimRequestField *f; | |
| 1112 | char tmp[512]; | |
| 1113 | int i; | |
| 1114 | ||
| 1115 | fields = gaim_request_fields_new(); | |
| 1116 | g = gaim_request_field_group_new(NULL); | |
| 1117 | f = gaim_request_field_list_new("list", NULL); | |
| 1118 | gaim_request_field_group_add_field(g, f); | |
| 1119 | gaim_request_field_list_set_multi_select(f, FALSE); | |
| 1120 | gaim_request_fields_add_group(fields, g); | |
| 1121 | ||
| 1122 | for (i = 0; i < clients_count; i++) { | |
| 1123 | g_snprintf(tmp, sizeof(tmp), "%s - %s (%s@%s)", | |
| 1124 | clients[i]->realname, clients[i]->nickname, | |
| 1125 | clients[i]->username, clients[i]->hostname ? | |
| 1126 | clients[i]->hostname : ""); | |
| 1127 | gaim_request_field_list_add(f, tmp, clients[i]); | |
| 1128 | } | |
| 1129 | ||
|
11201
f8fed1f48ca3
[gaim-migrate @ 13329]
Mark Doliner <markdoliner@pidgin.im>
parents:
11165
diff
changeset
|
1130 | gaim_request_fields(r->client->application, _("Add Buddy"), |
| 8891 | 1131 | _("Select correct user"), |
| 1132 | r->pubkey_search | |
| 1133 | ? _("More than one user was found with the same public key. Select " | |
| 1134 | "the correct user from the list to add to the buddy list.") | |
| 1135 | : _("More than one user was found with the same name. Select " | |
| 1136 | "the correct user from the list to add to the buddy list."), | |
| 1137 | fields, | |
| 1138 | _("OK"), G_CALLBACK(silcgaim_add_buddy_select_cb), | |
| 1139 | _("Cancel"), G_CALLBACK(silcgaim_add_buddy_select_cancel), r); | |
| 8849 | 1140 | } |
| 1141 | ||
| 1142 | static void | |
| 1143 | silcgaim_add_buddy_resolved(SilcClient client, | |
| 1144 | SilcClientConnection conn, | |
| 1145 | SilcClientEntry *clients, | |
| 1146 | SilcUInt32 clients_count, | |
| 1147 | void *context) | |
| 1148 | { | |
| 1149 | SilcGaimBuddyRes r = context; | |
| 1150 | GaimBuddy *b = r->b; | |
| 1151 | SilcAttributePayload pub; | |
| 1152 | SilcAttributeObjPk userpk; | |
| 1153 | unsigned char *pk; | |
| 1154 | SilcUInt32 pk_len; | |
| 1155 | const char *filename; | |
| 1156 | ||
|
10029
849bb075efb9
[gaim-migrate @ 10965]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9927
diff
changeset
|
1157 | filename = gaim_blist_node_get_string((GaimBlistNode *)b, "public-key"); |
|
849bb075efb9
[gaim-migrate @ 10965]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9927
diff
changeset
|
1158 | |
| 8849 | 1159 | /* If the buddy is offline/nonexistent, we will require user |
| 1160 | to associate a public key with the buddy or the buddy | |
| 1161 | cannot be added. */ | |
| 1162 | if (!clients_count) { | |
| 1163 | if (r->init) { | |
| 1164 | silc_free(r); | |
| 1165 | return; | |
| 1166 | } | |
| 1167 | ||
| 1168 | r->offline = TRUE; | |
|
10029
849bb075efb9
[gaim-migrate @ 10965]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9927
diff
changeset
|
1169 | /* If the user has already associated a public key, try loading it |
|
849bb075efb9
[gaim-migrate @ 10965]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9927
diff
changeset
|
1170 | * before prompting the user to load it again */ |
|
849bb075efb9
[gaim-migrate @ 10965]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9927
diff
changeset
|
1171 | if (filename != NULL) |
|
849bb075efb9
[gaim-migrate @ 10965]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9927
diff
changeset
|
1172 | silcgaim_add_buddy_ask_import(r, filename); |
|
849bb075efb9
[gaim-migrate @ 10965]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9927
diff
changeset
|
1173 | else |
|
849bb075efb9
[gaim-migrate @ 10965]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9927
diff
changeset
|
1174 | silcgaim_add_buddy_ask_pk(r); |
| 8849 | 1175 | return; |
| 1176 | } | |
| 1177 | ||
| 1178 | /* If more than one client was found with nickname, we need to verify | |
| 1179 | from user which one is the correct. */ | |
| 1180 | if (clients_count > 1 && !r->pubkey_search) { | |
| 1181 | if (r->init) { | |
| 1182 | silc_free(r); | |
| 1183 | return; | |
| 1184 | } | |
| 1185 | ||
| 1186 | silcgaim_add_buddy_select(r, clients, clients_count); | |
| 1187 | return; | |
| 1188 | } | |
| 1189 | ||
| 1190 | /* If we searched using public keys and more than one entry was found | |
| 1191 | the same person is logged on multiple times. */ | |
| 1192 | if (clients_count > 1 && r->pubkey_search && b->name) { | |
| 1193 | if (r->init) { | |
| 1194 | /* Find the entry that closest matches to the | |
| 1195 | buddy nickname. */ | |
| 1196 | int i; | |
| 1197 | for (i = 0; i < clients_count; i++) { | |
| 1198 | if (!strncasecmp(b->name, clients[i]->nickname, | |
| 1199 | strlen(b->name))) { | |
| 1200 | clients[0] = clients[i]; | |
| 1201 | break; | |
| 1202 | } | |
| 1203 | } | |
| 1204 | } else { | |
| 1205 | /* Verify from user which one is correct */ | |
| 1206 | silcgaim_add_buddy_select(r, clients, clients_count); | |
| 1207 | return; | |
| 1208 | } | |
| 1209 | } | |
| 1210 | ||
| 1211 | /* The client was found. Now get its public key and verify | |
| 1212 | that before adding the buddy. */ | |
| 1213 | memset(&userpk, 0, sizeof(userpk)); | |
| 1214 | b->proto_data = silc_memdup(clients[0]->id, sizeof(*clients[0]->id)); | |
| 1215 | r->client_id = *clients[0]->id; | |
| 1216 | ||
| 1217 | /* Get the public key from attributes, if not present then | |
| 1218 | resolve it with GETKEY unless we have it cached already. */ | |
| 1219 | if (clients[0]->attrs && !clients[0]->public_key) { | |
| 1220 | pub = silcgaim_get_attr(clients[0]->attrs, | |
| 1221 | SILC_ATTRIBUTE_USER_PUBLIC_KEY); | |
| 1222 | if (!pub || !silc_attribute_get_object(pub, (void *)&userpk, | |
| 1223 | sizeof(userpk))) { | |
| 1224 | /* Get public key with GETKEY */ | |
| 1225 | silc_client_command_call(client, conn, NULL, | |
| 1226 | "GETKEY", clients[0]->nickname, NULL); | |
| 1227 | silc_client_command_pending(conn, SILC_COMMAND_GETKEY, | |
| 1228 | conn->cmd_ident, | |
| 1229 | (SilcCommandCb)silcgaim_add_buddy_getkey_cb, | |
| 1230 | r); | |
| 1231 | return; | |
| 1232 | } | |
| 1233 | if (!silc_pkcs_public_key_decode(userpk.data, userpk.data_len, | |
| 1234 | &clients[0]->public_key)) | |
| 1235 | return; | |
| 1236 | silc_free(userpk.data); | |
| 1237 | } else if (filename && !clients[0]->public_key) { | |
| 1238 | if (!silc_pkcs_load_public_key(filename, &clients[0]->public_key, | |
| 1239 | SILC_PKCS_FILE_PEM) && | |
| 1240 | !silc_pkcs_load_public_key(filename, &clients[0]->public_key, | |
| 1241 | SILC_PKCS_FILE_BIN)) { | |
| 1242 | /* Get public key with GETKEY */ | |
| 1243 | silc_client_command_call(client, conn, NULL, | |
| 1244 | "GETKEY", clients[0]->nickname, NULL); | |
| 1245 | silc_client_command_pending(conn, SILC_COMMAND_GETKEY, | |
| 1246 | conn->cmd_ident, | |
| 1247 | (SilcCommandCb)silcgaim_add_buddy_getkey_cb, | |
| 1248 | r); | |
| 1249 | return; | |
| 1250 | } | |
| 1251 | } else if (!clients[0]->public_key) { | |
| 1252 | /* Get public key with GETKEY */ | |
| 1253 | silc_client_command_call(client, conn, NULL, | |
| 1254 | "GETKEY", clients[0]->nickname, NULL); | |
| 1255 | silc_client_command_pending(conn, SILC_COMMAND_GETKEY, | |
| 1256 | conn->cmd_ident, | |
| 1257 | (SilcCommandCb)silcgaim_add_buddy_getkey_cb, | |
| 1258 | r); | |
| 1259 | return; | |
| 1260 | } | |
| 1261 | ||
| 1262 | /* We have the public key, verify it. */ | |
| 1263 | pk = silc_pkcs_public_key_encode(clients[0]->public_key, &pk_len); | |
| 1264 | silcgaim_verify_public_key(client, conn, clients[0]->nickname, | |
| 1265 | SILC_SOCKET_TYPE_CLIENT, | |
| 1266 | pk, pk_len, SILC_SKE_PK_TYPE_SILC, | |
| 1267 | silcgaim_add_buddy_save, r); | |
| 1268 | silc_free(pk); | |
| 1269 | } | |
| 1270 | ||
| 1271 | static void | |
| 1272 | silcgaim_add_buddy_i(GaimConnection *gc, GaimBuddy *b, gboolean init) | |
| 1273 | { | |
| 1274 | SilcGaim sg = gc->proto_data; | |
| 1275 | SilcClient client = sg->client; | |
| 1276 | SilcClientConnection conn = sg->conn; | |
| 1277 | SilcGaimBuddyRes r; | |
| 1278 | SilcBuffer attrs; | |
| 1279 | const char *filename, *name = b->name; | |
| 1280 | ||
| 1281 | r = silc_calloc(1, sizeof(*r)); | |
| 1282 | if (!r) | |
| 1283 | return; | |
| 1284 | r->client = client; | |
| 1285 | r->conn = conn; | |
| 1286 | r->b = b; | |
| 1287 | r->init = init; | |
| 1288 | ||
| 1289 | /* See if we have this buddy's public key. If we do use that | |
| 1290 | to search the details. */ | |
| 1291 | filename = gaim_blist_node_get_string((GaimBlistNode *)b, "public-key"); | |
| 1292 | if (filename) { | |
| 1293 | SilcPublicKey public_key; | |
| 1294 | SilcAttributeObjPk userpk; | |
| 1295 | ||
| 1296 | if (!silc_pkcs_load_public_key(filename, &public_key, | |
| 1297 | SILC_PKCS_FILE_PEM) && | |
| 1298 | !silc_pkcs_load_public_key(filename, &public_key, | |
| 1299 | SILC_PKCS_FILE_BIN)) | |
| 1300 | return; | |
| 1301 | ||
| 1302 | /* Get all attributes, and use the public key to search user */ | |
| 1303 | name = NULL; | |
| 1304 | attrs = silc_client_attributes_request(SILC_ATTRIBUTE_USER_INFO, | |
| 1305 | SILC_ATTRIBUTE_SERVICE, | |
| 1306 | SILC_ATTRIBUTE_STATUS_MOOD, | |
| 1307 | SILC_ATTRIBUTE_STATUS_FREETEXT, | |
| 1308 | SILC_ATTRIBUTE_STATUS_MESSAGE, | |
| 1309 | SILC_ATTRIBUTE_PREFERRED_LANGUAGE, | |
| 1310 | SILC_ATTRIBUTE_PREFERRED_CONTACT, | |
| 1311 | SILC_ATTRIBUTE_TIMEZONE, | |
| 1312 | SILC_ATTRIBUTE_GEOLOCATION, | |
| 1313 | SILC_ATTRIBUTE_DEVICE_INFO, 0); | |
| 1314 | userpk.type = "silc-rsa"; | |
| 1315 | userpk.data = silc_pkcs_public_key_encode(public_key, &userpk.data_len); | |
| 1316 | attrs = silc_attribute_payload_encode(attrs, | |
| 1317 | SILC_ATTRIBUTE_USER_PUBLIC_KEY, | |
| 1318 | SILC_ATTRIBUTE_FLAG_VALID, | |
| 1319 | &userpk, sizeof(userpk)); | |
| 1320 | silc_free(userpk.data); | |
| 1321 | silc_pkcs_public_key_free(public_key); | |
| 1322 | r->pubkey_search = TRUE; | |
| 1323 | } else { | |
| 1324 | /* Get all attributes */ | |
| 1325 | attrs = silc_client_attributes_request(0); | |
| 1326 | } | |
| 1327 | ||
| 1328 | /* Resolve */ | |
| 1329 | silc_client_get_clients_whois(client, conn, name, NULL, attrs, | |
| 1330 | silcgaim_add_buddy_resolved, r); | |
| 1331 | silc_buffer_free(attrs); | |
| 1332 | } | |
| 1333 | ||
|
9285
9cedf5d26577
[gaim-migrate @ 10088]
Mark Doliner <markdoliner@pidgin.im>
parents:
9272
diff
changeset
|
1334 | void silcgaim_add_buddy(GaimConnection *gc, GaimBuddy *buddy, GaimGroup *group) |
| 8849 | 1335 | { |
|
9285
9cedf5d26577
[gaim-migrate @ 10088]
Mark Doliner <markdoliner@pidgin.im>
parents:
9272
diff
changeset
|
1336 | silcgaim_add_buddy_i(gc, buddy, FALSE); |
| 8849 | 1337 | } |
| 1338 | ||
|
10869
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1339 | void silcgaim_send_buddylist(GaimConnection *gc) |
|
10341
92c66f97b73f
[gaim-migrate @ 11550]
Mark Doliner <markdoliner@pidgin.im>
parents:
10246
diff
changeset
|
1340 | { |
|
10869
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1341 | GaimBuddyList *blist; |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1342 | GaimBlistNode *gnode, *cnode, *bnode; |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1343 | GaimBuddy *buddy; |
|
12111
a939a3c185f9
[gaim-migrate @ 14411]
Sadrul Habib Chowdhury <sadrul@pidgin.im>
parents:
12058
diff
changeset
|
1344 | GaimAccount *account; |
|
a939a3c185f9
[gaim-migrate @ 14411]
Sadrul Habib Chowdhury <sadrul@pidgin.im>
parents:
12058
diff
changeset
|
1345 | |
|
a939a3c185f9
[gaim-migrate @ 14411]
Sadrul Habib Chowdhury <sadrul@pidgin.im>
parents:
12058
diff
changeset
|
1346 | account = gaim_connection_get_account(gc); |
|
10869
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1347 | |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1348 | if ((blist = gaim_get_blist()) != NULL) |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1349 | { |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1350 | for (gnode = blist->root; gnode != NULL; gnode = gnode->next) |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1351 | { |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1352 | if (!GAIM_BLIST_NODE_IS_GROUP(gnode)) |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1353 | continue; |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1354 | for (cnode = gnode->child; cnode != NULL; cnode = cnode->next) |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1355 | { |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1356 | if (!GAIM_BLIST_NODE_IS_CONTACT(cnode)) |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1357 | continue; |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1358 | for (bnode = cnode->child; bnode != NULL; bnode = bnode->next) |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1359 | { |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1360 | if (!GAIM_BLIST_NODE_IS_BUDDY(bnode)) |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1361 | continue; |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1362 | buddy = (GaimBuddy *)bnode; |
|
12111
a939a3c185f9
[gaim-migrate @ 14411]
Sadrul Habib Chowdhury <sadrul@pidgin.im>
parents:
12058
diff
changeset
|
1363 | if (gaim_buddy_get_account(buddy) == account) |
|
a939a3c185f9
[gaim-migrate @ 14411]
Sadrul Habib Chowdhury <sadrul@pidgin.im>
parents:
12058
diff
changeset
|
1364 | silcgaim_add_buddy_i(gc, buddy, TRUE); |
|
10869
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1365 | } |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1366 | } |
|
86a3144baf08
[gaim-migrate @ 12556]
Mark Doliner <markdoliner@pidgin.im>
parents:
10662
diff
changeset
|
1367 | } |
|
10341
92c66f97b73f
[gaim-migrate @ 11550]
Mark Doliner <markdoliner@pidgin.im>
parents:
10246
diff
changeset
|
1368 | } |
|
92c66f97b73f
[gaim-migrate @ 11550]
Mark Doliner <markdoliner@pidgin.im>
parents:
10246
diff
changeset
|
1369 | } |
|
92c66f97b73f
[gaim-migrate @ 11550]
Mark Doliner <markdoliner@pidgin.im>
parents:
10246
diff
changeset
|
1370 | |
|
9285
9cedf5d26577
[gaim-migrate @ 10088]
Mark Doliner <markdoliner@pidgin.im>
parents:
9272
diff
changeset
|
1371 | void silcgaim_remove_buddy(GaimConnection *gc, GaimBuddy *buddy, |
|
9cedf5d26577
[gaim-migrate @ 10088]
Mark Doliner <markdoliner@pidgin.im>
parents:
9272
diff
changeset
|
1372 | GaimGroup *group) |
| 8849 | 1373 | { |
|
9285
9cedf5d26577
[gaim-migrate @ 10088]
Mark Doliner <markdoliner@pidgin.im>
parents:
9272
diff
changeset
|
1374 | silc_free(buddy->proto_data); |
| 8849 | 1375 | } |
| 1376 | ||
| 1377 | void silcgaim_idle_set(GaimConnection *gc, int idle) | |
| 1378 | ||
| 1379 | { | |
| 1380 | SilcGaim sg = gc->proto_data; | |
| 1381 | SilcClient client = sg->client; | |
| 1382 | SilcClientConnection conn = sg->conn; | |
| 1383 | SilcAttributeObjService service; | |
| 1384 | const char *server; | |
| 1385 | int port; | |
| 1386 | ||
| 1387 | server = gaim_account_get_string(sg->account, "server", | |
| 1388 | "silc.silcnet.org"); | |
| 1389 | port = gaim_account_get_int(sg->account, "port", 706), | |
| 1390 | ||
| 1391 | memset(&service, 0, sizeof(service)); | |
| 1392 | silc_client_attribute_del(client, conn, | |
| 1393 | SILC_ATTRIBUTE_SERVICE, NULL); | |
| 1394 | service.port = port; | |
| 1395 | g_snprintf(service.address, sizeof(service.address), "%s", server); | |
| 1396 | service.idle = idle; | |
| 1397 | silc_client_attribute_add(client, conn, SILC_ATTRIBUTE_SERVICE, | |
| 1398 | &service, sizeof(service)); | |
| 1399 | } | |
| 1400 | ||
| 1401 | char *silcgaim_status_text(GaimBuddy *b) | |
| 1402 | { | |
| 1403 | SilcGaim sg = b->account->gc->proto_data; | |
| 1404 | SilcClient client = sg->client; | |
| 1405 | SilcClientConnection conn = sg->conn; | |
| 1406 | SilcClientID *client_id = b->proto_data; | |
| 1407 | SilcClientEntry client_entry; | |
| 1408 | SilcAttributePayload attr; | |
| 1409 | SilcAttributeMood mood = 0; | |
| 1410 | ||
| 1411 | /* Get the client entry. */ | |
| 1412 | client_entry = silc_client_get_client_by_id(client, conn, client_id); | |
| 1413 | if (!client_entry) | |
| 1414 | return NULL; | |
| 1415 | ||
| 1416 | /* If user is online, we show the mood status, if available. | |
| 1417 | If user is offline or away that status is indicated. */ | |
| 1418 | ||
| 1419 | if (client_entry->mode & SILC_UMODE_DETACHED) | |
| 1420 | return g_strdup(_("Detached")); | |
| 1421 | if (client_entry->mode & SILC_UMODE_GONE) | |
| 1422 | return g_strdup(_("Away")); | |
| 1423 | if (client_entry->mode & SILC_UMODE_INDISPOSED) | |
| 1424 | return g_strdup(_("Indisposed")); | |
| 1425 | if (client_entry->mode & SILC_UMODE_BUSY) | |
| 1426 | return g_strdup(_("Busy")); | |
| 1427 | if (client_entry->mode & SILC_UMODE_PAGE) | |
| 1428 | return g_strdup(_("Wake Me Up")); | |
| 1429 | if (client_entry->mode & SILC_UMODE_HYPER) | |
| 1430 | return g_strdup(_("Hyper Active")); | |
| 1431 | if (client_entry->mode & SILC_UMODE_ROBOT) | |
| 1432 | return g_strdup(_("Robot")); | |
| 1433 | ||
| 1434 | attr = silcgaim_get_attr(client_entry->attrs, SILC_ATTRIBUTE_STATUS_MOOD); | |
| 1435 | if (attr && silc_attribute_get_object(attr, &mood, sizeof(mood))) { | |
| 1436 | /* The mood is a bit mask, so we could show multiple moods, | |
| 1437 | but let's show only one for now. */ | |
| 1438 | if (mood & SILC_ATTRIBUTE_MOOD_HAPPY) | |
| 1439 | return g_strdup(_("Happy")); | |
| 1440 | if (mood & SILC_ATTRIBUTE_MOOD_SAD) | |
| 1441 | return g_strdup(_("Sad")); | |
| 1442 | if (mood & SILC_ATTRIBUTE_MOOD_ANGRY) | |
| 1443 | return g_strdup(_("Angry")); | |
| 1444 | if (mood & SILC_ATTRIBUTE_MOOD_JEALOUS) | |
| 1445 | return g_strdup(_("Jealous")); | |
| 1446 | if (mood & SILC_ATTRIBUTE_MOOD_ASHAMED) | |
| 1447 | return g_strdup(_("Ashamed")); | |
| 1448 | if (mood & SILC_ATTRIBUTE_MOOD_INVINCIBLE) | |
| 1449 | return g_strdup(_("Invincible")); | |
| 1450 | if (mood & SILC_ATTRIBUTE_MOOD_INLOVE) | |
| 1451 | return g_strdup(_("In Love")); | |
| 1452 | if (mood & SILC_ATTRIBUTE_MOOD_SLEEPY) | |
| 1453 | return g_strdup(_("Sleepy")); | |
| 1454 | if (mood & SILC_ATTRIBUTE_MOOD_BORED) | |
| 1455 | return g_strdup(_("Bored")); | |
| 1456 | if (mood & SILC_ATTRIBUTE_MOOD_EXCITED) | |
| 1457 | return g_strdup(_("Excited")); | |
| 1458 | if (mood & SILC_ATTRIBUTE_MOOD_ANXIOUS) | |
| 1459 | return g_strdup(_("Anxious")); | |
| 1460 | } | |
| 1461 | ||
| 1462 | return NULL; | |
| 1463 | } | |
| 1464 | ||
| 1465 | char *silcgaim_tooltip_text(GaimBuddy *b) | |
| 1466 | { | |
| 1467 | SilcGaim sg = b->account->gc->proto_data; | |
| 1468 | SilcClient client = sg->client; | |
| 1469 | SilcClientConnection conn = sg->conn; | |
| 1470 | SilcClientID *client_id = b->proto_data; | |
| 1471 | SilcClientEntry client_entry; | |
|
9488
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1472 | char *moodstr, *statusstr, *contactstr, *langstr, *devicestr, *tzstr, *geostr; |
| 8849 | 1473 | GString *s; |
| 1474 | char *buf; | |
| 1475 | char tmp[256]; | |
| 1476 | ||
| 1477 | s = g_string_new(""); | |
| 1478 | ||
| 1479 | /* Get the client entry. */ | |
| 1480 | client_entry = silc_client_get_client_by_id(client, conn, client_id); | |
| 1481 | if (!client_entry) | |
| 1482 | return NULL; | |
| 1483 | ||
| 1484 | if (client_entry->nickname) | |
| 9272 | 1485 | g_string_append_printf(s, "\n<b>%s:</b> %s", _("Nickname"), |
| 8849 | 1486 | client_entry->nickname); |
| 1487 | if (client_entry->username && client_entry->hostname) | |
| 9272 | 1488 | g_string_append_printf(s, "\n<b>%s:</b> %s@%s", _("Username"), |
| 8849 | 1489 | client_entry->username, client_entry->hostname); |
| 1490 | if (client_entry->mode) { | |
|
9488
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1491 | g_string_append_printf(s, "\n<b>%s:</b> ", _("User Modes")); |
| 8849 | 1492 | memset(tmp, 0, sizeof(tmp)); |
| 1493 | silcgaim_get_umode_string(client_entry->mode, | |
| 1494 | tmp, sizeof(tmp) - strlen(tmp)); | |
| 9272 | 1495 | g_string_append_printf(s, "%s", tmp); |
| 8849 | 1496 | } |
| 1497 | ||
|
9488
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1498 | silcgaim_parse_attrs(client_entry->attrs, &moodstr, &statusstr, &contactstr, &langstr, &devicestr, &tzstr, &geostr); |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1499 | if (moodstr) { |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1500 | g_string_append_printf(s, "\n<b>%s:</b> %s", _("Mood"), moodstr); |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1501 | g_free(moodstr); |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1502 | } |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1503 | if (statusstr) { |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1504 | g_string_append_printf(s, "\n<b>%s:</b> %s", _("Status Text"), statusstr); |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1505 | g_free(statusstr); |
| 8849 | 1506 | } |
| 1507 | ||
|
9488
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1508 | if (contactstr) { |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1509 | g_string_append_printf(s, "\n<b>%s:</b> %s", _("Preferred Contact"), contactstr); |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1510 | g_free(contactstr); |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1511 | } |
| 8849 | 1512 | |
|
9488
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1513 | if (langstr) { |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1514 | g_string_append_printf(s, "\n<b>%s:</b> %s", _("Preferred Language"), langstr); |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1515 | g_free(langstr); |
| 8849 | 1516 | } |
| 1517 | ||
|
9488
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1518 | if (devicestr) { |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1519 | g_string_append_printf(s, "\n<b>%s:</b> %s", _("Device"), devicestr); |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1520 | g_free(devicestr); |
| 8849 | 1521 | } |
| 1522 | ||
|
9488
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1523 | if (tzstr) { |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1524 | g_string_append_printf(s, "\n<b>%s:</b> %s", _("Timezone"), tzstr); |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1525 | g_free(tzstr); |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1526 | } |
| 8849 | 1527 | |
|
9488
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1528 | if (geostr) { |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1529 | g_string_append_printf(s, "\n<b>%s:</b> %s", _("Geolocation"), geostr); |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1530 | g_free(geostr); |
|
9d6520fa53fd
[gaim-migrate @ 10313]
Stu Tomlinson <nosnilmot@pidgin.im>
parents:
9466
diff
changeset
|
1531 | } |
| 8849 | 1532 | |
| 1533 | buf = g_string_free(s, FALSE); | |
| 1534 | return buf; | |
| 1535 | } | |
| 1536 | ||
| 1537 | static void | |
| 9038 | 1538 | silcgaim_buddy_kill(GaimBlistNode *node, gpointer data) |
| 8849 | 1539 | { |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1540 | GaimBuddy *b; |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1541 | GaimConnection *gc; |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1542 | SilcGaim sg; |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1543 | |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1544 | g_return_if_fail(GAIM_BLIST_NODE_IS_BUDDY(node)); |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1545 | |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1546 | b = (GaimBuddy *) node; |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1547 | gc = gaim_account_get_connection(b->account); |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1548 | sg = gc->proto_data; |
| 8849 | 1549 | |
| 1550 | /* Call KILL */ | |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1551 | silc_client_command_call(sg->client, sg->conn, NULL, "KILL", |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1552 | b->name, "Killed by operator", NULL); |
| 8849 | 1553 | } |
| 1554 | ||
|
12058
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1555 | typedef struct { |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1556 | SilcGaim sg; |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1557 | SilcClientEntry client_entry; |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1558 | } *SilcGaimBuddyWb; |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1559 | |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1560 | static void |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1561 | silcgaim_buddy_wb(GaimBlistNode *node, gpointer data) |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1562 | { |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1563 | SilcGaimBuddyWb wb = data; |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1564 | silcgaim_wb_init(wb->sg, wb->client_entry); |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1565 | silc_free(wb); |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1566 | } |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1567 | |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1568 | GList *silcgaim_buddy_menu(GaimBuddy *buddy) |
| 8849 | 1569 | { |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1570 | GaimConnection *gc = gaim_account_get_connection(buddy->account); |
| 8849 | 1571 | SilcGaim sg = gc->proto_data; |
| 1572 | SilcClientConnection conn = sg->conn; | |
| 1573 | const char *pkfile = NULL; | |
| 1574 | SilcClientEntry client_entry = NULL; | |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1575 | GaimBlistNodeAction *act; |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1576 | GList *m = NULL; |
|
12058
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1577 | SilcGaimBuddyWb wb; |
| 8849 | 1578 | |
| 9038 | 1579 | pkfile = gaim_blist_node_get_string((GaimBlistNode *) buddy, "public-key"); |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1580 | client_entry = silc_client_get_client_by_id(sg->client, |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1581 | sg->conn, |
| 9038 | 1582 | buddy->proto_data); |
| 8849 | 1583 | |
| 1584 | if (client_entry && client_entry->send_key) { | |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1585 | act = gaim_blist_node_action_new(_("Reset IM Key"), |
| 10662 | 1586 | silcgaim_buddy_resetkey, NULL, NULL); |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1587 | m = g_list_append(m, act); |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1588 | |
| 8849 | 1589 | } else { |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1590 | act = gaim_blist_node_action_new(_("IM with Key Exchange"), |
| 10662 | 1591 | silcgaim_buddy_keyagr, NULL, NULL); |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1592 | m = g_list_append(m, act); |
| 8849 | 1593 | |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1594 | act = gaim_blist_node_action_new(_("IM with Password"), |
| 10662 | 1595 | silcgaim_buddy_privkey_menu, |
| 1596 | NULL, NULL); | |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1597 | m = g_list_append(m, act); |
| 8849 | 1598 | } |
| 1599 | ||
| 1600 | if (pkfile) { | |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1601 | act = gaim_blist_node_action_new(_("Show Public Key"), |
| 10662 | 1602 | silcgaim_buddy_showkey, NULL, NULL); |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1603 | m = g_list_append(m, act); |
|
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1604 | |
| 8849 | 1605 | } else { |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1606 | act = gaim_blist_node_action_new(_("Get Public Key..."), |
| 10662 | 1607 | silcgaim_buddy_getkey_menu, |
| 1608 | NULL, NULL); | |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1609 | m = g_list_append(m, act); |
| 8849 | 1610 | } |
| 1611 | ||
| 1612 | if (conn && conn->local_entry->mode & SILC_UMODE_ROUTER_OPERATOR) { | |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1613 | act = gaim_blist_node_action_new(_("Kill User"), |
| 10662 | 1614 | silcgaim_buddy_kill, NULL, NULL); |
|
9030
7b574a641391
[gaim-migrate @ 9806]
Mark Doliner <markdoliner@pidgin.im>
parents:
8910
diff
changeset
|
1615 | m = g_list_append(m, act); |
| 8849 | 1616 | } |
| 1617 | ||
|
12058
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1618 | wb = silc_calloc(1, sizeof(*wb)); |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1619 | wb->sg = sg; |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1620 | wb->client_entry = client_entry; |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1621 | act = gaim_blist_node_action_new(_("Draw On Whiteboard"), |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1622 | silcgaim_buddy_wb, (void *)wb, NULL); |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1623 | m = g_list_append(m, act); |
|
6d4b6e3bd0ba
[gaim-migrate @ 14353]
Pekka Riikonen <priikone@silcnet.org>
parents:
11586
diff
changeset
|
1624 | |
| 8849 | 1625 | return m; |
| 1626 | } |