client_ops.c
- Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
+ Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2001 - 2005 Pekka Riikonen
+ Copyright (C) 2001 - 2007 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
static void
silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
- const char *name, SilcSocketType conn_type,
- unsigned char *pk, SilcUInt32 pk_len,
- SilcSKEPKType pk_type,
+ const char *name, SilcConnectionType conn_type,
+ SilcPublicKey public_key,
SilcVerifyPublicKey completion, void *context);
char *silc_get_session_filename(SILC_SERVER_REC *server)
static void silc_parse_channel_public_keys(SILC_SERVER_REC *server,
SilcChannelEntry channel_entry,
- SilcBuffer channel_pubkeys)
+ SilcDList channel_pubkeys)
{
- SilcUInt16 argc;
- SilcArgumentPayload chpks;
- unsigned char *pk;
+ SilcArgumentDecodedList e;
+ SilcPublicKey pubkey;
+ SilcSILCPublicKey silc_pubkey;
SilcUInt32 pk_len, type;
- int c = 1;
+ unsigned char *pk;
char *fingerprint, *babbleprint;
- SilcPublicKey pubkey;
- SilcPublicKeyIdentifier ident;
+ int c = 1;
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;
+ silc_dlist_start(channel_pubkeys);
+ while ((e = silc_dlist_get(channel_pubkeys))) {
+ pubkey = e->argument;
+ type = e->arg_type;
+
+ if (silc_pkcs_get_type(pubkey) != SILC_PKCS_SILC)
+ continue;
+
+ pk = silc_pkcs_public_key_encode(pubkey, &pk_len);
+ if (!pk)
+ continue;
- 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);
+ fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
+ babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
+ silc_pubkey = silc_pkcs_get_context(SILC_PKCS_SILC, pubkey);
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 : "",
+ silc_pubkey->identifier.realname ?
+ silc_pubkey->identifier.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_free(pk);
}
-
- silc_argument_payload_free(chpks);
}
void silc_say(SilcClient client, SilcClientConnection conn,
va_end(va);
}
-/* try to verify a message using locally stored public key data */
+/* Try to verify a message using locally stored public key data */
+
int verify_message_signature(SilcClientEntry sender,
- SilcMessageSignedPayload sig,
SilcMessagePayload message)
{
SilcPublicKey pk;
char file[256], filename[256];
char *fingerprint, *fingerprint2;
- unsigned char *pk_data;
+ const unsigned char *pk_data;
SilcUInt32 pk_datalen;
struct stat st;
int ret = SILC_MSG_SIGNED_VERIFIED, i;
- if (sig == NULL)
- return SILC_MSG_SIGNED_UNKNOWN;
-
/* get public key from the signature payload and compare it with the
one stored in the client entry */
- pk = silc_message_signed_get_public_key(sig, &pk_data, &pk_datalen);
+ pk = silc_message_signed_get_public_key(message, &pk_data, &pk_datalen);
if (pk != NULL) {
fingerprint = silc_hash_fingerprint(NULL, pk_data, pk_datalen);
- if (sender->fingerprint) {
+ if (sender->fingerprint[0]) {
fingerprint2 = silc_fingerprint(sender->fingerprint,
- sender->fingerprint_len);
+ sizeof(sender->fingerprint));
if (strcmp(fingerprint, fingerprint2)) {
/* since the public key differs from the senders public key, the
verification _failed_ */
}
silc_free(fingerprint2);
}
- } else if (sender->fingerprint)
+ } else if (sender->fingerprint[0])
fingerprint = silc_fingerprint(sender->fingerprint,
- sender->fingerprint_len);
+ sizeof(sender->fingerprint));
else
/* no idea, who or what signed that message ... */
return SILC_MSG_SIGNED_UNKNOWN;
SilcPublicKey cached_pk=NULL;
/* try to load the file */
- if (!silc_pkcs_load_public_key(filename, &cached_pk, SILC_PKCS_FILE_PEM) &&
- !silc_pkcs_load_public_key(filename, &cached_pk,
- SILC_PKCS_FILE_BIN)) {
+ if (!silc_pkcs_load_public_key(filename, &cached_pk)) {
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_COULD_NOT_LOAD, "client");
if (pk == NULL)
}
/* the public key is now in pk, our "level of trust" in ret */
- if ((pk) && silc_message_signed_verify(sig, message, pk,
- silc_client->sha1hash)!= SILC_AUTH_OK)
+ if ((pk) && silc_message_signed_verify(message, pk,
+ sha1hash) != SILC_AUTH_OK)
ret = SILC_MSG_SIGNED_FAILED;
if (pk)
return ret;
}
-char * silc_unescape_data(const char *escaped_data, SilcUInt32 *length)
+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;
- }
+ 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;
+ *length = j;
+ return data;
}
-char * silc_escape_data(const char *data, SilcUInt32 len)
+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;
- }
+ 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;
+ 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)
+ const char *data, SilcUInt32 data_len,
+ const char *nick, int verified)
{
- char *escaped_data;
+ char *escaped_data;
- escaped_data = silc_escape_data(data, data_len);
+ escaped_data = silc_escape_data(data, data_len);
- signal_emit("mime", 5, server, item, escaped_data, nick, verified);
+ signal_emit("mime", 5, server, item, escaped_data, nick, verified);
- silc_free(escaped_data);
+ silc_free(escaped_data);
}
SilcChannelUser chu = silc_client_on_channel(channel, sender);
if (chu)
nick = silc_nicklist_insert(chanrec, chu, FALSE);
+ if (!nick)
+ return;
}
/* If the messages is digitally signed, verify it, if possible. */
if (flags & SILC_MESSAGE_FLAG_SIGNED) {
if (!settings_get_bool("ignore_message_signatures")) {
- SilcMessageSignedPayload sig = silc_message_get_signature(payload);
- verified = verify_message_signature(sender, sig, payload);
+ verified = verify_message_signature(sender, payload);
} else {
flags &= ~SILC_MESSAGE_FLAG_SIGNED;
}
if (flags & SILC_MESSAGE_FLAG_DATA) {
silc_emit_mime_sig(server, (WI_ITEM_REC *)chanrec, message, message_len,
- nick == NULL ? NULL : nick->nick,
- flags & SILC_MESSAGE_FLAG_SIGNED ? verified : -1);
+ nick == NULL ? NULL : nick->nick,
+ flags & SILC_MESSAGE_FLAG_SIGNED ? verified : -1);
message = NULL;
}
server = conn == NULL ? NULL : conn->context;
memset(userhost, 0, sizeof(userhost));
- if (sender->username)
+ if (sender->username[0])
snprintf(userhost, sizeof(userhost) - 1, "%s@%s",
sender->username, sender->hostname);
/* If the messages is digitally signed, verify it, if possible. */
if (flags & SILC_MESSAGE_FLAG_SIGNED) {
if (!settings_get_bool("ignore_message_signatures")) {
- SilcMessageSignedPayload sig = silc_message_get_signature(payload);
- verified = verify_message_signature(sender, sig, payload);
+ verified = verify_message_signature(sender, payload);
} else {
flags &= ~SILC_MESSAGE_FLAG_SIGNED;
}
if (flags & SILC_MESSAGE_FLAG_DATA) {
silc_emit_mime_sig(server,
- sender->nickname ?
+ sender->nickname[0] ?
(WI_ITEM_REC *)query_find(SERVER(server), sender->nickname) :
NULL,
message, message_len,
- sender->nickname ? sender->nickname : "[<unknown>]",
+ sender->nickname[0] ? sender->nickname : "[<unknown>]",
flags & SILC_MESSAGE_FLAG_SIGNED ? verified : -1);
message = NULL;
}
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,
+ sender->nickname[0] ? sender->nickname : "[<unknown>]",
+ sender->username[0] ? userhost : NULL,
NULL, verified);
else
signal_emit("message silc private_action", 5, server, cp,
- sender->nickname ? sender->nickname : "[<unknown>]",
- sender->username ? userhost : NULL, NULL);
+ sender->nickname[0] ? sender->nickname : "[<unknown>]",
+ sender->username[0] ? 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,
+ sender->nickname[0] ? sender->nickname : "[<unknown>]",
+ sender->username[0] ? userhost : NULL,
NULL, verified);
else
signal_emit("message silc private_action", 5, server, message,
- sender->nickname ? sender->nickname : "[<unknown>]",
- sender->username ? userhost : NULL, NULL);
+ sender->nickname[0] ? sender->nickname : "[<unknown>]",
+ sender->username[0] ? userhost : NULL, NULL);
}
else if (flags & SILC_MESSAGE_FLAG_NOTICE)
if(flags & SILC_MESSAGE_FLAG_UTF8 && !silc_term_utf8()) {
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,
+ sender->nickname[0] ? sender->nickname : "[<unknown>]",
+ sender->username[0] ? userhost : NULL,
NULL, verified);
else
signal_emit("message silc private_notice", 5, server, cp,
- sender->nickname ? sender->nickname : "[<unknown>]",
- sender->username ? userhost : NULL, NULL);
+ sender->nickname[0] ? sender->nickname : "[<unknown>]",
+ sender->username[0] ? 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,
+ sender->nickname[0] ? sender->nickname : "[<unknown>]",
+ sender->username[0] ? userhost : NULL,
NULL, verified);
else
signal_emit("message silc private_notice", 5, server, message,
- sender->nickname ? sender->nickname : "[<unknown>]",
- sender->username ? userhost : NULL, NULL);
+ sender->nickname[0] ? sender->nickname : "[<unknown>]",
+ sender->username[0] ? userhost : NULL, NULL);
}
else {
if (flags & SILC_MESSAGE_FLAG_UTF8 && !silc_term_utf8()) {
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);
+ sender->nickname[0] ? sender->nickname : "[<unknown>]",
+ sender->username[0] ? userhost : NULL, verified);
else
signal_emit("message private", 4, server, cp,
- sender->nickname ? sender->nickname : "[<unknown>]",
- sender->username ? userhost : NULL);
+ sender->nickname[0] ? sender->nickname : "[<unknown>]",
+ sender->username[0] ? 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);
+ sender->nickname[0] ? sender->nickname : "[<unknown>]",
+ sender->username[0] ? userhost : NULL, verified);
else
signal_emit("message private", 4, server, message,
- sender->nickname ? sender->nickname : "[<unknown>]",
- sender->username ? userhost : NULL);
+ sender->nickname[0] ? sender->nickname : "[<unknown>]",
+ sender->username[0] ? userhost : NULL);
}
}
void *entry;
SilcUInt32 mode;
char buf[512];
- char *name, *tmp;
+ char *name, *tmp, *cipher, *hmac;
GSList *list1, *list_tmp;
- SilcBuffer buffer;
+ SilcDList chpks, clients;
SILC_LOG_DEBUG(("Start"));
name = va_arg(va, char *);
client_entry = va_arg(va, SilcClientEntry);
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf) - 1, "%s@%s",
- client_entry->username, client_entry->hostname);
- signal_emit("message invite", 4, server, channel ? channel->channel_name :
- name, client_entry->nickname, buf);
+ silc_snprintf(buf, sizeof(buf) - 1, "%s@%s",
+ client_entry->username, client_entry->hostname);
+ signal_emit("message invite", 4, server, name,
+ client_entry->nickname, buf);
break;
case SILC_NOTIFY_TYPE_JOIN:
if (client_entry == server->conn->local_entry) {
/* You joined to channel */
chanrec = silc_channel_find(server, channel->channel_name);
- if (chanrec != NULL && !chanrec->joined)
+ if (chanrec == NULL)
+ chanrec = silc_channel_create(server, channel->channel_name,
+ channel->channel_name, TRUE);
+ if (!chanrec->joined)
chanrec->entry = channel;
} else {
chanrec = silc_channel_find_entry(server, channel);
}
memset(buf, 0, sizeof(buf));
- if (client_entry->username)
- snprintf(buf, sizeof(buf) - 1, "%s@%s",
- client_entry->username, client_entry->hostname);
+ if (client_entry->username[0])
+ snprintf(buf, sizeof(buf) - 1, "%s@%s",
+ client_entry->username, client_entry->hostname);
signal_emit("message join", 4, server, channel->channel_name,
client_entry->nickname,
- client_entry->username == NULL ? "" : buf);
+ !client_entry->username[0] ? "" : buf);
+
+ /* If there are multiple same nicknames on channel now, tell it to user. */
+ if (client_entry != server->conn->local_entry) {
+ char *nick, tmp[32];
+ int count = 0;
+
+ silc_client_nickname_parse(client, conn, client_entry->nickname, &nick);
+ clients = silc_client_get_clients_local(client, conn, nick, TRUE);
+ if (!clients || silc_dlist_count(clients) < 2) {
+ silc_free(nick);
+ silc_client_list_free(client, conn, clients);
+ break;
+ }
+ silc_dlist_start(clients);
+ while ((client_entry2 = silc_dlist_get(clients)))
+ if (silc_client_on_channel(channel, client_entry2))
+ count++;
+ if (count > 1) {
+ silc_snprintf(tmp, sizeof(tmp), "%d", silc_dlist_count(clients));
+ printformat_module("fe-common/silc", server, channel->channel_name,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_MANY_NICKS,
+ tmp, nick);
+ printformat_module("fe-common/silc", server, channel->channel_name,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_USER_APPEARS,
+ buf, client_entry->nickname);
+ }
+ silc_client_list_free(client, conn, clients);
+ silc_free(nick);
+ }
break;
case SILC_NOTIFY_TYPE_LEAVE:
snprintf(buf, sizeof(buf) - 1, "%s@%s",
client_entry->username, client_entry->hostname);
signal_emit("message part", 5, server, channel->channel_name,
- client_entry->nickname, client_entry->username ?
+ client_entry->nickname, client_entry->username[0] ?
buf : "", client_entry->nickname);
chanrec = silc_channel_find_entry(server, channel);
if (nickrec != NULL)
nicklist_remove(CHANNEL(chanrec), NICK(nickrec));
}
+
+ /* If there is only one client with this same nickname on channel now
+ change it to the base format if it is formatted nickname. */
+ if (channel) {
+ silc_client_nickname_parse(client, conn, client_entry->nickname, &name);
+ clients = silc_client_get_clients_local(client, conn, name, TRUE);
+ if (!clients || silc_dlist_count(clients) != 2) {
+ silc_free(name);
+ silc_client_list_free(client, conn, clients);
+ break;
+ }
+ silc_dlist_start(clients);
+ client_entry2 = silc_dlist_get(clients);
+ if (client_entry2 == client_entry)
+ client_entry2 = silc_dlist_get(clients);
+ if (silc_client_on_channel(channel, client_entry2)) {
+ silc_snprintf(buf, sizeof(buf), "%s", client_entry2->nickname);
+ silc_client_nickname_format(client, conn, client_entry2, TRUE);
+ if (!silc_utf8_strcasecmp(buf, client_entry2->nickname)) {
+ nicklist_rename_unique(SERVER(server), client_entry2, buf,
+ client_entry2, client_entry2->nickname);
+ printformat_module("fe-common/silc", server, channel->channel_name,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_USER_APPEARS,
+ buf, client_entry2->nickname);
+ }
+ }
+ silc_client_list_free(client, conn, clients);
+ silc_free(name);
+ }
break;
case SILC_NOTIFY_TYPE_SIGNOFF:
client_entry = va_arg(va, SilcClientEntry);
tmp = va_arg(va, char *);
+ channel = va_arg(va, SilcChannelEntry);
silc_server_free_ftp(server, client_entry);
- /* Print only if we have the nickname. If this cliente has just quit
- when we were only resolving it, it is possible we don't have the
- nickname. */
- if (client_entry->nickname) {
- memset(buf, 0, sizeof(buf));
- if (client_entry->username)
- snprintf(buf, sizeof(buf) - 1, "%s@%s",
- client_entry->username, client_entry->hostname);
- signal_emit("message quit", 4, server, client_entry->nickname,
- client_entry->username ? buf : "",
- tmp ? tmp : "");
- }
+ memset(buf, 0, sizeof(buf));
+ if (client_entry->username)
+ snprintf(buf, sizeof(buf) - 1, "%s@%s",
+ client_entry->username, client_entry->hostname);
+ signal_emit("message quit", 4, server, client_entry->nickname,
+ client_entry->username[0] ? buf : "", tmp ? tmp : "");
list1 = nicklist_get_same_unique(SERVER(server), client_entry);
for (list_tmp = list1; list_tmp != NULL; list_tmp =
nicklist_remove(channel, nickrec);
}
+
+ /* If there is only one client with this same nickname on channel now
+ change it to the base format if it is formatted nickname. */
+ if (channel) {
+ silc_client_nickname_parse(client, conn, client_entry->nickname, &name);
+ clients = silc_client_get_clients_local(client, conn, name, TRUE);
+ if (!clients || silc_dlist_count(clients) != 2) {
+ silc_free(name);
+ silc_client_list_free(client, conn, clients);
+ break;
+ }
+ silc_dlist_start(clients);
+ client_entry2 = silc_dlist_get(clients);
+ if (client_entry2 == client_entry)
+ client_entry2 = silc_dlist_get(clients);
+ if (silc_client_on_channel(channel, client_entry2)) {
+ silc_snprintf(buf, sizeof(buf), "%s", client_entry2->nickname);
+ silc_client_nickname_format(client, conn, client_entry2, TRUE);
+ if (!silc_utf8_strcasecmp(buf, client_entry2->nickname)) {
+ nicklist_rename_unique(SERVER(server), client_entry2, buf,
+ client_entry2, client_entry2->nickname);
+ printformat_module("fe-common/silc", server, channel->channel_name,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_USER_APPEARS,
+ buf, client_entry2->nickname);
+ }
+ }
+ silc_client_list_free(client, conn, clients);
+ silc_free(name);
+ }
break;
case SILC_NOTIFY_TYPE_TOPIC_SET:
SILC_LOG_DEBUG(("Notify: NICK_CHANGE"));
client_entry = va_arg(va, SilcClientEntry);
- client_entry2 = va_arg(va, SilcClientEntry);
+ name = va_arg(va, char *); /* old nickname */
- if (!strcmp(client_entry->nickname, client_entry2->nickname))
+ if (!strcmp(client_entry->nickname, name))
break;
memset(buf, 0, sizeof(buf));
snprintf(buf, sizeof(buf) - 1, "%s@%s",
- client_entry2->username, client_entry2->hostname);
+ client_entry->username, client_entry->hostname);
nicklist_rename_unique(SERVER(server),
- client_entry, client_entry->nickname,
- client_entry2, client_entry2->nickname);
- signal_emit("message nick", 4, server, client_entry2->nickname,
- client_entry->nickname, buf);
+ client_entry, name,
+ client_entry, client_entry->nickname);
+ signal_emit("message nick", 4, server, client_entry->nickname, name, buf);
break;
case SILC_NOTIFY_TYPE_CMODE_CHANGE:
idtype = va_arg(va, int);
entry = va_arg(va, void *);
mode = va_arg(va, SilcUInt32);
- (void)va_arg(va, char *); /* cipher */
- (void)va_arg(va, char *); /* hmac */
+ cipher = va_arg(va, char *); /* cipher */
+ hmac = 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 */
+ chpks = va_arg(va, SilcDList); /* channel public keys */
channel = va_arg(va, SilcChannelEntry);
- tmp = silc_client_chmode(mode,
- channel->channel_key ?
- silc_cipher_get_name(channel->channel_key) : "",
- channel->hmac ?
- silc_hmac_get_name(channel->hmac) : "");
+ tmp = silc_client_chmode(mode, cipher ? cipher : "",
+ hmac ? hmac : "");
chanrec = silc_channel_find_entry(server, channel);
if (chanrec != NULL) {
}
/* Print the channel public key list */
- if (buffer)
- silc_parse_channel_public_keys(server, channel, buffer);
+ if (chpks)
+ silc_parse_channel_public_keys(server, channel, chpks);
silc_free(tmp);
break;
/*
* Server has quit the network.
*/
- int i;
- SilcClientEntry *clients;
- SilcUInt32 clients_count;
+ SilcDList clients;
- SILC_LOG_DEBUG(("Notify: SIGNOFF"));
+ SILC_LOG_DEBUG(("Notify: SERVER_SIGNOFF"));
(void)va_arg(va, void *);
- clients = va_arg(va, SilcClientEntry *);
- clients_count = va_arg(va, SilcUInt32);
+ clients = va_arg(va, SilcDList);
- for (i = 0; i < clients_count; i++) {
+ silc_dlist_start(clients);
+ while ((client_entry = silc_dlist_get(clients))) {
memset(buf, 0, sizeof(buf));
/* Print only if we have the nickname. If this client has just quit
when we were only resolving it, it is possible we don't have the
nickname. */
- if (clients[i]->nickname) {
- if (clients[i]->username)
+ if (client_entry->nickname[0]) {
+ if (client_entry->username[0])
snprintf(buf, sizeof(buf) - 1, "%s@%s",
- clients[i]->username, clients[i]->hostname);
- signal_emit("message quit", 4, server, clients[i]->nickname,
- clients[i]->username ? buf : "",
+ client_entry->username, client_entry->hostname);
+ signal_emit("message quit", 4, server, client_entry->nickname,
+ client_entry->username[0] ? buf : "",
"server signoff");
}
- silc_server_free_ftp(server, clients[i]);
+ silc_server_free_ftp(server, client_entry);
- list1 = nicklist_get_same_unique(SERVER(server), clients[i]);
+ list1 = nicklist_get_same_unique(SERVER(server), client_entry);
for (list_tmp = list1; list_tmp != NULL; list_tmp =
list_tmp->next->next) {
CHANNEL_REC *channel = list_tmp->data;
va_end(va);
}
-/* Called to indicate that connection was either successfully established
- or connecting failed. This is also the first time application receives
- the SilcClientConnection object which it should save somewhere. */
-
-void silc_connect(SilcClient client, SilcClientConnection conn,
- SilcClientConnectionStatus status)
-{
- SILC_SERVER_REC *server = conn->context;
-
- if (!server || server->disconnected) {
- silc_client_close_connection(client, conn);
- return;
- }
-
- switch (status) {
- case SILC_CLIENT_CONN_SUCCESS:
- /* We have successfully connected to server */
- if ((client->nickname != NULL) &&
- (strcmp(client->nickname, client->username)))
- silc_queue_enable(conn); /* enable queueing until we have our nick */
- server->connected = TRUE;
- signal_emit("event connected", 1, server);
- break;
-
- case SILC_CLIENT_CONN_SUCCESS_RESUME:
- /* We have successfully resumed old detached session */
- server->connected = TRUE;
- signal_emit("event connected", 1, server);
-
- /* If we resumed old session check whether we need to update
- our nickname */
- if (strcmp(server->nick, conn->local_entry->nickname)) {
- char *old;
- old = g_strdup(server->nick);
- server_change_nick(SERVER(server), conn->local_entry->nickname);
- nicklist_rename_unique(SERVER(server),
- conn->local_entry, server->nick,
- conn->local_entry, conn->local_entry->nickname);
- 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:
- {
- 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;
- }
- }
-}
-
-/* Called to indicate that connection was disconnected to the server. */
-
-void silc_disconnect(SilcClient client, SilcClientConnection conn,
- SilcStatus status, const char *message)
-{
- SILC_SERVER_REC *server = conn->context;
-
- SILC_LOG_DEBUG(("Start"));
-
- if (!server || server->connection_lost)
- return;
-
- if (server->conn && server->conn->local_entry) {
- nicklist_rename_unique(SERVER(server),
- server->conn->local_entry, server->nick,
- server->conn->local_entry,
- silc_client->username);
- silc_change_nick(server, silc_client->username);
- }
-
- if (message)
- silc_say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
- "Server closed connection: %s (%d) %s",
- silc_get_status_message(status), status,
- message ? message : "");
-
- if (server->conn)
- server->conn->context = NULL;
- server->conn = NULL;
- server->connection_lost = TRUE;
- server_disconnect(SERVER(server));
-}
-
/* Command handler. This function is called always in the command function.
If error occurs it will be called as well. `conn' is the associated
client connection. `cmd_context' is the command context that was
after application has called the command. Just to tell application
that the command really was processed. */
-static bool cmode_list_chpks = FALSE;
+static SilcBool cmode_list_chpks = FALSE;
void silc_command(SilcClient client, SilcClientConnection conn,
- SilcClientCommandContext cmd_context, bool success,
- SilcCommand command, SilcStatus status)
+ SilcBool success, SilcCommand command, SilcStatus status,
+ SilcUInt32 argc, unsigned char **argv)
{
SILC_SERVER_REC *server = conn->context;
switch (command) {
case SILC_COMMAND_INVITE:
- if (cmd_context->argc > 2)
+ if (argc > 2)
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_CHANNEL_INVITING,
- cmd_context->argv[2],
- (cmd_context->argv[1][0] == '*' ?
+ argv[2],
+ (argv[1][0] == '*' ?
(char *)conn->current_channel->channel_name :
- (char *)cmd_context->argv[1]));
+ (char *)argv[1]));
break;
case SILC_COMMAND_DETACH:
break;
case SILC_COMMAND_CMODE:
- if (cmd_context->argc == 3 &&
- !strcmp(cmd_context->argv[2], "+C"))
+ if (argc == 3 && !strcmp(argv[2], "+C"))
cmode_list_chpks = TRUE;
else
cmode_list_chpks = FALSE;
}
}
-typedef struct {
- SilcChannelEntry channel;
- bool retry;
-} *SilcJoinResolve;
-
-/* Client info resolving callback when JOIN command reply is received.
- This will cache all users on the channel. */
-
-static void silc_client_join_get_users(SilcClient client,
- SilcClientConnection conn,
- SilcClientEntry *clients,
- SilcUInt32 clients_count,
- void *context)
-{
- SilcJoinResolve r = context;
- SilcChannelEntry channel = r->channel;
- SilcHashTableList htl;
- SilcChannelUser chu;
- SILC_SERVER_REC *server = conn->context;
- SILC_CHANNEL_REC *chanrec;
- SilcClientEntry founder = NULL;
- NICK_REC *ownnick;
-
- SILC_LOG_DEBUG(("Start, channel %s, %d users", channel->channel_name,
- silc_hash_table_count(channel->user_list)));
-
- 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);
- return;
- }
-
- chanrec = silc_channel_find(server, channel->channel_name);
- if (chanrec == NULL)
- return;
-
- silc_hash_table_list(channel->user_list, &htl);
- while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
- if (!chu->client->nickname)
- continue;
- if (chu->mode & SILC_CHANNEL_UMODE_CHANFO)
- founder = chu->client;
- silc_nicklist_insert(chanrec, chu, FALSE);
- }
- silc_hash_table_list_reset(&htl);
-
- ownnick = NICK(silc_nicklist_find(chanrec, conn->local_entry));
- nicklist_set_own(CHANNEL(chanrec), ownnick);
- signal_emit("channel joined", 1, chanrec);
- chanrec->entry = channel;
-
- if (chanrec->topic)
- printformat_module("fe-common/silc", server, channel->channel_name,
- MSGLEVEL_CRAP, SILCTXT_CHANNEL_TOPIC,
- channel->channel_name, chanrec->topic);
-
- if (founder) {
- if (founder == conn->local_entry) {
- printformat_module("fe-common/silc",
- server, channel->channel_name, MSGLEVEL_CRAP,
- SILCTXT_CHANNEL_FOUNDER_YOU,
- channel->channel_name);
- signal_emit("nick mode changed", 2, chanrec, ownnick);
- } else
- printformat_module("fe-common/silc",
- server, channel->channel_name, MSGLEVEL_CRAP,
- SILCTXT_CHANNEL_FOUNDER,
- channel->channel_name, founder->nickname);
- }
-}
-
typedef struct {
SilcClient client;
SilcClientConnection conn;
void *entry;
SilcIdType id_type;
- char *fingerprint;
} *GetkeyContext;
void silc_getkey_cb(bool success, void *context)
char *name = (getkey->id_type == SILC_ID_CLIENT ?
((SilcClientEntry)getkey->entry)->nickname :
((SilcServerEntry)getkey->entry)->server_name);
+ SilcPublicKey public_key = (getkey->id_type == SILC_ID_CLIENT ?
+ ((SilcClientEntry)getkey->entry)->public_key :
+ ((SilcServerEntry)getkey->entry)->public_key);
+ SilcSILCPublicKey silc_pubkey;
+
+ silc_pubkey = silc_pkcs_get_context(SILC_PKCS_SILC, public_key);
if (success) {
- printformat_module("fe-common/silc", NULL, NULL,
- MSGLEVEL_CRAP, SILCTXT_PUBKEY_VERIFIED, entity, name);
+ if (getkey->id_type == SILC_ID_CLIENT)
+ printformat_module("fe-common/silc", NULL, NULL,
+ MSGLEVEL_CRAP, SILCTXT_PUBKEY_VERIFIED_CLIENT,
+ name,
+ silc_pubkey->identifier.realname ?
+ silc_pubkey->identifier.realname : "",
+ silc_pubkey->identifier.email ?
+ silc_pubkey->identifier.email : "");
+ else
+ printformat_module("fe-common/silc", NULL, NULL,
+ MSGLEVEL_CRAP, SILCTXT_PUBKEY_VERIFIED,
+ entity, name);
} else {
printformat_module("fe-common/silc", NULL, NULL,
MSGLEVEL_CRAP, SILCTXT_PUBKEY_NOTVERIFIED,
entity, name);
}
- silc_free(getkey->fingerprint);
silc_free(getkey);
}
MSGLEVEL_CRAP, SILCTXT_CHANNEL_INVITEBAN_LIST,
channel->channel_name, list_type);
- /* parse the list */
+ /* Parse the list */
tmp = silc_argument_get_first_arg(list, &type, &len);
while (tmp) {
switch (type) {
case 1:
{
- /* an invite string */
+ /* An invite string */
char **list;
int i=0;
case 2:
{
- /* a public key */
+ /* A public key */
char *fingerprint, *babbleprint;
/* tmp is Public Key Payload, take public key from it. */
case 3:
{
- /* a client ID */
- SilcClientID *client_id;
+ /* A Client ID */
SilcClientEntry client_entry;
+ SilcID id;
- client_id = silc_id_payload_parse_id(tmp, len, NULL);
-
- if (client_id == NULL) {
+ if (!silc_id_payload_parse_id(tmp, len, &id)) {
silc_say_error("Invalid data in %s list encountered", list_type);
break;
}
- client_entry = silc_client_get_client_by_id(client, conn, client_id);
-
+ client_entry = silc_client_get_client_by_id(client, conn,
+ &id.u.client_id);
if (client_entry) {
printformat_module("fe-common/silc", server,
(chanrec ? chanrec->visible_name : NULL),
MSGLEVEL_CRAP, SILCTXT_CHANNEL_INVITEBAN_STRING,
++counter, channel->channel_name, list_type,
client_entry->nickname);
+ silc_client_unref_client(client, conn, client_entry);
} else {
resolving = TRUE;
- silc_client_get_client_by_id_resolve(client, conn, client_id,
+ silc_client_get_client_by_id_resolve(client, conn, &id.u.client_id,
NULL, NULL, NULL);
}
-
- silc_free(client_id);
}
break;
/* "trash" */
silc_say_error("Unkown type in %s list: %u (len %u)",
list_type, type, len);
+ break;
}
tmp = silc_argument_get_next_arg(list, &type, &len);
}
and each command defines the number and type of arguments it passes to the
application (on error they are not sent). */
-void
-silc_command_reply(SilcClient client, SilcClientConnection conn,
- SilcCommandPayload cmd_payload, bool success,
- SilcCommand command, SilcStatus status, ...)
-
+void silc_command_reply(SilcClient client, SilcClientConnection conn,
+ SilcCommand command, SilcStatus status,
+ SilcStatus error, va_list vp)
{
SILC_SERVER_REC *server = conn->context;
SILC_CHANNEL_REC *chanrec;
- va_list vp;
-
- va_start(vp, status);
SILC_LOG_DEBUG(("Start"));
{
char buf[1024], *nickname, *username, *realname, *nick;
unsigned char *fingerprint;
- SilcUInt32 idle, mode;
- SilcBuffer channels, user_modes;
+ SilcUInt32 idle, mode, *user_modes;
+ SilcDList channels;
SilcClientEntry client_entry;
SilcDList attrs;
if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
/* Print the unknown nick for user */
- unsigned char *tmp =
- silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
- 2, NULL);
+ char *tmp = va_arg(vp, char *);
if (tmp)
- silc_say_error("%s: %s", tmp,
- silc_get_status_message(status));
+ silc_say_error("%s: %s", tmp, silc_get_status_message(status));
break;
} else if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
/* Try to find the entry for the unknown client ID, since we
might have, and print the nickname of it for user. */
- SilcUInt32 tmp_len;
- unsigned char *tmp =
- silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
- 2, &tmp_len);
- if (tmp) {
- SilcClientID *client_id = silc_id_payload_parse_id(tmp, tmp_len,
- NULL);
- if (client_id) {
- client_entry = silc_client_get_client_by_id(client, conn,
- client_id);
- if (client_entry && client_entry->nickname)
- silc_say_error("%s: %s", client_entry->nickname,
- silc_get_status_message(status));
- silc_free(client_id);
- }
+ SilcClientID *id = va_arg(vp, SilcClientID *);
+ if (id) {
+ client_entry = silc_client_get_client_by_id(client, conn, id);
+ if (client_entry && client_entry->nickname[0])
+ silc_say_error("%s: %s", client_entry->nickname,
+ silc_get_status_message(status));
+ silc_client_unref_client(client, conn, client_entry);
}
break;
- } else if (!success) {
+ } else if (SILC_STATUS_IS_ERROR(status)) {
silc_say_error("WHOIS: %s", silc_get_status_message(status));
return;
}
nickname = va_arg(vp, char *);
username = va_arg(vp, char *);
realname = va_arg(vp, char *);
- channels = va_arg(vp, SilcBuffer);
+ channels = va_arg(vp, SilcDList);
mode = va_arg(vp, SilcUInt32);
idle = va_arg(vp, SilcUInt32);
fingerprint = va_arg(vp, unsigned char *);
- user_modes = va_arg(vp, SilcBuffer);
+ user_modes = va_arg(vp, SilcUInt32 *);
attrs = va_arg(vp, SilcDList);
- silc_parse_userfqdn(nickname, &nick, NULL);
+ silc_client_nickname_parse(client, conn, client_entry->nickname, &nick);
printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
SILCTXT_WHOIS_USERINFO, nickname,
client_entry->username, client_entry->hostname,
silc_free(nick);
if (channels && user_modes) {
- SilcUInt32 *umodes;
- SilcDList list = silc_channel_payload_parse_list(channels->data,
- channels->len);
- if (list && silc_get_mode_list(user_modes, silc_dlist_count(list),
- &umodes)) {
- SilcChannelPayload entry;
- int i = 0;
+ SilcChannelPayload entry;
+ int i = 0;
- memset(buf, 0, sizeof(buf));
- silc_dlist_start(list);
- while ((entry = silc_dlist_get(list)) != SILC_LIST_END) {
- SilcUInt32 name_len;
- char *m = silc_client_chumode_char(umodes[i++]);
- char *name = silc_channel_get_name(entry, &name_len);
-
- if (m)
- silc_strncat(buf, sizeof(buf) - 1, m, strlen(m));
- silc_strncat(buf, sizeof(buf) - 1, name, name_len);
- silc_strncat(buf, sizeof(buf) - 1, " ", 1);
- silc_free(m);
- }
-
- printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
- SILCTXT_WHOIS_CHANNELS, buf);
- silc_channel_payload_list_free(list);
- silc_free(umodes);
+ memset(buf, 0, sizeof(buf));
+ silc_dlist_start(channels);
+ while ((entry = silc_dlist_get(channels))) {
+ SilcUInt32 name_len;
+ char *m = silc_client_chumode_char(user_modes[i++]);
+ char *name = silc_channel_get_name(entry, &name_len);
+
+ if (m)
+ silc_strncat(buf, sizeof(buf) - 1, m, strlen(m));
+ silc_strncat(buf, sizeof(buf) - 1, name, name_len);
+ silc_strncat(buf, sizeof(buf) - 1, " ", 1);
+ silc_free(m);
}
+
+ printformat_module("fe-common/silc", server, NULL, MSGLEVEL_CRAP,
+ SILCTXT_WHOIS_CHANNELS, buf);
}
if (mode) {
}
break;
- case SILC_COMMAND_IDENTIFY:
- {
- SilcClientEntry client_entry;
-
- if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
- /* Print the unknown nick for user */
- unsigned 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));
- break;
- } else if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) {
- /* Try to find the entry for the unknown client ID, since we
- might have, and print the nickname of it for user. */
- SilcUInt32 tmp_len;
- unsigned char *tmp =
- silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
- 2, &tmp_len);
- if (tmp) {
- SilcClientID *client_id = silc_id_payload_parse_id(tmp, tmp_len,
- NULL);
- if (client_id) {
- client_entry = silc_client_get_client_by_id(client, conn,
- client_id);
- if (client_entry && client_entry->nickname)
- silc_say_error("%s: %s", client_entry->nickname,
- silc_get_status_message(status));
- silc_free(client_id);
- }
- }
- break;
- }
-
- break;
- }
-
case SILC_COMMAND_WHOWAS:
{
char *nickname, *username, *realname;
if (status == SILC_STATUS_ERR_NO_SUCH_NICK) {
- char *tmp =
- silc_argument_get_arg_type(silc_command_get_args(cmd_payload),
- 2, NULL);
+ char *tmp = va_arg(vp, char *);
if (tmp)
silc_say_error("%s: %s", tmp,
silc_get_status_message(status));
break;
- } else if (!success) {
+ } else if (SILC_STATUS_IS_ERROR(status)) {
silc_say_error("WHOWAS: %s", silc_get_status_message(status));
return;
}
case SILC_COMMAND_INVITE:
{
SilcChannelEntry channel;
- SilcBuffer payload;
SilcArgumentPayload invite_list;
- SilcUInt16 argc;
- if (!success)
+ if (SILC_STATUS_IS_ERROR(status))
return;
channel = va_arg(vp, SilcChannelEntry);
- payload = va_arg(vp, SilcBuffer);
-
- if (payload) {
- SILC_GET16_MSB(argc, payload->data);
- invite_list = silc_argument_payload_parse(payload->data + 2,
- payload->len - 2, argc);
- if (invite_list) {
- silc_parse_inviteban_list(client, conn, server, channel,
- "invite", invite_list);
- silc_argument_payload_free(invite_list);
- }
- }
+ invite_list = va_arg(vp, SilcArgumentPayload);
+
+ if (invite_list)
+ silc_parse_inviteban_list(client, conn, server, channel,
+ "invite", invite_list);
}
break;
case SILC_COMMAND_JOIN:
{
- char *channel, *mode, *topic;
+ char *channel, *mode, *topic, *cipher, *hmac;
SilcUInt32 modei;
+ SilcHashTableList *user_list;
SilcChannelEntry channel_entry;
- SilcBuffer client_id_list;
- SilcUInt32 list_count;
-
- if (!success)
+ SilcChannelUser chu;
+ SilcClientEntry founder = NULL;
+ NICK_REC *ownnick;
+
+ if (SILC_STATUS_IS_ERROR(status)) {
+ if (status == SILC_STATUS_ERR_NO_SUCH_SERVER) {
+ char *tmp = va_arg(vp, char *);
+ if (tmp)
+ silc_say_error("JOIN: %s: %s", tmp,
+ silc_get_status_message(status));
+ return;
+ }
+ if (status == SILC_STATUS_ERR_NO_SUCH_CHANNEL) {
+ char *tmp = va_arg(vp, char *);
+ if (tmp)
+ silc_say_error("JOIN: %s: %s", tmp,
+ silc_get_status_message(status));
+ return;
+ }
+ silc_say_error("JOIN: %s", silc_get_status_message(status));
return;
+ }
channel = va_arg(vp, char *);
channel_entry = va_arg(vp, SilcChannelEntry);
modei = va_arg(vp, SilcUInt32);
- (void)va_arg(vp, SilcUInt32);
- (void)va_arg(vp, unsigned char *);
- (void)va_arg(vp, unsigned char *);
- (void)va_arg(vp, unsigned char *);
+ user_list = va_arg(vp, SilcHashTableList *);
topic = va_arg(vp, char *);
- (void)va_arg(vp, unsigned char *);
- list_count = va_arg(vp, SilcUInt32);
- client_id_list = va_arg(vp, SilcBuffer);
+ cipher = va_arg(vp, char *);
+ hmac = va_arg(vp, char *);
chanrec = silc_channel_find(server, channel);
if (!chanrec)
silc_free(dm);
}
- mode = silc_client_chmode(modei,
- channel_entry->channel_key ?
- silc_cipher_get_name(channel_entry->
- channel_key) : "",
- channel_entry->hmac ?
- silc_hmac_get_name(channel_entry->hmac) : "");
+ mode = silc_client_chmode(modei, cipher ? cipher : "", hmac ? hmac : "");
g_free_not_null(chanrec->mode);
chanrec->mode = g_strdup(mode == NULL ? "" : mode);
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);
+ /* Get user list */
+ while (silc_hash_table_get(user_list, NULL, (void *)&chu)) {
+ if (!chu->client->nickname[0])
+ continue;
+ if (chu->mode & SILC_CHANNEL_UMODE_CHANFO)
+ founder = chu->client;
+ silc_nicklist_insert(chanrec, chu, FALSE);
+ }
+
+ ownnick = NICK(silc_nicklist_find(chanrec, conn->local_entry));
+ if (!ownnick)
+ break;
+ nicklist_set_own(CHANNEL(chanrec), ownnick);
+ signal_emit("channel joined", 1, chanrec);
+ chanrec->entry = channel_entry;
+
+ if (chanrec->topic)
+ printformat_module("fe-common/silc", server,
+ channel_entry->channel_name,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_TOPIC,
+ channel_entry->channel_name, chanrec->topic);
+
+ if (founder) {
+ if (founder == conn->local_entry) {
+ printformat_module("fe-common/silc",
+ server, channel_entry->channel_name,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_FOUNDER_YOU,
+ channel_entry->channel_name);
+ signal_emit("nick mode changed", 2, chanrec, ownnick);
+ } else
+ printformat_module("fe-common/silc",
+ server, channel_entry->channel_name,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_FOUNDER,
+ channel_entry->channel_name, founder->nickname);
}
break;
SilcClientEntry client_entry = va_arg(vp, SilcClientEntry);
GSList *nicks;
- if (!success)
+ if (SILC_STATUS_IS_ERROR(status)) {
+ silc_say_error("NICK: %s", silc_get_status_message(status));
return;
+ }
nicks = nicklist_get_same(SERVER(server), client_entry->nickname);
if ((nicks != NULL) &&
- (strcmp(SERVER(server)->nick, client_entry->nickname))) {
+ (strcmp(SERVER(server)->nick, client_entry->nickname))) {
char buf[512];
SilcClientEntry collider, old;
old = ((SILC_NICK_REC *)(nicks->next->data))->silc_user->client;
- collider = silc_client_get_client_by_id(client, conn,
- old->id);
-
+ collider = silc_client_get_client_by_id(client, conn, &old->id);
if (collider != client_entry) {
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf) - 1, "%s@%s",
- collider->username, collider->hostname);
+ 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);
+ old, old->nickname,
+ collider, collider->nickname);
silc_print_nick_change(server, collider->nickname,
- client_entry->nickname, buf);
+ client_entry->nickname, buf);
}
+ silc_client_unref_client(client, conn, collider);
}
if (nicks != NULL)
char users[20];
char tmp[256], *cp, *dm = NULL;
- if (!success)
+ if (SILC_STATUS_IS_ERROR(status))
return;
(void)va_arg(vp, SilcChannelEntry);
name = va_arg(vp, char *);
- if (!name)
- return;
topic = va_arg(vp, char *);
usercount = va_arg(vp, int);
SilcUInt32 mode;
char *reason;
- if (!success)
+ if (SILC_STATUS_IS_ERROR(status))
return;
mode = va_arg(vp, SilcUInt32);
break;
case SILC_COMMAND_OPER:
- if (!success)
+ if (SILC_STATUS_IS_ERROR(status)) {
+ silc_say_error("OPER: %s", silc_get_status_message(status));
return;
+ }
server->umode |= SILC_UMODE_SERVER_OPERATOR;
signal_emit("user mode changed", 2, server, NULL);
break;
case SILC_COMMAND_SILCOPER:
- if (!success)
+ if (SILC_STATUS_IS_ERROR(status)) {
+ silc_say_error("SILCOPER: %s", silc_get_status_message(status));
return;
+ }
server->umode |= SILC_UMODE_ROUTER_OPERATOR;
signal_emit("user mode changed", 2, server, NULL);
SilcChannelEntry channel;
SilcChannelUser chu;
- if (!success)
+ if (SILC_STATUS_IS_ERROR(status)) {
+ silc_say_error("USERS: %s", silc_get_status_message(status));
return;
+ }
channel = va_arg(vp, SilcChannelEntry);
SilcClientEntry e = chu->client;
char stat[5], *mode;
- if (!e->nickname)
+ if (!e->nickname[0])
continue;
memset(stat, 0, sizeof(stat));
printformat_module("fe-common/silc", server, channel->channel_name,
MSGLEVEL_CRAP, SILCTXT_USERS,
e->nickname, stat,
- e->username ? e->username : "",
- e->hostname ? e->hostname : "",
+ e->username[0] ? e->username : "",
+ e->hostname[0] ? e->hostname : "",
e->realname ? e->realname : "");
if (mode)
silc_free(mode);
case SILC_COMMAND_BAN:
{
SilcChannelEntry channel;
- SilcBuffer payload;
- SilcArgumentPayload ban_list;
- SilcUInt16 argc;
+ SilcArgumentPayload invite_list;
- if (!success)
+ if (SILC_STATUS_IS_ERROR(status))
return;
channel = va_arg(vp, SilcChannelEntry);
- payload = va_arg(vp, SilcBuffer);
-
- if (payload) {
- SILC_GET16_MSB(argc, payload->data);
- ban_list = silc_argument_payload_parse(payload->data + 2,
- payload->len - 2, argc);
- if (ban_list) {
- silc_parse_inviteban_list(client, conn, server, channel,
- "ban", ban_list);
- silc_argument_payload_free(ban_list);
- }
- }
+ invite_list = va_arg(vp, SilcArgumentPayload);
+
+ if (invite_list)
+ silc_parse_inviteban_list(client, conn, server, channel,
+ "ban", invite_list);
}
break;
SilcIdType id_type;
void *entry;
SilcPublicKey public_key;
- unsigned char *pk;
- SilcUInt32 pk_len;
GetkeyContext getkey;
char *name;
- if (!success)
+ if (SILC_STATUS_IS_ERROR(status)) {
+ silc_say_error("GETKEY: %s", silc_get_status_message(status));
return;
+ }
id_type = va_arg(vp, SilcUInt32);
entry = va_arg(vp, void *);
public_key = va_arg(vp, SilcPublicKey);
if (public_key) {
- pk = silc_pkcs_public_key_encode(public_key, &pk_len);
-
getkey = silc_calloc(1, sizeof(*getkey));
getkey->entry = entry;
getkey->id_type = id_type;
getkey->client = client;
getkey->conn = conn;
- getkey->fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
name = (id_type == SILC_ID_CLIENT ?
((SilcClientEntry)entry)->nickname :
silc_verify_public_key_internal(client, conn, name,
(id_type == SILC_ID_CLIENT ?
- SILC_SOCKET_TYPE_CLIENT :
- SILC_SOCKET_TYPE_SERVER),
- pk, pk_len, SILC_SKE_PK_TYPE_SILC,
- silc_getkey_cb, getkey);
- silc_free(pk);
+ SILC_CONN_CLIENT :
+ SILC_CONN_SERVER),
+ public_key, silc_getkey_cb, getkey);
} else {
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_PUBKEY_NOKEY);
char *server_name;
char *server_info;
- if (!success)
+ if (SILC_STATUS_IS_ERROR(status))
return;
server_entry = va_arg(vp, SilcServerEntry);
char *topic;
char tmp[256], *cp, *dm = NULL;
- if (!success)
+ if (SILC_STATUS_IS_ERROR(status))
return;
channel = va_arg(vp, SilcChannelEntry);
case SILC_COMMAND_STATS:
{
- SilcUInt32 starttime, uptime, my_clients, my_channels, my_server_ops,
- my_router_ops, cell_clients, cell_channels, cell_servers,
- clients, channels, servers, routers, server_ops, router_ops;
- SilcUInt32 buf_len;
- SilcBufferStruct buf;
- unsigned char *tmp_buf;
+ SilcClientStats *cstats;
char tmp[40];
const char *tmptime;
int days, hours, mins, secs;
- if (!success)
+ if (SILC_STATUS_IS_ERROR(status))
return;
- tmp_buf = va_arg(vp, unsigned char *);
- buf_len = va_arg(vp, SilcUInt32);
-
- if (!tmp_buf || !buf_len) {
+ cstats = va_arg(vp, SilcClientStats *);
+ if (!cstats) {
printtext(server, NULL, MSGLEVEL_CRAP, "No statistics available");
return;
}
- /* Get statistics structure */
- silc_buffer_set(&buf, tmp_buf, buf_len);
- silc_buffer_unformat(&buf,
- SILC_STR_UI_INT(&starttime),
- SILC_STR_UI_INT(&uptime),
- SILC_STR_UI_INT(&my_clients),
- SILC_STR_UI_INT(&my_channels),
- SILC_STR_UI_INT(&my_server_ops),
- SILC_STR_UI_INT(&my_router_ops),
- SILC_STR_UI_INT(&cell_clients),
- SILC_STR_UI_INT(&cell_channels),
- SILC_STR_UI_INT(&cell_servers),
- SILC_STR_UI_INT(&clients),
- SILC_STR_UI_INT(&channels),
- SILC_STR_UI_INT(&servers),
- SILC_STR_UI_INT(&routers),
- SILC_STR_UI_INT(&server_ops),
- SILC_STR_UI_INT(&router_ops),
- SILC_STR_END);
-
- tmptime = silc_get_time(starttime);
+ tmptime = silc_time_string(cstats->starttime);
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_STATS,
"Local server start time", tmptime);
- days = uptime / (24 * 60 * 60);
- uptime -= days * (24 * 60 * 60);
- hours = uptime / (60 * 60);
- uptime -= hours * (60 * 60);
- mins = uptime / 60;
- uptime -= mins * 60;
- secs = uptime;
+ days = cstats->uptime / (24 * 60 * 60);
+ cstats->uptime -= days * (24 * 60 * 60);
+ hours = cstats->uptime / (60 * 60);
+ cstats->uptime -= hours * (60 * 60);
+ mins = cstats->uptime / 60;
+ cstats->uptime -= mins * 60;
+ secs = cstats->uptime;
snprintf(tmp, sizeof(tmp) - 1, "%d days %d hours %d mins %d secs",
days, hours, mins, secs);
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_STATS,
"Local server uptime", tmp);
- snprintf(tmp, sizeof(tmp) - 1, "%d", (int)my_clients);
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cstats->my_clients);
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_STATS,
"Local server clients", tmp);
- snprintf(tmp, sizeof(tmp) - 1, "%d", (int)my_channels);
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cstats->my_channels);
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_STATS,
"Local server channels", tmp);
- snprintf(tmp, sizeof(tmp) - 1, "%d", (int)my_server_ops);
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cstats->my_server_ops);
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_STATS,
"Local server operators", tmp);
- snprintf(tmp, sizeof(tmp) - 1, "%d", (int)my_router_ops);
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cstats->my_router_ops);
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_STATS,
"Local router operators", tmp);
- snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cell_clients);
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cstats->cell_clients);
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_STATS,
"Local cell clients", tmp);
- snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cell_channels);
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cstats->cell_channels);
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_STATS,
"Local cell channels", tmp);
- snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cell_servers);
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cstats->cell_servers);
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_STATS,
"Local cell servers", tmp);
- snprintf(tmp, sizeof(tmp) - 1, "%d", (int)clients);
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cstats->clients);
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_STATS,
"Total clients", tmp);
- snprintf(tmp, sizeof(tmp) - 1, "%d", (int)channels);
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cstats->channels);
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_STATS,
"Total channels", tmp);
- snprintf(tmp, sizeof(tmp) - 1, "%d", (int)servers);
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cstats->servers);
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_STATS,
"Total servers", tmp);
- snprintf(tmp, sizeof(tmp) - 1, "%d", (int)routers);
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cstats->routers);
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_STATS,
"Total routers", tmp);
- snprintf(tmp, sizeof(tmp) - 1, "%d", (int)server_ops);
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cstats->server_ops);
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_STATS,
"Total server operators", tmp);
- snprintf(tmp, sizeof(tmp) - 1, "%d", (int)router_ops);
+ snprintf(tmp, sizeof(tmp) - 1, "%d", (int)cstats->router_ops);
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_STATS,
"Total router operators", tmp);
case SILC_COMMAND_CMODE:
{
SilcChannelEntry channel_entry;
- SilcBuffer channel_pubkeys;
+ SilcDList chpks;
channel_entry = va_arg(vp, SilcChannelEntry);
(void)va_arg(vp, SilcUInt32);
(void)va_arg(vp, SilcPublicKey);
- channel_pubkeys = va_arg(vp, SilcBuffer);
+ chpks = va_arg(vp, SilcDList);
- if (!success || !cmode_list_chpks ||
+ if (SILC_STATUS_IS_ERROR(status) || !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);
+ if (chpks)
+ silc_parse_channel_public_keys(server, channel_entry, chpks);
else
printformat_module("fe-common/silc", server, NULL,
MSGLEVEL_CRAP, SILCTXT_CHANNEL_PK_NO_LIST,
case SILC_COMMAND_LEAVE:
{
- /* we might be cycling, so disable queueing again */
+ if (SILC_STATUS_IS_ERROR(status))
+ return;
+
+ /* We might be cycling, so disable queueing again */
silc_queue_disable(conn);
}
break;
- }
+ case SILC_COMMAND_DETACH:
+ {
+ /* Save the detachment data to file. */
+ char *file;
+ SilcBuffer detach;
+
+ if (SILC_STATUS_IS_ERROR(status))
+ return;
- va_end(vp);
+ detach = va_arg(vp, SilcBuffer);
+ file = silc_get_session_filename(server);
+ silc_file_writefile(file, silc_buffer_data(detach),
+ silc_buffer_len(detach));
+ silc_free(file);
+ }
+ break;
+
+ case SILC_COMMAND_KILL:
+ {
+ SilcClientEntry client_entry;
+
+ if (SILC_STATUS_IS_ERROR(status)) {
+ silc_say_error("KILL: %s", silc_get_status_message(status));
+ return;
+ }
+
+ client_entry = va_arg(vp, SilcClientEntry);
+ if (!client_entry || !client_entry->nickname[0])
+ break;
+
+ /* Print this only if the killed client isn't joined on channels.
+ If it is, we receive KILLED notify and we'll print this there. */
+ if (!silc_hash_table_count(client_entry->channels))
+ printformat_module("fe-common/silc", server, NULL,
+ MSGLEVEL_CRAP, SILCTXT_CHANNEL_KILLED,
+ client_entry->nickname,
+ conn->local_entry->nickname, "");
+ }
+ }
}
typedef struct {
char *filename;
char *entity;
char *entity_name;
- unsigned char *pk;
- SilcUInt32 pk_len;
- SilcSKEPKType pk_type;
+ SilcPublicKey public_key;
SilcVerifyPublicKey completion;
void *context;
} *PublicKeyVerify;
verify->completion(TRUE, verify->context);
/* Save the key for future checking */
- silc_pkcs_save_public_key_data(verify->filename, verify->pk,
- verify->pk_len, SILC_PKCS_FILE_PEM);
+ silc_pkcs_save_public_key(verify->filename, verify->public_key,
+ SILC_PKCS_FILE_BASE64);
} else {
/* Call the completion */
if (verify->completion)
silc_free(verify->filename);
silc_free(verify->entity);
silc_free(verify->entity_name);
- silc_free(verify->pk);
silc_free(verify);
}
static void
silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
- const char *name, SilcSocketType conn_type,
- unsigned char *pk, SilcUInt32 pk_len,
- SilcSKEPKType pk_type,
+ const char *name,
+ SilcConnectionType conn_type,
+ SilcPublicKey public_key,
SilcVerifyPublicKey completion, void *context)
{
- int i;
+ PublicKeyVerify verify;
char file[256], filename[256], filename2[256], *ipf, *hostf = NULL;
char *fingerprint, *babbleprint, *format;
+ SilcPublicKey local_pubkey;
+ SilcSILCPublicKey silc_pubkey;
+ SilcUInt16 port;
+ const char *hostname, *ip;
+ unsigned char *pk;
+ SilcUInt32 pk_len;
struct passwd *pw;
struct stat st;
- char *entity = ((conn_type == SILC_SOCKET_TYPE_SERVER ||
- conn_type == SILC_SOCKET_TYPE_ROUTER) ?
+ char *entity = ((conn_type == SILC_CONN_SERVER ||
+ conn_type == SILC_CONN_ROUTER) ?
"server" : "client");
- PublicKeyVerify verify;
+ int i;
- if (pk_type != SILC_SKE_PK_TYPE_SILC) {
+ if (silc_pkcs_get_type(public_key) != SILC_PKCS_SILC) {
printformat_module("fe-common/silc", NULL, NULL,
MSGLEVEL_CRAP, SILCTXT_PUBKEY_UNSUPPORTED,
- entity, pk_type);
+ entity, silc_pkcs_get_type(public_key));
+ if (completion)
+ completion(FALSE, context);
+ return;
+ }
+
+ /* Encode public key */
+ pk = silc_pkcs_public_key_encode(public_key, &pk_len);
+ if (!pk) {
if (completion)
completion(FALSE, context);
return;
}
+ silc_pubkey = silc_pkcs_get_context(SILC_PKCS_SILC, public_key);
+
pw = getpwuid(getuid());
if (!pw) {
if (completion)
completion(FALSE, context);
+ silc_free(pk);
return;
}
memset(filename2, 0, sizeof(filename2));
memset(file, 0, sizeof(file));
- if (conn_type == SILC_SOCKET_TYPE_SERVER ||
- conn_type == SILC_SOCKET_TYPE_ROUTER) {
+ /* Get remote host information */
+ silc_socket_stream_get_info(silc_packet_stream_get_stream(conn->stream),
+ NULL, &hostname, &ip, &port);
+
+ if (conn_type == SILC_CONN_SERVER ||
+ conn_type == SILC_CONN_ROUTER) {
if (!name) {
- snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
- conn->sock->ip, conn->sock->port);
+ snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity, ip, port);
snprintf(filename, sizeof(filename) - 1, "%s/%skeys/%s",
get_irssi_dir(), entity, file);
snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
- conn->sock->hostname, conn->sock->port);
+ hostname, port);
snprintf(filename2, sizeof(filename2) - 1, "%s/%skeys/%s",
get_irssi_dir(), entity, file);
hostf = filename2;
} else {
snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
- name, conn->sock->port);
+ name, port);
snprintf(filename, sizeof(filename) - 1, "%s/%skeys/%s",
get_irssi_dir(), entity, file);
verify->conn = conn;
verify->filename = strdup(ipf);
verify->entity = strdup(entity);
- verify->entity_name = (conn_type != SILC_SOCKET_TYPE_CLIENT ?
- (name ? strdup(name) : strdup(conn->sock->hostname))
+ verify->entity_name = (conn_type != SILC_CONN_CLIENT ?
+ (name ? strdup(name) : strdup(hostname))
: NULL);
- verify->pk = silc_memdup(pk, pk_len);
- verify->pk_len = pk_len;
- verify->pk_type = pk_type;
+ verify->public_key = public_key;
verify->completion = completion;
verify->context = context;
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_RECEIVED,verify->entity_name ?
verify->entity_name : entity);
+ if (conn_type == SILC_CONN_CLIENT && name &&
+ silc_pubkey->identifier.realname)
+ printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+ SILCTXT_PUBKEY_RECEIVED_CLIENT, name,
+ silc_pubkey->identifier.realname,
+ silc_pubkey->identifier.email ?
+ silc_pubkey->identifier.email : "");
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
format, 0, verify);
g_free(format);
silc_free(fingerprint);
+ silc_free(babbleprint);
+ silc_free(pk);
return;
} else {
/* The key already exists, verify it. */
- SilcPublicKey public_key;
unsigned char *encpk;
SilcUInt32 encpk_len;
/* Load the key file, try for both IP filename and hostname filename */
- if (!silc_pkcs_load_public_key(ipf, &public_key,
- SILC_PKCS_FILE_PEM) &&
- !silc_pkcs_load_public_key(ipf, &public_key,
- SILC_PKCS_FILE_BIN) &&
- (!hostf || (!silc_pkcs_load_public_key(hostf, &public_key,
- SILC_PKCS_FILE_PEM) &&
- !silc_pkcs_load_public_key(hostf, &public_key,
- SILC_PKCS_FILE_BIN)))) {
+ if (!silc_pkcs_load_public_key(ipf, &local_pubkey) &&
+ (!hostf || (!silc_pkcs_load_public_key(hostf, &local_pubkey)))) {
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_RECEIVED,verify->entity_name ?
verify->entity_name : entity);
+ if (conn_type == SILC_CONN_CLIENT && name &&
+ silc_pubkey->identifier.realname)
+ printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+ SILCTXT_PUBKEY_RECEIVED_CLIENT, name,
+ silc_pubkey->identifier.realname,
+ silc_pubkey->identifier.email ?
+ silc_pubkey->identifier.email : "");
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
format, 0, verify);
g_free(format);
silc_free(fingerprint);
+ silc_free(babbleprint);
+ silc_free(pk);
return;
}
/* Encode the key data */
- encpk = silc_pkcs_public_key_encode(public_key, &encpk_len);
+ encpk = silc_pkcs_public_key_encode(local_pubkey, &encpk_len);
if (!encpk) {
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_RECEIVED,verify->entity_name ?
verify->entity_name : entity);
+ if (conn_type == SILC_CONN_CLIENT && name &&
+ silc_pubkey->identifier.realname)
+ printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+ SILCTXT_PUBKEY_RECEIVED_CLIENT, name,
+ silc_pubkey->identifier.realname,
+ silc_pubkey->identifier.email ?
+ silc_pubkey->identifier.email : "");
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
format, 0, verify);
g_free(format);
silc_free(fingerprint);
+ silc_free(babbleprint);
+ silc_free(pk);
return;
}
+ silc_pkcs_public_key_free(local_pubkey);
/* Compare the keys */
if (memcmp(encpk, pk, encpk_len)) {
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_RECEIVED,verify->entity_name ?
verify->entity_name : entity);
+ if (conn_type == SILC_CONN_CLIENT && name &&
+ silc_pubkey->identifier.realname)
+ printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+ SILCTXT_PUBKEY_RECEIVED_CLIENT, name,
+ silc_pubkey->identifier.realname,
+ silc_pubkey->identifier.email ?
+ silc_pubkey->identifier.email : "");
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
format, 0, verify);
g_free(format);
silc_free(fingerprint);
+ silc_free(babbleprint);
+ silc_free(encpk);
+ silc_free(pk);
return;
}
/* Local copy matched */
if (completion)
completion(TRUE, context);
+ silc_free(encpk);
silc_free(fingerprint);
+ silc_free(babbleprint);
silc_free(verify->filename);
silc_free(verify->entity);
silc_free(verify->entity_name);
- silc_free(verify->pk);
silc_free(verify);
+ silc_free(pk);
}
}
void
silc_verify_public_key(SilcClient client, SilcClientConnection conn,
- SilcSocketType conn_type, unsigned char *pk,
- SilcUInt32 pk_len, SilcSKEPKType pk_type,
+ SilcConnectionType conn_type,
+ SilcPublicKey public_key,
SilcVerifyPublicKey completion, void *context)
{
- silc_verify_public_key_internal(client, conn, NULL, conn_type, pk,
- pk_len, pk_type,
+ silc_verify_public_key_internal(client, conn, NULL, conn_type, public_key,
completion, context);
}
typedef struct {
SilcGetAuthMeth completion;
void *context;
-} *InternalGetAuthMethod;
+} *GetAuthMethod;
-/* Callback called when we've received the authentication method information
- from the server after we've requested it. This will get the authentication
- data from the user if needed. */
-
-static void silc_get_auth_method_callback(SilcClient client,
- SilcClientConnection conn,
- SilcAuthMethod auth_meth,
- void *context)
+static void silc_get_auth_ask_passphrase(const unsigned char *passphrase,
+ SilcUInt32 passphrase_len,
+ void *context)
{
- InternalGetAuthMethod internal = (InternalGetAuthMethod)context;
-
- SILC_LOG_DEBUG(("Start"));
-
- switch (auth_meth) {
- case SILC_AUTH_NONE:
- /* No authentication required. */
- (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
- break;
- case SILC_AUTH_PASSWORD:
- {
- /* Check whether we find the password for this server in our
- configuration. If not, then don't provide so library will ask
- it from the user. */
- SERVER_SETUP_REC *setup = server_setup_find_port(conn->remote_host,
- conn->remote_port);
- if (!setup || !setup->password) {
- (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
- break;
- }
-
- (*internal->completion)(TRUE, auth_meth, setup->password,
- strlen(setup->password), internal->context);
- }
- break;
- case SILC_AUTH_PUBLIC_KEY:
- /* Do not get the authentication data now, the library will generate
- it using our default key, if we do not provide it here. */
- /* XXX In the future when we support multiple local keys and multiple
- local certificates we will need to ask from user which one to use. */
- (*internal->completion)(TRUE, auth_meth, NULL, 0, internal->context);
- break;
- }
-
- silc_free(internal);
+ GetAuthMethod a = context;
+ a->completion(passphrase ? SILC_AUTH_PASSWORD : SILC_AUTH_NONE,
+ passphrase, passphrase_len, a->context);
+ silc_free(a);
}
-/* Find authentication method and authentication data by hostname and
- port. The hostname may be IP address as well. The found authentication
- method and authentication data is returned to `auth_meth', `auth_data'
- and `auth_data_len'. The function returns TRUE if authentication method
- is found and FALSE if not. `conn' may be NULL. */
+/* Find authentication data by hostname and port. The hostname may be IP
+ address as well.*/
void silc_get_auth_method(SilcClient client, SilcClientConnection conn,
char *hostname, SilcUInt16 port,
+ SilcAuthMethod auth_meth,
SilcGetAuthMeth completion, void *context)
{
- InternalGetAuthMethod internal;
+ SERVER_SETUP_REC *setup;
SILC_LOG_DEBUG(("Start"));
- /* If we do not have this connection configured by the user in a
- configuration file then resolve the authentication method from the
- server for this session. */
- internal = silc_calloc(1, sizeof(*internal));
- internal->completion = completion;
- internal->context = context;
-
- silc_client_request_authentication_method(client, conn,
- silc_get_auth_method_callback,
- internal);
-}
-
-/* Notifies application that failure packet was received. This is called
- if there is some protocol active in the client. The `protocol' is the
- protocol context. The `failure' is opaque pointer to the failure
- indication. Note, that the `failure' is protocol dependant and application
- must explicitly cast it to correct type. Usually `failure' is 32 bit
- failure type (see protocol specs for all protocol failure types). */
-
-void silc_failure(SilcClient client, SilcClientConnection conn,
- SilcProtocol protocol, void *failure)
-{
- SILC_LOG_DEBUG(("Start"));
-
- if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_KEY_EXCHANGE) {
- SilcSKEStatus status = (SilcSKEStatus)failure;
-
- if (status == SILC_SKE_STATUS_BAD_VERSION)
- printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_KE_BAD_VERSION);
- if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY)
- printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_KE_UNSUPPORTED_PUBLIC_KEY);
- if (status == SILC_SKE_STATUS_UNKNOWN_GROUP)
- printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_KE_UNKNOWN_GROUP);
- if (status == SILC_SKE_STATUS_UNKNOWN_CIPHER)
- printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_KE_UNKNOWN_CIPHER);
- if (status == SILC_SKE_STATUS_UNKNOWN_PKCS)
- printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_KE_UNKNOWN_PKCS);
- if (status == SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION)
- printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_KE_UNKNOWN_HASH_FUNCTION);
- if (status == SILC_SKE_STATUS_UNKNOWN_HMAC)
- printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_KE_UNKNOWN_HMAC);
- if (status == SILC_SKE_STATUS_INCORRECT_SIGNATURE)
- printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_KE_INCORRECT_SIGNATURE);
- if (status == SILC_SKE_STATUS_INVALID_COOKIE)
- printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_KE_INVALID_COOKIE);
+ if (auth_meth == SILC_AUTH_PUBLIC_KEY) {
+ /* Returning NULL will cause library to use our private key configured
+ for this connection */
+ completion(SILC_AUTH_PUBLIC_KEY, NULL, 0, context);
+ return;
}
- if (protocol->protocol->type == SILC_PROTOCOL_CLIENT_CONNECTION_AUTH) {
- SilcUInt32 err = (SilcUInt32)failure;
+ /* Check whether we find the password for this server in our
+ configuration. If it's set, always send it server. */
+ setup = server_setup_find_port(hostname, port);
+ if (setup && setup->password) {
+ completion(SILC_AUTH_PASSWORD, setup->password, strlen(setup->password),
+ context);
+ return;
+ }
- if (err == SILC_AUTH_FAILED)
- printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_AUTH_FAILED);
+ /* Didn't find password. If server wants it, ask it from user. */
+ if (auth_meth == SILC_AUTH_PASSWORD) {
+ GetAuthMethod a;
+ a = silc_calloc(1, sizeof(*a));
+ if (a) {
+ a->completion = completion;
+ a->context = context;
+ silc_ask_passphrase(client, conn, silc_get_auth_ask_passphrase, a);
+ return;
+ }
}
+
+ /* No authentication */
+ completion(SILC_AUTH_NONE, NULL, 0, context);
}
/* Asks whether the user would like to perform the key agreement protocol.
desired (application may start it later by calling the function
silc_client_perform_key_agreement). */
-bool silc_key_agreement(SilcClient client, SilcClientConnection conn,
+void silc_key_agreement(SilcClient client, SilcClientConnection conn,
SilcClientEntry client_entry, const char *hostname,
- SilcUInt16 port, SilcKeyAgreementCallback *completion,
- void **context)
+ SilcUInt16 protocol, SilcUInt16 port)
{
- char portstr[12];
+ char portstr[12], protostr[5];
SILC_LOG_DEBUG(("Start"));
/* We will just display the info on the screen and return FALSE and user
will have to start the key agreement with a command. */
- if (hostname)
+ if (hostname) {
snprintf(portstr, sizeof(portstr) - 1, "%d", port);
+ snprintf(protostr, sizeof(protostr) - 1, "%s", protocol == 1 ? "UDP" :
+ "TCP");
+ }
if (!hostname)
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
else
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_KEY_AGREEMENT_REQUEST_HOST,
- client_entry->nickname, hostname, portstr);
-
- *completion = NULL;
- *context = NULL;
-
- return FALSE;
+ client_entry->nickname, hostname, portstr, protostr);
}
/* Notifies application that file transfer protocol session is being
client_entry->nickname, hostname, portstr);
}
-/* Delivers SILC session detachment data indicated by `detach_data' to the
- application. If application has issued SILC_COMMAND_DETACH command
- the client session in the SILC network is not quit. The client remains
- in the network but is detached. The detachment data may be used later
- to resume the session in the SILC Network. The appliation is
- responsible of saving the `detach_data', to for example in a file.
-
- The detachment data can be given as argument to the functions
- silc_client_connect_to_server, or silc_client_add_connection when
- creating connection to remote server, inside SilcClientConnectionParams
- structure. If it is provided the client library will attempt to resume
- the session in the network. After the connection is created
- successfully, the application is responsible of setting the user
- interface for user into the same state it was before detaching (showing
- same channels, channel modes, etc). It can do this by fetching the
- information (like joined channels) from the client library. */
-
-void
-silc_detach(SilcClient client, SilcClientConnection conn,
- const unsigned char *detach_data, SilcUInt32 detach_data_len)
-{
- SILC_SERVER_REC *server = conn->context;
- char *file;
-
- /* Save the detachment data to file. */
-
- file = silc_get_session_filename(server);
- silc_file_writefile(file, detach_data, detach_data_len);
- silc_free(file);
-}
-
-
/* SILC client operations */
SilcClientOperations ops = {
silc_say,
silc_notify,
silc_command,
silc_command_reply,
- silc_connect,
- silc_disconnect,
silc_get_auth_method,
silc_verify_public_key,
silc_ask_passphrase,
- silc_failure,
silc_key_agreement,
silc_ftp,
- silc_detach,
};