/* Update statistics */
server->stat.clients--;
- if (server->server_type == SILC_ROUTER)
+ if (server->stat.cell_clients)
server->stat.cell_clients--;
SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
* Distribute the notify to local clients on the channel
*/
unsigned char *id, *id2;
+ char *nickname;
+ SilcUInt32 nickname_len;
SILC_LOG_DEBUG(("NICK CHANGE notify"));
SILC_LOG_DEBUG(("New Client ID id(%s)",
silc_id_render(client_id2, SILC_ID_CLIENT)));
+ /* From protocol version 1.1 we also get the new nickname */
+ nickname = silc_argument_get_arg_type(args, 3, &nickname_len);;
+
/* Replace the Client ID */
client = silc_idlist_replace_client_id(server->global_list, client_id,
- client_id2);
+ client_id2, nickname);
if (!client)
client = silc_idlist_replace_client_id(server->local_list, client_id,
- client_id2);
+ client_id2, nickname);
if (client) {
- /* The nickname is not valid anymore, set it NULL. This causes that
- the nickname will be queried if someone wants to know it. */
- if (client->nickname)
- silc_free(client->nickname);
- client->nickname = NULL;
-
/* Send the NICK_CHANGE notify type to local clients on the channels
this client is joined to. */
- silc_server_send_notify_on_channels(server, NULL, client,
- SILC_NOTIFY_TYPE_NICK_CHANGE, 2,
- id, tmp_len,
- id2, tmp_len);
+ silc_server_send_notify_on_channels(server, NULL, client,
+ SILC_NOTIFY_TYPE_NICK_CHANGE, 3,
+ id, tmp_len, id2, tmp_len,
+ nickname, nickname ?
+ nickname_len : 0);
}
silc_free(client_id);
tmp = silc_argument_get_arg_type(args, 5, &tmp_len);
if (tmp) {
silc_free(channel->passphrase);
- channel->passphrase = strdup(tmp);
+ channel->passphrase = silc_memdup(tmp, tmp_len);
}
break;
/* Update statistics */
server->stat.clients--;
- if (server->server_type == SILC_ROUTER)
+ if (server->stat.cell_clients)
server->stat.cell_clients--;
SILC_OPER_STATS_UPDATE(client, server, SILC_UMODE_SERVER_OPERATOR);
SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR);
if (chl->mode & SILC_CHANNEL_UMODE_CHANFO)
goto out;
- /* Get kicker. In protocol version 1.0 this is not mandatory argument
- so we check it only if it is provided. */
+ /* From protocol version 1.1 we get the kicker's ID as well. */
tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
if (tmp) {
client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
/*
* Distribute the notify to local clients on channels
*/
- unsigned char *id;
- SilcUInt32 id_len;
+ unsigned char *id, *comment;
+ SilcUInt32 id_len, comment_len;
SILC_LOG_DEBUG(("KILLED notify"));
}
/* Get comment */
- tmp = silc_argument_get_arg_type(args, 2, &tmp_len);
- if (tmp_len > 128)
- tmp = NULL;
+ comment = silc_argument_get_arg_type(args, 2, &comment_len);
+ if (comment_len > 128)
+ comment_len = 127;
+
+ /* From protocol version 1.1 we get the killer's ID as well. */
+ tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
+ if (tmp) {
+ client_id = silc_id_payload_parse_id(tmp, tmp_len, NULL);
+ if (!client_id)
+ goto out;
+
+ /* If the the client is not in local list we check global list */
+ client2 = silc_idlist_find_client_by_id(server->global_list,
+ client_id, TRUE, NULL);
+ if (!client2) {
+ client2 = silc_idlist_find_client_by_id(server->local_list,
+ client_id, TRUE, NULL);
+ if (!client2) {
+ silc_free(client_id);
+ goto out;
+ }
+ }
+ silc_free(client_id);
+
+ /* Killer must be router operator */
+ if (!(client2->mode & SILC_UMODE_ROUTER_OPERATOR)) {
+ SILC_LOG_DEBUG(("Killing is not allowed"));
+ goto out;
+ }
+ }
/* Send the notify to local clients on the channels except to the
client who is killed. */
silc_server_send_notify_on_channels(server, client, client,
- SILC_NOTIFY_TYPE_KILLED,
- tmp ? 2 : 1,
- id, id_len,
+ SILC_NOTIFY_TYPE_KILLED, 3,
+ id, id_len, comment, comment_len,
tmp, tmp_len);
/* Remove the client from all channels */
SilcChannelID *id = NULL;
void *sender_id = NULL;
SilcClientEntry sender_entry = NULL;
+ SilcChannelClientEntry chl;
bool local = TRUE;
SILC_LOG_DEBUG(("Processing channel message"));
sender_id, TRUE, NULL);
}
if (!sender_entry || !silc_server_client_on_channel(sender_entry,
- channel, NULL)) {
+ channel, &chl)) {
SILC_LOG_DEBUG(("Client not on channel"));
goto out;
}
+ /* If channel is moderated check that client is allowed to send
+ messages. */
+ if (channel->mode & SILC_CHANNEL_MODE_SILENCE_USERS && !chl->mode) {
+ SILC_LOG_DEBUG(("Channel is silenced from normal users"));
+ goto out;
+ }
+ if (channel->mode & SILC_CHANNEL_MODE_SILENCE_OPERS &&
+ chl->mode & SILC_CHANNEL_UMODE_CHANOP &&
+ !(chl->mode & SILC_CHANNEL_UMODE_CHANFO)) {
+ SILC_LOG_DEBUG(("Channel is silenced from operators"));
+ goto out;
+ }
+
/* If the packet is coming from router, but the client entry is local
entry to us then some router is rerouting this to us and it is not
allowed. When the client is local to us it means that we've routed
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("Your host is %s, running version %s",
server->server_name, server_version));
- if (server->server_type == SILC_ROUTER) {
+
+ if (server->stat.clients && server->stat.servers + 1)
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("There are %d clients on %d servers in SILC "
"Network", server->stat.clients,
server->stat.servers + 1));
+ if (server->stat.cell_clients && server->stat.cell_servers + 1)
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("There are %d clients on %d server in our cell",
server->stat.cell_clients,
server->stat.cell_servers + 1));
+ if (server->server_type == SILC_ROUTER) {
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("I have %d clients, %d channels, %d servers and "
"%d routers",
server->stat.my_channels,
server->stat.my_servers,
server->stat.my_routers));
+ } else {
+ SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
+ ("I have %d clients and %d channels formed",
+ server->stat.my_clients,
+ server->stat.my_channels));
+ }
+
+ if (server->stat.server_ops || server->stat.router_ops)
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("There are %d server operators and %d router "
"operators online",
server->stat.server_ops,
server->stat.router_ops));
+ if (server->stat.my_router_ops + server->stat.my_server_ops)
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("I have %d operators online",
server->stat.my_router_ops +
server->stat.my_server_ops));
- } else {
- SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
- ("I have %d clients and %d channels formed",
- server->stat.my_clients,
- server->stat.my_channels));
- SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
- ("%d operators online",
- server->stat.my_server_ops));
- }
+
SILC_SERVER_SEND_NOTIFY(server, sock, SILC_NOTIFY_TYPE_NONE,
("Your connection is secured with %s cipher, "
"key length %d bits",