#include "levels.h"
#include "settings.h"
#include "ignore.h"
+#include "special-vars.h"
#include "fe-common/core/printtext.h"
#include "fe-common/core/fe-channels.h"
#include "fe-common/core/keyboard.h"
SilcSKEPKType pk_type,
SilcVerifyPublicKey completion, void *context);
+char *silc_get_session_filename(SILC_SERVER_REC *server)
+{
+ char *file, *expanded;
+
+ expanded = parse_special_string(settings_get_str("session_filename"),
+ SERVER(server), NULL, "", NULL, 0);
+
+ file = silc_calloc(1, strlen(expanded) + 255);
+ snprintf(file, strlen(expanded) + 255, "%s/%s", get_irssi_dir(), expanded);
+ free(expanded);
+
+ return file;
+}
+
static void silc_get_umode_string(SilcUInt32 mode, char *buf,
SilcUInt32 buf_size)
{
g_slist_free(windows);
}
+static void silc_parse_channel_public_keys(SILC_SERVER_REC *server,
+ SilcChannelEntry channel_entry,
+ SilcBuffer channel_pubkeys)
+{
+ SilcUInt16 argc;
+ SilcArgumentPayload chpks;
+ unsigned char *pk;
+ SilcUInt32 pk_len, type;
+ int c = 1;
+ char *fingerprint, *babbleprint;
+ SilcPublicKey pubkey;
+ SilcPublicKeyIdentifier ident;
+
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_PK_LIST,
+ channel_entry->channel_name);
+
+ SILC_GET16_MSB(argc, channel_pubkeys->data);
+ chpks = silc_argument_payload_parse(channel_pubkeys->data + 2,
+ channel_pubkeys->len - 2, argc);
+ if (!chpks)
+ return;
+
+ pk = silc_argument_get_first_arg(chpks, &type, &pk_len);
+ while (pk) {
+ fingerprint = silc_hash_fingerprint(NULL, pk + 4, pk_len - 4);
+ babbleprint = silc_hash_babbleprint(NULL, pk + 4, pk_len - 4);
+ silc_pkcs_public_key_payload_decode(pk, pk_len, &pubkey);
+ ident = silc_pkcs_decode_identifier(pubkey->identifier);
+
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_PK_LIST_ENTRY,
+ c++, channel_entry->channel_name,
+ type == 0x00 ? "Added" : "Removed",
+ ident->realname ? ident->realname : "",
+ fingerprint, babbleprint);
+
+ silc_free(fingerprint);
+ silc_free(babbleprint);
+ silc_pkcs_public_key_free(pubkey);
+ silc_pkcs_free_identifier(ident);
+ pk = silc_argument_get_next_arg(chpks, &type, &pk_len);
+ }
+
+ silc_argument_payload_free(chpks);
+}
+
void silc_say(SilcClient client, SilcClientConnection conn,
SilcClientMessageType type, char *msg, ...)
{
return ret;
}
+char * silc_unescape_data(const char *escaped_data, SilcUInt32 *length)
+{
+ 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;
+ }
+ }
+
+ *length = j;
+ return data;
+}
+
+char * silc_escape_data(const char *data, SilcUInt32 len)
+{
+ 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, WI_ITEM_REC *item,
+ 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", 5, server, item, escaped_data, nick, verified);
+
+ silc_free(escaped_data);
+}
+
+
/* Message for a channel. The `sender' is the nickname of the sender
received in the packet. The `channel_name' is the name of the channel. */
}
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 {
- printformat_module("fe-common/silc", server, channel->channel_name,
- MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA,
- nick == NULL ? "[<unknown>]" : nick->nick, type);
- message = NULL;
- }
+ silc_emit_mime_sig(server, (WI_ITEM_REC *)chanrec, message, message_len,
+ nick == NULL ? NULL : nick->nick,
+ flags & SILC_MESSAGE_FLAG_SIGNED ? verified : -1);
+ message = NULL;
}
if (!message)
return;
- /* FIXME: replace those printformat calls with signals and add signature
- information to them (if present) */
if (flags & SILC_MESSAGE_FLAG_ACTION)
- printformat_module("fe-common/silc", server, channel->channel_name,
- MSGLEVEL_ACTIONS, SILCTXT_CHANNEL_ACTION,
- nick == NULL ? "[<unknown>]" : nick->nick, message);
+ if(flags & SILC_MESSAGE_FLAG_UTF8 && !silc_term_utf8()) {
+ char tmp[256], *cp, *dm = NULL;
+ memset(tmp, 0, sizeof(tmp));
+ cp = tmp;
+ if(message_len > sizeof(tmp) - 1) {
+ dm = silc_calloc(message_len + 1, sizeof(*dm));
+ cp = dm;
+ }
+ silc_utf8_decode(message, message_len, SILC_STRING_LANGUAGE,
+ cp, message_len);
+ if (flags & SILC_MESSAGE_FLAG_SIGNED)
+ signal_emit("message silc signed_action", 6, server, cp, nick->nick,
+ nick->host, channel->channel_name, verified);
+ else
+ signal_emit("message silc action", 5, server, cp, nick->nick,
+ nick->host, channel->channel_name);
+ silc_free(dm);
+ } else {
+ if (flags & SILC_MESSAGE_FLAG_SIGNED)
+ signal_emit("message silc signed_action", 6, server, message,
+ nick->nick, nick->host, channel->channel_name, verified);
+ else
+ signal_emit("message silc action", 5, server, message,
+ nick->nick, nick->host, channel->channel_name);
+ }
else if (flags & SILC_MESSAGE_FLAG_NOTICE)
- printformat_module("fe-common/silc", server, channel->channel_name,
- MSGLEVEL_NOTICES, SILCTXT_CHANNEL_NOTICE,
- nick == NULL ? "[<unknown>]" : nick->nick, message);
+ if(flags & SILC_MESSAGE_FLAG_UTF8 && !silc_term_utf8()) {
+ char tmp[256], *cp, *dm = NULL;
+ memset(tmp, 0, sizeof(tmp));
+ cp = tmp;
+ if(message_len > sizeof(tmp) - 1) {
+ dm = silc_calloc(message_len + 1, sizeof(*dm));
+ cp = dm;
+ }
+ silc_utf8_decode(message, message_len, SILC_STRING_LANGUAGE,
+ cp, message_len);
+ if (flags & SILC_MESSAGE_FLAG_SIGNED)
+ signal_emit("message silc signed_notice", 6, server, cp, nick->nick,
+ nick->host, channel->channel_name, verified);
+ else
+ signal_emit("message silc notice", 5, server, cp, nick->nick,
+ nick->host, channel->channel_name);
+ silc_free(dm);
+ } else {
+ if (flags & SILC_MESSAGE_FLAG_SIGNED)
+ signal_emit("message silc signed_notice", 6, server, message,
+ nick->nick, nick->host, channel->channel_name, verified);
+ else
+ signal_emit("message silc notice", 5, server, message,
+ nick->nick, nick->host, channel->channel_name);
+ }
else {
if (flags & SILC_MESSAGE_FLAG_UTF8 && !silc_term_utf8()) {
char tmp[256], *cp, *dm = NULL;
}
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 {
- printformat_module("fe-common/silc", server, NULL,
- MSGLEVEL_CRAP, SILCTXT_MESSAGE_DATA,
- sender->nickname ? sender->nickname : "[<unknown>]",
- type);
- message = NULL;
- }
+ silc_emit_mime_sig(server,
+ sender->nickname ?
+ (WI_ITEM_REC *)query_find(SERVER(server), sender->nickname) :
+ NULL,
+ message, message_len,
+ sender->nickname ? sender->nickname : "[<unknown>]",
+ flags & SILC_MESSAGE_FLAG_SIGNED ? verified : -1);
+ message = NULL;
}
if (!message)
return;
- if (flags & SILC_MESSAGE_FLAG_UTF8 && !silc_term_utf8()) {
- char tmp[256], *cp, *dm = NULL;
-
- memset(tmp, 0, sizeof(tmp));
- cp = tmp;
- if (message_len > sizeof(tmp) - 1) {
- dm = silc_calloc(message_len + 1, sizeof(*dm));
- cp = dm;
+ if (flags & SILC_MESSAGE_FLAG_ACTION)
+ if(flags & SILC_MESSAGE_FLAG_UTF8 && !silc_term_utf8()) {
+ char tmp[256], *cp, *dm = NULL;
+ memset(tmp, 0, sizeof(tmp));
+ cp = tmp;
+ if(message_len > sizeof(tmp) - 1) {
+ dm = silc_calloc(message_len + 1, sizeof(*dm));
+ cp = dm;
+ }
+ silc_utf8_decode(message, message_len, SILC_STRING_LANGUAGE,
+ cp, message_len);
+ if (flags & SILC_MESSAGE_FLAG_SIGNED)
+ signal_emit("message silc signed_private_action", 6, server, cp,
+ sender->nickname ? sender->nickname : "[<unknown>]",
+ sender->username ? userhost : NULL,
+ NULL, verified);
+ else
+ signal_emit("message silc private_action", 5, server, cp,
+ sender->nickname ? sender->nickname : "[<unknown>]",
+ sender->username ? userhost : NULL, NULL);
+ silc_free(dm);
+ } else {
+ if (flags & SILC_MESSAGE_FLAG_SIGNED)
+ signal_emit("message silc signed_private_action", 6, server, message,
+ sender->nickname ? sender->nickname : "[<unknown>]",
+ sender->username ? userhost : NULL,
+ NULL, verified);
+ else
+ signal_emit("message silc private_action", 5, server, message,
+ sender->nickname ? sender->nickname : "[<unknown>]",
+ sender->username ? userhost : NULL, NULL);
+ }
+ else if (flags & SILC_MESSAGE_FLAG_NOTICE)
+ if(flags & SILC_MESSAGE_FLAG_UTF8 && !silc_term_utf8()) {
+ char tmp[256], *cp, *dm = NULL;
+ memset(tmp, 0, sizeof(tmp));
+ cp = tmp;
+ if(message_len > sizeof(tmp) - 1) {
+ dm = silc_calloc(message_len + 1, sizeof(*dm));
+ cp = dm;
+ }
+ silc_utf8_decode(message, message_len, SILC_STRING_LANGUAGE,
+ cp, message_len);
+ if (flags & SILC_MESSAGE_FLAG_SIGNED)
+ signal_emit("message silc signed_private_notice", 6, server, cp,
+ sender->nickname ? sender->nickname : "[<unknown>]",
+ sender->username ? userhost : NULL,
+ NULL, verified);
+ else
+ signal_emit("message silc private_notice", 5, server, cp,
+ sender->nickname ? sender->nickname : "[<unknown>]",
+ sender->username ? userhost : NULL, NULL);
+ silc_free(dm);
+ } else {
+ if (flags & SILC_MESSAGE_FLAG_SIGNED)
+ signal_emit("message silc signed_private_notice", 6, server, message,
+ sender->nickname ? sender->nickname : "[<unknown>]",
+ sender->username ? userhost : NULL,
+ NULL, verified);
+ else
+ signal_emit("message silc private_notice", 5, server, message,
+ sender->nickname ? sender->nickname : "[<unknown>]",
+ sender->username ? userhost : NULL, NULL);
}
+ else {
+ if (flags & SILC_MESSAGE_FLAG_UTF8 && !silc_term_utf8()) {
+ char tmp[256], *cp, *dm = NULL;
+
+ memset(tmp, 0, sizeof(tmp));
+ cp = tmp;
+ if (message_len > sizeof(tmp) - 1) {
+ dm = silc_calloc(message_len + 1, sizeof(*dm));
+ cp = dm;
+ }
+
+ silc_utf8_decode(message, message_len, SILC_STRING_LANGUAGE,
+ cp, message_len);
+ if (flags & SILC_MESSAGE_FLAG_SIGNED)
+ signal_emit("message signed_private", 5, server, cp,
+ sender->nickname ? sender->nickname : "[<unknown>]",
+ sender->username ? userhost : NULL, verified);
+ else
+ signal_emit("message private", 4, server, cp,
+ sender->nickname ? sender->nickname : "[<unknown>]",
+ sender->username ? userhost : NULL);
+ silc_free(dm);
+ return;
+ }
- silc_utf8_decode(message, message_len, SILC_STRING_LANGUAGE,
- cp, message_len);
if (flags & SILC_MESSAGE_FLAG_SIGNED)
- signal_emit("message signed_private", 5, server, cp,
- sender->nickname ? sender->nickname : "[<unknown>]",
- sender->username ? userhost : NULL, verified);
+ signal_emit("message signed_private", 5, server, message,
+ sender->nickname ? sender->nickname : "[<unknown>]",
+ sender->username ? userhost : NULL, verified);
else
- signal_emit("message private", 4, server, cp,
- sender->nickname ? sender->nickname : "[<unknown>]",
- sender->username ? userhost : NULL);
- silc_free(dm);
- return;
- }
-
- if (flags & SILC_MESSAGE_FLAG_SIGNED)
- signal_emit("message signed_private", 5, server, message,
- sender->nickname ? sender->nickname : "[<unknown>]",
- sender->username ? userhost : NULL, verified);
- else
- signal_emit("message private", 4, server, message,
- sender->nickname ? sender->nickname : "[<unknown>]",
- sender->username ? userhost : NULL);
+ signal_emit("message private", 4, server, message,
+ sender->nickname ? sender->nickname : "[<unknown>]",
+ sender->username ? userhost : NULL);
+ }
}
/* Notify message to the client. The notify arguments are sent in the
char buf[512];
char *name, *tmp;
GSList *list1, *list_tmp;
+ SilcBuffer buffer;
SILC_LOG_DEBUG(("Start"));
idtype = va_arg(va, int);
entry = va_arg(va, void *);
mode = va_arg(va, SilcUInt32);
- (void)va_arg(va, char *);
- (void)va_arg(va, char *);
+ (void)va_arg(va, char *); /* cipher */
+ (void)va_arg(va, char *); /* hmac */
+ (void)va_arg(va, char *); /* passphrase */
+ (void)va_arg(va, SilcPublicKey); /* founder key */
+ buffer = va_arg(va, SilcBuffer); /* channel public keys */
channel = va_arg(va, SilcChannelEntry);
tmp = silc_client_chmode(mode,
channel2->channel_name);
}
+ /* Print the channel public key list */
+ if (buffer)
+ silc_parse_channel_public_keys(server, channel, buffer);
+
silc_free(tmp);
break;
signal_emit("message own_nick", 4, server, server->nick, old, "");
g_free(old);
}
+
+ /* remove the detach data now */
+ {
+ char *file;
+
+ file = silc_get_session_filename(server);
+
+ unlink(file);
+ silc_free(file);
+ }
break;
default:
- server->connection_lost = TRUE;
- if (server->conn)
- server->conn->context = NULL;
- server_disconnect(SERVER(server));
- break;
+ {
+ char * file;
+
+ file = silc_get_session_filename(server);
+
+ if (silc_file_size(file) > 0)
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_REATTACH_FAILED, file);
+
+ silc_free(file);
+
+ server->connection_lost = TRUE;
+ if (server->conn)
+ server->conn->context = NULL;
+ server_disconnect(SERVER(server));
+
+ break;
+ }
}
}
after application has called the command. Just to tell application
that the command really was processed. */
+static bool cmode_list_chpks = FALSE;
+
void silc_command(SilcClient client, SilcClientConnection conn,
SilcClientCommandContext cmd_context, bool success,
SilcCommand command, SilcStatus status)
server->no_reconnect = TRUE;
break;
+ case SILC_COMMAND_CMODE:
+ if (cmd_context->argc == 3 &&
+ !strcmp(cmd_context->argv[2], "+C"))
+ cmode_list_chpks = TRUE;
+ else
+ cmode_list_chpks = FALSE;
+ break;
+
default:
break;
}
if (!clients && r->retry < 1) {
/* Retry to resolve */
+ r->retry++;
silc_client_get_clients_by_channel(client, conn, channel,
silc_client_join_get_users, context);
- r->retry++;
return;
}
}
/* Parse an invite or ban list */
-void silc_parse_inviteban_list(SilcClient client,
- SilcClientConnection conn,
- SILC_SERVER_REC *server,
- SilcChannelEntry channel,
- const char *list_type,
- SilcArgumentPayload list)
+void silc_parse_inviteban_list(SilcClient client,
+ SilcClientConnection conn,
+ SILC_SERVER_REC *server,
+ SilcChannelEntry channel,
+ const char *list_type,
+ SilcArgumentPayload list)
{
unsigned char *tmp;
SilcUInt32 type, len;
/* Print the unknown nick for user */
unsigned char *tmp =
silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
- 3, NULL);
+ 2, NULL);
if (tmp)
silc_say_error("%s: %s", tmp,
silc_get_status_message(status));
/* Print the unknown nick for user */
unsigned char *tmp =
silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
- 3, NULL);
+ 2, NULL);
if (tmp)
silc_say_error("%s: %s", tmp,
silc_get_status_message(status));
{
char *nickname, *username, *realname;
- if (status == SILC_STATUS_ERR_NO_SUCH_NICK ||
- status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
- char *tmp;
- tmp = silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
- 3, NULL);
+ if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
+ char *tmp =
+ silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
+ 2, NULL);
if (tmp)
silc_say_error("%s: %s", tmp,
silc_get_status_message(status));
SilcChannelEntry channel;
SilcBuffer payload;
SilcArgumentPayload invite_list;
- SilcUInt32 argc;
+ SilcUInt16 argc;
if (!success)
return;
signal_emit("channel mode changed", 1, chanrec);
/* Resolve the client information */
- SilcJoinResolve r = silc_calloc(1, sizeof(*r));
- r->channel = channel_entry;
- silc_client_get_clients_by_list(client, conn, list_count, client_id_list,
- silc_client_join_get_users, r);
+ {
+ SilcJoinResolve r = silc_calloc(1, sizeof(*r));
+ r->channel = channel_entry;
+ silc_client_get_clients_by_list(client, conn, list_count,
+ client_id_list,
+ silc_client_join_get_users, r);
+ }
break;
}
collider = silc_client_get_client_by_id(client, conn,
old->id);
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf) - 1, "%s@%s",
- collider->username, collider->hostname);
- nicklist_rename_unique(SERVER(server),
- old, old->nickname,
- collider, collider->nickname);
- silc_print_nick_change(server, collider->nickname,
- client_entry->nickname, buf);
- g_slist_free(nicks);
+ if (collider != client_entry) {
+
+ memset(buf, 0, sizeof(buf));
+ snprintf(buf, sizeof(buf) - 1, "%s@%s",
+ collider->username, collider->hostname);
+ nicklist_rename_unique(SERVER(server),
+ old, old->nickname,
+ collider, collider->nickname);
+ silc_print_nick_change(server, collider->nickname,
+ client_entry->nickname, buf);
+ }
}
+ if (nicks != NULL)
+ g_slist_free(nicks);
+
old = g_strdup(server->nick);
server_change_nick(SERVER(server), client_entry->nickname);
nicklist_rename_unique(SERVER(server),
SilcChannelEntry channel;
SilcBuffer payload;
SilcArgumentPayload ban_list;
- SilcUInt32 argc;
+ SilcUInt16 argc;
if (!success)
return;
}
break;
+ case SILC_COMMAND_CMODE:
+ {
+ SilcChannelEntry channel_entry;
+ SilcBuffer channel_pubkeys;
+
+ channel_entry = va_arg(vp, SilcChannelEntry);
+ (void)va_arg(vp, SilcUInt32);
+ (void)va_arg(vp, SilcPublicKey);
+ channel_pubkeys = va_arg(vp, SilcBuffer);
+
+ if (!success || !cmode_list_chpks ||
+ !channel_entry || !channel_entry->channel_name)
+ return;
+
+ /* Print the channel public key list */
+ if (channel_pubkeys)
+ silc_parse_channel_public_keys(server, channel_entry, channel_pubkeys);
+ else
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_PK_NO_LIST,
+ channel_entry->channel_name);
+ }
+ break;
+
}
va_end(vp);
silc_detach(SilcClient client, SilcClientConnection conn,
const unsigned char *detach_data, SilcUInt32 detach_data_len)
{
- char file[256];
+ SILC_SERVER_REC *server = conn->context;
+ char *file;
/* Save the detachment data to file. */
- memset(file, 0, sizeof(file));
- snprintf(file, sizeof(file) - 1, "%s/session", get_irssi_dir());
+ file = silc_get_session_filename(server);
silc_file_writefile(file, detach_data, detach_data_len);
+ silc_free(file);
}