From db5be1005b40b416681909cd557ba79ac6935203 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sun, 21 Apr 2002 17:59:11 +0000 Subject: [PATCH] updates. --- CHANGES | 15 +++ TODO | 4 +- apps/irssi/src/silc/core/client_ops.c | 12 +-- apps/silcd/packet_receive.c | 87 +++++++-------- apps/silcd/server.c | 124 ++++++++++++++-------- apps/silcd/server.h | 2 +- apps/silcd/server_util.c | 13 +-- doc/draft-riikonen-silc-commands-03.nroff | 25 ++++- doc/draft-riikonen-silc-pp-05.nroff | 13 ++- lib/silcclient/client.c | 22 +++- lib/silcclient/client_internal.h | 2 +- lib/silcclient/command.c | 4 +- lib/silcclient/command_reply.c | 111 +++++-------------- lib/silcclient/command_reply.h | 11 -- lib/silccore/silcstatus.h | 6 +- lib/silcutil/silcutil.c | 74 +++++++++++++ lib/silcutil/silcutil.h | 14 +++ 17 files changed, 324 insertions(+), 215 deletions(-) diff --git a/CHANGES b/CHANGES index da7eafb5..b3aecd1f 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,18 @@ +Sun Apr 21 19:44:38 EEST 2002 Pekka Riikonen + + * Disconnect Payload includes now the status type. Updated + the protocol specs and the code. Protocol TODO #25. + Affected files are silcd/server.c, lib/silcclient/client.c. + + * Added NOT_AUTHENTICATED, BAD_SERVER_ID, INCOMPLETE_INFORMATION, + KEY_EXCHANGE_FAILED and BAD_VERSION error status types. + Moved the silc_client_command_status_messages table to the + lib/silcutil/silcutil.c and added new funtion + silc_get_status_message, which deprecates function + silc_client_status_message. Affected files are + lib/silccore/silcstatus.h, lib/silcclient/command_reply.[ch], + lib/silcutil/silcutil.[ch]. + Fri Apr 19 17:35:15 EEST 2002 Pekka Riikonen * Defined that the nickname hash in Client ID MUST be from diff --git a/TODO b/TODO index 16393d8e..6ce2572a 100644 --- a/TODO +++ b/TODO @@ -115,5 +115,5 @@ TODO in SILC Protocol 24. Implement the and the Attribute Payload to the core library, client and server. - 25. Disconnect Payload change to include Status Type instead of - human readable error message? + 26. INVITE notify blocking by mode? Quiet user mode to quiet a user on + channel, settable by chan op/founder? diff --git a/apps/irssi/src/silc/core/client_ops.c b/apps/irssi/src/silc/core/client_ops.c index dc6f358d..846f910f 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -696,7 +696,7 @@ void silc_notify(SilcClient client, SilcClientConnection conn, SilcStatus error = va_arg(va, int); silc_say(client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(error)); + "%s", silc_get_status_message(error)); } break; @@ -1013,7 +1013,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, 3, NULL); if (tmp) silc_say_error("%s: %s", tmp, - silc_client_status_message(status)); + silc_get_status_message(status)); break; } else if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) { /* Try to find the entry for the unknown client ID, since we @@ -1030,7 +1030,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, client_id); if (client_entry && client_entry->nickname) silc_say_error("%s: %s", client_entry->nickname, - silc_client_status_message(status)); + silc_get_status_message(status)); silc_free(client_id); } } @@ -1126,7 +1126,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, 3, NULL); if (tmp) silc_say_error("%s: %s", tmp, - silc_client_status_message(status)); + silc_get_status_message(status)); break; } else if (status == SILC_STATUS_ERR_NO_SUCH_CLIENT_ID) { /* Try to find the entry for the unknown client ID, since we @@ -1143,7 +1143,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, client_id); if (client_entry && client_entry->nickname) silc_say_error("%s: %s", client_entry->nickname, - silc_client_status_message(status)); + silc_get_status_message(status)); silc_free(client_id); } } @@ -1164,7 +1164,7 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, 3, NULL); if (tmp) silc_say_error("%s: %s", tmp, - silc_client_status_message(status)); + silc_get_status_message(status)); break; } diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 6fcbf601..080e9eb5 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -1863,8 +1863,8 @@ SilcClientEntry silc_server_new_client(SilcServer server, /* Remove the old cache entry. */ if (!silc_idcache_del_by_context(server->local_list->clients, client)) { SILC_LOG_INFO(("Unauthenticated client attempted to register to network")); - silc_server_disconnect_remote(server, sock, "Server closed connection: " - "You have not been authenticated"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL); return NULL; } @@ -1879,8 +1879,9 @@ SilcClientEntry silc_server_new_client(SilcServer server, silc_free(realname); SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing " "connection", sock->hostname, sock->ip)); - silc_server_disconnect_remote(server, sock, "Server closed connection: " - "Incomplete client information"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_INCOMPLETE_INFORMATION, + NULL); return NULL; } @@ -1889,8 +1890,9 @@ SilcClientEntry silc_server_new_client(SilcServer server, silc_free(realname); SILC_LOG_ERROR(("Client %s (%s) did not send its username, closing " "connection", sock->hostname, sock->ip)); - silc_server_disconnect_remote(server, sock, "Server closed connection: " - "Incomplete client information"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_INCOMPLETE_INFORMATION, + NULL); return NULL; } @@ -1925,8 +1927,8 @@ SilcClientEntry silc_server_new_client(SilcServer server, SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing " "connection", sock->hostname, sock->ip)); silc_server_disconnect_remote(server, sock, - "Server closed connection: " - "Incomplete client information"); + SILC_STATUS_ERR_INCOMPLETE_INFORMATION, + NULL); return NULL; } @@ -1945,8 +1947,8 @@ SilcClientEntry silc_server_new_client(SilcServer server, SILC_LOG_ERROR(("Client %s (%s) sent incomplete information, closing " "connection", sock->hostname, sock->ip)); silc_server_disconnect_remote(server, sock, - "Server closed connection: " - "Incomplete client information"); + SILC_STATUS_ERR_INCOMPLETE_INFORMATION, + NULL); return NULL; } @@ -1994,7 +1996,7 @@ SilcClientEntry silc_server_new_client(SilcServer server, nickfail++; if (nickfail > 9) { silc_server_disconnect_remote(server, sock, - "Server closed connection: Bad nickname"); + SILC_STATUS_ERR_BAD_NICKNAME, NULL); return NULL; } snprintf(&nickname[strlen(nickname) - 1], 1, "%d", nickfail); @@ -2071,8 +2073,8 @@ SilcServerEntry silc_server_new_server(SilcServer server, SILC_LOG_INFO(("Unauthenticated %s attempted to register to " "network", (sock->type == SILC_SOCKET_TYPE_SERVER ? "server" : "router"))); - silc_server_disconnect_remote(server, sock, "Server closed connection: " - "You have not been authenticated"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_NOT_AUTHENTICATED, NULL); return NULL; } local = FALSE; @@ -2114,8 +2116,8 @@ SilcServerEntry silc_server_new_server(SilcServer server, if (!silc_id_is_valid_server_id(server, server_id, sock)) { SILC_LOG_INFO(("Invalid server ID sent by %s (%s)", sock->ip, sock->hostname)); - silc_server_disconnect_remote(server, sock, "Server closed connection: " - "Your Server ID is not valid"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_BAD_SERVER_ID, NULL); silc_free(server_name); return NULL; } @@ -2932,9 +2934,9 @@ SILC_SERVER_CMD_FUNC(resume_resolve) if (!reply || !silc_command_get_status(reply->payload, NULL, NULL)) { SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, " "closing connection", sock->hostname, sock->ip)); - silc_server_disconnect_remote(server, sock, - "Server closed connection: " - "Incomplete resume information"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_INCOMPLETE_INFORMATION, + "Resuming not possible"); goto out; } @@ -2948,9 +2950,9 @@ SILC_SERVER_CMD_FUNC(resume_resolve) if (!client) { SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, " "closing connection", sock->hostname, sock->ip)); - silc_server_disconnect_remote(server, sock, - "Server closed connection: " - "Incomplete resume information"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_INCOMPLETE_INFORMATION, + "Resuming not possible"); goto out; } } @@ -2958,9 +2960,9 @@ SILC_SERVER_CMD_FUNC(resume_resolve) if (!(client->mode & SILC_UMODE_DETACHED)) { SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, " "closing connection", sock->hostname, sock->ip)); - silc_server_disconnect_remote(server, sock, - "Server closed connection: " - "Incomplete resume information"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_INCOMPLETE_INFORMATION, + "Resuming not possible"); goto out; } } @@ -3020,8 +3022,9 @@ void silc_server_resume_client(SilcServer server, if (!client_id || auth_len < 128) { SILC_LOG_ERROR(("Client %s (%s) sent incomplete resume information, " "closing connection", sock->hostname, sock->ip)); - silc_server_disconnect_remote(server, sock, "Server closed connection: " - "Incomplete resume information"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_INCOMPLETE_INFORMATION, + "Resuming not possible"); return; } @@ -3050,9 +3053,9 @@ void silc_server_resume_client(SilcServer server, } else { SILC_LOG_ERROR(("Client %s (%s) tried to resume unknown client, " "closing connection", sock->hostname, sock->ip)); - silc_server_disconnect_remote(server, sock, - "Server closed connection: " - "Incomplete resume information"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_INCOMPLETE_INFORMATION, + "Resuming not possible"); } return; } @@ -3081,9 +3084,9 @@ void silc_server_resume_client(SilcServer server, if (server->server_type == SILC_SERVER) { SILC_LOG_ERROR(("Client %s (%s) tried to resume un-detached client, " "closing connection", sock->hostname, sock->ip)); - silc_server_disconnect_remote(server, sock, - "Server closed connection: " - "Incomplete resume information"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_INCOMPLETE_INFORMATION, + "Resuming not possible"); return; } } @@ -3092,9 +3095,9 @@ void silc_server_resume_client(SilcServer server, resolve it first. */ if (!detached_client->data.public_key) { if (server->standalone) { - silc_server_disconnect_remote(server, sock, - "Server closed connection: " - "Incomplete resume information"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_INCOMPLETE_INFORMATION, + "Resuming not possible"); } else { /* We must retrieve the detached client's public key by sending GETKEY command. Reprocess this packet after receiving the key */ @@ -3127,9 +3130,9 @@ void silc_server_resume_client(SilcServer server, idata->public_key)) { /* We require that the connection and resuming authentication data must be using same key pair. */ - silc_server_disconnect_remote(server, sock, - "Server closed connection: " - "Incomplete resume information"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_INCOMPLETE_INFORMATION, + "Resuming not possible"); return; } @@ -3141,8 +3144,9 @@ void silc_server_resume_client(SilcServer server, SILC_ID_CLIENT)) { SILC_LOG_ERROR(("Client %s (%s) resume authentication failed, " "closing connection", sock->hostname, sock->ip)); - silc_server_disconnect_remote(server, sock, "Server closed connection: " - "Incomplete resume information"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_INCOMPLETE_INFORMATION, + "Resuming not possible"); return; } @@ -3200,8 +3204,7 @@ void silc_server_resume_client(SilcServer server, nickfail++; if (nickfail > 9) { silc_server_disconnect_remote(server, sock, - "Server closed connection: " - "Bad nickname"); + SILC_STATUS_ERR_BAD_NICKNAME, NULL); return; } snprintf(&client->nickname[strlen(client->nickname) - 1], 1, diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 09c54b7d..6aaf3e55 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -790,8 +790,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second) silc_free(sconn); silc_schedule_task_del_by_callback(server->schedule, silc_server_failure_callback); - silc_server_disconnect_remote(server, sock, "Server closed connection: " - "Key exchange failed"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); return; } @@ -821,8 +821,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second) silc_free(sconn); silc_schedule_task_del_by_callback(server->schedule, silc_server_failure_callback); - silc_server_disconnect_remote(server, sock, "Server closed connection: " - "Key exchange failed"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); return; } silc_ske_free_key_material(ctx->keymat); @@ -879,8 +879,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_second) silc_free(sconn); silc_schedule_task_del_by_callback(server->schedule, silc_server_failure_callback); - silc_server_disconnect_remote(server, sock, "Server closed connection: " - "Key exchange failed"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); return; } @@ -939,8 +939,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final) protocol->state == SILC_PROTOCOL_STATE_FAILURE) { /* Error occured during protocol */ silc_free(ctx->dest_id); - silc_server_disconnect_remote(server, sock, "Server closed connection: " - "Authentication failed"); + silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED, + NULL); goto out; } @@ -999,8 +999,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_final) if (!id_entry) { silc_free(ctx->dest_id); SILC_LOG_ERROR(("Cannot add new server entry to cache")); - silc_server_disconnect_remote(server, sock, "Server closed connection: " - "Authentication failed"); + silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED, + NULL); goto out; } @@ -1112,7 +1112,8 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection sock, sock->ip ? sock->ip : "")); server->stat.conn_failures++; silc_server_disconnect_remote(server, sock, - "Server closed connection: Unknown host"); + SILC_STATUS_ERR_INCOMPLETE_INFORMATION, + "Unknown host or IP"); return; } @@ -1137,10 +1138,9 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection sock, /* The connection is denied */ SILC_LOG_INFO(("Connection %s (%s) is denied", sock->hostname, sock->ip)); - silc_server_disconnect_remote(server, sock, deny->reason ? - deny->reason : - "Server closed connection: " - "Connection refused"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_BANNED_FROM_SERVER, + deny->reason); server->stat.conn_failures++; return; } @@ -1162,8 +1162,7 @@ silc_server_accept_new_connection_lookup(SilcSocketConnection sock, SILC_LOG_INFO(("Connection %s (%s) is not allowed", sock->hostname, sock->ip)); silc_server_disconnect_remote(server, sock, - "Server closed connection: " - "Connection refused"); + SILC_STATUS_ERR_BANNED_FROM_SERVER); server->stat.conn_failures++; return; } @@ -1289,8 +1288,9 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second) silc_free(ctx); silc_schedule_task_del_by_callback(server->schedule, silc_server_failure_callback); - silc_server_disconnect_remote(server, sock, "Server closed connection: " - "Key exchange failed"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, + NULL); server->stat.auth_failures++; return; } @@ -1320,8 +1320,8 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_second) silc_free(ctx); silc_schedule_task_del_by_callback(server->schedule, silc_server_failure_callback); - silc_server_disconnect_remote(server, sock, "Server closed connection: " - "Key exchange failed"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); server->stat.auth_failures++; return; } @@ -1400,8 +1400,8 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) silc_free(ctx); silc_schedule_task_del_by_callback(server->schedule, silc_server_failure_callback); - silc_server_disconnect_remote(server, sock, "Server closed connection: " - "Authentication failed"); + silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED, + NULL); server->stat.auth_failures++; return; } @@ -1434,9 +1434,8 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) if (!client) { SILC_LOG_ERROR(("Could not add new client to cache")); silc_free(sock->user_data); - silc_server_disconnect_remote(server, sock, - "Server closed connection: " - "Authentication failed"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_AUTH_FAILED, NULL); server->stat.auth_failures++; goto out; } @@ -1539,9 +1538,8 @@ SILC_TASK_CALLBACK(silc_server_accept_new_connection_final) if (!new_server) { SILC_LOG_ERROR(("Could not add new server to cache")); silc_free(sock->user_data); - silc_server_disconnect_remote(server, sock, - "Server closed connection: " - "Authentication failed"); + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_AUTH_FAILED, NULL); server->stat.auth_failures++; goto out; } @@ -1935,13 +1933,26 @@ void silc_server_packet_parse_type(SilcServer server, /* Parse the packet type */ switch (type) { case SILC_PACKET_DISCONNECT: - SILC_LOG_DEBUG(("Disconnect packet")); - if (packet->flags & SILC_PACKET_FLAG_LIST) - break; - if (silc_string_is_ascii(packet->buffer->data, packet->buffer->len)) { - /* Duplicate to null terminate the string. */ - char *message = silc_memdup(packet->buffer->data, packet->buffer->len); - SILC_LOG_ERROR(("%s", message)); + { + SilcStatus status; + char *message = NULL; + + SILC_LOG_DEBUG(("Disconnect packet")); + + if (packet->flags & SILC_PACKET_FLAG_LIST) + break; + if (packet->buffer->len < 1) + break; + + status = (SilcStatus)packet->buffer->data[0]; + if (packet->buffer->len > 1 && + silc_utf8_valid(packet->buffer->data + 1, packet->buffer->len - 1)) + message = silc_memdup(packet->buffer->data, packet->buffer->len); + + SILC_LOG_ERROR(("Disconnected by %s (%s): %s (%d) %s", + sock->ip, sock->hostname, + silc_get_status_message(status), status, + message ? message : "")); silc_free(message); } break; @@ -2444,25 +2455,48 @@ void silc_server_close_connection(SilcServer server, void silc_server_disconnect_remote(SilcServer server, SilcSocketConnection sock, - const char *fmt, ...) + SilcStatus status, ...) { va_list ap; - unsigned char buf[4096]; + unsigned char buf[512]; + SilcBuffer buffer; + char *cp; + int len; if (!sock) return; memset(buf, 0, sizeof(buf)); - va_start(ap, fmt); - vsprintf(buf, fmt, ap); + va_start(ap, status); + cp = va_arg(ap, char *); + if (cp) { + vsnprintf(buf, sizeof(buf) - 1, cp, ap); + cp = buf; + } va_end(ap); SILC_LOG_DEBUG(("Disconnecting remote host")); /* Notify remote end that the conversation is over. The notify message is tried to be sent immediately. */ + + len = 1; + if (cp) + len += silc_utf8_encoded_len(buf, strlen(buf), SILC_STRING_ASCII); + + buffer = silc_buffer_alloc_size(len); + if (!buffer) + goto out; + + buffer->data[0] = status; + if (cp) + silc_utf8_encode(buf, strlen(buf), SILC_STRING_ASCII, buffer->data + 1, + buffer->len - 1); silc_server_packet_send(server, sock, SILC_PACKET_DISCONNECT, 0, - buf, strlen(buf), TRUE); + buffer->data, buffer->len, TRUE); + silc_buffer_free(buffer); + + out: silc_server_packet_queue_purge(server, sock); /* Mark the connection to be disconnected */ @@ -2930,6 +2964,7 @@ SILC_TASK_CALLBACK(silc_server_timeout_remote) { SilcServer server = (SilcServer)context; SilcSocketConnection sock = server->sockets[fd]; + SilcProtocolType protocol = 0; SILC_LOG_DEBUG(("Start")); @@ -2942,6 +2977,7 @@ SILC_TASK_CALLBACK(silc_server_timeout_remote) /* If we have protocol active we must assure that we call the protocol's final callback so that all the memory is freed. */ if (sock->protocol) { + protocol = sock->protocol->protocol->type; silc_protocol_cancel(sock->protocol, server->schedule); sock->protocol->state = SILC_PROTOCOL_STATE_ERROR; silc_protocol_execute_final(sock->protocol, server->schedule); @@ -2952,7 +2988,11 @@ SILC_TASK_CALLBACK(silc_server_timeout_remote) if (sock->user_data) silc_server_free_sock_user_data(server, sock, NULL); - silc_server_disconnect_remote(server, sock, "Server closed connection: " + silc_server_disconnect_remote(server, sock, + protocol == + SILC_PROTOCOL_SERVER_CONNECTION_AUTH ? + SILC_STATUS_ERR_AUTH_FAILED : + SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, "Connection timeout"); } diff --git a/apps/silcd/server.h b/apps/silcd/server.h index 93ec1f49..c9659676 100644 --- a/apps/silcd/server.h +++ b/apps/silcd/server.h @@ -149,7 +149,7 @@ int silc_server_remove_from_one_channel(SilcServer server, int notify); void silc_server_disconnect_remote(SilcServer server, SilcSocketConnection sock, - const char *fmt, ...); + SilcStatus status, ...); SilcChannelEntry silc_server_create_new_channel(SilcServer server, SilcServerID *router_id, char *cipher, diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index b24d07ba..38a7c49c 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -937,7 +937,7 @@ bool silc_server_connection_allowed(SilcServer server, SILC_LOG_INFO(("Connection %s (%s) is too old version", sock->hostname, sock->ip)); silc_server_disconnect_remote(server, sock, - "Server closed connection: " + SILC_STATUS_ERR_BAD_VERSION, "You support too old protocol version"); return FALSE; } @@ -948,7 +948,7 @@ bool silc_server_connection_allowed(SilcServer server, SILC_LOG_INFO(("Connection %s (%s) is too old version", sock->hostname, sock->ip)); silc_server_disconnect_remote(server, sock, - "Server closed connection: " + SILC_STATUS_ERR_BAD_VERSION, "You support too old software version"); return FALSE; } @@ -959,7 +959,7 @@ bool silc_server_connection_allowed(SilcServer server, SILC_LOG_INFO(("Connection %s (%s) is unsupported version", sock->hostname, sock->ip)); silc_server_disconnect_remote(server, sock, - "Server closed connection: " + SILC_STATUS_ERR_BAD_VERSION, "Your software is not supported"); return FALSE; } @@ -977,7 +977,7 @@ bool silc_server_connection_allowed(SilcServer server, SILC_LOG_INFO(("Server is full, closing %s (%s) connection", sock->hostname, sock->ip)); silc_server_disconnect_remote(server, sock, - "Server closed connection: " + SILC_STATUS_ERR_RESOURCE_LIMIT, "Server is full, try again later"); return FALSE; } @@ -986,7 +986,7 @@ bool silc_server_connection_allowed(SilcServer server, SILC_LOG_INFO(("Too many connections from %s (%s), closing connection", sock->hostname, sock->ip)); silc_server_disconnect_remote(server, sock, - "Server closed connection: " + SILC_STATUS_ERR_RESOURCE_LIMIT, "Too many connections from your host"); return FALSE; } @@ -1294,7 +1294,8 @@ silc_server_check_watcher_list_foreach(void *key, void *context, silc_server_send_notify_watch(notify->server, sock, entry, notify->client, notify->new_nick ? notify->new_nick : - notify->client->nickname, notify->notify); + (const char *)notify->client->nickname, + notify->notify); } } diff --git a/doc/draft-riikonen-silc-commands-03.nroff b/doc/draft-riikonen-silc-commands-03.nroff index 470aad30..f5c6b311 100644 --- a/doc/draft-riikonen-silc-commands-03.nroff +++ b/doc/draft-riikonen-silc-commands-03.nroff @@ -190,7 +190,6 @@ described in the command reply descriptions. Status messages: SILC_STATUS_OK - SILC_STATUS_ERR_TOO_MANY_TARGETS SILC_STATUS_ERR_NOT_ENOUGH_PARAMS SILC_STATUS_ERR_NO_SUCH_NICK @@ -2043,11 +2042,10 @@ List of all defined status types: "No such server". Requested server name does not exist. - 13 SILC_STATUS_ERR_TOO_MANY_TARGETS + 13 SILC_STATUS_ERR_INCOMPLETE_INFORMATION - "Duplicate recipients. No message delivered". Message were - tried to be sent to recipient which has several occurrences in - the recipient list. + "Incomplete registration information". Information remote + sent was incomplete. 14 SILC_STATUS_ERR_NO_RECIPIENT @@ -2233,6 +2231,23 @@ List of all defined status types: "Service does not exist". Requested service identifier is unknown. + 50 SILC_STATUS_ERR_NOT_AUTHENTICATED + + "You have not been authenticated". Remote connection is not + authenticated even though it is supposed to be. + + 51 SILC_STATUS_ERR_BAD_SERVER_ID + + "Server ID is not valid". Provided server ID is not valid. + + 52 SILC_STATUS_ERR_KEY_EXCHANGE_FAILED + + "Key exchange failed". Key Exchange protocol failed. + + 53 SILC_STATUS_ERR_BAD_VERSION + + "Bad version". Protocol or software version mismatch. + .in 3 diff --git a/doc/draft-riikonen-silc-pp-05.nroff b/doc/draft-riikonen-silc-pp-05.nroff index b433e3a5..377c32d3 100644 --- a/doc/draft-riikonen-silc-pp-05.nroff +++ b/doc/draft-riikonen-silc-pp-05.nroff @@ -1044,6 +1044,8 @@ represents the Disconnect Payload. 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +| Status | | ++-+-+-+-+-+-+-+-+ + | | ~ Disconnect Message ~ | | @@ -1053,12 +1055,13 @@ represents the Disconnect Payload. .ce Figure 7: Disconnect Payload - - - .in 6 -o Disconnect Message (variable length) - Human readable - reason of the disconnection. +o Status (1 byte) - Indicates the Status Type, defined in [SILC3] + for the reason of disconnection. + +o Disconnect Message (variable length) - Human readable UTF-8 + encoded string indicating reason of the disconnection. This + MAY be omitted. .in 3 diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index becb0829..7b0f1ca7 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -1479,16 +1479,28 @@ SILC_TASK_CALLBACK(silc_client_disconnected_by_server_later) void silc_client_disconnected_by_server(SilcClient client, SilcSocketConnection sock, - SilcBuffer message) + SilcBuffer packet) { - char *msg; + SilcStatus status; + char *message = NULL; SILC_LOG_DEBUG(("Server disconnected us, sock %d", sock->sock)); - msg = silc_memdup(message->data, message->len); + if (packet->len < 1) + return; + + status = (SilcStatus)packet->data[0]; + + if (packet->len > 1 && + silc_utf8_valid(packet->data + 1, packet->len - 1)) + message = silc_memdup(packet->data, packet->len); + client->internal->ops->say(client, sock->user_data, - SILC_CLIENT_MESSAGE_AUDIT, msg); - silc_free(msg); + SILC_CLIENT_MESSAGE_AUDIT, + "Server closed connection: %s (%d) %s", + silc_get_status_message(status), status, + message ? message : ""); + silc_free(message); SILC_SET_DISCONNECTED(sock); diff --git a/lib/silcclient/client_internal.h b/lib/silcclient/client_internal.h index be5c05b1..7cc00499 100644 --- a/lib/silcclient/client_internal.h +++ b/lib/silcclient/client_internal.h @@ -166,7 +166,7 @@ void silc_client_close_connection_real(SilcClient client, SilcClientConnection conn); void silc_client_disconnected_by_server(SilcClient client, SilcSocketConnection sock, - SilcBuffer message); + SilcBuffer packet); void silc_client_error_by_server(SilcClient client, SilcSocketConnection sock, SilcBuffer message); diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index 48885cce..c70584a1 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -2284,9 +2284,9 @@ SILC_CLIENT_CMD_FUNC(getkey) server and did not find anybody. */ if (error == SILC_STATUS_ERR_NO_SUCH_SERVER) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", - silc_client_status_message(SILC_STATUS_ERR_NO_SUCH_NICK)); + silc_get_status_message(SILC_STATUS_ERR_NO_SUCH_NICK)); SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", - silc_client_status_message(error)); + silc_get_status_message(error)); COMMAND_ERROR(SILC_STATUS_ERR_NO_SUCH_NICK); goto out; } diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index 2e194d9f..43376be3 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -36,50 +36,6 @@ #include "silcclient.h" #include "client_internal.h" -const SilcStatusMessage silc_command_status_messages[] = { - - { STAT(NO_SUCH_NICK), "There was no such nickname" }, - { STAT(NO_SUCH_CHANNEL), "There was no such channel" }, - { STAT(NO_SUCH_SERVER), "There was no such server" }, - { STAT(TOO_MANY_TARGETS), "Duplicate recipients. No message delivered" }, - { STAT(NO_RECIPIENT), "No recipient given" }, - { STAT(UNKNOWN_COMMAND), "Unknown command" }, - { STAT(WILDCARDS), "Unknown command" }, - { STAT(NO_CLIENT_ID), "No Client ID given" }, - { STAT(NO_CHANNEL_ID), "No Channel ID given" }, - { STAT(NO_SERVER_ID), "No Server ID given" }, - { STAT(BAD_CLIENT_ID), "Bad Client ID" }, - { STAT(BAD_CHANNEL_ID), "Bad Channel ID" }, - { STAT(NO_SUCH_CLIENT_ID), "There is no such client" }, - { STAT(NO_SUCH_CHANNEL_ID),"There is no such channel" }, - { STAT(NICKNAME_IN_USE), "Nickname already exists" }, - { STAT(NOT_ON_CHANNEL), "You are not on that channel" }, - { STAT(USER_NOT_ON_CHANNEL),"They are not on the channel" }, - { STAT(USER_ON_CHANNEL), "User already on the channel" }, - { STAT(NOT_REGISTERED), "You have not registered" }, - { STAT(NOT_ENOUGH_PARAMS), "Not enough parameters" }, - { STAT(TOO_MANY_PARAMS), "Too many parameters" }, - { STAT(PERM_DENIED), "Permission denied" }, - { STAT(BANNED_FROM_SERVER),"You are banned from this server" }, - { STAT(BAD_PASSWORD), "Cannot join channel. Incorrect password" }, - { STAT(CHANNEL_IS_FULL), "Cannot join channel. Channel is full" }, - { STAT(NOT_INVITED), "Cannot join channel. You have not been invited" }, - { STAT(BANNED_FROM_CHANNEL), "Cannot join channel. You have been banned" }, - { STAT(UNKNOWN_MODE), "Unknown mode" }, - { STAT(NOT_YOU), "Cannot change mode for other users" }, - { STAT(NO_CHANNEL_PRIV), "Permission denied. You are not channel operator" }, - { STAT(NO_CHANNEL_FOPRIV),"Permission denied. You are not channel founder" }, - { STAT(NO_SERVER_PRIV), "Permission denied. You are not server operator" }, - { STAT(NO_ROUTER_PRIV), "Permission denied. You are not SILC operator" }, - { STAT(BAD_NICKNAME), "Bad nickname" }, - { STAT(BAD_CHANNEL), "Bad channel name" }, - { STAT(AUTH_FAILED), "Authentication failed" }, - { STAT(UNKNOWN_ALGORITHM), "Unsupported algorithm" }, - { STAT(NO_SUCH_SERVER_ID), "No such Server ID" }, - - { 0, NULL } -}; - #define SAY cmd->client->internal->ops->say /* All functions that call the COMMAND_CHECK_STATUS macro must have @@ -156,23 +112,6 @@ void silc_client_command_reply_process(SilcClient client, } } -/* Returns status message string */ - -char *silc_client_status_message(SilcStatus status) -{ - int i; - - for (i = 0; silc_command_status_messages[i].message; i++) { - if (silc_command_status_messages[i].status == status) - break; - } - - if (silc_command_status_messages[i].message == NULL) - return NULL; - - return silc_command_status_messages[i].message; -} - /* Free command reply context and its internals. */ void silc_client_command_reply_free(SilcClientCommandReplyContext cmd) @@ -554,7 +493,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(nick) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "Cannot set nickname: %s", - silc_client_status_message(cmd->error)); + silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -667,7 +606,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(topic) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -721,7 +660,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(invite) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -763,7 +702,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(kill) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -793,7 +732,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(info) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, "%s", - silc_client_status_message(cmd->error)); + silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -849,7 +788,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(ping) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -910,7 +849,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(join) if (cmd->error != SILC_STATUS_OK) { if (cmd->error != SILC_STATUS_ERR_USER_ON_CHANNEL) SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1089,7 +1028,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(motd) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; return; } @@ -1146,7 +1085,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(umode) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1182,7 +1121,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(cmode) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1241,7 +1180,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(cumode) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1315,7 +1254,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(kick) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1335,7 +1274,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(silcoper) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1355,7 +1294,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(oper) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1376,7 +1315,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(detach) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1405,7 +1344,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(watch) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1429,7 +1368,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(ban) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1475,7 +1414,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(leave) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1520,7 +1459,7 @@ static void silc_client_command_reply_users_cb(SilcClient client, cmd->status = cmd->error = SILC_STATUS_ERR_NO_SUCH_CHANNEL; SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_USERS); silc_client_command_reply_free(cmd); @@ -1724,7 +1663,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(users) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -1762,7 +1701,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(getkey) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -2001,7 +1940,7 @@ static void silc_client_command_reply_users_i_cb(SilcClient client, cmd->status = cmd->error = SILC_STATUS_ERR_NO_SUCH_CHANNEL; SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; SILC_CLIENT_PENDING_EXEC(cmd, SILC_COMMAND_USERS); silc_client_command_reply_free(cmd); @@ -2048,7 +1987,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(connect) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -2068,7 +2007,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(close) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } @@ -2088,7 +2027,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(shutdown) if (cmd->error != SILC_STATUS_OK) { SAY(cmd->client, conn, SILC_CLIENT_MESSAGE_ERROR, - "%s", silc_client_status_message(cmd->error)); + "%s", silc_get_status_message(cmd->error)); COMMAND_REPLY_ERROR; goto out; } diff --git a/lib/silcclient/command_reply.h b/lib/silcclient/command_reply.h index 9811e1c9..cace424a 100644 --- a/lib/silcclient/command_reply.h +++ b/lib/silcclient/command_reply.h @@ -65,19 +65,8 @@ struct SilcClientCommandReplyContextStruct { #define SILC_CLIENT_CMD_REPLY_FUNC(func) \ void silc_client_command_reply_##func(void *context, void *context2) -/* Status message structure. Messages are defined below. */ -typedef struct { - SilcStatus status; - char *message; -} SilcStatusMessage; - -/* Status messages returned by the server */ -#define STAT(x) SILC_STATUS_ERR_##x -DLLAPI extern const SilcStatusMessage silc_command_status_messages[]; - /* Prototypes */ -char *silc_client_status_message(SilcStatus status); void silc_client_command_reply_process(SilcClient client, SilcSocketConnection sock, SilcPacketContext *packet); diff --git a/lib/silccore/silcstatus.h b/lib/silccore/silcstatus.h index 6accc4a1..dea64e94 100644 --- a/lib/silccore/silcstatus.h +++ b/lib/silccore/silcstatus.h @@ -58,7 +58,7 @@ typedef SilcUInt8 SilcStatus; #define SILC_STATUS_ERR_NO_SUCH_NICK 10 #define SILC_STATUS_ERR_NO_SUCH_CHANNEL 11 #define SILC_STATUS_ERR_NO_SUCH_SERVER 12 -#define SILC_STATUS_ERR_TOO_MANY_TARGETS 13 +#define SILC_STATUS_ERR_INCOMPLETE_INFORMATION 13 #define SILC_STATUS_ERR_NO_RECIPIENT 14 #define SILC_STATUS_ERR_UNKNOWN_COMMAND 15 #define SILC_STATUS_ERR_WILDCARDS 16 @@ -95,6 +95,10 @@ typedef SilcUInt8 SilcStatus; #define SILC_STATUS_ERR_NO_SUCH_SERVER_ID 47 #define SILC_STATUS_ERR_RESOURCE_LIMIT 48 #define SILC_STATUS_ERR_NO_SUCH_SERVICE 49 +#define SILC_STATUS_ERR_NOT_AUTHENTICATED 50 +#define SILC_STATUS_ERR_BAD_SERVER_ID 51 +#define SILC_STATUS_ERR_KEY_EXCHANGE_FAILED 52 +#define SILC_STATUS_ERR_BAD_VERSION 53 /***/ #endif /* SILCSTATUS_H */ diff --git a/lib/silcutil/silcutil.c b/lib/silcutil/silcutil.c index f622bed5..acdf3a9b 100644 --- a/lib/silcutil/silcutil.c +++ b/lib/silcutil/silcutil.c @@ -957,3 +957,77 @@ bool silc_get_mode_list(SilcBuffer mode_list, SilcUInt32 mode_list_count, return TRUE; } + +/* Status message structure. Messages are defined below. */ +typedef struct { + SilcStatus status; + char *message; +} SilcStatusMessage; + +#define STAT(x) SILC_STATUS_ERR_##x +const SilcStatusMessage silc_status_messages[] = { + + { STAT(NO_SUCH_NICK), "There was no such nickname" }, + { STAT(NO_SUCH_CHANNEL), "There was no such channel" }, + { STAT(NO_SUCH_SERVER), "There was no such server" }, + { STAT(INCOMPLETE_INFORMATION), "Incomplete registration information" }, + { STAT(NO_RECIPIENT), "No recipient given" }, + { STAT(UNKNOWN_COMMAND), "Unknown command" }, + { STAT(WILDCARDS), "Wilcrads not allowed" }, + { STAT(NO_CLIENT_ID), "No Client ID given" }, + { STAT(NO_CHANNEL_ID), "No Channel ID given" }, + { STAT(NO_SERVER_ID), "No Server ID given" }, + { STAT(BAD_CLIENT_ID), "Bad Client ID" }, + { STAT(BAD_CHANNEL_ID), "Bad Channel ID" }, + { STAT(NO_SUCH_CLIENT_ID), "There is no such client" }, + { STAT(NO_SUCH_CHANNEL_ID),"There is no such channel" }, + { STAT(NICKNAME_IN_USE), "Nickname already exists" }, + { STAT(NOT_ON_CHANNEL), "You are not on that channel" }, + { STAT(USER_NOT_ON_CHANNEL),"They are not on the channel" }, + { STAT(USER_ON_CHANNEL), "User already on the channel" }, + { STAT(NOT_REGISTERED), "You have not registered" }, + { STAT(NOT_ENOUGH_PARAMS), "Not enough parameters" }, + { STAT(TOO_MANY_PARAMS), "Too many parameters" }, + { STAT(PERM_DENIED), "Permission denied" }, + { STAT(BANNED_FROM_SERVER),"You are banned from this server" }, + { STAT(BAD_PASSWORD), "Cannot join channel. Incorrect password" }, + { STAT(CHANNEL_IS_FULL), "Cannot join channel. Channel is full" }, + { STAT(NOT_INVITED), "Cannot join channel. You have not been invited" }, + { STAT(BANNED_FROM_CHANNEL), "Cannot join channel. You have been banned" }, + { STAT(UNKNOWN_MODE), "Unknown mode" }, + { STAT(NOT_YOU), "Cannot change mode for other users" }, + { STAT(NO_CHANNEL_PRIV), "Permission denied. You are not channel operator" }, + { STAT(NO_CHANNEL_FOPRIV),"Permission denied. You are not channel founder" }, + { STAT(NO_SERVER_PRIV), "Permission denied. You are not server operator" }, + { STAT(NO_ROUTER_PRIV), "Permission denied. You are not SILC operator" }, + { STAT(BAD_NICKNAME), "Bad nickname" }, + { STAT(BAD_CHANNEL), "Bad channel name" }, + { STAT(AUTH_FAILED), "Authentication failed" }, + { STAT(UNKNOWN_ALGORITHM), "Unsupported algorithm" }, + { STAT(NO_SUCH_SERVER_ID), "No such Server ID" }, + { STAT(RESOURCE_LIMIT), "No more free resources" }, + { STAT(NO_SUCH_SERVICE), "Service doesn't exist" }, + { STAT(NOT_AUTHENTICATED), "You have not been authenticated" }, + { STAT(BAD_SERVER_ID), "Server ID is not valid" }, + { STAT(KEY_EXCHANGE_FAILED), "Key exchange failed" }, + { STAT(BAD_VERSION), "Bad version" }, + + { 0, NULL } +}; + +/* Returns status message string */ + +char *silc_get_status_message(unsigned char status) +{ + int i; + + for (i = 0; silc_status_messages[i].message; i++) { + if (silc_status_messages[i].status == status) + break; + } + + if (silc_status_messages[i].message == NULL) + return ""; + + return silc_status_messages[i].message; +} diff --git a/lib/silcutil/silcutil.h b/lib/silcutil/silcutil.h index 0a01978e..2c0230fc 100644 --- a/lib/silcutil/silcutil.h +++ b/lib/silcutil/silcutil.h @@ -573,4 +573,18 @@ char *silc_get_real_name(); bool silc_get_mode_list(SilcBuffer mode_list, SilcUInt32 mode_list_count, SilcUInt32 **list); + +/****f* silcutil/SilcUtilAPI/silc_get_status_message + * + * SYNOPSIS + * + * char *silc_get_status_message(SilcStatus status) + * + * DESCRIPTION + * + * Returns status message string + * + ***/ +char *silc_get_status_message(unsigned char status); + #endif /* !SILCUTIL_H */ -- 2.24.0