silc_server_command_send_status_data(SilcServerCommandContext cmd,
SilcCommand command,
SilcCommandStatus status,
- unsigned int arg_type,
+ uint32 arg_type,
unsigned char *arg,
- unsigned int arg_len);
+ uint32 arg_len);
SILC_TASK_CALLBACK(silc_server_command_process_timeout);
/* Server command list. */
SILC_SERVER_CMD(cmode, CMODE, SILC_CF_LAG_STRICT | SILC_CF_REG),
SILC_SERVER_CMD(cumode, CUMODE, SILC_CF_LAG | SILC_CF_REG),
SILC_SERVER_CMD(kick, KICK, SILC_CF_LAG_STRICT | SILC_CF_REG),
- SILC_SERVER_CMD(restart, RESTART,
- SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER),
+ SILC_SERVER_CMD(ban, BAN, SILC_CF_LAG_STRICT | SILC_CF_REG),
SILC_SERVER_CMD(close, CLOSE,
SILC_CF_LAG | SILC_CF_REG | SILC_CF_OPER),
SILC_SERVER_CMD(shutdown, SHUTDOWN, SILC_CF_LAG | SILC_CF_REG |
SILC_CF_LAG | SILC_CF_REG | SILC_CF_SILC_OPER),
SILC_SERVER_CMD(leave, LEAVE, SILC_CF_LAG_STRICT | SILC_CF_REG),
SILC_SERVER_CMD(users, USERS, SILC_CF_LAG | SILC_CF_REG),
- SILC_SERVER_CMD(ban, BAN, SILC_CF_LAG_STRICT | SILC_CF_REG),
+ SILC_SERVER_CMD(getkey, GETKEY, SILC_CF_LAG | SILC_CF_REG),
{ NULL, 0 },
};
#define SILC_SERVER_COMMAND_CHECK_ARGC(command, context, min, max) \
do { \
- unsigned int _argc = silc_argument_get_arg_num(cmd->args); \
+ uint32 _argc = silc_argument_get_arg_num(cmd->args); \
\
SILC_LOG_DEBUG(("Start")); \
\
void silc_server_command_pending(SilcServer server,
SilcCommand reply_cmd,
- unsigned short ident,
+ uint16 ident,
SilcServerPendingDestructor destructor,
SilcCommandCb callback,
void *context)
void silc_server_command_pending_del(SilcServer server,
SilcCommand reply_cmd,
- unsigned short ident)
+ uint16 ident)
{
SilcServerCommandPending *r;
int silc_server_command_pending_check(SilcServer server,
SilcServerCommandReplyContext ctx,
SilcCommand command,
- unsigned short ident)
+ uint16 ident)
{
SilcServerCommandPending *r;
silc_server_command_send_status_data(SilcServerCommandContext cmd,
SilcCommand command,
SilcCommandStatus status,
- unsigned int arg_type,
+ uint32 arg_type,
unsigned char *arg,
- unsigned int arg_len)
+ uint32 arg_len)
{
SilcBuffer buffer;
static int
silc_server_command_whois_parse(SilcServerCommandContext cmd,
SilcClientID ***client_id,
- unsigned int *client_id_count,
+ uint32 *client_id_count,
char **nickname,
char **server_name,
int *count,
SilcCommand command)
{
unsigned char *tmp;
- unsigned int len;
- unsigned int argc = silc_argument_get_arg_num(cmd->args);
+ uint32 len;
+ uint32 argc = silc_argument_get_arg_num(cmd->args);
int i, k;
/* If client ID is in the command it must be used instead of nickname */
static char
silc_server_command_whois_check(SilcServerCommandContext cmd,
SilcClientEntry *clients,
- unsigned int clients_count)
+ uint32 clients_count)
{
SilcServer server = cmd->server;
int i;
for (i = 0; i < clients_count; i++) {
entry = clients[i];
- if (entry->data.registered == FALSE)
+ if (!entry || entry->data.registered == FALSE)
continue;
if (!entry->nickname || !entry->username || !entry->userinfo) {
SilcBuffer tmpbuf;
- unsigned short old_ident;
+ uint16 old_ident;
if (!entry->router)
continue;
static void
silc_server_command_whois_send_reply(SilcServerCommandContext cmd,
SilcClientEntry *clients,
- unsigned int clients_count,
+ uint32 clients_count,
int count)
{
SilcServer server = cmd->server;
SilcBuffer packet, idp, channels;
SilcClientEntry entry;
SilcCommandStatus status;
- unsigned short ident = silc_command_get_ident(cmd->payload);
+ uint16 ident = silc_command_get_ident(cmd->payload);
char nh[128], uh[128];
unsigned char idle[4], mode[4];
SilcSocketConnection hsock;
strncat(nh, entry->nickname, strlen(entry->nickname));
if (!strchr(entry->nickname, '@')) {
strncat(nh, "@", 1);
- len = entry->router ? strlen(entry->router->server_name) :
- strlen(server->server_name);
- strncat(nh, entry->router ? entry->router->server_name :
- server->server_name, len);
+ if (entry->servername) {
+ strncat(nh, entry->servername, strlen(entry->servername));
+ } else {
+ len = entry->router ? strlen(entry->router->server_name) :
+ strlen(server->server_name);
+ strncat(nh, entry->router ? entry->router->server_name :
+ server->server_name, len);
+ }
}
strncat(uh, entry->username, strlen(entry->username));
{
SilcServer server = cmd->server;
char *nick = NULL, *server_name = NULL;
- int count = 0, clients_count = 0;
+ int count = 0;
SilcClientEntry *clients = NULL, entry;
SilcClientID **client_id = NULL;
- unsigned int client_id_count = 0;
+ uint32 client_id_count = 0, clients_count = 0;
int i, ret = 0;
/* Protocol dictates that we must always send the received WHOIS request
if (server->server_type == SILC_SERVER && !cmd->pending &&
!server->standalone) {
SilcBuffer tmpbuf;
- unsigned short old_ident;
+ uint16 old_ident;
old_ident = silc_command_get_ident(cmd->payload);
silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
}
}
} else {
- clients = silc_idlist_get_clients_by_hash(server->local_list,
- nick, server->md5hash,
- &clients_count);
- if (!clients)
- clients = silc_idlist_get_clients_by_nickname(server->local_list,
- nick, server_name,
- &clients_count);
+ if (!silc_idlist_get_clients_by_hash(server->local_list,
+ nick, server->md5hash,
+ &clients, &clients_count))
+ silc_idlist_get_clients_by_nickname(server->local_list,
+ nick, server_name,
+ &clients, &clients_count);
}
/* Check global list as well */
- if (!clients) {
- if (client_id_count) {
- /* Check all Client ID's received in the command packet */
- for (i = 0; i < client_id_count; i++) {
- entry = silc_idlist_find_client_by_id(server->global_list,
- client_id[i], NULL);
- if (entry) {
- clients = silc_realloc(clients, sizeof(*clients) *
- (clients_count + 1));
- clients[clients_count++] = entry;
- }
+ if (client_id_count) {
+ /* Check all Client ID's received in the command packet */
+ for (i = 0; i < client_id_count; i++) {
+ entry = silc_idlist_find_client_by_id(server->global_list,
+ client_id[i], NULL);
+ if (entry) {
+ clients = silc_realloc(clients, sizeof(*clients) *
+ (clients_count + 1));
+ clients[clients_count++] = entry;
}
- } else {
- clients = silc_idlist_get_clients_by_hash(server->global_list,
- nick, server->md5hash,
- &clients_count);
- if (!clients)
- clients = silc_idlist_get_clients_by_nickname(server->global_list,
- nick, server_name,
- &clients_count);
}
+ } else {
+ if (!silc_idlist_get_clients_by_hash(server->global_list,
+ nick, server->md5hash,
+ &clients, &clients_count))
+ silc_idlist_get_clients_by_nickname(server->global_list,
+ nick, server_name,
+ &clients, &clients_count);
}
if (!clients) {
{
SilcServer server = cmd->server;
char *nick = NULL, *server_name = NULL;
- int count = 0, clients_count = 0;
+ int count = 0;
SilcClientEntry *clients = NULL, entry;
SilcClientID **client_id = NULL;
- unsigned int client_id_count = 0;
+ uint32 client_id_count = 0, clients_count = 0;
int i, ret = 0;
/* Parse the whois request */
}
}
} else {
- clients = silc_idlist_get_clients_by_hash(server->local_list,
- nick, server->md5hash,
- &clients_count);
- if (!clients)
- clients = silc_idlist_get_clients_by_nickname(server->local_list,
- nick, server_name,
- &clients_count);
+ if (!silc_idlist_get_clients_by_hash(server->local_list,
+ nick, server->md5hash,
+ &clients, &clients_count))
+ silc_idlist_get_clients_by_nickname(server->local_list,
+ nick, server_name,
+ &clients, &clients_count);
}
/* If we are router we will check our global list as well. */
- if (!clients && server->server_type == SILC_ROUTER) {
+ if (server->server_type == SILC_ROUTER) {
if (client_id_count) {
/* Check all Client ID's received in the command packet */
for (i = 0; i < client_id_count; i++) {
}
}
} else {
- clients = silc_idlist_get_clients_by_hash(server->global_list,
- nick, server->md5hash,
- &clients_count);
- if (!clients)
- clients = silc_idlist_get_clients_by_nickname(server->global_list,
- nick, server_name,
- &clients_count);
+ if (!silc_idlist_get_clients_by_hash(server->global_list,
+ nick, server->md5hash,
+ &clients, &clients_count))
+ silc_idlist_get_clients_by_nickname(server->global_list,
+ nick, server_name,
+ &clients, &clients_count);
}
}
int *count)
{
unsigned char *tmp;
- unsigned int len;
+ uint32 len;
tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
if (!tmp) {
static char
silc_server_command_whowas_check(SilcServerCommandContext cmd,
SilcClientEntry *clients,
- unsigned int clients_count)
+ uint32 clients_count)
{
SilcServer server = cmd->server;
int i;
if (!entry->nickname || !entry->username) {
SilcBuffer tmpbuf;
- unsigned short old_ident;
+ uint16 old_ident;
if (!entry->router)
continue;
static void
silc_server_command_whowas_send_reply(SilcServerCommandContext cmd,
SilcClientEntry *clients,
- unsigned int clients_count)
+ uint32 clients_count)
{
SilcServer server = cmd->server;
char *tmp;
SilcBuffer packet, idp;
SilcClientEntry entry = NULL;
SilcCommandStatus status;
- unsigned short ident = silc_command_get_ident(cmd->payload);
+ uint16 ident = silc_command_get_ident(cmd->payload);
char found = FALSE;
char nh[256], uh[256];
strncat(nh, entry->nickname, strlen(entry->nickname));
if (!strchr(entry->nickname, '@')) {
strncat(nh, "@", 1);
- len = entry->router ? strlen(entry->router->server_name) :
- strlen(server->server_name);
- strncat(nh, entry->router ? entry->router->server_name :
- server->server_name, len);
+ if (entry->servername) {
+ strncat(nh, entry->servername, strlen(entry->servername));
+ } else {
+ len = entry->router ? strlen(entry->router->server_name) :
+ strlen(server->server_name);
+ strncat(nh, entry->router ? entry->router->server_name :
+ server->server_name, len);
+ }
}
strncat(uh, entry->username, strlen(entry->username));
{
SilcServer server = cmd->server;
char *nick = NULL, *server_name = NULL;
- int count = 0, clients_count = 0;
+ int count = 0;
SilcClientEntry *clients = NULL;
+ uint32 clients_count = 0;
int ret = 0;
/* Protocol dictates that we must always send the received WHOWAS request
if (server->server_type == SILC_SERVER &&
!cmd->pending && !server->standalone) {
SilcBuffer tmpbuf;
- unsigned short old_ident;
+ uint16 old_ident;
old_ident = silc_command_get_ident(cmd->payload);
silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
return 0;
/* Get all clients matching that nickname from local list */
- clients = silc_idlist_get_clients_by_nickname(server->local_list,
- nick, server_name,
- &clients_count);
- if (!clients)
- clients = silc_idlist_get_clients_by_hash(server->local_list,
- nick, server->md5hash,
- &clients_count);
+ if (!silc_idlist_get_clients_by_nickname(server->local_list,
+ nick, server_name,
+ &clients, &clients_count))
+ silc_idlist_get_clients_by_hash(server->local_list,
+ nick, server->md5hash,
+ &clients, &clients_count);
/* Check global list as well */
- if (!clients) {
- clients = silc_idlist_get_clients_by_nickname(server->global_list,
- nick, server_name,
- &clients_count);
- if (!clients)
- clients = silc_idlist_get_clients_by_hash(server->global_list,
- nick, server->md5hash,
- &clients_count);
- }
+ if (!silc_idlist_get_clients_by_nickname(server->global_list,
+ nick, server_name,
+ &clients, &clients_count))
+ silc_idlist_get_clients_by_hash(server->global_list,
+ nick, server->md5hash,
+ &clients, &clients_count);
if (!silc_server_command_whowas_check(cmd, clients, clients_count)) {
ret = -1;
{
SilcServer server = cmd->server;
char *nick = NULL, *server_name = NULL;
- int count = 0, clients_count = 0;
+ int count = 0;
SilcClientEntry *clients = NULL;
+ uint32 clients_count = 0;
int ret = 0;
/* Parse the whowas request */
/* Process the command request. Let's search for the requested client and
send reply to the requesting server. */
- clients = silc_idlist_get_clients_by_nickname(server->local_list,
- nick, server_name,
- &clients_count);
- if (!clients)
- clients = silc_idlist_get_clients_by_hash(server->local_list,
- nick, server->md5hash,
- &clients_count);
+ if (!silc_idlist_get_clients_by_nickname(server->local_list,
+ nick, server_name,
+ &clients, &clients_count))
+ silc_idlist_get_clients_by_hash(server->local_list,
+ nick, server->md5hash,
+ &clients, &clients_count);
/* If we are router we will check our global list as well. */
- if (!clients && server->server_type == SILC_ROUTER) {
- clients = silc_idlist_get_clients_by_nickname(server->global_list,
- nick, server_name,
- &clients_count);
- if (!clients)
- clients = silc_idlist_get_clients_by_hash(server->global_list,
- nick, server->md5hash,
- &clients_count);
+ if (server->server_type == SILC_ROUTER) {
+ if (!silc_idlist_get_clients_by_nickname(server->global_list,
+ nick, server_name,
+ &clients, &clients_count))
+ silc_idlist_get_clients_by_hash(server->global_list,
+ nick, server->md5hash,
+ &clients, &clients_count);
}
if (!clients) {
static char
silc_server_command_identify_check(SilcServerCommandContext cmd,
SilcClientEntry *clients,
- unsigned int clients_count)
+ uint32 clients_count)
{
SilcServer server = cmd->server;
int i;
for (i = 0; i < clients_count; i++) {
entry = clients[i];
- if (entry->data.registered == FALSE)
+ if (!entry || entry->data.registered == FALSE)
continue;
if (!entry->nickname) {
SilcBuffer tmpbuf;
- unsigned short old_ident;
+ uint16 old_ident;
if (!entry->router)
continue;
static void
silc_server_command_identify_send_reply(SilcServerCommandContext cmd,
SilcClientEntry *clients,
- unsigned int clients_count,
+ uint32 clients_count,
int count)
{
SilcServer server = cmd->server;
SilcBuffer packet, idp;
SilcClientEntry entry;
SilcCommandStatus status;
- unsigned short ident = silc_command_get_ident(cmd->payload);
+ uint16 ident = silc_command_get_ident(cmd->payload);
char nh[256], uh[256];
SilcSocketConnection hsock;
strncat(nh, entry->nickname, strlen(entry->nickname));
if (!strchr(entry->nickname, '@')) {
strncat(nh, "@", 1);
- len = entry->router ? strlen(entry->router->server_name) :
- strlen(server->server_name);
- strncat(nh, entry->router ? entry->router->server_name :
- server->server_name, len);
+ if (entry->servername) {
+ strncat(nh, entry->servername, strlen(entry->servername));
+ } else {
+ len = entry->router ? strlen(entry->router->server_name) :
+ strlen(server->server_name);
+ strncat(nh, entry->router ? entry->router->server_name :
+ server->server_name, len);
+ }
}
if (!entry->username) {
{
SilcServer server = cmd->server;
char *nick = NULL, *server_name = NULL;
- int count = 0, clients_count = 0;
+ int count = 0;
SilcClientEntry *clients = NULL, entry;
SilcClientID **client_id = NULL;
- unsigned int client_id_count = 0;
+ uint32 client_id_count = 0, clients_count = 0;
int i, ret = 0;
/* Protocol dictates that we must always send the received IDENTIFY request
if (server->server_type == SILC_SERVER &&
!cmd->pending && !server->standalone) {
SilcBuffer tmpbuf;
- unsigned short old_ident;
+ uint16 old_ident;
old_ident = silc_command_get_ident(cmd->payload);
silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
}
}
} else {
- clients = silc_idlist_get_clients_by_nickname(server->local_list,
- nick, server_name,
- &clients_count);
- if (!clients)
- clients = silc_idlist_get_clients_by_hash(server->local_list,
- nick, server->md5hash,
- &clients_count);
+ if (!silc_idlist_get_clients_by_hash(server->local_list,
+ nick, server->md5hash,
+ &clients, &clients_count))
+ silc_idlist_get_clients_by_nickname(server->local_list,
+ nick, server_name,
+ &clients, &clients_count);
}
/* Check global list as well */
- if (!clients) {
- if (client_id_count) {
- /* Check all Client ID's received in the command packet */
- for (i = 0; i < client_id_count; i++) {
- entry = silc_idlist_find_client_by_id(server->global_list,
- client_id[i], NULL);
- if (entry) {
- clients = silc_realloc(clients, sizeof(*clients) *
- (clients_count + 1));
- clients[clients_count++] = entry;
- }
+ if (client_id_count) {
+ /* Check all Client ID's received in the command packet */
+ for (i = 0; i < client_id_count; i++) {
+ entry = silc_idlist_find_client_by_id(server->global_list,
+ client_id[i], NULL);
+ if (entry) {
+ clients = silc_realloc(clients, sizeof(*clients) *
+ (clients_count + 1));
+ clients[clients_count++] = entry;
}
- } else {
- clients = silc_idlist_get_clients_by_nickname(server->global_list,
- nick, server_name,
- &clients_count);
- if (!clients)
- clients = silc_idlist_get_clients_by_hash(server->global_list,
- nick, server->md5hash,
- &clients_count);
}
+ } else {
+ if (!silc_idlist_get_clients_by_hash(server->global_list,
+ nick, server->md5hash,
+ &clients, &clients_count))
+ silc_idlist_get_clients_by_nickname(server->global_list,
+ nick, server_name,
+ &clients, &clients_count);
}
if (!clients) {
{
SilcServer server = cmd->server;
char *nick = NULL, *server_name = NULL;
- int count = 0, clients_count = 0;
+ int count = 0;
SilcClientEntry *clients = NULL, entry;
SilcClientID **client_id = NULL;
- unsigned int client_id_count = 0;
+ uint32 client_id_count = 0, clients_count = 0;
int i, ret = 0;
/* Parse the IDENTIFY request */
}
}
} else {
- clients = silc_idlist_get_clients_by_nickname(server->local_list,
- nick, server_name,
- &clients_count);
- if (!clients)
- clients = silc_idlist_get_clients_by_hash(server->local_list,
- nick, server->md5hash,
- &clients_count);
+ if (!silc_idlist_get_clients_by_hash(server->local_list,
+ nick, server->md5hash,
+ &clients, &clients_count))
+ silc_idlist_get_clients_by_nickname(server->local_list,
+ nick, server_name,
+ &clients, &clients_count);
}
/* If we are router we will check our global list as well. */
- if (!clients && server->server_type == SILC_ROUTER) {
+ if (server->server_type == SILC_ROUTER) {
if (client_id_count) {
/* Check all Client ID's received in the command packet */
for (i = 0; i < client_id_count; i++) {
}
}
} else {
- clients = silc_idlist_get_clients_by_nickname(server->global_list,
- nick, server_name,
- &clients_count);
- if (!clients)
- clients = silc_idlist_get_clients_by_hash(server->global_list,
- nick, server->md5hash,
- &clients_count);
+ if (!silc_idlist_get_clients_by_hash(server->global_list,
+ nick, server->md5hash,
+ &clients, &clients_count))
+ silc_idlist_get_clients_by_nickname(server->global_list,
+ nick, server_name,
+ &clients, &clients_count);
}
}
SilcBuffer packet, nidp, oidp;
SilcClientID *new_id;
char *nick;
- unsigned short ident = silc_command_get_ident(cmd->payload);
+ uint16 ident = silc_command_get_ident(cmd->payload);
if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
goto out;
silc_server_send_notify_nick_change(server, server->router->connection,
server->server_type == SILC_SERVER ?
FALSE : TRUE, client->id,
- new_id, SILC_ID_CLIENT_LEN);
+ new_id);
/* Remove old cache entry */
- silc_idcache_del_by_id(server->local_list->clients, SILC_ID_CLIENT,
- client->id);
+ silc_idcache_del_by_context(server->local_list->clients, client);
oidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
/* Free old ID */
- if (client->id) {
- memset(client->id, 0, SILC_ID_CLIENT_LEN);
+ if (client->id)
silc_free(client->id);
- }
/* Save the nickname as this client is our local client */
if (client->nickname)
/* Update client cache */
silc_idcache_add(server->local_list->clients, client->nickname,
- strlen(client->nickname), SILC_ID_CLIENT, client->id,
- (void *)client, TRUE, FALSE);
+ client->id, (void *)client, FALSE);
nidp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
static void
silc_server_command_list_send_reply(SilcServerCommandContext cmd,
SilcChannelEntry *lch,
- unsigned int lch_count,
+ uint32 lch_count,
SilcChannelEntry *gch,
- unsigned int gch_count)
+ uint32 gch_count)
{
int i;
SilcBuffer packet, idp;
SilcChannelEntry entry;
SilcCommandStatus status;
- unsigned short ident = silc_command_get_ident(cmd->payload);
+ uint16 ident = silc_command_get_ident(cmd->payload);
char *topic;
unsigned char usercount[4];
- unsigned int users;
+ uint32 users;
for (i = 0; i < lch_count; i++)
if (lch[i]->mode & SILC_CHANNEL_MODE_SECRET)
SilcServer server = cmd->server;
SilcChannelID *channel_id = NULL;
unsigned char *tmp;
- unsigned int tmp_len;
+ uint32 tmp_len;
SilcChannelEntry *lchannels = NULL, *gchannels = NULL;
- unsigned int lch_count = 0, gch_count = 0;
+ uint32 lch_count = 0, gch_count = 0;
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_LIST, cmd, 0, 2);
SilcChannelClientEntry chl;
SilcBuffer packet, idp;
unsigned char *tmp;
- unsigned int argc, tmp_len;
- unsigned short ident = silc_command_get_ident(cmd->payload);
+ uint32 argc, tmp_len;
+ uint16 ident = silc_command_get_ident(cmd->payload);
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_TOPIC, cmd, 1, 2);
silc_server_send_notify_topic_set(server, server->router->connection,
server->server_type == SILC_ROUTER ?
TRUE : FALSE, channel, client->id,
- SILC_ID_CLIENT_LEN, channel->topic);
+ channel->topic);
idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
SilcIDListData idata;
SilcBuffer idp, idp2, packet;
unsigned char *tmp, *add, *del;
- unsigned int len;
- unsigned short ident = silc_command_get_ident(cmd->payload);
+ uint32 len;
+ uint16 ident = silc_command_get_ident(cmd->payload);
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_INVITE, cmd, 1, 4);
silc_server_send_notify_invite(server, server->router->connection,
server->server_type == SILC_ROUTER ?
TRUE : FALSE, channel,
- sender->id, SILC_ID_CLIENT_LEN,
- add, del);
+ sender->id, add, del);
/* Send command reply */
tmp = silc_argument_get_arg_type(cmd->args, 1, &len);
SilcSocketConnection sock = cmd->sock;
QuitInternal q;
unsigned char *tmp = NULL;
- unsigned int len = 0;
+ uint32 len = 0;
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_QUIT, cmd, 0, 1);
SilcClientEntry remote_client;
SilcClientID *client_id;
unsigned char *tmp, *comment;
- unsigned int tmp_len, tmp_len2;
+ uint32 tmp_len, tmp_len2;
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_KILL, cmd, 1, 2);
/* Send KILLED notify to primary route */
if (!server->standalone)
silc_server_send_notify_killed(server, server->router->connection, TRUE,
- remote_client->id, SILC_ID_CLIENT_LEN,
- comment);
+ remote_client->id, comment);
/* Send KILLED notify to the client directly */
silc_server_send_notify_killed(server, remote_client->connection ?
remote_client->connection :
remote_client->router->connection, FALSE,
- remote_client->id, SILC_ID_CLIENT_LEN,
- comment);
+ remote_client->id, comment);
/* Remove the client from all channels. This generates new keys to the
channels as well. */
SilcServer server = cmd->server;
SilcBuffer packet, idp;
unsigned char *tmp;
- unsigned int tmp_len;
+ uint32 tmp_len;
char *dest_server, *server_info = NULL, *server_name;
- unsigned short ident = silc_command_get_ident(cmd->payload);
+ uint16 ident = silc_command_get_ident(cmd->payload);
SilcServerEntry entry = NULL;
SilcServerID *server_id = NULL;
server->server_type == SILC_ROUTER && entry && !entry->server_info) {
/* Send to the server */
SilcBuffer tmpbuf;
- unsigned short old_ident;
+ uint16 old_ident;
old_ident = silc_command_get_ident(cmd->payload);
silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
if (!entry && !cmd->pending && !server->standalone) {
/* Send to the primary router */
SilcBuffer tmpbuf;
- unsigned short old_ident;
+ uint16 old_ident;
old_ident = silc_command_get_ident(cmd->payload);
silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SilcServer server = cmd->server;
SilcServerID *id;
- unsigned int len;
+ uint32 len;
unsigned char *tmp;
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_INFO, cmd, 1, 2);
if (!id)
goto out;
- if (!SILC_ID_SERVER_COMPARE(id, server->id)) {
+ if (SILC_ID_SERVER_COMPARE(id, server->id)) {
/* Send our reply */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_PING,
SILC_STATUS_OK);
SilcChannelEntry channel,
SilcClientID *client_id,
int created,
- unsigned int umode)
+ uint32 umode)
{
SilcSocketConnection sock = cmd->sock;
unsigned char *tmp;
- unsigned int tmp_len, user_count;
+ uint32 tmp_len, user_count;
unsigned char *passphrase = NULL, mode[4], tmp2[4], tmp3[4];
SilcClientEntry client;
SilcChannelClientEntry chl;
SilcBuffer reply, chidp, clidp, keyp = NULL, user_list, mode_list;
- unsigned short ident = silc_command_get_ident(cmd->payload);
+ uint16 ident = silc_command_get_ident(cmd->payload);
char check[512];
SILC_LOG_DEBUG(("Start"));
if (!server->standalone)
silc_server_send_notify_join(server, server->router->connection,
server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel, client->id,
- SILC_ID_CLIENT_LEN);
+ TRUE : FALSE, channel, client->id);
}
silc_buffer_free(reply);
{
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SilcServer server = cmd->server;
- int tmp_len;
+ uint32 tmp_len;
char *tmp, *channel_name = NULL, *cipher, *hmac;
SilcChannelEntry channel;
- unsigned int umode = 0;
+ uint32 umode = 0;
int created = FALSE;
SilcClientID *client_id;
be same as the client's ID. */
if (cmd->sock->type == SILC_SOCKET_TYPE_CLIENT) {
SilcClientEntry entry = (SilcClientEntry)cmd->sock->user_data;
- if (SILC_ID_CLIENT_COMPARE(entry->id, client_id)) {
+ if (!SILC_ID_CLIENT_COMPARE(entry->id, client_id)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_JOIN,
SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto out;
}
}
- if (!channel) {
+ if (!channel || !channel->id) {
/* Channel not found */
/* If we are standalone server we don't have a router, we just create
or joins the client to it). */
if (server->server_type == SILC_SERVER) {
SilcBuffer tmpbuf;
- unsigned short old_ident;
+ uint16 old_ident;
old_ident = silc_command_get_ident(cmd->payload);
silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
SilcServer server = cmd->server;
SilcBuffer packet, idp;
char *motd, *dest_server;
- int motd_len;
- unsigned short ident = silc_command_get_ident(cmd->payload);
+ uint32 motd_len;
+ uint16 ident = silc_command_get_ident(cmd->payload);
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_MOTD, cmd, 1, 1);
entry && !entry->motd) {
/* Send to the server */
SilcBuffer tmpbuf;
- unsigned short old_ident;
+ uint16 old_ident;
old_ident = silc_command_get_ident(cmd->payload);
silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
if (!entry && !cmd->pending && !server->standalone) {
/* Send to the primary router */
SilcBuffer tmpbuf;
- unsigned short old_ident;
+ uint16 old_ident;
old_ident = silc_command_get_ident(cmd->payload);
silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
SilcBuffer packet;
unsigned char *tmp_mask;
- unsigned int mask;
- unsigned short ident = silc_command_get_ident(cmd->payload);
+ uint32 mask;
+ uint16 ident = silc_command_get_ident(cmd->payload);
if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
goto out;
*/
if (mask & SILC_UMODE_SERVER_OPERATOR) {
- /* Cannot operator mode */
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
- SILC_STATUS_ERR_PERM_DENIED);
- goto out;
+ if (!(client->mode & SILC_UMODE_SERVER_OPERATOR)) {
+ /* Cannot operator mode */
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
+ SILC_STATUS_ERR_PERM_DENIED);
+ goto out;
+ }
} else {
if (client->mode & SILC_UMODE_SERVER_OPERATOR)
/* Remove the server operator rights */
}
if (mask & SILC_UMODE_ROUTER_OPERATOR) {
- /* Cannot operator mode */
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
- SILC_STATUS_ERR_PERM_DENIED);
- goto out;
+ if (!(client->mode & SILC_UMODE_ROUTER_OPERATOR)) {
+ /* Cannot operator mode */
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_UMODE,
+ SILC_STATUS_ERR_PERM_DENIED);
+ goto out;
+ }
} else {
if (client->mode & SILC_UMODE_ROUTER_OPERATOR)
/* Remove the router operator rights */
client->mode &= ~SILC_UMODE_ROUTER_OPERATOR;
}
+ if (mask & SILC_UMODE_GONE) {
+ client->mode |= SILC_UMODE_GONE;
+ } else {
+ if (client->mode & SILC_UMODE_GONE)
+ /* Remove the gone status */
+ client->mode &= ~SILC_UMODE_GONE;
+ }
+
/* Send UMODE change to primary router */
if (!server->standalone)
silc_server_send_notify_umode(server, server->router->connection, TRUE,
- client->id, SILC_ID_CLIENT_LEN,
- client->mode);
+ client->id, client->mode);
/* Send command reply to sender */
packet = silc_command_reply_payload_encode_va(SILC_COMMAND_UMODE,
int silc_server_check_cmode_rights(SilcChannelEntry channel,
SilcChannelClientEntry client,
- unsigned int mode)
+ uint32 mode)
{
int is_op = client->mode & SILC_CHANNEL_UMODE_CHANOP;
int is_fo = client->mode & SILC_CHANNEL_UMODE_CHANFO;
}
}
+ if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
+ if (is_op && !is_fo)
+ return FALSE;
+ } else {
+ if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
+ if (is_op && !is_fo)
+ return FALSE;
+ }
+ }
+
return TRUE;
}
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SilcServer server = cmd->server;
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
+ SilcIDListData idata = (SilcIDListData)client;
SilcChannelID *channel_id;
SilcChannelEntry channel;
SilcChannelClientEntry chl;
SilcBuffer packet, cidp;
unsigned char *tmp, *tmp_id, *tmp_mask;
char *cipher = NULL, *hmac = NULL;
- unsigned int argc, mode_mask, tmp_len, tmp_len2;
- unsigned short ident = silc_command_get_ident(cmd->payload);
-
- SILC_LOG_DEBUG(("Start"));
+ uint32 mode_mask, tmp_len, tmp_len2;
+ uint16 ident = silc_command_get_ident(cmd->payload);
- argc = silc_argument_get_arg_num(cmd->args);
- if (argc < 2) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
- goto out;
- }
- if (argc > 8) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
- SILC_STATUS_ERR_TOO_MANY_PARAMS);
- goto out;
- }
+ SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CMODE, cmd, 2, 7);
/* Get Channel ID */
tmp_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_len2);
if (mode_mask & SILC_CHANNEL_MODE_ULIMIT) {
/* User limit is set on channel */
- unsigned int user_limit;
+ uint32 user_limit;
/* Get user limit */
tmp = silc_argument_get_arg_type(cmd->args, 3, NULL);
}
}
+ if (mode_mask & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
+ if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
+ if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)) {
+ /* Set the founder authentication */
+ SilcAuthPayload auth;
+
+ tmp = silc_argument_get_arg_type(cmd->args, 7, &tmp_len);
+ if (!tmp) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ goto out;
+ }
+
+ auth = silc_auth_payload_parse(tmp, tmp_len);
+ if (!auth) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE,
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ goto out;
+ }
+
+ /* Save the public key */
+ tmp = silc_pkcs_public_key_encode(idata->public_key, &tmp_len);
+ silc_pkcs_public_key_decode(tmp, tmp_len, &channel->founder_key);
+ silc_free(tmp);
+
+ channel->founder_method = silc_auth_get_method(auth);
+
+ if (channel->founder_method == SILC_AUTH_PASSWORD) {
+ tmp = silc_auth_get_data(auth, &tmp_len);
+ channel->founder_passwd =
+ silc_calloc(tmp_len + 1, sizeof(*channel->founder_passwd));
+ memcpy(channel->founder_passwd, tmp, tmp_len);
+ channel->founder_passwd_len = tmp_len;
+ }
+
+ silc_auth_payload_free(auth);
+ }
+ }
+ } else {
+ if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
+ if (channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) {
+ if (channel->founder_key)
+ silc_pkcs_public_key_free(channel->founder_key);
+ if (channel->founder_passwd) {
+ silc_free(channel->founder_passwd);
+ channel->founder_passwd = NULL;
+ }
+ }
+ }
+ }
+
/* Finally, set the mode */
channel->mode = mode_mask;
silc_server_send_notify_to_channel(server, NULL, channel, FALSE,
SILC_NOTIFY_TYPE_CMODE_CHANGE, 4,
cidp->data, cidp->len,
- tmp_mask, tmp_len,
+ tmp_mask, 4,
cipher, cipher ? strlen(cipher) : 0,
hmac, hmac ? strlen(hmac) : 0);
server->server_type == SILC_ROUTER ?
TRUE : FALSE, channel,
mode_mask, client->id, SILC_ID_CLIENT,
- SILC_ID_CLIENT_LEN,
cipher, hmac);
/* Send command reply to sender */
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SilcServer server = cmd->server;
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
+ SilcIDListData idata = (SilcIDListData)client;
SilcChannelID *channel_id;
SilcClientID *client_id;
SilcChannelEntry channel;
SilcChannelClientEntry chl;
SilcBuffer packet, idp;
unsigned char *tmp_id, *tmp_ch_id, *tmp_mask;
- unsigned int target_mask, sender_mask, tmp_len, tmp_ch_len;
+ uint32 target_mask, sender_mask = 0, tmp_len, tmp_ch_len;
int notify = FALSE;
- unsigned short ident = silc_command_get_ident(cmd->payload);
+ uint16 ident = silc_command_get_ident(cmd->payload);
- SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CUMODE, cmd, 3, 3);
+ SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CUMODE, cmd, 3, 4);
/* Get Channel ID */
tmp_ch_id = silc_argument_get_arg_type(cmd->args, 1, &tmp_ch_len);
silc_list_start(channel->user_list);
while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END) {
if (chl->client == client) {
- if (!(chl->mode & SILC_CHANNEL_UMODE_CHANFO) &&
- !(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NO_CHANNEL_PRIV);
- goto out;
- }
-
sender_mask = chl->mode;
break;
}
client_id, NULL);
}
- /* Check whether target client is on the channel */
- if (!silc_server_client_on_channel(target_client, channel)) {
+ if (target_client != client &&
+ !(sender_mask & SILC_CHANNEL_UMODE_CHANFO) &&
+ !(sender_mask & SILC_CHANNEL_UMODE_CHANOP)) {
silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_USER_NOT_ON_CHANNEL);
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV);
goto out;
}
- /* Get entry to the channel user list */
- silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
- if (chl->client == target_client)
- break;
+ /* Check whether target client is on the channel */
+ if (target_client != client) {
+ if (!silc_server_client_on_channel(target_client, channel)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_USER_NOT_ON_CHANNEL);
+ goto out;
+ }
+
+ /* Get entry to the channel user list */
+ silc_list_start(channel->user_list);
+ while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
+ if (chl->client == target_client)
+ break;
+ }
/*
* Change the mode
}
if (target_mask & SILC_CHANNEL_UMODE_CHANFO) {
- /* Cannot promote anyone to channel founder */
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
- SILC_STATUS_ERR_NOT_YOU);
- goto out;
+ /* The client tries to claim the founder rights. */
+ unsigned char *tmp_auth;
+ uint32 tmp_auth_len, auth_len;
+ void *auth;
+
+ if (target_client != client) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_NOT_YOU);
+ goto out;
+ }
+
+ if (!(channel->mode & SILC_CHANNEL_MODE_FOUNDER_AUTH) ||
+ !channel->founder_key) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_NOT_YOU);
+ goto out;
+ }
+
+ tmp_auth = silc_argument_get_arg_type(cmd->args, 4, &tmp_auth_len);
+ if (!tmp_auth) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
+ goto out;
+ }
+
+ auth = (channel->founder_method == SILC_AUTH_PASSWORD ?
+ (void *)channel->founder_passwd : (void *)channel->founder_key);
+ auth_len = (channel->founder_method == SILC_AUTH_PASSWORD ?
+ channel->founder_passwd_len : 0);
+
+ if (!silc_auth_verify_data(tmp_auth, tmp_auth_len,
+ channel->founder_method, auth, auth_len,
+ idata->hash, client->id, SILC_ID_CLIENT)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_CUMODE,
+ SILC_STATUS_ERR_AUTH_FAILED);
+ goto out;
+ }
+
+ sender_mask = chl->mode |= SILC_CHANNEL_UMODE_CHANFO;
+ notify = TRUE;
} else {
if (chl->mode & SILC_CHANNEL_UMODE_CHANFO) {
if (target_client == client) {
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);
+ goto out;
+ }
+
chl->mode |= SILC_CHANNEL_UMODE_CHANOP;
notify = TRUE;
}
} 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);
+ goto out;
+ }
+
/* Demote to normal user */
chl->mode &= ~SILC_CHANNEL_UMODE_CHANOP;
notify = TRUE;
}
idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT);
+ tmp_id = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
/* Send notify to channel, notify only if mode was actually changed. */
if (notify) {
server->server_type == SILC_ROUTER ?
TRUE : FALSE, channel,
target_mask, client->id,
- SILC_ID_CLIENT_LEN,
- target_client->id,
- SILC_ID_CLIENT_LEN);
+ SILC_ID_CLIENT,
+ target_client->id);
}
/* Send command reply to sender */
SilcChannelEntry channel;
SilcChannelClientEntry chl;
SilcBuffer idp;
- unsigned int tmp_len;
+ uint32 tmp_len;
unsigned char *tmp, *comment;
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_LEAVE, cmd, 1, 3);
silc_server_send_notify_kicked(server, server->router->connection,
server->server_type == SILC_ROUTER ?
TRUE : FALSE, channel,
- target_client->id, SILC_ID_CLIENT_LEN,
- comment);
+ target_client->id, comment);
if (!(channel->mode & SILC_CHANNEL_MODE_PRIVKEY)) {
/* Re-generate channel key */
SilcServer server = cmd->server;
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
unsigned char *username, *auth;
- unsigned int tmp_len;
+ uint32 tmp_len;
SilcServerConfigSectionAdminConnection *admin;
SilcIDListData idata = (SilcIDListData)client;
/* Send UMODE change to primary router */
if (!server->standalone)
silc_server_send_notify_umode(server, server->router->connection, TRUE,
- client->id, SILC_ID_CLIENT_LEN,
- client->mode);
+ client->id, client->mode);
/* Send reply to the sender */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_OPER,
SilcServer server = cmd->server;
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
unsigned char *username, *auth;
- unsigned int tmp_len;
+ uint32 tmp_len;
SilcServerConfigSectionAdminConnection *admin;
SilcIDListData idata = (SilcIDListData)client;
/* Send UMODE change to primary router */
if (!server->standalone)
silc_server_send_notify_umode(server, server->router->connection, TRUE,
- client->id, SILC_ID_CLIENT_LEN,
- client->mode);
+ client->id, client->mode);
/* Send reply to the sender */
silc_server_command_send_status_reply(cmd, SILC_COMMAND_SILCOPER,
SilcServer server = cmd->server;
SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
unsigned char *tmp, *host;
- unsigned int tmp_len;
- unsigned int port = SILC_PORT;
+ uint32 tmp_len;
+ uint32 port = SILC_PORT;
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CONNECT, cmd, 1, 2);
silc_server_command_free(cmd);
}
-SILC_SERVER_CMD_FUNC(restart)
+/* Server side of command BAN. This is used to manage the ban list of the
+ channel. To add clients and remove clients from the ban list. */
+
+SILC_SERVER_CMD_FUNC(ban)
{
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
+ SilcServer server = cmd->server;
+ SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
+ SilcBuffer packet;
+ SilcChannelEntry channel;
+ SilcChannelClientEntry chl;
+ SilcChannelID *channel_id = NULL;
+ unsigned char *id, *add, *del;
+ uint32 id_len, tmp_len;
+ uint16 ident = silc_command_get_ident(cmd->payload);
+
+ if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
+ goto out;
+
+ SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_BAN, cmd, 0, 3);
+
+ /* Get Channel ID */
+ id = silc_argument_get_arg_type(cmd->args, 1, &id_len);
+ if (id) {
+ channel_id = silc_id_payload_parse_id(id, id_len);
+ if (!channel_id) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
+ SILC_STATUS_ERR_NO_CHANNEL_ID);
+ goto out;
+ }
+ }
+
+ /* Get channel entry. The server must know about the channel since the
+ client is expected to be on the channel. */
+ channel = silc_idlist_find_channel_by_id(server->local_list,
+ channel_id, NULL);
+ if (!channel) {
+ channel = silc_idlist_find_channel_by_id(server->global_list,
+ channel_id, NULL);
+ if (!channel) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
+ SILC_STATUS_ERR_NO_SUCH_CHANNEL);
+ goto out;
+ }
+ }
+
+ /* Check whether this client is on the channel */
+ if (!silc_server_client_on_channel(client, channel)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
+ SILC_STATUS_ERR_NOT_ON_CHANNEL);
+ goto out;
+ }
+
+ /* Get entry to the channel user list */
+ silc_list_start(channel->user_list);
+ while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
+ if (chl->client == client)
+ break;
+
+ /* The client must be at least channel operator. */
+ if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
+ SILC_STATUS_ERR_NO_CHANNEL_PRIV);
+ goto out;
+ }
+
+ /* Get the new ban and add it to the ban list */
+ add = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
+ if (add) {
+ if (!channel->ban_list)
+ channel->ban_list = silc_calloc(tmp_len + 2, sizeof(*channel->ban_list));
+ else
+ channel->ban_list = silc_realloc(channel->ban_list,
+ sizeof(*channel->ban_list) *
+ (tmp_len +
+ strlen(channel->ban_list) + 2));
+ if (add[tmp_len - 1] == ',')
+ add[tmp_len - 1] = '\0';
+
+ strncat(channel->ban_list, add, tmp_len);
+ strncat(channel->ban_list, ",", 1);
+ }
+
+ /* Get the ban to be removed and remove it from the list */
+ del = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
+ if (del && channel->ban_list) {
+ char *start, *end, *n;
+
+ if (!strncmp(channel->ban_list, del, strlen(channel->ban_list) - 1)) {
+ silc_free(channel->ban_list);
+ channel->ban_list = NULL;
+ } else {
+ start = strstr(channel->ban_list, del);
+ if (start && strlen(start) >= tmp_len) {
+ end = start + tmp_len;
+ n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
+ strncat(n, channel->ban_list, start - channel->ban_list);
+ strncat(n, end + 1, ((channel->ban_list + strlen(channel->ban_list)) -
+ end) - 1);
+ silc_free(channel->ban_list);
+ channel->ban_list = n;
+ }
+ }
+ }
+
+ /* Send the BAN notify type to our primary router. */
+ if (!server->standalone && (add || del))
+ silc_server_send_notify_ban(server, server->router->connection,
+ server->server_type == SILC_ROUTER ?
+ TRUE : FALSE, channel, add, del);
+ /* Send the reply back to the client */
+ if (channel->ban_list)
+ packet =
+ silc_command_reply_payload_encode_va(SILC_COMMAND_BAN,
+ SILC_STATUS_OK, ident, 2,
+ 2, id, id_len,
+ 3, channel->ban_list,
+ strlen(channel->ban_list) - 1);
+ else
+ packet =
+ silc_command_reply_payload_encode_va(SILC_COMMAND_BAN,
+ SILC_STATUS_OK, ident, 1,
+ 2, id, id_len);
+
+ silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
+ packet->data, packet->len, FALSE);
+
+ silc_buffer_free(packet);
+
+ out:
+ if (channel_id)
+ silc_free(channel_id);
silc_server_command_free(cmd);
}
SilcServerEntry server_entry;
SilcSocketConnection sock;
unsigned char *tmp;
- unsigned int tmp_len;
+ uint32 tmp_len;
unsigned char *name;
- unsigned int port = SILC_PORT;
+ uint32 port = SILC_PORT;
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_CLOSE, cmd, 1, 2);
SilcServer server = cmd->server;
SilcSocketConnection sock = cmd->sock;
SilcClientEntry id_entry = (SilcClientEntry)cmd->sock->user_data;
- SilcChannelID *id;
+ SilcChannelID *id = NULL;
SilcChannelEntry channel;
- unsigned int len;
+ uint32 len;
unsigned char *tmp;
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_LEAVE, cmd, 1, 2);
if (!server->standalone)
silc_server_send_notify_leave(server, server->router->connection,
server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel, id_entry->id,
- SILC_ID_CLIENT_LEN);
+ TRUE : FALSE, channel, id_entry->id);
silc_server_command_send_status_reply(cmd, SILC_COMMAND_LEAVE,
SILC_STATUS_OK);
FALSE : !server->standalone);
}
- silc_free(id);
-
out:
+ if (id)
+ silc_free(id);
silc_server_command_free(cmd);
}
SilcChannelID *id;
SilcBuffer packet;
unsigned char *channel_id;
- unsigned int channel_id_len;
+ uint32 channel_id_len;
SilcBuffer client_id_list;
SilcBuffer client_mode_list;
unsigned char lc[4];
- unsigned int list_count = 0;
- unsigned short ident = silc_command_get_ident(cmd->payload);
+ uint32 list_count = 0;
+ uint16 ident = silc_command_get_ident(cmd->payload);
SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_USERS, cmd, 1, 1);
silc_server_command_free(cmd);
}
-/* Server side of command BAN. This is used to manage the ban list of the
- channel. To add clients and remove clients from the ban list. */
+/* Server side of command GETKEY. This fetches the client's public key
+ from the server where to the client is connected. */
-SILC_SERVER_CMD_FUNC(ban)
+SILC_SERVER_CMD_FUNC(getkey)
{
SilcServerCommandContext cmd = (SilcServerCommandContext)context;
SilcServer server = cmd->server;
- SilcClientEntry client = (SilcClientEntry)cmd->sock->user_data;
SilcBuffer packet;
- SilcChannelEntry channel;
- SilcChannelClientEntry chl;
- SilcChannelID *channel_id = NULL;
- unsigned char *id, *add, *del;
- unsigned int id_len, tmp_len;
- unsigned short ident = silc_command_get_ident(cmd->payload);
+ SilcClientEntry client;
+ SilcServerEntry server_entry;
+ SilcClientID *client_id = NULL;
+ SilcServerID *server_id = NULL;
+ SilcIDPayload idp = NULL;
+ uint16 ident = silc_command_get_ident(cmd->payload);
+ unsigned char *tmp;
+ uint32 tmp_len;
+ SilcBuffer pk;
+ SilcIdType id_type;
- if (cmd->sock->type != SILC_SOCKET_TYPE_CLIENT)
+ tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
+ if (!tmp) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto out;
-
- SILC_SERVER_COMMAND_CHECK_ARGC(SILC_COMMAND_BAN, cmd, 0, 3);
-
- /* Get Channel ID */
- id = silc_argument_get_arg_type(cmd->args, 1, &id_len);
- if (id) {
- channel_id = silc_id_payload_parse_id(id, id_len);
- if (!channel_id) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
- SILC_STATUS_ERR_NO_CHANNEL_ID);
- goto out;
- }
}
-
- /* Get channel entry. The server must know about the channel since the
- client is expected to be on the channel. */
- channel = silc_idlist_find_channel_by_id(server->local_list,
- channel_id, NULL);
- if (!channel) {
- channel = silc_idlist_find_channel_by_id(server->global_list,
- channel_id, NULL);
- if (!channel) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
- SILC_STATUS_ERR_NO_SUCH_CHANNEL);
- goto out;
- }
- }
-
- /* Check whether this client is on the channel */
- if (!silc_server_client_on_channel(client, channel)) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
- SILC_STATUS_ERR_NOT_ON_CHANNEL);
+ idp = silc_id_payload_parse_data(tmp, tmp_len);
+ if (!idp) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
+ SILC_STATUS_ERR_NOT_ENOUGH_PARAMS);
goto out;
}
- /* Get entry to the channel user list */
- silc_list_start(channel->user_list);
- while ((chl = silc_list_get(channel->user_list)) != SILC_LIST_END)
- if (chl->client == client)
- break;
+ id_type = silc_id_payload_get_type(idp);
+ if (id_type == SILC_ID_CLIENT) {
+ client_id = silc_id_payload_get_id(idp);
- /* The client must be at least channel operator. */
- if (!(chl->mode & SILC_CHANNEL_UMODE_CHANOP)) {
- silc_server_command_send_status_reply(cmd, SILC_COMMAND_BAN,
- SILC_STATUS_ERR_NO_CHANNEL_PRIV);
- goto out;
- }
+ /* If the client is not found from local list there is no chance it
+ would be locally connected client so send the command further. */
+ client = silc_idlist_find_client_by_id(server->local_list,
+ client_id, NULL);
+
+ if ((!client && !cmd->pending && !server->standalone) ||
+ (client && !client->connection)) {
+ SilcBuffer tmpbuf;
+ uint16 old_ident;
+ SilcSocketConnection dest_sock;
+
+ dest_sock = silc_server_get_client_route(server, NULL, 0,
+ client_id, NULL);
+ if (!dest_sock)
+ goto out;
+
+ old_ident = silc_command_get_ident(cmd->payload);
+ silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+ tmpbuf = silc_command_payload_encode_payload(cmd->payload);
+
+ silc_server_packet_send(server, dest_sock,
+ SILC_PACKET_COMMAND, cmd->packet->flags,
+ tmpbuf->data, tmpbuf->len, TRUE);
+
+ /* Reprocess this packet after received reply from router */
+ silc_server_command_pending(server, SILC_COMMAND_GETKEY,
+ silc_command_get_ident(cmd->payload),
+ silc_server_command_destructor,
+ silc_server_command_getkey,
+ silc_server_command_dup(cmd));
+ cmd->pending = TRUE;
+
+ silc_command_set_ident(cmd->payload, old_ident);
+ silc_buffer_free(tmpbuf);
+ return;
+ }
- /* Get the new ban and add it to the ban list */
- add = silc_argument_get_arg_type(cmd->args, 2, &tmp_len);
- if (add) {
- if (!channel->ban_list)
- channel->ban_list = silc_calloc(tmp_len + 2, sizeof(*channel->ban_list));
- else
- channel->ban_list = silc_realloc(channel->ban_list,
- sizeof(*channel->ban_list) *
- (tmp_len +
- strlen(channel->ban_list) + 2));
- if (add[tmp_len - 1] == ',')
- add[tmp_len - 1] = '\0';
+ if (!client && cmd->pending) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
+ SILC_STATUS_ERR_NO_SUCH_CLIENT_ID);
+ goto out;
+ }
- strncat(channel->ban_list, add, tmp_len);
- strncat(channel->ban_list, ",", 1);
- }
+ /* The client is locally connected, just get the public key and
+ send it back. */
+ tmp = silc_pkcs_public_key_encode(client->data.public_key, &tmp_len);
+ pk = silc_buffer_alloc(4 + tmp_len);
+ silc_buffer_pull_tail(pk, SILC_BUFFER_END(pk));
+ silc_buffer_format(pk,
+ SILC_STR_UI_SHORT(tmp_len),
+ SILC_STR_UI_SHORT(SILC_SKE_PK_TYPE_SILC),
+ SILC_STR_UI_XNSTRING(tmp, tmp_len),
+ SILC_STR_END);
+ silc_free(tmp);
- /* Get the ban to be removed and remove it from the list */
- del = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
- if (del && channel->ban_list) {
- char *start, *end, *n;
+ } else if (id_type == SILC_ID_SERVER) {
+ server_id = silc_id_payload_get_id(idp);
- if (!strncmp(channel->ban_list, del, strlen(channel->ban_list) - 1)) {
- silc_free(channel->ban_list);
- channel->ban_list = NULL;
- } else {
- start = strstr(channel->ban_list, del);
- if (start && strlen(start) >= tmp_len) {
- end = start + tmp_len;
- n = silc_calloc(strlen(channel->ban_list) - tmp_len, sizeof(*n));
- strncat(n, channel->ban_list, start - channel->ban_list);
- strncat(n, end + 1, ((channel->ban_list + strlen(channel->ban_list)) -
- end) - 1);
- silc_free(channel->ban_list);
- channel->ban_list = n;
- }
+ /* If the server is not found from local list there is no chance it
+ would be locally connected server so send the command further. */
+ server_entry = silc_idlist_find_server_by_id(server->local_list,
+ server_id, NULL);
+
+ if ((!server_entry && !cmd->pending && !server->standalone) ||
+ (server_entry && !server_entry->connection)) {
+ SilcBuffer tmpbuf;
+ uint16 old_ident;
+
+ old_ident = silc_command_get_ident(cmd->payload);
+ silc_command_set_ident(cmd->payload, silc_rng_get_rn16(server->rng));
+ tmpbuf = silc_command_payload_encode_payload(cmd->payload);
+
+ silc_server_packet_send(server, server->router->connection,
+ SILC_PACKET_COMMAND, cmd->packet->flags,
+ tmpbuf->data, tmpbuf->len, TRUE);
+
+ /* Reprocess this packet after received reply from router */
+ silc_server_command_pending(server, SILC_COMMAND_GETKEY,
+ silc_command_get_ident(cmd->payload),
+ silc_server_command_destructor,
+ silc_server_command_getkey,
+ silc_server_command_dup(cmd));
+ cmd->pending = TRUE;
+
+ silc_command_set_ident(cmd->payload, old_ident);
+ silc_buffer_free(tmpbuf);
+ return;
}
- }
- /* Send the BAN notify type to our primary router. */
- if (!server->standalone && (add || del))
- silc_server_send_notify_ban(server, server->router->connection,
- server->server_type == SILC_ROUTER ?
- TRUE : FALSE, channel, add, del);
+ if (!server_entry && cmd->pending) {
+ silc_server_command_send_status_reply(cmd, SILC_COMMAND_GETKEY,
+ SILC_STATUS_ERR_NO_SUCH_SERVER_ID);
+ goto out;
+ }
- /* Send the reply back to the client */
- if (channel->ban_list)
- packet =
- silc_command_reply_payload_encode_va(SILC_COMMAND_BAN,
- SILC_STATUS_OK, ident, 2,
- 2, id, id_len,
- 3, channel->ban_list,
- strlen(channel->ban_list) - 1);
- else
- packet =
- silc_command_reply_payload_encode_va(SILC_COMMAND_BAN,
- SILC_STATUS_OK, ident, 1,
- 2, id, id_len);
+ /* The client is locally connected, just get the public key and
+ send it back. */
+ tmp = silc_pkcs_public_key_encode(server_entry->data.public_key, &tmp_len);
+ pk = silc_buffer_alloc(4 + tmp_len);
+ silc_buffer_pull_tail(pk, SILC_BUFFER_END(pk));
+ silc_buffer_format(pk,
+ SILC_STR_UI_SHORT(tmp_len),
+ SILC_STR_UI_SHORT(SILC_SKE_PK_TYPE_SILC),
+ SILC_STR_UI_XNSTRING(tmp, tmp_len),
+ SILC_STR_END);
+ silc_free(tmp);
+ } else {
+ goto out;
+ }
+ tmp = silc_argument_get_arg_type(cmd->args, 1, &tmp_len);
+ packet = silc_command_reply_payload_encode_va(SILC_COMMAND_GETKEY,
+ SILC_STATUS_OK, ident, 2,
+ 2, tmp, tmp_len,
+ 3, pk->data, pk->len);
silc_server_packet_send(server, cmd->sock, SILC_PACKET_COMMAND_REPLY, 0,
packet->data, packet->len, FALSE);
-
silc_buffer_free(packet);
+ silc_buffer_free(pk);
out:
- if (channel_id)
- silc_free(channel_id);
+ if (idp)
+ silc_id_payload_free(idp);
+ silc_free(client_id);
+ silc_free(server_id);
silc_server_command_free(cmd);
}