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);
}
}
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)
}
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 :
- "[<unknown>]");
- message = NULL;
- }
+ silc_emit_mime_sig(server, NULL, message, message_len,
+ sender->nickname ? sender->nickname : "[<unknown>]",
+ flags & SILC_MESSAGE_FLAG_SIGNED ? verified : -1);
+ message = NULL;
}
if (!message)
#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 ? "[<unknown>]" : nick, type);
+ channel == NULL ? NULL : channel->name,
+ MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA,
+ nick == NULL ? "[<unknown>]" : nick, type);
+
+ silc_free(message);
}
}
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);
}