static void
silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
- SilcSocketType conn_type, unsigned char *pk,
- uint32 pk_len, SilcSKEPKType pk_type,
+ const char *name, SilcSocketType conn_type,
+ unsigned char *pk, uint32 pk_len,
+ SilcSKEPKType pk_type,
SilcVerifyPublicKey completion, void *context);
void silc_say(SilcClient client, SilcClientConnection conn,
nick = silc_nicklist_find(chanrec, sender);
if (!nick) {
- /* We didn't find client but it clearly exists, add it. It must be
- found on the channel->clients list. */
- SilcChannelUser chu;
-
- silc_list_start(channel->clients);
- while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
- if (chu->client == sender) {
- nick = silc_nicklist_insert(chanrec, chu, FALSE);
- break;
- }
- }
+ /* We didn't find client but it clearly exists, add it. */
+ SilcChannelUser chu = silc_client_on_channel(channel, sender);
+ if (chu)
+ nick = silc_nicklist_insert(chanrec, chu, FALSE);
}
if (flags & SILC_MESSAGE_FLAG_ACTION)
signal_emit("event connected", 1, server);
} else {
server->connection_lost = TRUE;
- server->conn->context = NULL;
+ if (server->conn)
+ server->conn->context = NULL;
server_disconnect(SERVER(server));
}
}
void *context)
{
SilcChannelEntry channel = (SilcChannelEntry)context;
+ SilcHashTableList htl;
SilcChannelUser chu;
SILC_SERVER_REC *server = conn->context;
SILC_CHANNEL_REC *chanrec;
if (chanrec == NULL)
return;
- silc_list_start(channel->clients);
- while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
+ 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);
case SILC_COMMAND_USERS:
{
+ SilcHashTableList htl;
SilcChannelEntry channel;
SilcChannelUser chu;
MSGLEVEL_CRAP, SILCTXT_USERS_HEADER,
channel->channel_name);
- silc_list_start(channel->clients);
- while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
+ silc_hash_table_list(channel->user_list, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void *)&chu)) {
SilcClientEntry e = chu->client;
char stat[5], *mode;
if (mode)
silc_free(mode);
}
+ silc_hash_table_list_reset(&htl);
}
break;
unsigned char *pk;
uint32 pk_len;
GetkeyContext getkey;
+ char *name;
if (!success)
return;
getkey->client = client;
getkey->conn = conn;
getkey->fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
-
- silc_verify_public_key_internal(client, conn,
+
+ name = (id_type == SILC_ID_CLIENT ?
+ ((SilcClientEntry)entry)->nickname :
+ ((SilcServerEntry)entry)->server_name);
+
+ silc_verify_public_key_internal(client, conn, name,
(id_type == SILC_ID_CLIENT ?
SILC_SOCKET_TYPE_CLIENT :
SILC_SOCKET_TYPE_SERVER),
va_end(vp);
}
-/* Internal routine to verify public key. If the `completion' is provided
- it will be called to indicate whether public was verified or not. */
-
typedef struct {
SilcClient client;
SilcClientConnection conn;
char *filename;
char *entity;
+ char *entity_name;
unsigned char *pk;
uint32 pk_len;
SilcSKEPKType pk_type;
verify->completion(FALSE, verify->context);
printformat_module("fe-common/silc", NULL, NULL,
- MSGLEVEL_CRAP, SILCTXT_PUBKEY_DISCARD, verify->entity);
+ MSGLEVEL_CRAP, SILCTXT_PUBKEY_DISCARD,
+ verify->entity_name ? verify->entity_name :
+ verify->entity);
}
silc_free(verify->filename);
silc_free(verify->entity);
+ silc_free(verify->entity_name);
silc_free(verify->pk);
silc_free(verify);
}
+/* Internal routine to verify public key. If the `completion' is provided
+ it will be called to indicate whether public was verified or not. For
+ server/router public key this will check for filename that includes the
+ remote host's IP address and remote host's hostname. */
+
static void
silc_verify_public_key_internal(SilcClient client, SilcClientConnection conn,
- SilcSocketType conn_type, unsigned char *pk,
- uint32 pk_len, SilcSKEPKType pk_type,
+ const char *name, SilcSocketType conn_type,
+ unsigned char *pk, uint32 pk_len,
+ SilcSKEPKType pk_type,
SilcVerifyPublicKey completion, void *context)
{
int i;
- char file[256], filename[256], *fingerprint, *babbleprint, *format;
+ char file[256], filename[256], filename2[256], *ipf, *hostf = NULL;
+ char *fingerprint, *babbleprint, *format;
struct passwd *pw;
struct stat st;
char *entity = ((conn_type == SILC_SOCKET_TYPE_SERVER ||
}
memset(filename, 0, sizeof(filename));
+ memset(filename2, 0, sizeof(filename2));
memset(file, 0, sizeof(file));
if (conn_type == SILC_SOCKET_TYPE_SERVER ||
conn_type == SILC_SOCKET_TYPE_ROUTER) {
- snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
- conn->sock->ip, conn->sock->port);
- snprintf(filename, sizeof(filename) - 1, "%s/.silc/%skeys/%s",
- pw->pw_dir, entity, file);
+ if (!name) {
+ snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
+ conn->sock->ip, conn->sock->port);
+ snprintf(filename, sizeof(filename) - 1, "%s/.silc/%skeys/%s",
+ pw->pw_dir, entity, file);
+
+ snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
+ conn->sock->hostname, conn->sock->port);
+ snprintf(filename2, sizeof(filename2) - 1, "%s/.silc/%skeys/%s",
+ pw->pw_dir, entity, file);
+
+ ipf = filename;
+ hostf = filename2;
+ } else {
+ snprintf(file, sizeof(file) - 1, "%skey_%s_%d.pub", entity,
+ name, conn->sock->port);
+ snprintf(filename, sizeof(filename) - 1, "%s/.silc/%skeys/%s",
+ pw->pw_dir, entity, file);
+
+ ipf = filename;
+ }
} else {
/* Replace all whitespaces with `_'. */
fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
snprintf(filename, sizeof(filename) - 1, "%s/.silc/%skeys/%s",
pw->pw_dir, entity, file);
silc_free(fingerprint);
+
+ ipf = filename;
}
/* Take fingerprint of the public key */
verify = silc_calloc(1, sizeof(*verify));
verify->client = client;
verify->conn = conn;
- verify->filename = strdup(filename);
+ verify->filename = strdup(ipf);
verify->entity = strdup(entity);
+ verify->entity_name = (conn_type != SILC_SOCKET_TYPE_CLIENT ?
+ (name ? strdup(name) : strdup(conn->sock->hostname))
+ : NULL);
verify->pk = silc_calloc(pk_len, sizeof(*verify->pk));
memcpy(verify->pk, pk, pk_len);
verify->pk_len = pk_len;
verify->context = context;
/* Check whether this key already exists */
- if (stat(filename, &st) < 0) {
+ if (stat(ipf, &st) < 0 && (!hostf || stat(hostf, &st) < 0)) {
/* Key does not exist, ask user to verify the key and save it */
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_PUBKEY_RECEIVED, entity);
+ SILCTXT_PUBKEY_RECEIVED,verify->entity_name ?
+ verify->entity_name : entity);
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
unsigned char *encpk;
uint32 encpk_len;
- /* Load the key file */
- if (!silc_pkcs_load_public_key(filename, &public_key,
- SILC_PKCS_FILE_PEM))
- if (!silc_pkcs_load_public_key(filename, &public_key,
- SILC_PKCS_FILE_BIN)) {
- printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_PUBKEY_RECEIVED, entity);
- printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
- printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_PUBKEY_BABBLEPRINT, babbleprint);
- printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_PUBKEY_COULD_NOT_LOAD, entity);
- format = format_get_text("fe-common/silc", NULL, NULL, NULL,
- SILCTXT_PUBKEY_ACCEPT_ANYWAY);
- keyboard_entry_redirect((SIGNAL_FUNC)verify_public_key_completion,
- format, 0, verify);
- g_free(format);
- silc_free(fingerprint);
- return;
- }
-
+ /* 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)))) {
+ printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+ SILCTXT_PUBKEY_RECEIVED,verify->entity_name ?
+ verify->entity_name : entity);
+ printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+ SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
+ printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+ SILCTXT_PUBKEY_BABBLEPRINT, babbleprint);
+ printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
+ SILCTXT_PUBKEY_COULD_NOT_LOAD, entity);
+ format = format_get_text("fe-common/silc", NULL, NULL, NULL,
+ SILCTXT_PUBKEY_ACCEPT_ANYWAY);
+ keyboard_entry_redirect((SIGNAL_FUNC)verify_public_key_completion,
+ format, 0, verify);
+ g_free(format);
+ silc_free(fingerprint);
+ return;
+ }
+
/* Encode the key data */
encpk = silc_pkcs_public_key_encode(public_key, &encpk_len);
if (!encpk) {
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_PUBKEY_RECEIVED, entity);
+ SILCTXT_PUBKEY_RECEIVED,verify->entity_name ?
+ verify->entity_name : entity);
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
/* Compare the keys */
if (memcmp(encpk, pk, encpk_len)) {
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
- SILCTXT_PUBKEY_RECEIVED, entity);
+ SILCTXT_PUBKEY_RECEIVED,verify->entity_name ?
+ verify->entity_name : entity);
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
SILCTXT_PUBKEY_FINGERPRINT, entity, fingerprint);
printformat_module("fe-common/silc", NULL, NULL, MSGLEVEL_CRAP,
uint32 pk_len, SilcSKEPKType pk_type,
SilcVerifyPublicKey completion, void *context)
{
- silc_verify_public_key_internal(client, conn, conn_type, pk,
+ silc_verify_public_key_internal(client, conn, NULL, conn_type, pk,
pk_len, pk_type,
completion, context);
}