/** * Called when a channel message or private message is received. */ static int handle_incoming(char *word[], char *word_eol[], void *userdata) { const char *prefix; const char *command; const char *recipient; const char *encrypted; const char *peice; char *sender_nick; char *decrypted; char *message; size_t w; size_t ew; size_t uw; size_t length; if (!irc_parse_message((const char **)word, &prefix, &command, &w)) return HEXCHAT_EAT_NONE; // Topic (command 332) has an extra parameter if (!strcmp(command, "332")) w++; // Look for encrypted data for (ew = w+1; ew < HEXCHAT_MAX_WORDS-1; ew++) { const char *s = (ew == w+1 ? word[ew]+1 : word[ew]); if (strcmp(s, "+OK") == 0 || strcmp(s, "mcps") == 0) goto has_encrypted_data; } return HEXCHAT_EAT_NONE; has_encrypted_data: ; // Extract sender nick and recipient nick/channel sender_nick = irc_prefix_get_nick(prefix); recipient = word[w]; // Try to decrypt with these (the keys are searched for in the key store) encrypted = word[ew+1]; decrypted = fish_decrypt_from_nick(recipient, encrypted); if (!decrypted) decrypted = fish_decrypt_from_nick(sender_nick, encrypted); // Check for error if (!decrypted) goto decrypt_error; // Build unecrypted message message = NULL; length = 0; if (!append(&message, &length, "RECV")) goto decrypt_error; for (uw = 1; uw < HEXCHAT_MAX_WORDS; uw++) { if (word[uw][0] != '\0' && !append(&message, &length, " ")) goto decrypt_error; if (uw == ew) { // Add the encrypted data peice = decrypted; uw++; // Skip "OK+" if (ew == w+1) { // Prefix with colon, which gets stripped out otherwise if (!append(&message, &length, ":")) goto decrypt_error; } } else { // Add unencrypted data (for example, a prefix from a bouncer or bot) peice = word[uw]; } if (!append(&message, &length, peice)) goto decrypt_error; } free(decrypted); // Simulate unencrypted message //hexchat_printf(ph, "simulating: %s\n", message); hexchat_command(ph, message); free(message); free(sender_nick); return HEXCHAT_EAT_HEXCHAT; decrypt_error: free(decrypted); free(sender_nick); return HEXCHAT_EAT_NONE; }
/** * Called when a channel message or private message is received. */ static int handle_incoming(char *word[], char *word_eol[], hexchat_event_attrs *attrs, void *userdata) { const char *prefix; const char *command; const char *recipient; const char *encrypted; const char *peice; char *sender_nick; char *decrypted; size_t w; size_t ew; size_t uw; char prefix_char = 0; GString *message; if (!irc_parse_message((const char **)word, &prefix, &command, &w)) return HEXCHAT_EAT_NONE; /* Topic (command 332) has an extra parameter */ if (!strcmp(command, "332")) w++; /* Look for encrypted data */ for (ew = w+1; ew < HEXCHAT_MAX_WORDS-1; ew++) { const char *s = (ew == w+1 ? word[ew]+1 : word[ew]); if (*s && (s[1] == '+' || s[1] == 'm')) { prefix_char = *(s++); } else { prefix_char = 0; } if (strcmp(s, "+OK") == 0 || strcmp(s, "mcps") == 0) goto has_encrypted_data; } return HEXCHAT_EAT_NONE; has_encrypted_data: ; /* Extract sender nick and recipient nick/channel */ sender_nick = irc_prefix_get_nick(prefix); recipient = word[w]; /* Try to decrypt with these (the keys are searched for in the key store) */ encrypted = word[ew+1]; decrypted = fish_decrypt_from_nick(recipient, encrypted); if (!decrypted) decrypted = fish_decrypt_from_nick(sender_nick, encrypted); /* Check for error */ if (!decrypted) goto decrypt_error; /* Build unecrypted message */ message = g_string_sized_new (100); /* TODO: more accurate estimation of size */ g_string_append (message, "RECV"); if (attrs->server_time_utc) { GTimeVal tv = { (glong)attrs->server_time_utc, 0 }; char *timestamp = g_time_val_to_iso8601 (&tv); g_string_append (message, " @time="); g_string_append (message, timestamp); g_free (timestamp); } for (uw = 1; uw < HEXCHAT_MAX_WORDS; uw++) { if (word[uw][0] != '\0') g_string_append_c (message, ' '); if (uw == ew) { /* Add the encrypted data */ peice = decrypted; uw++; /* Skip "OK+" */ if (ew == w+1) { /* Prefix with colon, which gets stripped out otherwise */ g_string_append_c (message, ':'); } if (prefix_char) { g_string_append_c (message, prefix_char); } } else { /* Add unencrypted data (for example, a prefix from a bouncer or bot) */ peice = word[uw]; } g_string_append (message, peice); } g_free(decrypted); /* Simulate unencrypted message */ /* hexchat_printf(ph, "simulating: %s\n", message->str); */ hexchat_command(ph, message->str); g_string_free (message, TRUE); g_free(sender_nick); return HEXCHAT_EAT_HEXCHAT; decrypt_error: g_free(decrypted); g_free(sender_nick); return HEXCHAT_EAT_NONE; }