From: Jochen Eisinger Date: Tue, 21 Oct 2003 07:52:17 +0000 (+0000) Subject: Thu Oct 21 09:43:17 CEST 2003 Jochen Eisinger X-Git-Tag: silc.client.0.9.14~9 X-Git-Url: http://git.silcnet.org/gitweb/?a=commitdiff_plain;h=06f212436747d79170cbe2f582586afc26a202aa;p=silc.git Thu Oct 21 09:43:17 CEST 2003 Jochen Eisinger * Cleaned up the escape/unescape functions for correctness and speed. Affected file irssi/src/silc/core/client_ops.c * Removed handling for data messages with Content-Type: text/*, moved parsing of MIME headers to the signal handler, added support for signing and verifying data messages. Affected files are irssi/docs/signals.txt, irssi/src/silc/core/client_ops.c, irssi/src/silc/core/silc-{servers,channels}.c --- diff --git a/CHANGES b/CHANGES index ca81d557..711a8a04 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,21 @@ +Thu Oct 21 09:43:17 CEST 2003 Jochen Eisinger + + * Modified the MIME parsing to allow \n and \r\n as delimiters. + Affected files lib/silcutil/silcstrutil.c + + * Cleaned up the escape/unescape functions for correctness and + speed. Affected file irssi/src/silc/core/client_ops.c + + * Removed handling for data messages with Content-Type: text/*, + moved parsing of MIME headers to the signal handler, added + support for signing and verifying data messages. Affected + files are irssi/docs/signals.txt, irssi/src/silc/core/client_ops.c, + irssi/src/silc/core/silc-{servers,channels}.c + + * Added a perl script for handling data messages based on + information read from Mailcap files. New file + irssi/scripts/silc-mime.pl + Mon Oct 20 16:08:22 EEST 2003 Pekka Riikonen * Added new SILC_MESSAGE_FLAG_ACK that can be used to diff --git a/apps/irssi/docs/signals.txt b/apps/irssi/docs/signals.txt index 7c03fad5..8944ea0e 100644 --- a/apps/irssi/docs/signals.txt +++ b/apps/irssi/docs/signals.txt @@ -329,7 +329,7 @@ SILC --- silc-channels.c: - "mime", SERVER_REC, CHANNEL_REC, char *blob, char *enc, char *type, char *nick + "mime", SERVER_REC, CHANNEL_REC, char *blob, char *nick, int verified silc-servers.c: - "mime-send", SERVER_REC, WI_ITEM_REC, char *blob, char *enc, char *type + "mime-send", SERVER_REC, WI_ITEM_REC, char *blob, int sign diff --git a/apps/irssi/src/silc/core/client_ops.c b/apps/irssi/src/silc/core/client_ops.c index 476fbeda..f8347c96 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -290,61 +290,70 @@ int verify_message_signature(SilcClientEntry sender, char * silc_unescape_data(const char *escaped_data, SilcUInt32 *length) { - SilcUInt32 ctr, dest=0; - char *data; - - data = silc_calloc(strlen(escaped_data), sizeof(char)); + char *data, *ptr; + int i = 0, j = 0, len = strlen(escaped_data); + + data = silc_calloc(len, sizeof(char)); + + while (i < len) { + ptr = memchr(escaped_data + i, 1, len - i); + if (ptr) { + int inc = (ptr - escaped_data) - i; + memcpy(data + j, escaped_data + i, inc); + j += inc; + i += inc + 2; + data[j++] = *(ptr + 1) - 1; + } else { + memcpy(data + j, escaped_data + i, len - i); + j += (len - i); + break; + } + } - for (ctr = 0; ctr < strlen(escaped_data); ctr++) - if (escaped_data[ctr] == 1) - data[dest++] = escaped_data[++ctr] - 1; - else - data[dest++] = escaped_data[ctr]; - - *length = dest; - return data; + *length = j; + return data; } char * silc_escape_data(const char *data, SilcUInt32 len) { - char *escaped_data; - SilcUInt32 ctr, zeros=0; - - for (ctr = 0; ctr < len; ctr++) - if (data[ctr] == 0 || data[ctr] == 1) - zeros++; - - escaped_data = silc_calloc(zeros + len, sizeof(char)); - - zeros=0; - for (ctr = 0; ctr < len; ctr++) - switch (data[ctr]) { - case 0: - escaped_data[zeros++] = 1; - escaped_data[zeros++] = 1; - break; - - case 1: - escaped_data[zeros++] = 1; - escaped_data[zeros++] = 2; - break; - - default: - escaped_data[zeros++] = data[ctr]; - } - + char *escaped_data, *ptr, *ptr0, *ptr1; + int i = 0, j = 0; + + escaped_data = silc_calloc(2 * len, sizeof(char)); + + while (i < len) { + ptr0 = memchr(data + i, 0, len - i); + ptr1 = memchr(data + i, 1, len - i); + + ptr = (ptr0 < ptr1 ? (ptr0 ? ptr0 : ptr1) : (ptr1 ? ptr1 : ptr0)); + + if (ptr) { + int inc = (ptr - data) - i; + if (inc) + memcpy(escaped_data + j, data + i, inc); + j += inc; + i += inc; + escaped_data[j++] = 1; + escaped_data[j++] = *(data + i++) + 1; + } else { + memcpy(escaped_data + j, data + i, len - i); + j += (len - i); + break; + } + } + return escaped_data; } void silc_emit_mime_sig(SILC_SERVER_REC *server, SILC_CHANNEL_REC *channel, - const char *data, SilcUInt32 data_len, - const char *encoding, const char *type, const char *nick) + const char *data, SilcUInt32 data_len, const char *nick, + int verified) { char *escaped_data; escaped_data = silc_escape_data(data, data_len); - signal_emit("mime", 6, server, channel, escaped_data, encoding, type, nick); + signal_emit("mime", 4, server, channel, escaped_data, nick, verified); silc_free(escaped_data); } @@ -393,27 +402,10 @@ void silc_channel_message(SilcClient client, SilcClientConnection conn, } if (flags & SILC_MESSAGE_FLAG_DATA) { - /* MIME object received, try to display it as well as we can */ - char type[128], enc[128]; - unsigned char *data; - SilcUInt32 data_len; - - memset(type, 0, sizeof(type)); - memset(enc, 0, sizeof(enc)); - if (!silc_mime_parse(message, message_len, NULL, 0, type, sizeof(type) - 1, - enc, sizeof(enc) - 1, &data, &data_len)) - return; - - /* Then figure out what we can display */ - if (strstr(type, "text/") && !strstr(type, "text/t140") && - !strstr(type, "text/vnd")) { - /* It is something textual, display it */ - message = (const unsigned char *)data; - } else { - silc_emit_mime_sig(server, chanrec, data, data_len, - enc, type, nick == NULL ? NULL : nick->nick); - message = NULL; - } + silc_emit_mime_sig(server, chanrec, message, message_len, + nick == NULL ? NULL : nick->nick, + flags & SILC_MESSAGE_FLAG_SIGNED ? verified : -1); + message = NULL; } if (!message) @@ -535,28 +527,10 @@ void silc_private_message(SilcClient client, SilcClientConnection conn, } if (flags & SILC_MESSAGE_FLAG_DATA) { - /* MIME object received, try to display it as well as we can */ - char type[128], enc[128]; - unsigned char *data; - SilcUInt32 data_len; - - memset(type, 0, sizeof(type)); - memset(enc, 0, sizeof(enc)); - if (!silc_mime_parse(message, message_len, NULL, 0, type, sizeof(type) - 1, - enc, sizeof(enc) - 1, &data, &data_len)) - return; - - /* Then figure out what we can display */ - if (strstr(type, "text/") && !strstr(type, "text/t140") && - !strstr(type, "text/vnd")) { - /* It is something textual, display it */ - message = (const unsigned char *)data; - } else { - silc_emit_mime_sig(server, NULL, data, data_len, - enc, type, sender->nickname ? sender->nickname : - "[]"); - message = NULL; - } + silc_emit_mime_sig(server, NULL, message, message_len, + sender->nickname ? sender->nickname : "[]", + flags & SILC_MESSAGE_FLAG_SIGNED ? verified : -1); + message = NULL; } if (!message) diff --git a/apps/irssi/src/silc/core/silc-channels.c b/apps/irssi/src/silc/core/silc-channels.c index 2ebdcc7a..baff1b8c 100644 --- a/apps/irssi/src/silc/core/silc-channels.c +++ b/apps/irssi/src/silc/core/silc-channels.c @@ -46,17 +46,32 @@ #include "silc-commands.h" void sig_mime(SILC_SERVER_REC *server, SILC_CHANNEL_REC *channel, - const char *blob, const char *enc, const char *type, - const char *nick) + const char *blob, const char *nick, int verified) { + char type[128], enc[128]; + unsigned char *data, *message; + SilcUInt32 data_len, message_len; if (!(IS_SILC_SERVER(server))) return; + + message = silc_unescape_data(blob, &message_len); + + memset(type, 0, sizeof(type)); + memset(enc, 0, sizeof(enc)); + if (!silc_mime_parse(message, message_len, NULL, 0, type, sizeof(type) - 1, + enc, sizeof(enc) - 1, &data, &data_len)) { + silc_free(message); + return; + } + printformat_module("fe-common/silc", server, - channel == NULL ? NULL : channel->name, - MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA, - nick == NULL ? "[]" : nick, type); + channel == NULL ? NULL : channel->name, + MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA, + nick == NULL ? "[]" : nick, type); + + silc_free(message); } diff --git a/apps/irssi/src/silc/core/silc-servers.c b/apps/irssi/src/silc/core/silc-servers.c index 0287eb77..3cafc80c 100644 --- a/apps/irssi/src/silc/core/silc-servers.c +++ b/apps/irssi/src/silc/core/silc-servers.c @@ -175,50 +175,32 @@ static int silc_send_msg(SILC_SERVER_REC *server, char *nick, char *msg, } void silc_send_mime(SILC_SERVER_REC *server, WI_ITEM_REC *to, - const char *data, - const char *enc, const char *type) + const char *data, int sign) { SILC_CHANNEL_REC *channel; QUERY_REC *query; char *unescaped_data; SilcUInt32 unescaped_data_len; - char *mime_data; - int mime_data_len; - if (!(IS_SILC_SERVER(server)) || (data == NULL) || (to == NULL) || - (enc == NULL) || (type == NULL)) + if (!(IS_SILC_SERVER(server)) || (data == NULL) || (to == NULL)) return; unescaped_data = silc_unescape_data(data, &unescaped_data_len); -#define SILC_MIME_HEADER "MIME-Version: 1.0\r\nContent-Type: %s\r\nContent-Transfer-Encoding: %s\r\n\r\n" - - mime_data_len = unescaped_data_len + strlen(SILC_MIME_HEADER) - 4 - + strlen(enc) + strlen(type); - if (mime_data_len >= SILC_PACKET_MAX_LEN) - return; - - /* we risk to large packets here... */ - mime_data = silc_calloc(mime_data_len, sizeof(*mime_data)); - snprintf(mime_data, mime_data_len, SILC_MIME_HEADER, type, enc); - memmove(mime_data + strlen(SILC_MIME_HEADER) - 4 + strlen(enc) + strlen(type), - unescaped_data, unescaped_data_len); - -#undef SILC_MIME_HEADER - if (IS_SILC_CHANNEL(to)) { channel = SILC_CHANNEL(to); silc_client_send_channel_message(silc_client, server->conn, channel->entry, - NULL, SILC_MESSAGE_FLAG_DATA, - mime_data, mime_data_len, TRUE); + NULL, SILC_MESSAGE_FLAG_DATA | + (sign ? SILC_MESSAGE_FLAG_SIGNED : 0), + unescaped_data, unescaped_data_len, TRUE); } else if (IS_SILC_QUERY(to)) { query = SILC_QUERY(to); - silc_send_msg(server, query->name, mime_data, mime_data_len, - SILC_MESSAGE_FLAG_DATA); + silc_send_msg(server, query->name, unescaped_data, unescaped_data_len, + SILC_MESSAGE_FLAG_DATA | + (sign ? SILC_MESSAGE_FLAG_SIGNED : 0)); } - silc_free(mime_data); silc_free(unescaped_data); }