?? encrypt.c
字號:
if (strncmp(priv_key->digest, recv_key_sum, KEY_DIGEST_LENGTH) != 0) { /* Someone sent us a message, but didn't use our correct public key */ GE_send_key(gc->account, name, 1, 0); gaim_debug(GAIM_DEBUG_WARNING, "gaim-encryption", "Digests aren't same: {%*s} and {%*s}\n", KEY_DIGEST_LENGTH, priv_key->digest, KEY_DIGEST_LENGTH, recv_key_sum); conv = gaim_find_conversation_with_account(name, gc->account); if (conv != 0) { gaim_conversation_write(conv, 0, _("Received message encrypted with wrong key"), GAIM_MESSAGE_SYSTEM, time((time_t)NULL)); gaim_conv_window_flash(gaim_conversation_get_window(conv)); } else { gaim_debug(GAIM_DEBUG_WARNING, "gaim-encryption", "Received msg with wrong key, " "but can't write err msg to conv: %s\n", name); } g_free(*message); *message = NULL; return; } if (pub_key && (strncmp(pub_key->digest, send_key_sum, KEY_DIGEST_LENGTH) != 0)) { /* We have a key for this guy, but the digest didn't match. Store the message */ /* and ask for a new key */ GE_del_key_from_ring(GE_buddy_ring, name, gc->account); pub_key = GE_get_key(gc, name); /* will be 0 now */ } if (pub_key == 0) { gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "g_e_m: Storing message on Show stack\n"); GE_store_msg(name, gc, *message, &first_inc_msg, &last_inc_msg); g_free(*message); *message = NULL; return; } memmove(*message, *message + msg_pos, strlen(*message + msg_pos) + 1); gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "attempting decrypt on '%s'\n", *message); if (decrypt_msg(&tmp_msg, *message, name, priv_key, pub_key) < 0) { gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Error in decrypt\n"); conv = gaim_find_conversation_with_account(name, gc->account); if (conv != 0) { gaim_conversation_write(conv, 0, _("Error in decryption- asking for resend..."), GAIM_MESSAGE_SYSTEM, time((time_t)NULL)); gaim_conv_window_flash(gaim_conversation_get_window(conv)); } else { gaim_debug(GAIM_DEBUG_WARNING, "gaim-encryption", "Asking for resend, but can't write err msg to conv: %s\n", name); } GE_send_key(gc->account, name, 1, tmp_msg); g_free(*message); if (tmp_msg) g_free(tmp_msg); *message = NULL; return; } /* Successful Decryption */ /* Note- we're feeding gaim an arbitrarily formed message, which could potentially have lots of nasty control characters and stuff. But, that has been tested, and at present, at least, Gaim won't barf on any characters that we give it. As an aside- Gaim does now use g_convert() to convert to UTF-8 from other character streams. If we wanted to be all i18n, we could do the same, and even include the encoding type with the message. We're not all that, at least not yet. */ /* Why the extra space (and the extra buffered copy)? Well, the * * gaim server.c code does this, and having the extra space seems * * to prevent at least one possible type of crash. Pretty scary. */ g_free(*message); *message = g_malloc(MAX(strlen(tmp_msg) + 1, BUF_LONG)); strcpy(*message, tmp_msg);}/* Get account-specific message size limit*/static int GE_get_msg_size_limit(GaimAccount *acct) { const char* protocol_id = gaim_account_get_protocol_id(acct); if (strcmp(protocol_id, "prpl-yahoo") == 0) { return 945; } else if (strcmp(protocol_id, "prpl-msn") == 0) { return 1500; /* This may be too small... somewhere in the 1500-1600 (+ html on front/back) */ } else { /* Well, ok, this isn't too exciting. Someday we can actually check */ /* to see what the real limits are. For now, 2500 works for everyone */ /* but Yahoo. */ return 2500; }} static void GE_send_msg_cb(GaimAccount *acct, char *who, char **message, void* data) { unsigned char *out_msg, *crypt_msg = 0; char *dupname; int msgsize; const char msg_format[] = "%s: Msg:S%.10s:R%.10s: Len %d:%s%s"; GaimConversation *conv; crypt_key *our_key, *his_key; GSList *cur_msg; GQueue *sent_msg_queue; GE_SentMessage *sent_msg_item; int unencrypted_size_limit, msg_size_limit; int baggage_size; char baggage[BUF_LONG]; const gchar* header = g_hash_table_lookup(header_table, gaim_account_get_protocol_id(acct)); const gchar* footer = g_hash_table_lookup(footer_table, gaim_account_get_protocol_id(acct)); const gchar* notify = g_hash_table_lookup(notify_table, gaim_account_get_protocol_id(acct)); if (!header) header = header_default; if (!footer) footer = ""; msg_size_limit = GE_get_msg_size_limit(acct); /* who: name that you are sending to */ /* gc->username: your name */ gaim_debug(GAIM_DEBUG_MISC, "gaim-encryption", "send_msg: %s\n", who); /* Since we don't have a periodic callback, we do some housekeeping here */ gaim_conversation_foreach(reap_old_sent_messages); /* Message might have been eaten by another plugin: */ if ((message == NULL) || (*message == NULL)) { return; } conv = gaim_find_conversation_with_account(who, acct); if (conv == NULL) { conv = gaim_conversation_new(GAIM_CONV_IM, acct, who); } if( GE_get_tx_encryption(acct, who) == FALSE) { if (notify && gaim_prefs_get_bool("/plugins/gtk/encrypt/broadcast_notify") && !GE_has_been_notified(acct, who)) { GE_set_notified(acct, who, TRUE); if (GE_msg_starts_with_link(*message) == TRUE) { /* This is a hack- AOL's client has a bug in the html parsing so that adjacent links (like <a href="a"></a><a href="b"></a>) get concatenated (into <a href="ab"></a>). So we insert a space if the first thing in the message is a link. */ out_msg = g_strconcat(notify, " ", *message, 0); } else { out_msg = g_strconcat(notify, *message, 0); } g_free(*message); *message = out_msg; } gaim_debug(GAIM_DEBUG_MISC, "gaim-encryption", "Outgoing Msg::%s::\n", *message); return; } gaim_debug(GAIM_DEBUG_MISC, "gaim-encryption", "send_msg B: %s, %p, %p, %p\n", who, &GE_my_priv_ring, acct, conv); our_key = GE_find_own_key_by_name(&GE_my_priv_ring, acct->username, acct, conv); if (!our_key) { message[0] = 0; /* Nuke message so it doesn't look like it was sent. */ /* find_own_key (above) will have displayed error messages */ gaim_debug(GAIM_DEBUG_MISC, "gaim-encryption", "leaving\n"); return; } dupname = g_strdup(gaim_normalize(acct, who)); his_key = GE_get_key(acct->gc, dupname); if (his_key == 0) { /* Don't have key for this guy yet */ /* GE_get_key will have sent the key request, just let user know */ gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "requesting key\n"); gaim_conversation_write(conv, 0, _("Requesting key..."), GAIM_MESSAGE_SYSTEM, time((time_t)NULL)); gaim_conv_window_flash(gaim_conversation_get_window(conv)); GE_store_msg(who, acct->gc, *message, &first_out_msg, &last_out_msg); } else { /* We have a key. Encrypt and send. */ gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "has key\n", dupname); baggage_size = sprintf(baggage, msg_format, header, our_key->digest, his_key->digest, 10000, "", footer); /* Warning: message_split keeps static copies, so if our */ /* caller uses it, we're hosed. Looks like nobody else */ /* uses it now, though. */ unencrypted_size_limit = GE_calc_unencrypted_size(our_key, his_key, msg_size_limit - baggage_size); cur_msg = GE_message_split(*message, unencrypted_size_limit); while (cur_msg) { gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "im_write: %s\n", dupname); gaim_conv_im_write(GAIM_CONV_IM(conv), NULL, cur_msg->data, GAIM_MESSAGE_SEND, time((time_t)NULL)); /* Add message to stash of sent messages: in case a key or nonce is wrong, we */ /* can then re-send the message when asked. */ sent_msg_queue = g_hash_table_lookup(conv->data, "sent messages"); sent_msg_item = g_malloc(sizeof(GE_SentMessage)); sent_msg_item->time = time(0); sent_msg_item->id = GE_make_key_id(his_key); /* current nonce value */ sent_msg_item->msg = g_strdup(cur_msg->data); g_queue_push_head(sent_msg_queue, sent_msg_item); GE_encrypt_signed(&crypt_msg, cur_msg->data, our_key, his_key); msgsize = strlen(crypt_msg); out_msg = g_malloc(msgsize + baggage_size + 1); sprintf(out_msg, msg_format, header, our_key->digest, his_key->digest, msgsize, crypt_msg, footer); serv_send_im(acct->gc, who, out_msg, 0); gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "send_im: %s: %d\n", who, strlen(out_msg)); gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "outgoing:%s:\n", out_msg); g_free(out_msg); g_free(crypt_msg); cur_msg = cur_msg->next; /* if (gaim_prefs_get_bool("/gaim/gtk/conversations/im/hide_on_send")) { gaim_window_hide(gaim_conversation_get_window(conv)); } */ } } message[0] = 0; g_free(dupname); return;}void GE_resend_msg(GaimAccount* acct, const char* name, gchar *msg_id) { unsigned char *out_msg, *crypt_msg = 0, *msg = 0; GaimConversation* conv = gaim_find_conversation_with_account(name, acct); int msgsize; const char msg_format[] = "%s: Msg:S%.10s:R%.10s: Len %d:%s%s"; crypt_key *our_key, *his_key; GQueue *sent_msg_queue; GE_SentMessage *sent_msg_item; int baggage_size; char baggage[BUF_LONG]; const gchar *header, *footer; if (msg_id == 0) { gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Bad call to resend_msg: %p %p\n", conv, msg_id); return; } if (conv == 0) { conv = gaim_conversation_new(GAIM_CONV_IM, acct, name); } header = g_hash_table_lookup(header_table, gaim_account_get_protocol_id(conv->account)); footer = g_hash_table_lookup(footer_table, gaim_account_get_protocol_id(conv->account)); if (!header) header = header_default; if (!footer) footer = ""; /*Sometimes callers don't know whether there's a msg to send... */ if (msg_id == 0 || conv == 0) return; gaim_debug(GAIM_DEBUG_MISC, "gaim-encryption", "resend_encrypted_msg: %s:%s\n", conv->name, msg_id); our_key = GE_find_key_by_name(GE_my_priv_ring, conv->account->username, conv->account); his_key = GE_find_key_by_name(GE_buddy_ring, name, conv->account); if (his_key == 0) { /* Don't have key for this guy */ gaim_conversation_write(conv, 0, _("No key to resend message. Message lost."), GAIM_MESSAGE_SYSTEM, time((time_t)NULL)); gaim_conv_window_flash(gaim_conversation_get_window(conv)); } else { /* We have a key. Encrypt and send. */ sent_msg_queue = g_hash_table_lookup(conv->data, "sent messages"); /* Root through the queue looking for the right message. Any that are older than this */ /* one we will throw out, since they would have already been asked for. */ while (!g_queue_is_empty(sent_msg_queue)) { sent_msg_item = g_queue_pop_tail(sent_msg_queue); gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Examining Message: %s\n", sent_msg_item->id); if (strcmp(sent_msg_item->id, msg_id) == 0) { /* This is the one to resend */ msg = sent_msg_item->msg; g_free(sent_msg_item->id); g_free(sent_msg_item); break;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -