From c1c6f25c3ae8cb1d7a34216257f1a893cb601ed7 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Fri, 23 Feb 2001 10:48:00 +0000 Subject: [PATCH] updates. --- CHANGES | 9 ++++ apps/silc/client_ops.c | 13 ++++-- apps/silcd/command.c | 37 ++++++++++++--- apps/silcd/packet_receive.c | 7 ++- apps/silcd/server.c | 71 +++++++++++++++++------------ apps/silcd/server.h | 6 ++- doc/draft-riikonen-silc-pp-01.nroff | 2 +- lib/silcclient/client.c | 10 ++-- lib/silcclient/command.c | 43 +++++++++++++---- lib/silcske/silcske.c | 9 ++-- 10 files changed, 145 insertions(+), 62 deletions(-) diff --git a/CHANGES b/CHANGES index 544168d6..bf360649 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,12 @@ +Fri Feb 23 11:22:57 EET 2001 Pekka Riikonen + + * Added support for quit message that client can "leave" on the + channel when it quits the SILC. It is ditributed inside the + SILC_NOTIFY_TYPE_SIGNOFF notify type. + + Added silc_server_free_client_data that will take the + signoff message as argument. + Thu Feb 22 23:05:36 EET 2001 Pekka Riikonen * Updated parts of the protocol specification to keep it up diff --git a/apps/silc/client_ops.c b/apps/silc/client_ops.c index 0aeea8fe..830c6e90 100644 --- a/apps/silc/client_ops.c +++ b/apps/silc/client_ops.c @@ -85,7 +85,7 @@ void silc_notify(SilcClient client, SilcClientConnection conn, char message[4096]; SilcClientEntry client_entry, client_entry2; SilcChannelEntry channel_entry; - char *tmp; + char *tmp = NULL; unsigned int tmp_int; va_start(vp, type); @@ -130,12 +130,15 @@ void silc_notify(SilcClient client, SilcClientConnection conn, case SILC_NOTIFY_TYPE_SIGNOFF: client_entry = va_arg(vp, SilcClientEntry); + tmp = va_arg(vp, char *); if (client_entry->server) - snprintf(message, sizeof(message), "Signoff: %s@%s", - client_entry->nickname, client_entry->server); + snprintf(message, sizeof(message), "Signoff: %s@%s %s%s%s", + client_entry->nickname, client_entry->server, + tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : ""); else - snprintf(message, sizeof(message), "Signoff: %s", - client_entry->nickname); + snprintf(message, sizeof(message), "Signoff: %s %s%s%s", + client_entry->nickname, + tmp ? "(" : "", tmp ? tmp : "", tmp ? ")" : ""); break; case SILC_NOTIFY_TYPE_TOPIC_SET: diff --git a/apps/silcd/command.c b/apps/silcd/command.c index e0477ee4..188c04ca 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -1573,20 +1573,30 @@ SILC_SERVER_CMD_FUNC(invite) silc_server_command_free(cmd); } +typedef struct { + SilcServer server; + SilcSocketConnection sock; + char *signoff; +} *QuitInternal; + /* Quits connection to client. This gets called if client won't close the connection even when it has issued QUIT command. */ SILC_TASK_CALLBACK(silc_server_command_quit_cb) { - SilcServer server = (SilcServer)context; - SilcSocketConnection sock = server->sockets[fd]; + QuitInternal q = (QuitInternal)context; /* Free all client specific data, such as client entry and entires on channels this client may be on. */ - silc_server_free_sock_user_data(server, sock); + silc_server_free_client_data(q->server, q->sock, q->sock->user_data, + q->signoff); + q->sock->user_data = NULL; /* Close the connection on our side */ - silc_server_close_connection(server, sock); + silc_server_close_connection(q->server, q->sock); + + silc_free(q->signoff); + silc_free(q); } /* Quits SILC session. This is the normal way to disconnect client. */ @@ -1596,13 +1606,26 @@ SILC_SERVER_CMD_FUNC(quit) SilcServerCommandContext cmd = (SilcServerCommandContext)context; SilcServer server = cmd->server; SilcSocketConnection sock = cmd->sock; + QuitInternal q; + unsigned char *tmp = NULL; + unsigned int len = 0; - SILC_LOG_DEBUG(("Start")); + SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_QUIT, cmd, 0, 1); + + /* Get destination ID */ + tmp = silc_argument_get_arg_type(cmd->args, 1, &len); + if (len > 128) + tmp = NULL; + + q = silc_calloc(1, sizeof(*q)); + q->server = server; + q->sock = sock; + q->signoff = tmp ? strdup(tmp) : NULL; /* We quit the connection with little timeout */ silc_task_register(server->timeout_queue, sock->sock, - silc_server_command_quit_cb, server, - 0, 300000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); + silc_server_command_quit_cb, (void *)q, + 0, 200000, SILC_TASK_TIMEOUT, SILC_TASK_PRI_LOW); silc_server_command_free(cmd); } diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index b6c58ed1..3c66a912 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -240,8 +240,13 @@ void silc_server_notify(SilcServer server, } silc_free(client_id); + /* Get signoff message */ + tmp = silc_argument_get_arg_type(args, 2, &tmp_len); + if (tmp_len > 128) + tmp = NULL; + /* Remove the client from all channels */ - silc_server_remove_from_channels(server, NULL, client); + silc_server_remove_from_channels(server, NULL, client, tmp); /* Remove the client entry */ if (!silc_idlist_del_client(server->global_list, client)) diff --git a/apps/silcd/server.c b/apps/silcd/server.c index e12dfb04..e68fa380 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -1809,7 +1809,34 @@ void silc_server_disconnect_remote(SilcServer server, silc_server_close_connection(server, sock); } -/* Free's user_data pointer from socket connection object. This also sends +/* Frees client data and notifies about client's signoff. */ + +void silc_server_free_client_data(SilcServer server, + SilcSocketConnection sock, + SilcClientEntry user_data, char *signoff) +{ + /* Send REMOVE_ID packet to routers. */ + if (!server->standalone && server->router) + silc_server_send_notify_signoff(server, server->router->connection, + server->server_type == SILC_SERVER ? + FALSE : TRUE, user_data->id, + SILC_ID_CLIENT_LEN, signoff); + + /* Remove client from all channels */ + silc_server_remove_from_channels(server, sock, user_data, signoff); + + /* XXX must take some info to history before freeing */ + + /* Free the client entry and everything in it */ + silc_idlist_del_data(user_data); + silc_idlist_del_client(server->local_list, user_data); + server->stat.my_clients--; + server->stat.clients--; + if (server->server_type == SILC_ROUTER) + server->stat.cell_clients--; +} + +/* Frees user_data pointer from socket connection object. This also sends appropriate notify packets to the network to inform about leaving entities. */ @@ -1822,26 +1849,7 @@ void silc_server_free_sock_user_data(SilcServer server, case SILC_SOCKET_TYPE_CLIENT: { SilcClientEntry user_data = (SilcClientEntry)sock->user_data; - - /* Send REMOVE_ID packet to routers. */ - if (!server->standalone && server->router) - silc_server_send_notify_signoff(server, server->router->connection, - server->server_type == SILC_SERVER ? - FALSE : TRUE, user_data->id, - SILC_ID_CLIENT_LEN, NULL); - - /* Remove client from all channels */ - silc_server_remove_from_channels(server, sock, user_data); - - /* XXX must take some info to history before freeing */ - - /* Free the client entry and everything in it */ - silc_idlist_del_data(user_data); - silc_idlist_del_client(server->local_list, user_data); - server->stat.my_clients--; - server->stat.clients--; - if (server->server_type == SILC_ROUTER) - server->stat.cell_clients--; + silc_server_free_client_data(server, sock, user_data, NULL); break; } case SILC_SOCKET_TYPE_SERVER: @@ -1918,7 +1926,7 @@ int silc_server_remove_clients_by_server(SilcServer server, } /* Remove the client entry */ - silc_server_remove_from_channels(server, NULL, client); + silc_server_remove_from_channels(server, NULL, client, NULL); silc_idlist_del_client(server->local_list, client); if (!silc_idcache_list_next(list, &id_cache)) @@ -1943,7 +1951,7 @@ int silc_server_remove_clients_by_server(SilcServer server, } /* Remove the client entry */ - silc_server_remove_from_channels(server, NULL, client); + silc_server_remove_from_channels(server, NULL, client, NULL); silc_idlist_del_client(server->global_list, client); if (!silc_idcache_list_next(list, &id_cache)) @@ -1994,7 +2002,8 @@ int silc_server_channel_has_local(SilcChannelEntry channel) void silc_server_remove_from_channels(SilcServer server, SilcSocketConnection sock, - SilcClientEntry client) + SilcClientEntry client, + char *signoff_message) { SilcChannelEntry channel; SilcChannelClientEntry chl; @@ -2043,8 +2052,11 @@ void silc_server_remove_from_channels(SilcServer server, /* Notify about leaving client if this channel has global users. */ if (channel->global_users) silc_server_send_notify_to_channel(server, NULL, channel, FALSE, - SILC_NOTIFY_TYPE_SIGNOFF, 1, - clidp->data, clidp->len); + SILC_NOTIFY_TYPE_SIGNOFF, + signoff_message ? 2 : 1, + clidp->data, clidp->len, + signoff_message, signoff_message ? + strlen(signoff_message) : 0); if (!silc_idlist_del_channel(server->local_list, channel)) silc_idlist_del_channel(server->global_list, channel); @@ -2055,8 +2067,11 @@ void silc_server_remove_from_channels(SilcServer server, /* Send notify to channel about client leaving SILC and thus the entire channel. */ silc_server_send_notify_to_channel(server, NULL, channel, FALSE, - SILC_NOTIFY_TYPE_SIGNOFF, 1, - clidp->data, clidp->len); + SILC_NOTIFY_TYPE_SIGNOFF, + signoff_message ? 2 : 1, + clidp->data, clidp->len, + signoff_message, signoff_message ? + strlen(signoff_message) : 0); } silc_buffer_free(clidp); diff --git a/apps/silcd/server.h b/apps/silcd/server.h index 9b3f64ac..1b83e1a8 100644 --- a/apps/silcd/server.h +++ b/apps/silcd/server.h @@ -89,6 +89,9 @@ void silc_server_packet_parse_type(SilcServer server, SilcPacketContext *packet); void silc_server_close_connection(SilcServer server, SilcSocketConnection sock); +void silc_server_free_client_data(SilcServer server, + SilcSocketConnection sock, + SilcClientEntry user_data, char *signoff); void silc_server_free_sock_user_data(SilcServer server, SilcSocketConnection sock); int silc_server_channel_has_global(SilcChannelEntry channel); @@ -97,7 +100,8 @@ int silc_server_remove_clients_by_server(SilcServer server, SilcServerEntry entry); void silc_server_remove_from_channels(SilcServer server, SilcSocketConnection sock, - SilcClientEntry client); + SilcClientEntry client, + char *signoff_message); int silc_server_remove_from_one_channel(SilcServer server, SilcSocketConnection sock, SilcChannelEntry channel, diff --git a/doc/draft-riikonen-silc-pp-01.nroff b/doc/draft-riikonen-silc-pp-01.nroff index c3c6372b..30d1be15 100644 --- a/doc/draft-riikonen-silc-pp-01.nroff +++ b/doc/draft-riikonen-silc-pp-01.nroff @@ -1089,7 +1089,7 @@ ID's sent in arguments are sent inside ID Payload. and broadcast it to the network. Max Arguments: 2 - Arguments: (1) (2) + Arguments: (1) (2) The is the client who left SILC network. The is free text string indicating the reason of signoff. diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index 81cf7e02..4dd828f8 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -603,8 +603,7 @@ SILC_TASK_CALLBACK(silc_client_packet_process) return; } - client->ops->say(client, conn, "Connection closed: premature EOF"); - SILC_LOG_DEBUG(("Premature EOF from connection %d", sock->sock)); + SILC_LOG_DEBUG(("EOF from connection %d", sock->sock)); client->ops->disconnect(client, conn); silc_client_close_connection(client, sock); return; @@ -1531,8 +1530,13 @@ void silc_client_notify_by_server(SilcClient client, silc_idcache_del_by_id(conn->client_cache, SILC_ID_CLIENT, client_entry->id); + /* Get signoff message */ + tmp = silc_argument_get_arg_type(args, 2, &tmp_len); + if (tmp_len > 128) + tmp = NULL; + /* Notify application */ - client->ops->notify(client, conn, type, client_entry); + client->ops->notify(client, conn, type, client_entry, tmp); /* Free data */ if (client_entry->nickname) diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index b56ad210..594b13f2 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -32,7 +32,7 @@ SilcClientCommand silc_command_list[] = SILC_CLIENT_CMD(list, LIST, "LIST", SILC_CF_LAG | SILC_CF_REG, 2), SILC_CLIENT_CMD(topic, TOPIC, "TOPIC", SILC_CF_LAG | SILC_CF_REG, 3), SILC_CLIENT_CMD(invite, INVITE, "INVITE", SILC_CF_LAG | SILC_CF_REG, 3), - SILC_CLIENT_CMD(quit, QUIT, "QUIT", SILC_CF_LAG | SILC_CF_REG, 1), + SILC_CLIENT_CMD(quit, QUIT, "QUIT", SILC_CF_LAG | SILC_CF_REG, 2), SILC_CLIENT_CMD(kill, KILL, "KILL", SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER, 2), SILC_CLIENT_CMD(info, INFO, "INFO", SILC_CF_LAG | SILC_CF_REG, 2), @@ -519,12 +519,29 @@ SILC_CLIENT_CMD_FUNC(invite) silc_client_command_free(cmd); } +typedef struct { + SilcClient client; + SilcClientConnection conn; +} *QuitInternal; + +SILC_TASK_CALLBACK(silc_client_command_quit_cb) +{ + QuitInternal q = (QuitInternal)context; + + /* Close connection */ + q->client->ops->disconnect(q->client, q->conn); + silc_client_close_connection(q->client, q->conn->sock); + + silc_free(q); +} + /* Command QUIT. Closes connection with current server. */ SILC_CLIENT_CMD_FUNC(quit) { SilcClientCommandContext cmd = (SilcClientCommandContext)context; SilcBuffer buffer; + QuitInternal q; if (!cmd->conn) { SILC_NOT_CONNECTED(cmd->client, cmd->conn); @@ -532,20 +549,26 @@ SILC_CLIENT_CMD_FUNC(quit) goto out; } - buffer = silc_command_payload_encode(SILC_COMMAND_QUIT, cmd->argc - 1, - ++cmd->argv, ++cmd->argv_lens, - ++cmd->argv_types, 0); + if (cmd->argc > 1) + buffer = silc_command_payload_encode(SILC_COMMAND_QUIT, cmd->argc - 1, + &cmd->argv[1], &cmd->argv_lens[1], + &cmd->argv_types[1], 0); + else + buffer = silc_command_payload_encode(SILC_COMMAND_QUIT, 0, + NULL, NULL, NULL, 0); silc_client_packet_send(cmd->client, cmd->conn->sock, SILC_PACKET_COMMAND, NULL, 0, NULL, NULL, buffer->data, buffer->len, TRUE); silc_buffer_free(buffer); - cmd->argv--; - cmd->argv_lens--; - cmd->argv_types--; - /* Close connection */ - cmd->client->ops->disconnect(cmd->client, cmd->conn); - silc_client_close_connection(cmd->client, cmd->conn->sock); + q = silc_calloc(1, sizeof(*q)); + q->client = cmd->client; + q->conn = cmd->conn; + + /* We quit the connection with little timeout */ + silc_task_register(cmd->client->timeout_queue, cmd->conn->sock->sock, + silc_client_command_quit_cb, (void *)q, + 1, 0, SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); /* Notify application */ COMMAND; diff --git a/lib/silcske/silcske.c b/lib/silcske/silcske.c index c8de900e..7a7f6b69 100644 --- a/lib/silcske/silcske.c +++ b/lib/silcske/silcske.c @@ -353,9 +353,8 @@ SilcSKEStatus silc_ske_initiator_finish(SilcSKE ske, /* Verify signature */ silc_pkcs_public_key_data_set(ske->prop->pkcs, public_key->pk, public_key->pk_len); - if (ske->prop->pkcs->pkcs->verify(ske->prop->pkcs->context, - payload->sign_data, payload->sign_len, - hash, hash_len) == FALSE) { + if (silc_pkcs_verify(ske->prop->pkcs, payload->sign_data, + payload->sign_len, hash, hash_len) == FALSE) { SILC_LOG_DEBUG(("Signature don't match")); @@ -658,9 +657,7 @@ SilcSKEStatus silc_ske_responder_finish(SilcSKE ske, /* Sign the hash value */ silc_pkcs_private_key_data_set(ske->prop->pkcs, private_key->prv, private_key->prv_len); - ske->prop->pkcs->pkcs->sign(ske->prop->pkcs->context, - hash, hash_len, - sign, &sign_len); + silc_pkcs_sign(ske->prop->pkcs, hash, hash_len, sign, &sign_len); ske->ke2_payload->sign_data = silc_calloc(sign_len, sizeof(unsigned char)); memcpy(ske->ke2_payload->sign_data, sign, sign_len); memset(sign, 0, sizeof(sign)); -- 2.24.0