do { \
SilcUInt32 _argc; \
\
- SILC_LOG_DEBUG(("Start")); \
- \
if (silc_server_command_pending_error_check(cmd, context2, command)) { \
+ SILC_LOG_DEBUG(("Error occurred in command reply, command not called")); \
silc_server_command_free(cmd); \
return; \
} \
\
_argc = silc_argument_get_arg_num(cmd->args); \
if (_argc < min) { \
+ SILC_LOG_DEBUG(("Not enough parameters in command")); \
silc_server_command_send_status_reply(cmd, command, \
SILC_STATUS_ERR_NOT_ENOUGH_PARAMS, \
0); \
return; \
} \
if (_argc > max) { \
+ SILC_LOG_DEBUG(("Too many parameters in command")); \
silc_server_command_send_status_reply(cmd, command, \
SILC_STATUS_ERR_TOO_MANY_PARAMS, \
0); \
SilcClientEntry client = (SilcClientEntry)timeout->ctx->sock->user_data;
if (!client) {
+ SILC_LOG_DEBUG(("Client entry is invalid"));
silc_server_command_free(timeout->ctx);
silc_free(timeout);
}
/* Update access time */
client->last_command = time(NULL);
- if (!(timeout->cmd->flags & SILC_CF_REG))
+ if (!(timeout->cmd->flags & SILC_CF_REG)) {
+ SILC_LOG_DEBUG(("Calling %s command",
+ silc_get_command_name(timeout->cmd->cmd)));
timeout->cmd->cb(timeout->ctx, NULL);
- else if (silc_server_is_registered(timeout->ctx->server,
- timeout->ctx->sock,
- timeout->ctx,
- timeout->cmd->cmd))
+ } else if (silc_server_is_registered(timeout->ctx->server,
+ timeout->ctx->sock,
+ timeout->ctx,
+ timeout->cmd->cmd)) {
+ SILC_LOG_DEBUG(("Calling %s command",
+ silc_get_command_name(timeout->cmd->cmd)));
timeout->cmd->cb(timeout->ctx, NULL);
- else
+ } else {
+ SILC_LOG_DEBUG(("Client is not registered"));
silc_server_command_free(timeout->ctx);
+ }
silc_free(timeout);
}
SilcServerCommand *cmd;
SilcCommand command;
- SILC_LOG_DEBUG(("Start"));
-
/* Allocate command context. This must be free'd by the
command routine receiving it. */
ctx = silc_server_command_alloc();
packet->buffer->len);
if (!ctx->payload) {
SILC_LOG_ERROR(("Bad command payload, packet dropped"));
- silc_buffer_free(packet->buffer);
silc_packet_context_free(packet);
silc_socket_free(ctx->sock);
silc_free(ctx);
break;
if (!cmd || !cmd->cb) {
+ SILC_LOG_DEBUG(("Unknown command %d", command));
silc_server_command_send_status_reply(ctx, command,
SILC_STATUS_ERR_UNKNOWN_COMMAND, 0);
silc_server_command_free(ctx);
/* Execute for server */
- if (!(cmd->flags & SILC_CF_REG))
+ if (!(cmd->flags & SILC_CF_REG)) {
+ SILC_LOG_DEBUG(("Calling %s command", silc_get_command_name(cmd->cmd)));
cmd->cb(ctx, NULL);
- else if (silc_server_is_registered(server, sock, ctx, cmd->cmd))
+ } else if (silc_server_is_registered(server, sock, ctx, cmd->cmd)) {
+ SILC_LOG_DEBUG(("Calling %s command", silc_get_command_name(cmd->cmd)));
cmd->cb(ctx, NULL);
- else
+ } else {
+ SILC_LOG_DEBUG(("Server is not registered"));
silc_server_command_free(ctx);
+ }
}
/* Allocate Command Context */
unsigned char *fkey = NULL;
SilcUInt32 fkey_len = 0;
- SILC_LOG_DEBUG(("Start"));
+ SILC_LOG_DEBUG(("Joining client to channel"));
if (!channel)
return;
*/
if (auth && auth_len && channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
SilcIDListData idata = (SilcIDListData)client;
+ SilcChannelClientEntry chl2;
+ SilcHashTableList htl;
if (channel->founder_key && idata->public_key &&
silc_pkcs_public_key_compare(channel->founder_key,
if (silc_auth_verify_data(auth, auth_len, SILC_AUTH_PUBLIC_KEY,
channel->founder_key, 0, server->sha1hash,
client->id, SILC_ID_CLIENT)) {
+
+ /* There cannot be anyone else as founder on the channel now. This
+ client is definitely the founder due to this authentication */
+ silc_hash_table_list(channel->user_list, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
+ if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
+ chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
+ silc_server_force_cumode_change(server, NULL, channel, chl2,
+ chl2->mode);
+ break;
+ }
+ silc_hash_table_list_reset(&htl);
+
umode = (SILC_CHANNEL_UMODE_CHANOP | SILC_CHANNEL_UMODE_CHANFO);
founder = TRUE;
}
we'll ignore it (in packet_receive.c) so we must send it here. If
we are router then this will send it to local clients and local
servers. */
+ SILC_LOG_DEBUG(("Send JOIN notify to channel"));
silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
SILC_NOTIFY_TYPE_JOIN, 2,
clidp->data, clidp->len,
chidp->data, chidp->len);
+ /* Update statistics */
+ server->stat.my_chanclients++;
+ if (server->server_type == SILC_ROUTER) {
+ server->stat.cell_chanclients++;
+ server->stat.chanclients++;
+ }
+
if (!cmd->pending) {
/* Send JOIN notify packet to our primary router */
if (!server->standalone)
notify the mode change to the channel. */
if (founder) {
SILC_PUT32_MSB(chl->mode, mode);
+ SILC_LOG_DEBUG(("Send CUMODE_CHANGE notify to channel"));
silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
SILC_NOTIFY_TYPE_CUMODE_CHANGE, 4,
clidp->data, clidp->len,
mode, 4, clidp->data, clidp->len,
fkey, fkey_len);
-
- /* Set CUMODE notify type to network */
- if (!server->standalone)
- silc_server_send_notify_cumode(server, server->router->connection,
- server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel,
- chl->mode, client->id, SILC_ID_CLIENT,
- client->id, channel->founder_key);
}
}
+ /* Set CUMODE notify type to network */
+ if (founder && !server->standalone)
+ silc_server_send_notify_cumode(server, server->router->connection,
+ server->server_type == SILC_ROUTER ?
+ TRUE : FALSE, channel,
+ chl->mode, client->id, SILC_ID_CLIENT,
+ client->id, channel->founder_key);
+
silc_buffer_free(reply);
silc_buffer_free(clidp);
silc_buffer_free(chidp);
if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data;
+ silc_free(client_id);
client_id = silc_id_dup(entry->id, SILC_ID_CLIENT);
if (!channel ||
cmd, SILC_COMMAND_JOIN,
SILC_STATUS_ERR_UNKNOWN_ALGORITHM,
0);
+ silc_free(client_id);
goto out;
}
/* If this is pending command callback then we've resolved
it and it didn't work, return since we've notified the
client already in the command reply callback. */
- if (cmd->pending)
+ if (cmd->pending) {
+ silc_free(client_id);
goto out;
+ }
old_ident = silc_command_get_ident(cmd->payload);
silc_command_set_ident(cmd->payload, ++server->cmd_ident);
cmd->pending = TRUE;
silc_command_set_ident(cmd->payload, old_ident);
silc_buffer_free(tmpbuf);
+ silc_free(client_id);
goto out;
}
silc_server_command_send_status_reply(
cmd, SILC_COMMAND_JOIN,
SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
+ silc_free(client_id);
goto out;
}
something went wrong with the joining as the channel was not found.
We can't do anything else but ignore this. */
if (cmd->sock->type == SILC_SOCKET_TYPE_ROUTER ||
- server->server_type != SILC_ROUTER)
+ server->server_type != SILC_ROUTER) {
+ silc_free(client_id);
goto out;
+ }
/* We are router and the channel does not seem exist so we will check
our global list as well for the channel. */
silc_server_command_send_status_reply(
cmd, SILC_COMMAND_JOIN,
SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0);
+ silc_free(client_id);
goto out;
}
SILC_GET32_MSB(created, tmp);
if (silc_argument_get_arg_type(reply->args, 7, NULL))
create_key = FALSE; /* Router returned the key already */
+
+ if (silc_command_get_status(reply->payload, NULL, NULL) &&
+ channel->mode & SILC_CHANNEL_MODE_PASSPHRASE) {
+ /* Save channel passphrase, if user provided it successfully */
+ unsigned char *pa;
+ SilcUInt32 pa_len;
+ pa = silc_argument_get_arg_type(reply->args, 3, &pa_len);
+ if (pa) {
+ silc_free(channel->passphrase);
+ channel->passphrase = silc_memdup(pa, pa_len);
+ }
+ }
}
if (silc_command_get(reply->payload) == SILC_COMMAND_WHOIS &&
if (server->config && server->config->server_info &&
server->config->server_info->motd_file) {
/* Send motd */
- motd = silc_file_readfile(server->config->server_info->motd_file, &motd_len);
+ motd = silc_file_readfile(server->config->server_info->motd_file,
+ &motd_len);
if (!motd)
goto out;
}
}
+ /* Update statistics */
+ if (mask & SILC_UMODE_GONE) {
+ if (!(client->mode & SILC_UMODE_GONE))
+ server->stat.my_aways++;
+ } else {
+ if (client->mode & SILC_UMODE_GONE)
+ server->stat.my_aways--;
+ }
+
/* Change the mode */
client->mode = mask;
/* The client tries to claim the founder rights. */
unsigned char *tmp_auth;
SilcUInt32 tmp_auth_len;
+ SilcChannelClientEntry chl2;
+ SilcHashTableList htl;
if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
!channel->founder_key || !idata->public_key ||
goto out;
}
- sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
notify = TRUE;
founder_key = channel->founder_key;
fkey = silc_pkcs_public_key_encode(founder_key, &fkey_len);
SILC_STATUS_ERR_AUTH_FAILED, 0);
goto out;
}
+
+ /* There cannot be anyone else as founder on the channel now. This
+ client is definitely the founder due to this authentication */
+ silc_hash_table_list(channel->user_list, &htl);
+ while (silc_hash_table_get(&htl, NULL, (void *)&chl2))
+ if (chl2->mode & SILC_CHANNEL_UMODE_CHANFO) {
+ chl2->mode &= ~SILC_CHANNEL_UMODE_CHANFO;
+ silc_server_force_cumode_change(server, NULL, channel, chl2,
+ chl2->mode);
+ break;
+ }
+ silc_hash_table_list_reset(&htl);
+
+ sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
}
} else {
if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
if (target_mask & SILC_CHANNEL_UMODE_CHANOP) {
/* Promote to operator */
if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
- if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
- !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NO_CHANNEL_PRIV,
- 0);
- goto out;
+ if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
+ !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV,
+ 0);
+ goto out;
}
chl->mode |= SILC_CHANNEL_UMODE_CHANOP;
} else {
if (chl->mode & SILC_CHANNEL_UMODE_CHANOP) {
if (!(sender_mask & SILC_CHANNEL_UMODE_CHANOP) &&
- !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NO_CHANNEL_PRIV,
- 0);
- goto out;
+ !(sender_mask & SILC_CHANNEL_UMODE_CHANFO)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV,
+ 0);
+ goto out;
}
-
+
/* Demote to normal user */
chl->mode &= ~SILC_CHANNEL_UMODE_CHANOP;
notify = TRUE;
}
}
+ if (target_mask & SILC_CHANNEL_UMODE_QUIET) {
+ if (!(chl->mode & SILC_CHANNEL_UMODE_QUIET)) {
+ if (client == target_client) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_PERM_DENIED, 0);
+ goto out;
+ }
+ chl->mode |= SILC_CHANNEL_UMODE_QUIET;
+ notify = TRUE;
+ }
+ } else {
+ if (chl->mode & SILC_CHANNEL_UMODE_QUIET) {
+ if (client == target_client) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_PERM_DENIED, 0);
+ goto out;
+ }
+ chl->mode &= ~SILC_CHANNEL_UMODE_QUIET;
+ notify = TRUE;
+ }
+ }
+
idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
SILC_TASK_CALLBACK(silc_server_command_detach_timeout)
{
QuitInternal q = (QuitInternal)context;
- SilcClientEntry client = (SilcClientEntry)q->sock;
+ SilcClientID *client_id = (SilcClientID *)q->sock;
+ SilcClientEntry client;
- SILC_LOG_DEBUG(("Start"));
+ client = silc_idlist_find_client_by_id(q->server->local_list, client_id,
+ FALSE, NULL);
- if (client->mode & SILC_UMODE_DETACHED)
+ if (client && client->mode & SILC_UMODE_DETACHED)
silc_server_free_client_data(q->server, NULL, client, TRUE,
"Detach timeout");
+
+ silc_free(client_id);
silc_free(q);
}
if (server->config->detach_disabled) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_DETACH,
- SILC_STATUS_ERR_UNKNOWN_COMMAND,
- 0);
+ SILC_STATUS_ERR_UNKNOWN_COMMAND, 0);
goto out;
}
silc_server_send_notify_umode(server, server->router->connection,
server->server_type == SILC_SERVER ?
FALSE : TRUE, client->id, client->mode);
+ server->stat.my_detached++;
/* Check if anyone is watching this nickname */
if (server->server_type == SILC_ROUTER)
if (server->config->detach_timeout) {
q = silc_calloc(1, sizeof(*q));
q->server = server;
- q->sock = (void *)client;
+ q->sock = silc_id_dup(client->id, SILC_ID_CLIENT);
silc_schedule_task_add(server->schedule, 0,
silc_server_command_detach_timeout,
q, server->config->detach_timeout * 60,
silc_free(tmp);
}
+ /* Distribute the watch list to backup routers too */
+ if (server->backup) {
+ SilcBuffer tmpbuf;
+ silc_command_set_ident(cmd->payload, ++server->cmd_ident);
+ tmpbuf = silc_command_payload_encode_payload(cmd->payload);
+ silc_server_backup_send(server, NULL, SILC_PACKET_COMMAND,
+ cmd->packet->flags, tmpbuf->data, tmpbuf->len,
+ FALSE, TRUE);
+ silc_buffer_free(tmpbuf);
+ }
+
silc_server_command_send_status_reply(cmd, SILC_COMMAND_WATCH,
SILC_STATUS_OK, 0);
SilcIdType id_type;
SilcPublicKey public_key;
- SILC_LOG_DEBUG(("Start"));
-
tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
if (!tmp) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,