From ea1378b9634fa68df8fcdf1f50b6d90609137a85 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Mon, 2 Apr 2001 10:24:13 +0000 Subject: [PATCH] updates. --- CHANGES | 2 +- TODO | 54 ++++++--------------------------- apps/silcd/command.c | 2 +- apps/silcd/command_reply.c | 7 ++--- apps/silcd/idlist.c | 2 ++ apps/silcd/idlist.h | 13 ++++++++ apps/silcd/server.c | 62 ++++++++++++++++++++++++++++++++++++-- lib/silcutil/silctask.c | 22 ++++++++++++++ lib/silcutil/silctask.h | 1 + 9 files changed, 111 insertions(+), 54 deletions(-) diff --git a/CHANGES b/CHANGES index 0755122a..8fb8dede 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,4 @@ -Mon Apr 2 15:13:23 EEST 2001 Pekka Riikonen +Mon Apr 2 13:13:23 EEST 2001 Pekka Riikonen * Updated TODO. diff --git a/TODO b/TODO index 27988137..13beb86d 100644 --- a/TODO +++ b/TODO @@ -1,17 +1,3 @@ -TODO -==== - -This is more or less complete list of tasks that has to be done before -SILC 1.0 could ever be released. It is clear that the list does not -include all the bugs that exists. At the end of list are tasks that -needs to be done but are probably post 1.0. - -Feel free to contribute if you have the ability and free time - all the -help is really appreciated - and needed. - - - Pekka - - TODO General ============ @@ -32,20 +18,9 @@ TODO In SILC Client Library the SilcSocketConnection reference counter at all. This must be fixed. - o Logic for handling multiple same nicknames for example in private - message sending. I guess the logic is done in server side but is - missing from client. - o I guess, public key authentication (when connecting to a server) is not working currently. It is just matter of loading the keys - from file and using them (see corresponding code in server, it should - support public key authentication already). - - o Non-blocking connection on the background must be stopped if some - other connection on same window has established. Now it is possible - that some non-blocking connection timeouts on the background when - we already have a working connection to some other place; things - goes bad. + from file and using them (see corresponding code in server). o Add client library parameters or options that handle what kind of messages the library should print out (using `say' client operation, @@ -75,20 +50,20 @@ TODO In SILC Server o SERVER_SIGNOFF notify type is not implemented - o Packet processing can be made faster. All packet function in the - packet_receive.c has same prototypes. Instead of calling those from - huge switch() make a table of callback functions that can be called - directly by the packet type. + o Acceptance of incoming connections (client and server connections) + should be checked before key exchange protocol. Currently it is + checked at the authentication phase after KE, that is ok, but it should + be checked before starting KE, as well. o DNS/IP lookup blocks the server. This must be fixed. Check the resolver stuff (resolver(3), resolver(5)). Either we have to do the own resolver stuff (through scheduler, if possible without writing too much own stuff) or use threads. - o Acceptance of incoming connections (client and server connections) - should be checked before key exchange protocol. Currently it is - checked at the authentication phase after KE, that is ok, but it should - be checked before starting KE, as well. + o Packet processing can be made faster. All packet function in the + packet_receive.c has same prototypes. Instead of calling those from + huge switch() make a table of callback functions that can be called + directly by the packet type. o Server says that it is able to listen on multiple ports but currently that is bogus. It can, but internals are for single server. @@ -105,10 +80,6 @@ TODO In SILC Server TODO In SILC Libraries ====================== - o The SKE Start Payload parsing routines are an overkill. Use the - SILC_STR_UI16_NSTRING_ALLOC in the parsing and not parsing them - one by one like done now. - o Implement PFS (Perfect Forward Secrecy) flag in SKE (and in client and server, actually). If PFS is set, re-key must cause new key exchange. This is required by the SILC protocol. @@ -151,13 +122,6 @@ TODO in the protocol before SILC 0.x public keys blindly without third party verification; that's why SENDKEY is not for servers). - o New features in the KE/auth protocol - (draft-riikonen-silc-ke-auth-xx.txt): - - o Define group exchange support for the SKE so that the SKE - could be performed among more than two entities. This is not - a showstopper and may be defined later. - TODO After 1.0 ============== diff --git a/apps/silcd/command.c b/apps/silcd/command.c index c317a546..75afbfd9 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -3919,7 +3919,7 @@ SILC_SERVER_CMD_FUNC(cumode) goto out; } - chl->mode |= SILC_CHANNEL_UMODE_CHANFO; + sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO; notify = TRUE; } else { if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) { diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index 79eb2bbe..588c1a0c 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -722,8 +722,8 @@ SILC_SERVER_CMD_REPLY_FUNC(join) } } else { /* The entry exists. */ - if (entry->id) - silc_free(entry->id); + if (cache->id) + silc_free(cache->id); entry->id = id; cache->id = entry->id; @@ -784,9 +784,8 @@ SILC_SERVER_CMD_REPLY_FUNC(join) entry->mode = mode; /* Save channel key */ - if (!(entry->mode & SILC_CHANNEL_MODE_PRIVKEY)) { + if (!(entry->mode & SILC_CHANNEL_MODE_PRIVKEY)) silc_server_save_channel_key(server, keyp, entry); - } if (keyp) silc_buffer_free(keyp); diff --git a/apps/silcd/idlist.c b/apps/silcd/idlist.c index 99b375e7..02f9f41e 100644 --- a/apps/silcd/idlist.c +++ b/apps/silcd/idlist.c @@ -630,6 +630,8 @@ int silc_idlist_del_channel(SilcIDList id_list, SilcChannelEntry entry) silc_free(entry->cipher); if (entry->hmac_name) silc_free(entry->hmac_name); + if (entry->rekey) + silc_free(entry->rekey); /* Free all data, free also any reference from the client's channel list since they share the same memory. */ diff --git a/apps/silcd/idlist.h b/apps/silcd/idlist.h index 57eb1d06..f36a6a63 100644 --- a/apps/silcd/idlist.h +++ b/apps/silcd/idlist.h @@ -33,6 +33,13 @@ typedef struct { void *timeout_queue; } *SilcIDListPurge; +/* Channel key re-key context. */ +typedef struct { + void *context; + SilcChannelEntry channel; + unsigned int key_len; +} *SilcServerChannelRekey; + /* Generic ID list data structure. @@ -394,6 +401,10 @@ struct SilcClientEntryStruct { HMAC of the channel. + SilcServerChannelRekey rekey + + Channel key re-key context. + */ struct SilcChannelEntryStruct { char *channel_name; @@ -426,6 +437,8 @@ struct SilcChannelEntryStruct { unsigned int key_len; unsigned char iv[SILC_CIPHER_MAX_IV_SIZE]; SilcHmac hmac; + + SilcServerChannelRekey rekey; }; /* diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 64e70fd1..b96d5043 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -2266,11 +2266,13 @@ void silc_server_remove_from_channels(SilcServer server, silc_list_count(channel->user_list) < 2) { server->stat.my_channels--; + if (channel->rekey) + silc_task_unregister_by_context(server->timeout_queue, channel->rekey); + if (channel->founder_key) { /* The founder auth data exists, do not remove the channel entry */ SilcChannelClientEntry chl2; - silc_free(channel->id); channel->id = NULL; silc_list_start(channel->user_list); @@ -2313,11 +2315,13 @@ void silc_server_remove_from_channels(SilcServer server, server->stat.my_channels--; + if (channel->rekey) + silc_task_unregister_by_context(server->timeout_queue, channel->rekey); + if (channel->founder_key) { /* The founder auth data exists, do not remove the channel entry */ SilcChannelClientEntry chl2; - silc_free(channel->id); channel->id = NULL; silc_list_start(channel->user_list); @@ -2394,6 +2398,8 @@ int silc_server_remove_from_one_channel(SilcServer server, /* Remove channel if there is no users anymore */ if (server->server_type == SILC_ROUTER && silc_list_count(channel->user_list) < 2) { + if (channel->rekey) + silc_task_unregister_by_context(server->timeout_queue, channel->rekey); if (!silc_idlist_del_channel(server->local_list, channel)) silc_idlist_del_channel(server->global_list, channel); silc_buffer_free(clidp); @@ -2425,11 +2431,13 @@ int silc_server_remove_from_one_channel(SilcServer server, server->stat.my_channels--; silc_buffer_free(clidp); + if (channel->rekey) + silc_task_unregister_by_context(server->timeout_queue, channel->rekey); + if (channel->founder_key) { /* The founder auth data exists, do not remove the channel entry */ SilcChannelClientEntry chl2; - silc_free(channel->id); channel->id = NULL; silc_list_start(channel->user_list); @@ -2622,6 +2630,23 @@ silc_server_create_new_channel_with_id(SilcServer server, return entry; } +/* Channel's key re-key timeout callback. */ + +SILC_TASK_CALLBACK(silc_server_channel_key_rekey) +{ + SilcServerChannelRekey rekey = (SilcServerChannelRekey)context; + SilcServer server = (SilcServer)rekey->context; + + silc_server_create_channel_key(server, rekey->channel, rekey->key_len); + silc_server_send_channel_key(server, NULL, rekey->channel, FALSE); + + silc_task_register(server->timeout_queue, 0, + silc_server_channel_key_rekey, + (void *)rekey, 3600, 0, + SILC_TASK_TIMEOUT, + SILC_TASK_PRI_NORMAL); +} + /* Generates new channel key. This is used to create the initial channel key but also to re-generate new key for channel. If `key_len' is provided it is the bytes of the key length. */ @@ -2676,6 +2701,22 @@ void silc_server_create_channel_key(SilcServer server, silc_hash_make(channel->hmac->hash, channel->key, len, hash); silc_hmac_set_key(channel->hmac, hash, silc_hash_len(channel->hmac->hash)); memset(hash, 0, sizeof(hash)); + + if (server->server_type == SILC_ROUTER) { + if (!channel->rekey) + channel->rekey = silc_calloc(1, sizeof(*channel->rekey)); + channel->rekey->context = (void *)server; + channel->rekey->channel = channel; + channel->rekey->key_len = key_len; + + silc_task_unregister_by_callback(server->timeout_queue, + silc_server_channel_key_rekey); + silc_task_register(server->timeout_queue, 0, + silc_server_channel_key_rekey, + (void *)channel->rekey, 3600, 0, + SILC_TASK_TIMEOUT, + SILC_TASK_PRI_NORMAL); + } } /* Saves the channel key found in the encoded `key_payload' buffer. This @@ -2767,6 +2808,21 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server, memset(hash, 0, sizeof(hash)); memset(tmp, 0, tmp_len); + if (server->server_type == SILC_ROUTER) { + if (!channel->rekey) + channel->rekey = silc_calloc(1, sizeof(*channel->rekey)); + channel->rekey->context = (void *)server; + channel->rekey->channel = channel; + + silc_task_unregister_by_callback(server->timeout_queue, + silc_server_channel_key_rekey); + silc_task_register(server->timeout_queue, 0, + silc_server_channel_key_rekey, + (void *)channel->rekey, 3600, 0, + SILC_TASK_TIMEOUT, + SILC_TASK_PRI_NORMAL); + } + out: if (id) silc_free(id); diff --git a/lib/silcutil/silctask.c b/lib/silcutil/silctask.c index 19c17f37..688594c9 100644 --- a/lib/silcutil/silctask.c +++ b/lib/silcutil/silctask.c @@ -594,6 +594,28 @@ void silc_task_unregister_by_callback(SilcTaskQueue queue, } } +/* Unregister a task by context. This invalidates the task. */ + +void silc_task_unregister_by_context(SilcTaskQueue queue, void *context) +{ + SilcTask next; + + SILC_LOG_DEBUG(("Unregister task by context")); + + if (queue->task == NULL) + return; + + next = queue->task; + + while(1) { + if (next->context == context) + next->valid = FALSE; + if (queue->task == next->next) + break; + next = next->next; + } +} + /* Sets the I/O mask for the task. Only one I/O type can be set at a time. */ diff --git a/lib/silcutil/silctask.h b/lib/silcutil/silctask.h index 13a3ec90..6fff792e 100644 --- a/lib/silcutil/silctask.h +++ b/lib/silcutil/silctask.h @@ -351,6 +351,7 @@ void silc_task_unregister(SilcTaskQueue queue, SilcTask task); void silc_task_unregister_by_fd(SilcTaskQueue queue, int fd); void silc_task_unregister_by_callback(SilcTaskQueue queue, SilcTaskCallback callback); +void silc_task_unregister_by_context(SilcTaskQueue queue, void *context); void silc_task_set_iotype(SilcTask task, int type); void silc_task_reset_iotype(SilcTask task, int type); int silc_task_timeout_compare(struct timeval *smaller, -- 2.24.0