+++ /dev/null
-/*
-
- server_st_command_reply.c
-
- Author: Pekka Riikonen <priikone@silcnet.org>
-
- Copyright (C) 1997 - 2005 Pekka Riikonen
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
-*/
-
-#include "silc.h"
-#include "silcserver.h"
-#include "server_internal.h"
-
-/************************** Types and definitions ***************************/
-
-/* All functions that call the COMMAND_CHECK_STATUS macros must have
- out: and err: goto labels. */
-
-#define COMMAND_CHECK_STATUS \
-do { \
- SILC_LOG_DEBUG(("Start")); \
- if (!silc_command_get_status(cmd->payload, &status, &error)) { \
- if (SILC_STATUS_IS_ERROR(status)) \
- goto out; \
- if (status == SILC_STATUS_LIST_END) \
- goto out; \
- goto err; \
- } \
-} while(0)
-
-
-/************************ Static utility functions **************************/
-
-/* Free's command reply context */
-
-static void silc_server_command_reply_free(SilcServerCommand cmd)
-{
- /* If pending commmands existed, they will eventually free this context */
- if (!cmd->pending)
- silc_server_command_free(cmd);
-}
-
-
-/************************* Command reply received ***************************/
-
-/* Received a COMMAND_REPLY packet. We parse the packet and process the
- command reply. */
-
-SILC_FSM_STATE(silc_server_st_packet_command_reply)
-{
- SilcServerThread thread = fsm_context;
- SilcPacket packet = state_context;
- SilcEntryData data = silc_packet_get_context(packet->stream);
- SilcServerCommand cmd;
- SilcCommandPayload payload;
- SilcCommand command;
-
- SILC_LOG_DEBUG(("Process command reply"));
-
- /* Allocate command context. */
- cmd = silc_server_command_alloc(thread);
- if (!cmd) {
- silc_packet_free(packet);
- return SILC_FSM_FINISH;
- }
-
- cmd->packet = packet;
-
- /* Get command reply payload from packet */
- cmd->payload = silc_command_payload_parse(packet->buffer.data,
- silc_buffer_len(&packet->buffer));
- if (!cmd->payload) {
- SILC_LOG_DEBUG(("Bad command reply payload"));
- silc_server_command_reply_free(cmd);
- return SILC_FSM_FINISH;
- }
-
- /* Client is allowed to send reply only to WHOIS command. */
- if (data->type == SILC_CONN_CLIENT &&
- silc_command_get(cmd->payload) != SILC_COMMAND_WHOIS) {
- silc_server_command_reply_free(cmd);
- return SILC_FSM_FINISH;
- }
-
- /* Get all command pending for this reply */
- cmd->pending =
- silc_server_command_pending_get(thread,
- silc_command_get_ident(cmd->payload));
-
- silc_fsm_set_state_context(fsm, cmd);
-
- /* Process command reply */
- switch (silc_command_get(cmd->payload)) {
-
- case SILC_COMMAND_WHOIS:
- /** Command reply WHOIS */
- silc_fsm_next(fsm, silc_server_st_command_reply_whois);
- break;
-
- case SILC_COMMAND_WHOWAS:
- /** Command reply WHOWAS */
- silc_fsm_next(fsm, silc_server_st_command_reply_whowas);
- break;
-
- case SILC_COMMAND_IDENTIFY:
- /** Command reply IDENTIFY */
- silc_fsm_next(fsm, silc_server_st_command_reply_identify);
- break;
-
- case SILC_COMMAND_LIST:
- /** Command reply LIST */
- silc_fsm_next(fsm, silc_server_st_command_reply_list);
- break;
-
- case SILC_COMMAND_INFO:
- /** Command reply INFO */
- silc_fsm_next(fsm, silc_server_st_command_reply_info);
- break;
-
- case SILC_COMMAND_STATS:
- /** Command reply STATS */
- silc_fsm_next(fsm, silc_server_st_command_reply_stats);
- break;
-
- case SILC_COMMAND_PING:
- /** Command reply PING */
- silc_fsm_next(fsm, silc_server_st_command_reply_ping);
- break;
-
- case SILC_COMMAND_JOIN:
- /** Command reply JOIN */
- silc_fsm_next(fsm, silc_server_st_command_reply_join);
- break;
-
- case SILC_COMMAND_MOTD:
- /** Command reply MOTD */
- silc_fsm_next(fsm, silc_server_st_command_reply_motd);
- break;
-
- case SILC_COMMAND_WATCH:
- /** Command reply WATCH */
- silc_fsm_next(fsm, silc_server_st_command_reply_watch);
- break;
-
- case SILC_COMMAND_USERS:
- /** Command reply USERS */
- silc_fsm_next(fsm, silc_server_st_command_reply_users);
- break;
-
- case SILC_COMMAND_GETKEY:
- /** Command reply SERVICE */
- silc_fsm_next(fsm, silc_server_st_command_reply_getkey);
- break;
-
- case SILC_COMMAND_SERVICE:
- /** Command reply SERVICE */
- silc_fsm_next(fsm, silc_server_st_command_reply_service);
- break;
-
- default:
- SILC_LOG_DEBUG(("Unknown command %d", silc_command_get(cmd->payload)));
- cmd->pending = NULL;
- silc_server_command_reply_free(cmd);
- return SILC_FSM_FINISH;
- break;
- }
-
- /* Statistics */
-
- return SILC_FSM_CONTINUE;
-}
-
-
-/********************************* WHOIS ************************************/
-
-SILC_FSM_STATE(silc_server_st_command_reply_whois)
-{
- SilcServerThread thread = fsm_context;
- SilcServerCommand cmd = state_context;
- SilcStatus status, error;
-
- COMMAND_CHECK_STATUS;
-
- out:
- silc_server_command_pending_signal(cmd);
- err:
- silc_server_command_reply_free(cmd);
-
- return SILC_FSM_FINISH;
-}
-
-
-/********************************* WHOWAS ***********************************/
-
-SILC_FSM_STATE(silc_server_st_command_reply_whowas)
-{
- SilcServerThread thread = fsm_context;
- SilcServerCommand cmd = state_context;
- SilcStatus status, error;
-
- COMMAND_CHECK_STATUS;
-
- out:
- silc_server_command_pending_signal(cmd);
- err:
- silc_server_command_reply_free(cmd);
-
- return SILC_FSM_FINISH;
-}
-
-
-/******************************** IDENTIFY **********************************/
-
-SILC_FSM_STATE(silc_server_st_command_reply_identify)
-{
- SilcServerThread thread = fsm_context;
- SilcServerCommand cmd = state_context;
- SilcStatus status, error;
-
- COMMAND_CHECK_STATUS;
-
- out:
- silc_server_command_pending_signal(cmd);
- err:
- silc_server_command_reply_free(cmd);
-
- return SILC_FSM_FINISH;
-}
-
-
-/********************************** LIST ************************************/
-
-SILC_FSM_STATE(silc_server_st_command_reply_list)
-{
- SilcServerThread thread = fsm_context;
- SilcServerCommand cmd = state_context;
- SilcStatus status, error;
-
- COMMAND_CHECK_STATUS;
-
- out:
- silc_server_command_pending_signal(cmd);
- err:
- silc_server_command_reply_free(cmd);
-
- return SILC_FSM_FINISH;
-}
-
-
-/********************************** INFO ************************************/
-
-SILC_FSM_STATE(silc_server_st_command_reply_info)
-{
- SilcServerThread thread = fsm_context;
- SilcServerCommand cmd = state_context;
- SilcStatus status, error;
-
- COMMAND_CHECK_STATUS;
-
- out:
- silc_server_command_pending_signal(cmd);
- err:
- silc_server_command_reply_free(cmd);
-
- return SILC_FSM_FINISH;
-}
-
-
-/********************************** STATS ***********************************/
-
-SILC_FSM_STATE(silc_server_st_command_reply_stats)
-{
- SilcServerThread thread = fsm_context;
- SilcServer server = thread->server;
- SilcServerCommand cmd = state_context;
- SilcArgumentPayload args = silc_command_get_args(cmd->payload);
- SilcStatus status, error;
- unsigned char *tmp;
- SilcUInt32 tmp_len;
- SilcBufferStruct buf;
-
- COMMAND_CHECK_STATUS;
-
- /* Get statistics structure */
- tmp = silc_argument_get_arg_type(args, 3, &tmp_len);
- if (server->server_type != SILC_ROUTER && tmp) {
- silc_buffer_set(&buf, tmp, tmp_len);
- silc_buffer_unformat(&buf,
- SILC_STR_UI_INT(NULL),
- SILC_STR_UI_INT(NULL),
- SILC_STR_UI_INT(NULL),
- SILC_STR_UI_INT(NULL),
- SILC_STR_UI_INT(NULL),
- SILC_STR_UI_INT(NULL),
- SILC_STR_UI_INT(&server->stat.cell_clients),
- SILC_STR_UI_INT(&server->stat.cell_channels),
- SILC_STR_UI_INT(&server->stat.cell_servers),
- SILC_STR_UI_INT(&server->stat.clients),
- SILC_STR_UI_INT(&server->stat.channels),
- SILC_STR_UI_INT(&server->stat.servers),
- SILC_STR_UI_INT(&server->stat.routers),
- SILC_STR_UI_INT(&server->stat.server_ops),
- SILC_STR_UI_INT(&server->stat.router_ops),
- SILC_STR_END);
- }
-
- out:
- silc_server_command_pending_signal(cmd);
- err:
- silc_server_command_reply_free(cmd);
-
- return SILC_FSM_FINISH;
-}
-
-
-/********************************** PING ************************************/
-
-SILC_FSM_STATE(silc_server_st_command_reply_ping)
-{
- SilcServerThread thread = fsm_context;
- SilcServerCommand cmd = state_context;
- SilcStatus status, error;
-
- COMMAND_CHECK_STATUS;
-
- out:
- silc_server_command_pending_signal(cmd);
- err:
- silc_server_command_reply_free(cmd);
-
- return SILC_FSM_FINISH;
-}
-
-
-/********************************** JOIN ************************************/
-
-SILC_FSM_STATE(silc_server_st_command_reply_join)
-{
- SilcServerThread thread = fsm_context;
- SilcServerCommand cmd = state_context;
- SilcStatus status, error;
-
- COMMAND_CHECK_STATUS;
-
- out:
- silc_server_command_pending_signal(cmd);
- err:
- silc_server_command_reply_free(cmd);
-
- return SILC_FSM_FINISH;
-}
-
-
-/********************************** MOTD ************************************/
-
-SILC_FSM_STATE(silc_server_st_command_reply_motd)
-{
- SilcServerThread thread = fsm_context;
- SilcServerCommand cmd = state_context;
- SilcStatus status, error;
-
- COMMAND_CHECK_STATUS;
-
- out:
- silc_server_command_pending_signal(cmd);
- err:
- silc_server_command_reply_free(cmd);
-
- return SILC_FSM_FINISH;
-}
-
-
-/********************************** WATCH ***********************************/
-
-SILC_FSM_STATE(silc_server_st_command_reply_watch)
-{
- SilcServerThread thread = fsm_context;
- SilcServerCommand cmd = state_context;
- SilcStatus status, error;
-
- COMMAND_CHECK_STATUS;
-
- out:
- silc_server_command_pending_signal(cmd);
- err:
- silc_server_command_reply_free(cmd);
-
- return SILC_FSM_FINISH;
-}
-
-
-/********************************** USERS ***********************************/
-
-SILC_FSM_STATE(silc_server_st_command_reply_users)
-{
- SilcServerThread thread = fsm_context;
- SilcServerCommand cmd = state_context;
- SilcStatus status, error;
-
- COMMAND_CHECK_STATUS;
-
- out:
- silc_server_command_pending_signal(cmd);
- err:
- silc_server_command_reply_free(cmd);
-
- return SILC_FSM_FINISH;
-}
-
-
-/********************************** GETKEY **********************************/
-
-SILC_FSM_STATE(silc_server_st_command_reply_getkey)
-{
- SilcServerThread thread = fsm_context;
- SilcServer server = thread->server;
- SilcServerCommand cmd = state_context;
- SilcArgumentPayload args = silc_command_get_args(cmd->payload);
- SilcStatus status, error;
- unsigned char *tmp;
- SilcUInt32 len;
- SilcClientEntry client = NULL;
- SilcServerEntry server_entry = NULL;
- SilcIDPayload idp = NULL;
- SilcClientID client_id;
- SilcServerID server_id;
- SilcIdType id_type;
- SilcPublicKey public_key = NULL;
-
- COMMAND_CHECK_STATUS;
-
- /* Get ID */
- tmp = silc_argument_get_arg_type(args, 2, &len);
- if (!tmp)
- goto out;
- idp = silc_id_payload_parse(tmp, len);
- if (!idp)
- goto out;
-
- /* Get the public key payload */
- tmp = silc_argument_get_arg_type(args, 3, &len);
- if (!tmp)
- goto out;
- if (!silc_public_key_payload_decode(tmp, len, &public_key))
- goto out;
-
- /* Store the public key */
- id_type = silc_id_payload_get_type(idp);
- if (id_type == SILC_ID_CLIENT) {
- if (!silc_id_payload_get_id(idp, &client_id, sizeof(client_id)))
- goto out;
-
- client = silc_server_find_client_by_id(server, &client_id, TRUE, NULL);
- if (!client)
- goto out;
-
- if (!client->data.public_key) {
- silc_skr_add_public_key_simple(server->repository, public_key,
- SILC_SKR_USAGE_IDENTIFICATION, client);
- client->data.public_key = public_key;
- public_key = NULL;
- }
-
- } else if (id_type == SILC_ID_SERVER) {
- if (!silc_id_payload_get_id(idp, &server_id, sizeof(server_id)))
- goto out;
-
- server_entry = silc_server_find_server_by_id(server, &server_id,
- TRUE, NULL);
- if (!server_entry)
- goto out;
-
- server_entry->data.public_key = public_key;
- public_key = NULL;
- }
-
- out:
- silc_server_command_pending_signal(cmd);
- if (idp)
- silc_id_payload_free(idp);
- if (public_key)
- silc_pkcs_public_key_free(public_key);
- err:
- silc_server_command_reply_free(cmd);
-
- return SILC_FSM_FINISH;
-}
-
-
-/******************************** SERVICE ***********************************/
-
-SILC_FSM_STATE(silc_server_st_command_reply_service)
-{
- SilcServerThread thread = fsm_context;
- SilcServerCommand cmd = state_context;
- SilcStatus status, error;
-
- COMMAND_CHECK_STATUS;
-
- out:
- silc_server_command_pending_signal(cmd);
- err:
- silc_server_command_reply_free(cmd);
-
- return SILC_FSM_FINISH;
-}