From ecb19b3983b3e74bc4aaa82277abd125c53c3623 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Thu, 20 Feb 2003 15:27:21 +0000 Subject: [PATCH] Merged from silc_1_0_branch (second merge). --- CHANGES | 88 +++++ CREDITS | 8 +- INSTALL | 5 +- TODO | 12 +- apps/irssi/docs/help/in/cmode.in | 29 +- apps/irssi/docs/help/in/kill.in | 12 +- apps/irssi/src/core/network.c | 22 +- apps/irssi/src/core/session.c | 2 + .../irssi/src/fe-common/core/fe-common-core.c | 2 +- apps/irssi/src/fe-text/gui-readline.c | 7 +- apps/irssi/src/fe-text/silc.c | 2 + apps/irssi/src/silc/core/client_ops.c | 3 +- apps/irssi/src/silc/core/silc-core.c | 2 + apps/silcd/command.c | 73 ++-- apps/silcd/idlist.c | 2 +- apps/silcd/packet_receive.c | 47 ++- apps/silcd/packet_send.c | 1 + apps/silcd/server.c | 98 +++-- apps/silcd/server_backup.c | 28 +- apps/silcd/server_util.c | 77 ++-- apps/silcd/server_util.h | 3 + apps/silcd/serverconfig.c | 37 +- apps/silcd/serverconfig.h | 2 +- apps/silcd/serverid.c | 2 +- apps/silcd/silcd.c | 31 ++ configure.in.pre | 74 +++- doc/silcd.conf.yo | 3 +- lib/doc/LIBINDEX | 7 + lib/doc/command_reply_args.html | 373 ++++++++++++++++++ lib/doc/notifyargs.html | 269 +++++++++++++ lib/doc/platforms.html | 60 +++ lib/silcclient/DIRECTORY | 6 +- lib/silcclient/client_notify.c | 2 +- lib/silcclient/command.c | 4 + lib/silcclient/protocol.c | 6 +- lib/silcclient/silcclient.h | 3 +- lib/silccore/Makefile.am | 2 +- lib/silccore/silcauth.c | 8 +- lib/silccrypt/pkcs1.c | 16 +- lib/silccrypt/rsa.c | 65 +-- lib/silccrypt/silcpkcs.c | 121 +++--- lib/silccrypt/silcrng.c | 2 +- lib/silcmath/silcmp.h | 24 +- lib/silcske/silcske.c | 63 ++- lib/silcutil/silcbuffer.h | 32 +- lib/silcutil/silcbuffmt.c | 11 +- lib/silcutil/silcconfig.c | 23 +- lib/silcutil/silcconfig.h | 4 +- lib/silcutil/silclog.c | 2 +- lib/silcutil/silclog.h | 2 +- lib/silcutil/silcschedule.c | 22 +- lib/silcutil/silctypes.h | 54 ++- lib/silcutil/unix/silcunixsockconn.c | 5 +- prepare | 2 +- scripts/stripspaces.tcl | 4 +- tutorial/Makefile.defines_int.in | 2 +- 56 files changed, 1409 insertions(+), 457 deletions(-) create mode 100644 lib/doc/command_reply_args.html create mode 100644 lib/doc/notifyargs.html create mode 100644 lib/doc/platforms.html diff --git a/CHANGES b/CHANGES index 40e281ac..abc7a30a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,91 @@ +Tue Feb 4 22:53:26 EET 2003 Pekka Riikonen + + * NULL terminate allocated string in silc_buffer_strformat. + Affected file lib/silcutil/silcbuffmt.c. + + * Rewrote the invite/ban list string handling in server to + use SilcBuffer instead. Affected files are silcd/command.c + and silcd/server_util.c. + +Mon Feb 3 14:43:52 CET 2003 Pekka Riikonen + + * Fixed double free in CMODE command when setting new HMAC + for channel. Affected file silcd/command.c. + + * Added couple of missing memset's to zero sensitive memory. + Affected files silcd/command.c, lib/silcclient/command.c. + +Sun Jan 26 12:20:30 EET 2003 Pekka Riikonen + + * Fixed a double free in INVITE command error handling in + server. Affected file silcd/command.c. + + * Added macros SILC_SWAB_[16|32] to swab byte order of + 16-bit and 32-bit unsigned integers. Affected file + lib/silcutil/silctypes.h. + + * Use the SILC_SWAB_16 instead of htons() in server when + handling ports since the ports in structures are always + in little-endian order (regardless of platform). Affected + file silcd/serverid.c and silcd/server_backup.c. + +Tue Jan 21 17:18:04 EET 2003 Pekka Riikonen + + * Send DISCONNECT in close admin command in server. Affected + file silcd/command.c. + + * Check whether we are already connecting to a remote router + (in addition of checking whether we are already connected) + before creating new connection. Affected file silcd/server.c. + +Thu Jan 16 18:47:00 EET 2003 Pekka Riikonen + + * Added better compiler and compiler flags checking in + configure. + + * Check that socket is valid after QoS is applied to data. + Affected file lib/silcutil/unix/silcunixsockconn.c. + + * Make sure the socket connecetion is not closed to early + when closing connection in server. Also make sure the + connection is always closed after error in a protocol. + Affected file silcd/server.c. + +Wed Jan 15 11:03:36 CET 2003 Pekka Riikonen + + * Removed --session and --dummy options from Irssi SILC Client. + -d option is available only if --enable-debug was given. + Affected files are irssi/src/silc/core/silc-core, + irssi/src/core/session.c and irssi/src/fe-text/silc.c. + +Tue Jan 14 12:25:09 CET 2003 Pekka Riikonen + + * Added silc_buffer_steal to steal the data from the buffer. + Affected file lib/silcutil/silcbuffer.h. + +Sat Jan 11 18:16:29 CET 2003 Giovanni Giacobbi + + * Fixed server crash with double Primary block in config file. + + Fixed also various memory leaks around the config file + parser. Affected files lib/silcutil/silcconfig.c, + silcd/serverconfig.c. + + * Changed my nickname (Johnny Mnemonic) to my real name, this + means that bugs introduced by him were actually introduced + by me! + +Tue Jan 7 21:58:53 CET 2003 Jochen Eisinger + + * Don't display "foo appears as foo\nYou're now known as foo" + messages. Affected file irssi/src/silc/core/client_ops.c + +Tue Jan 7 20:08:15 EET 2003 Pekka Riikonen + + * Fixed error handling of invalid client entry when calling + commands in server. Fixes a crash. Affected file + silcd/command.c. + Thu Dec 26 14:19:29 EET 2002 Pekka Riikonen * Added some sanity checks in server for correctness of the diff --git a/CREDITS b/CREDITS index 63ec9f6a..950df4ab 100644 --- a/CREDITS +++ b/CREDITS @@ -33,12 +33,12 @@ S: Skinnarilankatu 28 E 2 S: 53850 Lappeenranta S: Finland -N: Johnny Mnemonic +N: Giovanni Giacobbi +E: giovanni@giacobbi.net E: johnny@themnemonic.org -W: http://www.themnemonic.org/ -P: 1024D/34E2AB40 9AC6 1460 A5D0 4DB7 70D0 5DA5 C17F 50CD 34E2 AB40 +P: 1024D/B2D79FC1 6247 640C 1C90 1EE4 D800 E4E2 2D58 3DF1 B2D7 9FC1 +D: silcconfig, silclog, various patches around D: RPM packages -D: silclog, misc bugfixes S: 35100 Padova S: Italy diff --git a/INSTALL b/INSTALL index 9871e92e..bca665aa 100644 --- a/INSTALL +++ b/INSTALL @@ -1,7 +1,7 @@ Quick Installation ================== - To configure and compile SILC package give the comands: + To configure and compile SILC package give the commands: ./configure make (or gmake) @@ -11,6 +11,9 @@ Quick Installation /usr/local/silc/ directory. System wide configuration files are installed into the /etc/silc/ directory. +You may need to add the /usr/local/silc path to your PATH environment +variable after the installation. + Some Configuration Options ========================== diff --git a/TODO b/TODO index 1d5f3a69..fb406ebf 100644 --- a/TODO +++ b/TODO @@ -9,6 +9,11 @@ TODO for Irssi SILC Client 1.0 TODO for SILC Server 1.0 ======================== + o INVITE and BAN notifys send the entire list as notify, but only the + added/removed info should be sent. + + o The CMODE cipher & hmac change problem (#101). + o Fix CUMODE_CHANGE and CMODE_CHANGE for founder key things. o 1.2 backup router support @@ -32,18 +37,11 @@ TODO in Toolkit Documentation Stuff that needs to be done in order to complete the Tooolkit Reference Manual (Do these to 0.9.x). - o Document the "notify" and "command_reply" client operations variable - argument lists for all possible notify types and command replys. - o Write "Programming with Toolkit" document, describing how to build Toolkit, how the build system works, where is everything, how new (external) projects can be glued into Toolkit (use irssi as an example), and how external projects can use Toolkit without gluing into it (how to link etc), debugging, architecture, types, etc. - o Write "Platform Implementations" document to describe what platforms - Toolkit support, what has been implemented, what has not been, what - works differently etc. - o Searching of predefined keywords, exact and partial matches (would be nice). diff --git a/apps/irssi/docs/help/in/cmode.in b/apps/irssi/docs/help/in/cmode.in index 6806bea1..e4cf6b4c 100644 --- a/apps/irssi/docs/help/in/cmode.in +++ b/apps/irssi/docs/help/in/cmode.in @@ -5,27 +5,28 @@ This command is used to manage the modes of the channel. Most of the modes require special privileges, such as channel operator or channel founder privileges to work. The mode is added by adding + before the option(s) and removed by adding - before the -option(s). The following modes are available: +option(s). The (*) mark below means that only founder may set/unset +that mode. Other modes both channel operator and founder may manage. + +The following modes are available: p Set/unset channel as private channel s Set/unset channel as secret channel - k Set/unset that channel uses private channel key + k Enable/disable channel private key usage (*) i Set/unset channel as invite only channel t Set/unset that only channel operator or founder may set channel topic m Set/unset user silencing. Normal users - are not able to talk on channel. Only - channel founder may set this mode + are not able to talk on channel. (*) M Set/unset operator silencing. Operators - are not able to talk on channel. Only - channel founder may set this mode + are not able to talk on channel. (*) l Set/unset channel's user limit a Set/unset passphrase for channel that must - be provided when joining to the channel. - c Set/unset channel's cipher - h Set/unset channel's hmac + be provided when joining to the channel. (*) + c Set/unset channel's cipher (*) + h Set/unset channel's hmac (*) f [ []] - Set/unset channel founder authentication. + Set/unset channel founder authentication. (*) Channel founder may set this mode so that if the client leaves the channel it can claim the founder rights when it returns @@ -45,4 +46,10 @@ Multiple modes can be set/unset at once if the modes does not require any arguments. If mode requires an argument then only one mode can be set at once. -See also: CUMODE, UMODE, JOIN +When the +k (channel private key mode) mode is set the channel's +default cipher and HMAC are not used. The private key (see /HELP KEY +for help how to set the private key) defines the cipher and HMAC for +the channel while +k mode is set. Also the +c and +h modes are ignored +when channel private key is set. + +See also: CUMODE, UMODE, JOIN, KEY diff --git a/apps/irssi/docs/help/in/kill.in b/apps/irssi/docs/help/in/kill.in index 96b6b6ca..aa274c98 100644 --- a/apps/irssi/docs/help/in/kill.in +++ b/apps/irssi/docs/help/in/kill.in @@ -16,15 +16,15 @@ SILC operator -pubkey has no effect. Examples: - /KILL myself -pubkey + /KILL myself -pubkey - Kill yourself with nickname "myself" from network. + Kill yourself with nickname "myself" from network. - /SILCOPER user - /KILL someclient You have been killed + /SILCOPER user + /KILL someclient You have been killed - Become SILC operator and kill client named - "someclient", with comment "You have been killed". + Become SILC operator and kill client named + "someclient", with comment "You have been killed". See also: OPER, SILCOPER diff --git a/apps/irssi/src/core/network.c b/apps/irssi/src/core/network.c index bb46dd54..5892ac69 100644 --- a/apps/irssi/src/core/network.c +++ b/apps/irssi/src/core/network.c @@ -27,7 +27,7 @@ # define INADDR_NONE INADDR_BROADCAST #endif -union sockaddr_union { +union irssi_sockaddr_union { struct sockaddr sa; struct sockaddr_in sin; #ifdef HAVE_IPV6 @@ -71,7 +71,7 @@ G_INLINE_FUNC #else static #endif -void sin_set_ip(union sockaddr_union *so, const IPADDR *ip) +void sin_set_ip(union irssi_sockaddr_union *so, const IPADDR *ip) { if (ip == NULL) { #ifdef HAVE_IPV6 @@ -93,7 +93,7 @@ void sin_set_ip(union sockaddr_union *so, const IPADDR *ip) memcpy(&so->sin.sin_addr, &ip->ip, 4); } -void sin_get_ip(const union sockaddr_union *so, IPADDR *ip) +void sin_get_ip(const union irssi_sockaddr_union *so, IPADDR *ip) { ip->family = so->sin.sin_family; @@ -110,7 +110,7 @@ G_INLINE_FUNC #else static #endif -void sin_set_port(union sockaddr_union *so, int port) +void sin_set_port(union irssi_sockaddr_union *so, int port) { #ifdef HAVE_IPV6 if (so->sin.sin_family == AF_INET6) @@ -125,7 +125,7 @@ G_INLINE_FUNC #else static #endif -int sin_get_port(union sockaddr_union *so) +int sin_get_port(union irssi_sockaddr_union *so) { #ifdef HAVE_IPV6 if (so->sin.sin_family == AF_INET6) @@ -173,7 +173,7 @@ GIOChannel *net_connect(const char *addr, int port, IPADDR *my_ip) /* Connect to socket with ip address */ GIOChannel *net_connect_ip(IPADDR *ip, int port, IPADDR *my_ip) { - union sockaddr_union so; + union irssi_sockaddr_union so; int handle, ret, opt = 1; if (my_ip != NULL && ip->family != my_ip->family) { @@ -274,7 +274,7 @@ void net_disconnect(GIOChannel *handle) address. */ GIOChannel *net_listen(IPADDR *my_ip, int *port) { - union sockaddr_union so; + union irssi_sockaddr_union so; int ret, handle, opt = 1; socklen_t len; @@ -331,7 +331,7 @@ GIOChannel *net_listen(IPADDR *my_ip, int *port) /* Accept a connection on a socket */ GIOChannel *net_accept(GIOChannel *handle, IPADDR *addr, int *port) { - union sockaddr_union so; + union irssi_sockaddr_union so; int ret; socklen_t addrlen; @@ -391,7 +391,7 @@ int net_transmit(GIOChannel *handle, const char *data, int len) /* Get socket address/port */ int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port) { - union sockaddr_union so; + union irssi_sockaddr_union so; socklen_t addrlen; g_return_val_if_fail(handle != NULL, -1); @@ -414,7 +414,7 @@ int net_getsockname(GIOChannel *handle, IPADDR *addr, int *port) int net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6) { #ifdef HAVE_IPV6 - union sockaddr_union *so; + union irssi_sockaddr_union *so; struct addrinfo hints, *ai, *ailist; int ret, count; #else @@ -437,7 +437,7 @@ int net_gethostbyname(const char *addr, IPADDR *ip4, IPADDR *ip6) count = 0; for (ai = ailist; ai != NULL && count < 2; ai = ai->ai_next) { - so = (union sockaddr_union *) ai->ai_addr; + so = (union irssi_sockaddr_union *) ai->ai_addr; if (ai->ai_family == AF_INET6 && ip6->family == 0) { sin_get_ip(so, ip6); diff --git a/apps/irssi/src/core/session.c b/apps/irssi/src/core/session.c index 7ebd8f82..40c4f547 100644 --- a/apps/irssi/src/core/session.c +++ b/apps/irssi/src/core/session.c @@ -350,7 +350,9 @@ static void sig_init_finished(void) void session_init(void) { static struct poptOption options[] = { +#if 0 /* --session is not available in SILC Client */ { "session", 0, POPT_ARG_STRING, &session_file, 0, "Used by /UPGRADE command", "PATH" }, +#endif { NULL, '\0', 0, NULL } }; diff --git a/apps/irssi/src/fe-common/core/fe-common-core.c b/apps/irssi/src/fe-common/core/fe-common-core.c index aa830350..bc556a6a 100644 --- a/apps/irssi/src/fe-common/core/fe-common-core.c +++ b/apps/irssi/src/fe-common/core/fe-common-core.c @@ -132,7 +132,7 @@ void fe_common_core_init(void) static struct poptOption options[] = { { NULL, '\0', POPT_ARG_INCLUDE_TABLE, version_options, 0, NULL, NULL }, POPT_AUTOHELP - { "connect", 'c', POPT_ARG_STRING, &autocon_server, 0, "Automatically connect to server/ircnet", "SERVER" }, + { "connect", 'c', POPT_ARG_STRING, &autocon_server, 0, "Automatically connect to server", "SERVER" }, { "password", 'w', POPT_ARG_STRING, &autocon_password, 0, "Autoconnect password", "PASSWORD" }, { "port", 'p', POPT_ARG_INT, &autocon_port, 0, "Autoconnect port", "PORT" }, { "noconnect", '!', POPT_ARG_NONE, &no_autoconnect, 0, "Disable autoconnecting", NULL }, diff --git a/apps/irssi/src/fe-text/gui-readline.c b/apps/irssi/src/fe-text/gui-readline.c index 66867ffb..4de1936e 100644 --- a/apps/irssi/src/fe-text/gui-readline.c +++ b/apps/irssi/src/fe-text/gui-readline.c @@ -182,6 +182,7 @@ static void key_send_line(void) { HISTORY_REC *history; char *str, *add_history; + gint flags = (redir ? redir->flags : 0); str = gui_entry_get_text(active_entry); @@ -197,9 +198,13 @@ static void key_send_line(void) active_win->active_server, active_win->active); } else { - if (redir->flags & ENTRY_REDIRECT_FLAG_HIDDEN) + if (flags & ENTRY_REDIRECT_FLAG_HIDDEN && add_history) { + memset(add_history, 0, strlen(add_history)); g_free_and_null(add_history); + } handle_entry_redirect(str); + if (flags & ENTRY_REDIRECT_FLAG_HIDDEN && str) + memset(str, 0, strlen(str)); } if (add_history != NULL) { diff --git a/apps/irssi/src/fe-text/silc.c b/apps/irssi/src/fe-text/silc.c index 452fa009..1591e601 100644 --- a/apps/irssi/src/fe-text/silc.c +++ b/apps/irssi/src/fe-text/silc.c @@ -310,7 +310,9 @@ static void winsock_init(void) int main(int argc, char **argv) { static struct poptOption options[] = { +#if 0 /* --dummy is not available in SILC Client */ { "dummy", 'd', POPT_ARG_NONE, &dummy, 0, "Use the dummy terminal mode", NULL }, +#endif { NULL, '\0', 0, NULL } }; diff --git a/apps/irssi/src/silc/core/client_ops.c b/apps/irssi/src/silc/core/client_ops.c index b55b0d31..2f9c7541 100644 --- a/apps/irssi/src/silc/core/client_ops.c +++ b/apps/irssi/src/silc/core/client_ops.c @@ -1688,7 +1688,8 @@ silc_command_reply(SilcClient client, SilcClientConnection conn, return; nicks = nicklist_get_same(SERVER(server), client_entry->nickname); - if (nicks != NULL) { + if ((nicks != NULL) && + (strcmp(SERVER(server)->nick, client_entry->nickname))) { char buf[512]; SilcClientEntry collider, old; diff --git a/apps/irssi/src/silc/core/silc-core.c b/apps/irssi/src/silc/core/silc-core.c index eeea2685..bf572810 100644 --- a/apps/irssi/src/silc/core/silc-core.c +++ b/apps/irssi/src/silc/core/silc-core.c @@ -360,8 +360,10 @@ void silc_core_init(void) "List supported HMACs", NULL }, { "list-pkcs", 0, POPT_ARG_NONE, NULL, 0, "List supported PKCSs", NULL }, +#ifdef SILC_DEBUG { "debug", 'd', POPT_ARG_STRING, NULL, 0, "Enable debugging", "STRING" }, +#endif /* SILC_DEBUG */ { "create-key-pair", 'C', POPT_ARG_NONE, NULL, 0, "Create new public key pair", NULL }, { "pkcs", 0, POPT_ARG_STRING, &opt_pkcs, 0, diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 78beef6f..f5fcb1b4 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -160,6 +160,7 @@ SILC_TASK_CALLBACK(silc_server_command_process_timeout) SILC_LOG_DEBUG(("Client entry is invalid")); silc_server_command_free(timeout->ctx); silc_free(timeout); + return; } /* Update access time */ @@ -239,6 +240,7 @@ void silc_server_command_process(SilcServer server, if (!client) { SILC_LOG_DEBUG(("Client entry is invalid")); silc_server_command_free(ctx); + return; } timeout = silc_calloc(1, sizeof(*timeout)); @@ -1106,8 +1108,6 @@ SILC_SERVER_CMD_FUNC(invite) silc_server_command_invite, silc_server_command_dup(cmd)); cmd->pending = TRUE; - silc_free(channel_id); - silc_free(dest_id); goto out; } @@ -1222,14 +1222,9 @@ SILC_SERVER_CMD_FUNC(invite) channel->invite_list)), SILC_STR_END); silc_hash_table_list(channel->invite_list, &htl); - while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2)) { - if (type == 1) - list = silc_argument_payload_encode_one(list, (char *)tmp2, - strlen((char *)tmp2), type); - else - list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len, - type); - } + while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2)) + list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len, + type); silc_hash_table_list_reset(&htl); } @@ -2050,17 +2045,10 @@ static void silc_server_command_join_channel(SilcServer server, SILC_STR_END); silc_hash_table_list(channel->invite_list, &htl); - while (silc_hash_table_get(&htl, (void **)&tmp_len, (void **)&reply)) { - if (tmp_len == 1) - invite_list = silc_argument_payload_encode_one(invite_list, - (char *)reply, - strlen((char *)reply), - tmp_len); - else - invite_list = silc_argument_payload_encode_one(invite_list, - reply->data, - reply->len, tmp_len); - } + while (silc_hash_table_get(&htl, (void **)&tmp_len, (void **)&reply)) + invite_list = silc_argument_payload_encode_one(invite_list, + reply->data, + reply->len, tmp_len); silc_hash_table_list_reset(&htl); } @@ -2076,17 +2064,10 @@ static void silc_server_command_join_channel(SilcServer server, SILC_STR_END); silc_hash_table_list(channel->ban_list, &htl); - while (silc_hash_table_get(&htl, (void **)&tmp_len, (void **)&reply)) { - if (tmp_len == 1) - ban_list = silc_argument_payload_encode_one(ban_list, - (char *)reply, - strlen((char *)reply), - tmp_len); - else - ban_list = silc_argument_payload_encode_one(ban_list, - reply->data, - reply->len, tmp_len); - } + while (silc_hash_table_get(&htl, (void **)&tmp_len, (void **)&reply)) + ban_list = silc_argument_payload_encode_one(ban_list, + reply->data, + reply->len, tmp_len); silc_hash_table_list_reset(&htl); } @@ -2184,6 +2165,8 @@ static void silc_server_command_join_channel(SilcServer server, silc_buffer_free(ban_list); out: + if (passphrase) + memset(passphrase, 0, strlen(passphrase)); silc_free(passphrase); } @@ -2939,7 +2922,6 @@ SILC_SERVER_CMD_FUNC(cmode) hmac = channel->hmac_name; /* Delete old hmac and allocate default one */ - silc_hmac_free(channel->hmac); if (!silc_hmac_alloc(hmac ? hmac : SILC_DEFAULT_HMAC, NULL, &newhmac)) { silc_server_command_send_status_reply(cmd, SILC_COMMAND_CMODE, SILC_STATUS_ERR_UNKNOWN_ALGORITHM, 0); @@ -4214,14 +4196,9 @@ SILC_SERVER_CMD_FUNC(ban) channel->ban_list)), SILC_STR_END); silc_hash_table_list(channel->ban_list, &htl); - while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2)) { - if (type == 1) - list = silc_argument_payload_encode_one(list, (char *)tmp2, - strlen((char *)tmp2), type); - else - list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len, - type); - } + while (silc_hash_table_get(&htl, (void **)&type, (void **)&tmp2)) + list = silc_argument_payload_encode_one(list, tmp2->data, tmp2->len, + type); silc_hash_table_list_reset(&htl); } @@ -4770,17 +4747,19 @@ SILC_SERVER_CMD_FUNC(close) /* Close the connection to the server */ sock = (SilcSocketConnection)server_entry->connection; - /* If we shutdown primary router connection manually then don't trigger - any reconnect or backup router connections, by setting the router - to NULL here. */ + server->backup_noswitch = TRUE; if (server->router == server_entry) { server->id_entry->router = NULL; server->router = NULL; server->standalone = TRUE; } - silc_server_free_sock_user_data(server, sock, NULL); - silc_server_close_connection(server, sock); - + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_BANNED_FROM_SERVER, + "Closed by administrator"); + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); + server->backup_noswitch = FALSE; + out: silc_server_command_free(cmd); } diff --git a/apps/silcd/idlist.c b/apps/silcd/idlist.c index 9acdd068..fb457b6c 100644 --- a/apps/silcd/idlist.c +++ b/apps/silcd/idlist.c @@ -227,7 +227,7 @@ silc_idlist_find_server_by_conn(SilcIDList id_list, char *hostname, if (sock && ((sock->hostname && !strcasecmp(sock->hostname, hostname)) || (sock->ip && !strcasecmp(sock->ip, hostname))) - && server->id->port == htons(port)) + && server->id->port == SILC_SWAB_16(port)) break; id_cache = NULL; diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index e49fafb5..ee45290f 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -2164,6 +2164,16 @@ SilcClientEntry silc_server_new_client(SilcServer server, return NULL; } + /* Make sure this client hasn't registered already */ + if (idata->status & SILC_IDLIST_STATUS_REGISTERED) { + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_OPERATION_ALLOWED, + "Too many registrations"); + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); + return NULL; + } + /* Parse incoming packet */ ret = silc_buffer_unformat(buffer, SILC_STR_UI16_NSTRING_ALLOC(&username, @@ -2413,6 +2423,16 @@ SilcServerEntry silc_server_new_server(SilcServer server, local = FALSE; } + /* Make sure this server hasn't registered already */ + if (idata->status & SILC_IDLIST_STATUS_REGISTERED) { + silc_server_disconnect_remote(server, sock, + SILC_STATUS_ERR_OPERATION_ALLOWED, + "Too many registrations"); + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); + return NULL; + } + /* Parse the incoming packet */ ret = silc_buffer_unformat(buffer, SILC_STR_UI16_NSTRING_ALLOC(&id_string, &id_len), @@ -2474,19 +2494,38 @@ SilcServerEntry silc_server_new_server(SilcServer server, server_entry = silc_idlist_find_server_by_id(server->local_list, server_id, TRUE, NULL); if (server_entry) { - silc_idcache_del_by_context(server->local_list->servers, server_entry); + if (SILC_IS_LOCAL(server_entry)) { + silc_server_disconnect_remote(server, server_entry->connection, + SILC_STATUS_ERR_OPERATION_ALLOWED, + "Too many registrations"); + if (((SilcSocketConnection)server_entry->connection)->user_data) + silc_server_free_sock_user_data(server, sock, NULL); + } else { + silc_idcache_del_by_context(server->local_list->servers, server_entry); + } } else { server_entry = silc_idlist_find_server_by_id(server->global_list, server_id, TRUE, NULL); - if (server_entry) - silc_idcache_del_by_context(server->global_list->servers, server_entry); + if (server_entry) { + if (SILC_IS_LOCAL(server_entry)) { + silc_server_disconnect_remote(server, server_entry->connection, + SILC_STATUS_ERR_OPERATION_ALLOWED, + "Too many registrations"); + if (((SilcSocketConnection)server_entry->connection)->user_data) + silc_server_free_sock_user_data(server, server_entry->connection, + NULL); + } else { + silc_idcache_del_by_context(server->global_list->servers, + server_entry); + } + } } /* Update server entry */ idata->status |= SILC_IDLIST_STATUS_REGISTERED; new_server->server_name = server_name; new_server->id = server_id; - + SILC_LOG_DEBUG(("New server id(%s)", silc_id_render(server_id, SILC_ID_SERVER))); diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 8e3ab0f2..80d2d71b 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -2005,6 +2005,7 @@ void silc_server_packet_queue_purge(SilcServer server, { if (sock && SILC_IS_OUTBUF_PENDING(sock) && (SILC_IS_DISCONNECTED(sock) == FALSE)) { + SILC_LOG_DEBUG(("Purging ourgoing queue")); server->stat.packets_sent++; silc_packet_send(sock, TRUE); SILC_UNSET_OUTBUF_PENDING(sock); diff --git a/apps/silcd/server.c b/apps/silcd/server.c index c3359196..0c55b28d 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -430,11 +430,7 @@ bool silc_server_init(SilcServer server) timeout. It expires as soon as the caller calls silc_server_run. This task performs authentication protocol and key exchange with our primary router. */ - silc_schedule_task_add(server->schedule, 0, - silc_server_connect_to_router, - (void *)server, 0, 1, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); + silc_server_create_connections(server); /* Add listener task to the scheduler. This task receives new connections to the server. This task remains on the queue until the end of the @@ -695,12 +691,8 @@ bool silc_server_rehash(SilcServer server) } } - /* Go through all configured routers after rehash */ - silc_schedule_task_add(server->schedule, 0, - silc_server_connect_to_router, - (void *)server, 0, 1, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); + /* Create connections after rehash */ + silc_server_create_connections(server); /* Check whether our router status has changed */ if (newconfig->servers) { @@ -1047,7 +1039,7 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_connect_to_router) server->wait_backup = TRUE; if (ptr->initiator) { - /* Check whether we are connected to this host already */ + /* Check whether we are connecting or connected to this host already */ if (silc_server_num_sockets_by_remote(server, silc_net_is_ip(ptr->host) ? ptr->host : NULL, @@ -1057,6 +1049,15 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_connect_to_router) SILC_LOG_DEBUG(("We are already connected to this router")); continue; } + if (silc_server_num_sockets_by_remote(server, + silc_net_is_ip(ptr->host) ? + ptr->host : NULL, + silc_net_is_ip(ptr->host) ? + NULL : ptr->host, ptr->port, + SILC_SOCKET_TYPE_UNKNOWN)) { + SILC_LOG_DEBUG(("We are already connecting to this router")); + continue; + } /* Allocate connection object for hold connection specific stuff. */ sconn = silc_calloc(1, sizeof(*sconn)); @@ -2239,12 +2240,9 @@ SILC_TASK_CALLBACK(silc_server_packet_process) else silc_server_free_sock_user_data(server, sock, NULL); } else if (server->router_conn && server->router_conn->sock == sock && - !server->router && server->standalone) - silc_schedule_task_add(server->schedule, 0, - silc_server_connect_to_router, - server, 1, 0, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); + !server->router && server->standalone) { + silc_server_create_connections(server); + } silc_server_close_connection(server, sock); return; @@ -2289,6 +2287,7 @@ SILC_TASK_CALLBACK(silc_server_packet_process) if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router) server->backup_noswitch = TRUE; + SILC_SET_DISCONNECTING(sock); if (sock->user_data) silc_server_free_sock_user_data(server, sock, NULL); silc_server_close_connection(server, sock); @@ -2433,6 +2432,7 @@ bool silc_server_packet_parse(SilcPacketParserContext *parser_context, if (SILC_PRIMARY_ROUTE(server) == sock && server->backup_router) server->backup_noswitch = TRUE; + SILC_SET_DISCONNECTING(sock); if (sock->user_data) silc_server_free_sock_user_data(server, sock, NULL); silc_server_close_connection(server, sock); @@ -2501,10 +2501,15 @@ void silc_server_packet_parse_type(SilcServer server, message ? message : "")); silc_free(message); + /* Do not switch to backup in case of error */ + server->backup_noswitch = (status == SILC_STATUS_OK ? FALSE : TRUE); + /* Handle the disconnection from our end too */ + SILC_SET_DISCONNECTING(sock); if (sock->user_data && SILC_IS_LOCAL(sock->user_data)) silc_server_free_sock_user_data(server, sock, NULL); silc_server_close_connection(server, sock); + server->backup_noswitch = FALSE; } break; @@ -2931,6 +2936,7 @@ void silc_server_close_connection(SilcServer server, if (!server->sockets[sock->sock] && SILC_IS_DISCONNECTED(sock)) { silc_schedule_unset_listen_fd(server->schedule, sock->sock); silc_schedule_task_del_by_fd(server->schedule, sock->sock); + silc_net_close_connection(sock->sock); silc_schedule_task_add(server->schedule, sock->sock, silc_server_close_connection_final, (void *)sock, 0, 1, SILC_TASK_TIMEOUT, @@ -2950,8 +2956,6 @@ void silc_server_close_connection(SilcServer server, /* Unregister all tasks */ silc_schedule_task_del_by_fd(server->schedule, sock->sock); - /* Close the actual connection */ - silc_net_close_connection(sock->sock); server->sockets[sock->sock] = NULL; /* If sock->user_data is NULL then we'll check for active protocols @@ -2971,6 +2975,9 @@ void silc_server_close_connection(SilcServer server, } } + /* Close the actual connection */ + silc_net_close_connection(sock->sock); + /* We won't listen for this connection anymore */ silc_schedule_unset_listen_fd(server->schedule, sock->sock); @@ -2993,8 +3000,13 @@ void silc_server_disconnect_remote(SilcServer server, char *cp; int len; - if (!sock || SILC_IS_DISCONNECTED(sock)) + if (!sock) + return; + + if (SILC_IS_DISCONNECTED(sock)) { + silc_server_close_connection(server, sock); return; + } memset(buf, 0, sizeof(buf)); va_start(ap, status); @@ -3152,12 +3164,7 @@ void silc_server_free_sock_user_data(SilcServer server, if (server->router == user_data) { /* Check whether we have a backup router connection */ if (!backup_router || backup_router == user_data) { - silc_schedule_task_add(server->schedule, 0, - silc_server_connect_to_router, - server, 1, 0, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); - + silc_server_create_connections(server); server->id_entry->router = NULL; server->router = NULL; server->standalone = TRUE; @@ -3205,15 +3212,12 @@ void silc_server_free_sock_user_data(SilcServer server, } else if (server->server_type == SILC_SERVER && sock->type == SILC_SOCKET_TYPE_ROUTER) { /* Reconnect to the router (backup) */ - silc_schedule_task_add(server->schedule, 0, - silc_server_connect_to_router, - server, 1, 0, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); + silc_server_create_connections(server); } - SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE, - ("Server %s signoff", user_data->server_name)); + if (user_data->server_name) + SILC_SERVER_SEND_OPERS(server, FALSE, TRUE, SILC_NOTIFY_TYPE_NONE, + ("Server %s signoff", user_data->server_name)); if (!backup_router) { /* Remove all servers that are originated from this server, and @@ -3851,7 +3855,12 @@ bool silc_server_create_channel_key(SilcServer server, /* Generate HMAC key from the channel key data and set it */ if (!channel->hmac) - silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac); + if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) { + memset(channel->key, 0, channel->key_len / 8); + silc_free(channel->key); + channel->channel_key = NULL; + return FALSE; + } silc_hash_make(silc_hmac_get_hash(channel->hmac), channel->key, len, hash); silc_hmac_set_key(channel->hmac, hash, silc_hash_len(silc_hmac_get_hash(channel->hmac))); @@ -3962,7 +3971,12 @@ SilcChannelEntry silc_server_save_channel_key(SilcServer server, /* Generate HMAC key from the channel key data and set it */ if (!channel->hmac) - silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac); + if (!silc_hmac_alloc(SILC_DEFAULT_HMAC, NULL, &channel->hmac)) { + memset(channel->key, 0, channel->key_len / 8); + silc_free(channel->key); + channel->channel_key = NULL; + return FALSE; + } silc_hash_make(silc_hmac_get_hash(channel->hmac), tmp, tmp_len, hash); silc_hmac_set_key(channel->hmac, hash, silc_hash_len(silc_hmac_get_hash(channel->hmac))); @@ -5062,8 +5076,8 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final) if (protocol->state == SILC_PROTOCOL_STATE_ERROR || protocol->state == SILC_PROTOCOL_STATE_FAILURE) { /* Error occured during protocol */ - SILC_LOG_ERROR(("Error occurred during rekey protocol with - %s (%s)", sock->hostname, sock->ip)); + SILC_LOG_ERROR(("Error occurred during rekey protocol with " + "%s (%s)", sock->hostname, sock->ip)); silc_protocol_cancel(protocol, server->schedule); silc_protocol_free(protocol); sock->protocol = NULL; @@ -5072,6 +5086,14 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_rekey_final) if (ctx->ske) silc_ske_free(ctx->ske); silc_free(ctx); + + /* Reconnect */ + SILC_SET_DISCONNECTING(sock); + server->backup_noswitch = TRUE; + if (sock->user_data) + silc_server_free_sock_user_data(server, sock, NULL); + silc_server_close_connection(server, sock); + silc_server_create_connections(server); return; } diff --git a/apps/silcd/server_backup.c b/apps/silcd/server_backup.c index 78634fe2..757f5177 100644 --- a/apps/silcd/server_backup.c +++ b/apps/silcd/server_backup.c @@ -96,7 +96,7 @@ void silc_server_backup_add(SilcServer server, SilcServerEntry backup_server, if (!server->backup->servers[i].server) { server->backup->servers[i].server = backup_server; server->backup->servers[i].local = local; - server->backup->servers[i].port = htons(port); + server->backup->servers[i].port = SILC_SWAB_16(port); memset(server->backup->servers[i].ip.data, 0, sizeof(server->backup->servers[i].ip.data)); silc_net_addr2bin(ip, server->backup->servers[i].ip.data, @@ -111,7 +111,7 @@ void silc_server_backup_add(SilcServer server, SilcServerEntry backup_server, (i + 1)); server->backup->servers[i].server = backup_server; server->backup->servers[i].local = local; - server->backup->servers[i].port = htons(port); + server->backup->servers[i].port = SILC_SWAB_16(port); memset(server->backup->servers[i].ip.data, 0, sizeof(server->backup->servers[i].ip.data)); silc_net_addr2bin(ip, server->backup->servers[i].ip.data, @@ -1054,6 +1054,8 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) SILC_LOG_DEBUG(("Sending RESUMED to %s", server_entry->server_name)); + SILC_LOG_INFO(("Sending RESUMED to %s", + server_entry->server_name)); server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED; @@ -1091,6 +1093,8 @@ SILC_TASK_CALLBACK_GLOBAL(silc_server_protocol_backup) SILC_LOG_DEBUG(("Sending RESUMED to %s", server_entry->server_name)); + SILC_LOG_INFO(("Sending RESUMED to %s", + server_entry->server_name)); server_entry->data.status &= ~SILC_IDLIST_STATUS_DISABLED; @@ -1257,16 +1261,13 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) protocol->state == SILC_PROTOCOL_STATE_FAILURE) { server->backup_noswitch = TRUE; server->server_type = SILC_BACKUP_ROUTER; + if (ctx->sock == sock) + ctx->sock = NULL; if (sock->user_data) silc_server_free_sock_user_data(server, sock, NULL); silc_server_close_connection(server, sock); - - silc_schedule_task_add(server->schedule, 0, - silc_server_connect_to_router, - server, 1, 0, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); + silc_server_create_connections(server); if (!silc_idcache_list_next(list, &id_cache)) break; @@ -1300,16 +1301,13 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) protocol->state == SILC_PROTOCOL_STATE_FAILURE) { server->backup_noswitch = TRUE; server->server_type = SILC_BACKUP_ROUTER; + if (ctx->sock == sock) + ctx->sock = NULL; if (sock->user_data) silc_server_free_sock_user_data(server, sock, NULL); silc_server_close_connection(server, sock); - - silc_schedule_task_add(server->schedule, 0, - silc_server_connect_to_router, - server, 1, 0, - SILC_TASK_TIMEOUT, - SILC_TASK_PRI_NORMAL); + silc_server_create_connections(server); if (!silc_idcache_list_next(list, &id_cache)) break; @@ -1332,7 +1330,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup_done) protocol->state != SILC_PROTOCOL_STATE_FAILURE) SILC_LOG_INFO(("Backup resuming protocol ended successfully")); - if (ctx->sock->protocol) + if (ctx->sock && ctx->sock->protocol) ctx->sock->protocol = NULL; silc_protocol_free(protocol); silc_free(ctx->sessions); diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index dead873a..839599d2 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -1754,7 +1754,7 @@ bool silc_server_inviteban_match(SilcServer server, SilcHashTable list, while (silc_hash_table_get(&htl, (void **)&t, (void **)&entry)) { if (type == t) { if (type == 1) { - if (silc_string_match((char *)entry, tmp)) { + if (silc_string_match(entry->data, tmp)) { ret = TRUE; break; } @@ -1772,12 +1772,6 @@ bool silc_server_inviteban_match(SilcServer server, SilcHashTable list, return ret; } -static void silc_server_inviteban_dummy_dest(void *key, void *context, - void *user_context) -{ - /* Nothing */ -} - /* Process invite or ban information */ void silc_server_inviteban_process(SilcServer server, SilcHashTable list, @@ -1800,24 +1794,16 @@ void silc_server_inviteban_process(SilcServer server, SilcHashTable list, if (type == 1) { /* Invite string. Get the old invite string from hash table and append this at the end of the existing one. */ - char *string = NULL; - silc_hash_table_find(list, (void *)1, - NULL, (void **)&string); - silc_hash_table_del_ext(list, (void *)1, NULL, NULL, NULL, NULL, - silc_server_inviteban_dummy_dest, NULL); - if (!string) - string = silc_calloc(len + 2, sizeof(*string)); - else - string = silc_realloc(string, sizeof(*string) * - (strlen(string) + len + 2)); - memset(string + strlen(string), 0, len + 2); + if (!silc_hash_table_find(list, (void *)1, NULL, (void **)&tmp2)) { + tmp2 = silc_calloc(1, sizeof(*tmp2)); + silc_hash_table_add(list, (void *)1, tmp2); + } if (tmp[len - 1] == ',') tmp[len - 1] = '\0'; - strncat(string, tmp, len); - strncat(string, ",", 1); - - /* Add new invite string to invite list */ - silc_hash_table_add(list, (void *)1, string); + if (len) { + silc_buffer_strformat(tmp2, tmp, SILC_STR_END); + silc_buffer_strformat(tmp2, ",", SILC_STR_END); + } } else if (type == 2) { /* Public key. Check first if the public key is already on the @@ -1875,25 +1861,23 @@ void silc_server_inviteban_process(SilcServer server, SilcHashTable list, the requested string. */ char *string = NULL, *start, *end, *n; - if (silc_hash_table_find(list, (void *)1, NULL, (void **)&string)) { - if (!strncmp(string, tmp, strlen(string) - 1)) { + if (silc_hash_table_find(list, (void *)1, NULL, (void **)&tmp2)) { + string = tmp2->head; + if (tmp2->truelen && !strncmp(string, tmp, tmp2->truelen - 1)) { + /* Delete entire string */ silc_hash_table_del(list, (void *)1); - string = NULL; - } else { + } else if (tmp2->truelen) { + /* Delete part of the string */ start = strstr(string, tmp); if (start && strlen(start) >= len) { end = start + len; n = silc_calloc(strlen(string) - len, sizeof(*n)); strncat(n, string, start - string); strncat(n, end + 1, ((string + strlen(string)) - end) - 1); - silc_hash_table_del(list, (void *)1); - string = n; + silc_free(tmp2->head); + silc_buffer_set(tmp2, n, strlen(n)); } } - - /* Add new invite string to invite list */ - if (string) - silc_hash_table_add(list, (void *)1, string); } } else if (type == 2) { @@ -1928,22 +1912,21 @@ void silc_server_inviteban_process(SilcServer server, SilcHashTable list, } } -/* Destructor for invite or ban list entrys */ +/* Destructor for invite and ban list entrys */ void silc_server_inviteban_destruct(void *key, void *context, void *user_context) { - switch ((SilcUInt32)key) { - case 1: - /* Invite string */ - silc_free(context); - break; - case 2: - case 3: - /* Public key/Channel ID SilcBuffer */ - silc_buffer_free(context); - break; - default: - break; - } + silc_buffer_free(context); +} + +/* Creates connections accoring to configuration. */ + +void silc_server_create_connections(SilcServer server) +{ + silc_schedule_task_del_by_callback(server->schedule, + silc_server_connect_to_router); + silc_schedule_task_add(server->schedule, 0, + silc_server_connect_to_router, server, 0, 1, + SILC_TASK_TIMEOUT, SILC_TASK_PRI_NORMAL); } diff --git a/apps/silcd/server_util.h b/apps/silcd/server_util.h index 393f0900..489abf87 100644 --- a/apps/silcd/server_util.h +++ b/apps/silcd/server_util.h @@ -207,4 +207,7 @@ void silc_server_inviteban_process(SilcServer server, SilcHashTable list, void silc_server_inviteban_destruct(void *key, void *context, void *user_context); +/* Creates connections accoring to configuration. */ +void silc_server_create_connections(SilcServer server); + #endif /* SERVER_UTIL_H */ diff --git a/apps/silcd/serverconfig.c b/apps/silcd/serverconfig.c index 911caff0..21212641 100644 --- a/apps/silcd/serverconfig.c +++ b/apps/silcd/serverconfig.c @@ -2,7 +2,7 @@ serverconfig.c - Author: Johnny Mnemonic + Author: Giovanni Giacobbi Copyright (C) 1997 - 2002 Pekka Riikonen @@ -495,22 +495,40 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo) SILC_SERVER_CONFIG_SECTION_INIT(SilcServerConfigServerInfoInterface); SilcServerConfigServerInfo *server_info = config->server_info; - /* if there isn't the struct alloc it */ + SERVER_CONFIG_DEBUG(("Received SERVERINFO type=%d name=\"%s\" (val=%x)", + type, name, context)); + + /* if there isn't the main struct alloc it */ if (!server_info) config->server_info = server_info = (SilcServerConfigServerInfo *) silc_calloc(1, sizeof(*server_info)); if (type == SILC_CONFIG_ARG_BLOCK) { if (!strcmp(name, "primary")) { + if (server_info->primary) { + SILC_SERVER_LOG_ERROR(("Error while parsing config file: " + "Double primary specification.")); + got_errno = SILC_CONFIG_EPRINTLINE; + goto got_err; + } CONFIG_IS_DOUBLE(server_info->primary); - if (!tmp) - return SILC_CONFIG_OK; + + /* now check the temporary struct, don't accept empty block and + make sure all fields are there */ + if (!tmp || !tmp->server_ip || !tmp->port) { + got_errno = SILC_CONFIG_EMISSFIELDS; + goto got_err; + } server_info->primary = tmp; config->tmp = NULL; return SILC_CONFIG_OK; } else if (!strcmp(name, "secondary")) { if (!tmp) return SILC_CONFIG_OK; + if (!tmp || !tmp->server_ip || !tmp->port) { + got_errno = SILC_CONFIG_EMISSFIELDS; + goto got_err; + } SILC_SERVER_CONFIG_LIST_APPENDTMP(server_info->secondary); config->tmp = NULL; return SILC_CONFIG_OK; @@ -603,9 +621,13 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo) return SILC_CONFIG_OK; got_err: - silc_free(tmp); - silc_free(config->tmp); - config->tmp = NULL; + /* here we need to check if tmp exists because this function handles + * misc data (multiple fields and single-only fields) */ + if (tmp) { + silc_free(tmp->server_ip); + silc_free(tmp); + config->tmp = NULL; + } return got_errno; } @@ -1438,6 +1460,7 @@ SilcServerConfig silc_server_config_alloc(const char *filename) } } silc_server_config_destroy(config_new); + silc_config_close(file); return NULL; } diff --git a/apps/silcd/serverconfig.h b/apps/silcd/serverconfig.h index 164647d8..03cb63a0 100644 --- a/apps/silcd/serverconfig.h +++ b/apps/silcd/serverconfig.h @@ -2,7 +2,7 @@ serverconfig.h - Author: Johnny Mnemonic + Author: Giovanni Giacobbi Copyright (C) 1997 - 2002 Pekka Riikonen diff --git a/apps/silcd/serverid.c b/apps/silcd/serverid.c index d9e39bb5..7d8fdea5 100644 --- a/apps/silcd/serverid.c +++ b/apps/silcd/serverid.c @@ -42,7 +42,7 @@ void silc_id_create_server_id(const char *ip, SilcUInt16 port, SilcRng rng, } (*new_id)->ip.data_len = silc_net_is_ip4(ip) ? 4 : 16; - (*new_id)->port = htons(port); + (*new_id)->port = SILC_SWAB_16(port); (*new_id)->rnd = silc_rng_get_rn16(rng); SILC_LOG_DEBUG(("New ID (%s)", silc_id_render(*new_id, SILC_ID_SERVER))); diff --git a/apps/silcd/silcd.c b/apps/silcd/silcd.c index 33a5043c..d7e276a6 100644 --- a/apps/silcd/silcd.c +++ b/apps/silcd/silcd.c @@ -306,6 +306,37 @@ SILC_TASK_CALLBACK(dump_stats) #undef STAT_OUTPUT #ifdef SILC_DEBUG + /* Dump internal flags */ + fprintf(fdd, "\nDumping internal flags\n"); + fprintf(fdd, " server_type : %d\n", silcd->server_type); + fprintf(fdd, " standalone : %d\n", silcd->standalone); + fprintf(fdd, " listenning : %d\n", silcd->listenning); + fprintf(fdd, " background : %d\n", silcd->background); + fprintf(fdd, " backup_router : %d\n", silcd->backup_router); + fprintf(fdd, " backup_primary : %d\n", silcd->backup_primary); + fprintf(fdd, " backup_noswitch : %d\n", silcd->backup_noswitch); + fprintf(fdd, " wait_backup : %d\n", silcd->wait_backup); + if (silcd->router) + fprintf(fdd, " primary router : %s\n", + silcd->router->server_name ? silcd->router->server_name : ""); + + /* Dump socket connections */ + { + int i; + SilcSocketConnection s; + + fprintf(fdd, "\nDumping socket connections\n"); + for (i = 0; i < silcd->config->param.connections_max; i++) { + s = silcd->sockets[i]; + if (!s) + continue; + fprintf(fdd, " %d: host %s ip %s port %d type %d flags 0x%x\n", + s->sock, s->hostname ? s->hostname : "N/A", + s->ip ? s->ip : "N/A", s->port, s->type, + (unsigned int)s->flags); + } + } + /* Dump lists */ { SilcIDCacheList list = NULL; diff --git a/configure.in.pre b/configure.in.pre index 671dac89..1fb1bdef 100644 --- a/configure.in.pre +++ b/configure.in.pre @@ -39,6 +39,7 @@ AM_INIT_AUTOMAKE(SILC_PACKAGE, SILC_VERSION) AC_PREREQ(2.52) AC_CONFIG_HEADERS(includes/silcdefs.h) +CFLAGS= AC_PROG_CC AC_C_INLINE AC_C_CONST @@ -46,23 +47,18 @@ AC_C_CONST AC_PROG_LN_S AC_SUBST(LN_S) -# Distribution definition. ./prepare will automatically add here a correct -# value. Do not edit! -# +## +## Distribution definition. ./prepare will automatically add here a correct +## value. Do not edit! +## silc_dist=SILC_PACKAGE SILC_DIST_SUBDIRS="SILC_DISTRIBUTION_SUBDIRS" AC_DEFINE(SILC_DIST_DEFINE) -# XXX -# Compiler flags -# -if test "$GCC"; then - CFLAGS="-Wall -finline-functions $CFLAGS" -fi -# -# Library versioning. -# +## +## Library versioning. +## # Do the releases and library versioning according to following rules: # # - If any code has changed in library, increment [LIB]_REVISION @@ -205,7 +201,6 @@ AM_CONDITIONAL(HAVE_REGEX, test x$have_regex = x1) AC_CHECK_FUNC(getopt_long, have_getopt_long=1, have_getopt_long=0) AM_CONDITIONAL(HAVE_GETOPT_LONG, test x$have_getopt_long = x1) - ## ## Enable/disable checking ## @@ -277,17 +272,14 @@ AC_ARG_ENABLE(debug, yes) AC_MSG_RESULT(yes) AC_DEFINE(SILC_DEBUG) - CFLAGS="-O -g $CFLAGS" summary_debug="yes" ;; *) AC_MSG_RESULT(no) - CFLAGS="-O2 -g $CFLAGS" ;; esac ], [ - CFLAGS="-O2 -g $CFLAGS" AC_MSG_RESULT(no) ]) @@ -327,6 +319,49 @@ AC_ARG_ENABLE(asm, ]) +## +## Compiler and compiler flag checks +## + +# Function to check if compiler flag works +# Usage: SILC_ADD_CFLAGS(FLAGS, [ACTION-IF-FAILED]) +AC_DEFUN(SILC_ADD_CFLAGS, +[ tmp_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $1" + AC_MSG_CHECKING(whether $CC accepts $1 flag) + AC_TRY_LINK(, , AC_MSG_RESULT(yes), [AC_MSG_RESULT(no) + CFLAGS="$tmp_CFLAGS" + $2]) + unset tmp_CFLAGS +]) + +if test "$GCC"; then + # GCC specific options + if test "x$summary_debug" = "xyes"; then + SILC_ADD_CFLAGS(-g -O) + else + SILC_ADD_CFLAGS(-g -O2) + fi + SILC_ADD_CFLAGS(-Wall -finline-functions) +else + # Other compilers + case "$target" in + alpha*-dec-osf*) + SILC_ADD_CFLAGS(-g3 -O2, SILC_ADD_CFLAGS(-g3 -O, SILC_ADD_CFLAGS(-O))) + ;; + *) + SILC_ADD_CFLAGS(-g) + SILC_ADD_CFLAGS(-O2, SILC_ADD_CFLAGS(-O)) + ;; + esac + + # Intel C++ Compiler needs -restrict + if test "x$CC" = "xicc"; then + SILC_ADD_CFLAGS(-restrict) + fi +fi + + ## ## Installation ## @@ -1141,6 +1176,7 @@ echo "" echo " Installation prefix ...........: $prefix" echo " bin directory .................: $s_bindir" echo " sbin directory ................: $s_sbindir" +echo " etc directory .................: $ETCDIR" echo " man directory .................: $s_mandir" echo " help directory ................: $HELPDIR" echo " doc directory .................: $DOCDIR" @@ -1174,8 +1210,14 @@ if test x$sim_support = xfalse; then else sim_support="yes" fi +if test x$has_iconv = xfalse; then + iconv_support="no" +else + iconv_support="yes" +fi echo " SIM support ...................: $sim_support" echo " IPv6 support ..................: $summary_ipv6" +echo " Iconv support .................: $iconv_support" echo " Assembler optimizations .......: $summary_asm" mp="MPI" diff --git a/doc/silcd.conf.yo b/doc/silcd.conf.yo index 9eab20c4..a78ed964 100644 --- a/doc/silcd.conf.yo +++ b/doc/silcd.conf.yo @@ -455,7 +455,8 @@ manpageauthor() SILC is designed and written by Pekka Riikonen and rest of the SILC Project. -Configuration file format and parser is by Johnny Mnemonic. +Configuration file format and parser is by Giovanni Giacobbi +. This manpage was written by Mika 'Bostik' Boström diff --git a/lib/doc/LIBINDEX b/lib/doc/LIBINDEX index 59524bfb..b10c4bb5 100644 --- a/lib/doc/LIBINDEX +++ b/lib/doc/LIBINDEX @@ -28,6 +28,13 @@ of the Toolkit always delivers the latest version of this reference manual.
  • Introduction to the Manual
  • Programming Conventions
  • Building the Toolkit +
  • Platform Implementations + +

    +Guides & Tutorials +

    +
  • Client Library Guides & Reference +
  • Introduction to SILC Random Number Generator

    Toolkit Reference diff --git a/lib/doc/command_reply_args.html b/lib/doc/command_reply_args.html new file mode 100644 index 00000000..5a964271 --- /dev/null +++ b/lib/doc/command_reply_args.html @@ -0,0 +1,373 @@ +Command Reply Arguments + +
     
    +The SILC Client Library 'command_reply client operation (which is part of the + +SilcClientOperation callback functions) returns command replies +from the SILC Server for commands that the client has earlier sent to the +server. The 'command_reply' client operation implementation has a variable +argument list to deliver SilcCommand +specific arguments to the application. This document describes these +arguments for all command replies to help SILC client software developers +to process them. + +
     
     
    +command_reply Client Library operation + +
     
    +The 'command_reply' client operation callback function prototype is as follows: + +
     
    + +   +void (*command_reply)(SilcClient client, SilcClientConnection conn,
    +          +SilcCommandPayload cmd_payload, bool success, SilcCommand command,
    +          +SilcStatus status, ...); +
    + +
     
    +The first argument 'client' is the SILC Client Library context, the 'conn' +is the context for the connection to the remote server, the 'cmd_payload' +is the raw SilcCommandPayload and application usually ignores it, the +'success' boolean value indicates whether the earlier command was a success +or not, the 'command' is the command reply enumeration, and the 'status' +indicates the status of the command reply. If 'success' is FALSE then +'status' includes error status. + +
     
    +Rest of the arguments are 'command' specific and implementation should +handle them by the SilcCommand for example in a switch statement. +The commands are defined in lib/silccore/silccomand.h header file. A short +example: + +
     
    + +  switch(type)
    +    {
    +    case SILC_COMMAND_WHOIS:
    +    ...
    +    break;
    +    case SILC_COMMAND_WHOWAS:
    +    ...
    +    break;
    +    case SILC_COMMAND_NICK:
    +    ...
    +    break;
    +    ...
    +    } +
    + +
     
     
    +Arguments + +
     
    +The following table describes all commands and arguments that the client +library sends in the 'command_reply' client operation to the application. +By default all arguments that the library sends to application are valid +pointers. However, it is possible that some pointers may be NULL. If +this is the case it is separately mentioned that the argument may be NULL. +In this case application must ignore that argument. The 'command_reply' +arguments per SilcCommand is as follows: + +
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameDescriptionVariable Arguments
    SILC_COMMAND_WHOIS +Returns information about user. The following pointers may be NULL: 'channels', +'fingerprint', 'channel_usermodes' and 'attrs'. If 'fingerprint' is valid its +length is 20 bytes. If 'channels' is valid it can be parsed with +silc_channel_payload_parse_list function. It is the list of channels user +has joined. If the 'channel_usermodes' is valid it can be parsed with +silc_get_mode_list function. It is the list of the user's modes on the +joined channels. The 'attr' is the Requested Attributes that may have been +returned by the client and it can be parsed by traversing the SilcDList +and using silc_attribute_get_attribute function. +SilcClientEntry client_entry, char *nickname, +char *username, char *realname, SilcBuffer channels, SilcUInt32 usermode, +SilcUInt32 idletime, unsigned char *fingerprint, SilcBuffer channel_usermodes, +SilcDList attrs +
    SILC_COMMAND_WHOWAS +Returns history information about user. The 'client_entry' and 'realname' +may be NULL. +SilcClientEntry client_entry, char *nickname, +char *username, char *realname +
    SILC_COMMAND_IDENTIFY +Returns information about user, channel or server. This is similar to +WHOIS command but does not return so much information and can be used to +get information about channels and servers too. Application should ignore +this command reply. The 'name' and 'info' may be NULL. +void *entry, char *name, char *info +
    SILC_COMMAND_NICK +Returns the new Client ID after user has changed nickname. +SilcClientEntry local_entry, char *nickname +
    SILC_COMMAND_LIST +Returns the list of channel in the SILC network. Each call of command reply +returns one channel. This means that the command reply is called multiple +times to return list of channels. The 'channel_topic' may be NULL. +SilcChannelEntry channel, char *channel_name, +char *channel_topic, SilcUInt32 user_count +
    SILC_COMMAND_TOPIC +Returns the topic of the channel. +SilcChannelEntry channel, char *topic +
    SILC_COMMAND_INVITE +Returns the invite list of the channel. Called also even if invite list +was not modified but SILC_COMMAND_INVITE command was used to invite a user +into a channel. In this case the invite list is not returned by the +server and 'invite_list' is NULL. The 'invite_list' is list of +SilcArgumentPayloads. The first 2 bytes are the number of arguments in +the list and can be parsed with SILC_GET16_MSB macro. The list can be +parsed with silc_argument_payload_parse function. +SilcChannelEntry channel, SilcBuffer invite_list +
    SILC_COMMAND_KILL +Called after killing a client. There is no arguments to this reply. +none +
    SILC_COMMAND_INFO +Returns information about the server user is connected to. +SilcServerEntry server, char *server_name, +char *server_info +
    SILC_COMMAND_STATS +Returns network statistics from the server. The 'stats_buffer' of length of +'buffer_length' bytes includes 32-bit integers one after the other each +representing some statistics. The integers can be parsed for example with +SILC_GET32_MSB macro. The integers in the buffer are: starttime, uptime, +local_clients, local_channels, local_serverops, local_routerops, cell_clients, +cell_channels, cell_servers, all_clients, all_channel, all_servers, +all_routers, all_serverops, all_routerops. All integers are always present. +unsigned char *stats_buffer, SilcUInt32 buffer_length +
    SILC_COMMAND_PING +Returns reply to earlier ping. There is no arguments to this reply. +none +
    SILC_COMMAND_OPER +Returns reply to earlier SILC_COMMAND_OPER command. There is no arguments +to this reply. +none +
    SILC_COMMAND_JOIN +Reply received when user joined a channel. The 'ignored' argument can +be ignored by the application. The 'topic' and 'hmac_name' may be NULL. +The 'key_payload' is usually ignored by the application. The 'list_count' +is the number of entries in both 'client_id_list' and 'client_mode_list'. +The 'client_id_list' is a list of clients on the channel and 'client_mode_list' +includes those clients' modes on the channel. If application likes to +resolve information about the clients on the channel it may call +silc_client_get_clients_by_list function and pass the 'client_id_list' as +argument to it. The 'client_mode_list' includes 32-bit integers one after +the other and they are in same order as clients in 'client_mode_list'. +If application resolves the information with silc_client_get_clients_by_list +parsing the 'client_mode_list' is not necessary. +char *channel_name, SilcChannelEntry channel, +SilcUInt32 channel_mode, int ignored, SilcBuffer key_payload, NULL, NULL, +char *topic, char *hmac_name, SilcUInt32 list_count, SilcBuffer client_id_list, +SilcBuffer client_mode_list +
    SILC_COMMAND_MOTD +Returns the Message of the Day from the server. The 'motd' may be NULL. +char *motd +
    SILC_COMMAND_UMODE +Returns the user mode after changing it. +SilcUInt32 user_mode +
    SILC_COMMAND_CMODE +Returns channel's mode after changing it. +SilcChannelEntry channel, SilcUInt32 mode +
    SILC_COMMAND_CUMODE +Returns user's mode on channel after changing it. +SilcUInt32 mode, SilcChannelEntry channel, +SilcClientEntry target_client +
    SILC_COMMAND_KICK +Called after kicking a client. There is no arguments to this reply. +none +
    SILC_COMMAND_BAN +Returns channel's ban list. The 'ban_list' may be NULL. The construction +of that list is equivalent to invite list. See description of +SILC_COMMAND_INVITE command reply. +SilcChannelEntry channel, SilcBuffer ban_list +
    SILC_COMMAND_DETACH +Called after being detached from the SILC network. There is no arguments +to this reply. +none +
    SILC_COMMAND_WATCH +Called after modifying the watch list in the server. There is no arguments +to this reply. +none +
    SILC_COMMAND_SILCOPER +Returns reply to earlier SILC_COMMAND_SILCOPER command. There is no +arguments to this reply. +none +
    SILC_COMMAND_LEAVE +Called after leaving the channel. +SilcChannelEntry channel +
    SILC_COMMAND_USERS +Returns list of users in channel. If application wishes not to parse +the raw lists the channel->user_list hash table is updated before calling +this command reply and application may traverse that table instead of +parssing the raw lists. +SilcChannelEntry channel, SilcUInt32 list_count, +SilcBuffer client_id_list, SilcBuffer client_mode_list +
    SILC_COMMAND_GETKEY +Returns public key of client or server. The 'public_key' may be NULL. +The 'entry_type' is used to check what type of pointer the entry' is. For +SILC_ID_CLIENT SilcClientEntry and for SILC_ID_SERVER SilcServerEntry. +SilcIdType entry_type, void *entry, +SilcPublicKey public_key +
    + +
     
    +SILC protocol defines some additional commands but command replies to +those commands are not delivered to the application. Only the command +replies listed above are delivered to application. diff --git a/lib/doc/notifyargs.html b/lib/doc/notifyargs.html new file mode 100644 index 00000000..ebe124ac --- /dev/null +++ b/lib/doc/notifyargs.html @@ -0,0 +1,269 @@ +SilcNotifyType Arguments + +
     
    +The SILC Client Library 'notify' client operation (which is part of the + +SilcClientOperation callback functions) returns different kind of +notifications from the SILC server to the SILC client. The 'notify' +client operation implementation has a variable argument list to deliver +SilcNotifyType type specific arguments to the application. This document +describes these arguments for all notify types to help SILC client +software developers to handle the incoming notifications. + +
     
     
    +notify Client Library operation + +
     
    +The 'notify' client operation callback function prototype is as follows: + +
     
    + +  void (*notify)(SilcClient client, SilcClientConnection conn, +SilcNotifyType type, ...); + + +
     
    +The first argument 'client' is the SILC Client Library context, the `conn' +is the context for the connection to the remote server, and the `type' is +the notify type enumeration sent by the server. Rest of the arguments are +`type' specific and implementation should handle them by the +SilcNotifyType for example in a switch statement. The notify +types are defined in lib/silccore/silcnotify.h header file. A short +example: + +
     
    + +  switch(type)
    +    {
    +    case SILC_NOTIFY_TYPE_NONE:
    +    ...
    +    break;
    +    case SILC_NOTIFY_TYPE_INVITE:
    +    ...
    +    break;
    +    case SILC_NOTIFY_TYPE_JOIN:
    +    ...
    +    break;
    +    ...
    +    } +
    + +
     
     
    +Arguments + +
     
    +The following table describes all notify types and arguments that the +client library sends in the 'notify' client operation to the application. +By default all arguments that the library sends to application are valid +pointers. However, it is possible that some pointers may be NULL. If +this is the case it is separately mentioned that the argument may be NULL. +In this case application must ignore that argument. The SilcNotifyType +arguments per notify type is as follows: + +
     
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameDescriptionVariable Arguments
    SILC_NOTIFY_TYPE_NONE +A message from server that usually does not include any critical +information. Application may ignore this or display it for the user. +The 'message' argument may be NULL. +char *message
    SILC_NOTIFY_TYPE_INVITE +Sent to the client if the user is invited on a channel. The 'channel_name' +argument may be NULL. +SilcClientChannel channel, char *channel_name, +SilcClientEntry inviter +
    SILC_NOTIFY_TYPE_JOIN +Sent when someone joins to a channel. +SilcClientEntry joining_client, SilcChannelEntry channel +
    SILC_NOTIFY_TYPE_LEAVE +Sent when someone leaves (parts) the channel. +SilcClientEntry leaving_client, SilcChannelEntry channel +
    SILC_NOTIFY_TYPE_SIGNOFF +Sent when someone signoff the SILC network. The 'signoff_message' may be +NULL. The 'leaving_client' SilcClientEntry may be incomplete and contain +NULL pointers, application must check it's pointers before attempting to +display for example nickname information. +SilcClientEntry signoff_client, char *signoff_message +
    SILC_NOTIFY_TYPE_TOPIC_SET +Sent when the topic of a channel is set/changed. The 'setter_id_type' +is used to check what type of pointer the 'setter_entry' is. For +SILC_ID_CLIENT SilcClientEntry, for SILC_ID_SERVER SilcServerEntry and for +SILC_ID_CHANNEL SilcChannelEntry. +SilcIdType setter_id_type, void *setter_entry, +char *topic, SilcChannelEntry channel +
    SILC_NOTIFY_TYPE_NICK_CHANGE +Sent when someone changes their nickname. The 'old_client_entry' includes +the old nickname and the 'new_client_entry' includes the new nickname. +Application must understand that the 'old_client_entry' pointer becomes +invalid after returning from the function. +SilcClientEntry old_client_entry, +SilcClientEntry new_client_entry +
    SILC_NOTIFY_TYPE_CMODE_CHANGE +Sent when channel's mode has changed. The 'changer_id_type' +is used to check what type of pointer the 'changer_entry' is. For +SILC_ID_CLIENT SilcClientEntry, for SILC_ID_SERVER SilcServerEntry and for +SILC_ID_CHANNEL SilcChannelEntry. The 'mode' is the mode mask after the +change. The 'hmac_name' argument may be NULL. +SilcIdType changer_id_type, void *changer_entry, +SilcUInt32 mode, NULL, char *hmac_name, SilcChannelEntry channel +
    SILC_NOTIFY_TYPE_CUMODE_CHANGE +Sent when a users mode on a channel has changed. The 'changer_id_type' +is used to check what type of pointer the 'changer_entry' is. For +SILC_ID_CLIENT SilcClientEntry, for SILC_ID_SERVER SilcServerEntry and for +SILC_ID_CHANNEL SilcChannelEntry. The 'mode' is the mode mask after the +change. The 'target_client' is the client whose mode was changed. +SilcIdType changer_id_type, void *changer_entry, +SilcUInt32 mode, SilcClientEntry target_client, SilcChannelEntry channel +
    SILC_NOTIFY_TYPE_MOTD +Message of the Day from the server. +char *motd +
    SILC_NOTIFY_TYPE_CHANNEL_CHANGE +Sent when a channel's Channel ID changes. It is possible that channel's +ID changes and this notify is sent by the server when this happens. +Usually application does not need to handle this notify type and may +safely ignore it when received. +SilcChannelEntry channel +
    SILC_NOTIFY_TYPE_SERVER_SIGNOFF +Sent when a server quits the network. The 'clients' is an array +SilcClientEntry pointers of size of 'clients_count'. Each client in the +entry is one client signing off from the SILC network. +NULL, SilcClientEntry *clients, SilcUInt32 clients_count +
    SILC_NOTIFY_TYPE_KICKED +Sent when a client (possibly our client) is kicked from a channel. The +'kick_message' may be NULL. If our client was kicked then 'kicked' is our +local SilcClientEntry pointer. +SilcClientEntry kicked, char *kick_message, +SilcClientEntry kicker, SilcChannelEntry channel +
    SILC_NOTIFY_TYPE_KILLED +Sent when a client (possibly our client) is killed from the network. The +'kill_message' may be NULL. If our client was killed then 'killed' is our +local SilcClientEntry pointer. The 'killer_type' is used to check what +type of pointer the 'killer' is. For SILC_ID_CLIENT SilcClientEntry, for +SILC_ID_SERVER SilcServerEntry and for SILC_ID_CHANNEL SilcChannelEntry. +SilcClientEntry killed, char *kill_message, +SilcIdType killer_type, void *killer, SilcChannelEntry channel +
    SILC_NOTIFY_TYPE_ERROR +Sent when an error occurs while handling some operation (except command) +from the client. Application usually cannot handle this notify type and +may safely ignore it. +SilcStatus error +
    SILC_NOTIFY_TYPE_WATCH +Sent to notify some status change of a client we are wathing. The +SILC_COMMAND_WATCH is used to manage clients we are wathing and this +notify type is used to deliver information about that client. If the +client just changed nickname the 'new_nickname' includes the new nickname. +Otherwise this pointer is NULL. The 'user_mode' is the client's mode in +the SILC network. The 'notification' contains the notify type that +happened for the 'watched_client' (for example +SILC_NOTIFY_TYPE_NICK_CHANGE if the client changed their nickname). +SilcClientEntry watched_client, char *new_nickname, +SilcUInt32 user_mode, SilcNotifyType notification +
    + +
     
    +SILC protocol defines some additional notify types but those notify types +are not delivered to the application. Some of those notify types are only +delivered between servers and routers and clients never receive them. +Only the notify types listed above are delivered to application. diff --git a/lib/doc/platforms.html b/lib/doc/platforms.html new file mode 100644 index 00000000..fa873d93 --- /dev/null +++ b/lib/doc/platforms.html @@ -0,0 +1,60 @@ +Platform Implementations + +
     
    +This document describes the implementation issues with different platforms +that the SILC Toolkit support. Some of the supported platforms does not +support all the features delivered with the Toolkit or they may behave +differently from other platforms. This document descibres these +differences between platforms. + +
     
    +
  • Unix & Linux Implementation
    +
  • Windows Implementation
    +
  • Mac OS X Implementation + +
     
     
    +Supported Platforms + +
     
    +SILC Toolkit supports by default all Unix and Linux platforms, Windows +platforms from Windows 98 and newer, and Mac OS X. In the future there is +also plans to add support for other platforms such as Symbian OS (EPOC). + +
     
     
    +Unix Implementation + +
     
    +All features and components delivered with the SILC Toolkit work on all +Unix and Linux platforms. There are no special Unix platform related +implementation issues with current version of SILC Toolkit. + + +
     
     
    +Windows Implementation + +
     
    +By default all features and components delivered with SILC Toolkit are +supported on Windows. However, there are some certain issues with the +Windows version of the SILC Toolkit. + +
     
    +
  • Toolkit users should not use silc_client_run function to +execute the Client Library. Instead the silc_client_run_one should +be used, for example as an timer task and the Windows application's own +message loop should be used as the main message loop. + +
  • The function silc_net_create_connection_async is not actually +asynchronous on Windows, but synchronous and it will block the process +while the connection is created. This means also that the function +silc_client_connect_to_server is not asynchronous but +synchronous. + + +
     
     
    +Mac OS X Implementation + +
     
    +All features and components delivered with the SILC Toolkit work on Mac +OS X platform. There are no special Mac OS X platform related +implementation issues with current version of SILC Toolkit. + diff --git a/lib/silcclient/DIRECTORY b/lib/silcclient/DIRECTORY index 7fa78c18..84267123 100644 --- a/lib/silcclient/DIRECTORY +++ b/lib/silcclient/DIRECTORY @@ -1,8 +1,10 @@ SILC Client Library diff --git a/lib/silcclient/client_notify.c b/lib/silcclient/client_notify.c index f42ebaa6..b6df9915 100644 --- a/lib/silcclient/client_notify.c +++ b/lib/silcclient/client_notify.c @@ -639,7 +639,7 @@ void silc_client_notify_by_server(SilcClient client, client_entry2->fingerprint = client_entry->fingerprint; client_entry2->fingerprint_len = client_entry->fingerprint_len; client_entry->fingerprint = NULL; - client_entry->fingerprint_len = NULL; + client_entry->fingerprint_len = 0; silc_client_update_client(client, conn, client_entry2, tmp, NULL, NULL, client_entry->mode); diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index 3131900e..40e1d256 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -1175,6 +1175,8 @@ SILC_CLIENT_CMD_FUNC(join) silc_buffer_free(idp); if (auth) silc_buffer_free(auth); + if (passphrase) + memset(passphrase, 0, strlen(passphrase)); silc_free(passphrase); /* Notify application */ @@ -1935,6 +1937,7 @@ static void silc_client_command_oper_send(unsigned char *data, 0, NULL, NULL, buffer->data, buffer->len, TRUE); silc_buffer_free(buffer); + silc_buffer_clear(auth); silc_buffer_free(auth); /* Notify application */ @@ -2006,6 +2009,7 @@ static void silc_client_command_silcoper_send(unsigned char *data, 0, NULL, NULL, buffer->data, buffer->len, TRUE); silc_buffer_free(buffer); + silc_buffer_clear(auth); silc_buffer_free(auth); /* Notify application */ diff --git a/lib/silcclient/protocol.c b/lib/silcclient/protocol.c index fb834aa0..0c68045a 100644 --- a/lib/silcclient/protocol.c +++ b/lib/silcclient/protocol.c @@ -249,7 +249,7 @@ static void silc_client_protocol_ke_continue(SilcSKE ske, function. */ if (ctx->responder == TRUE) { protocol->state++; - silc_protocol_execute(protocol, client->schedule, 0, 100000); + silc_protocol_execute(protocol, client->schedule, 0, 1); } } @@ -327,7 +327,7 @@ SILC_TASK_CALLBACK(silc_client_protocol_key_exchange) /* Advance protocol state and call the next state if we are responder */ protocol->state++; if (ctx->responder == TRUE) - silc_protocol_execute(protocol, client->schedule, 0, 100000); + silc_protocol_execute(protocol, client->schedule, 0, 1); } break; case 2: @@ -360,7 +360,7 @@ SILC_TASK_CALLBACK(silc_client_protocol_key_exchange) /* Advance protocol state and call next state if we are initiator */ protocol->state++; if (ctx->responder == FALSE) - silc_protocol_execute(protocol, client->schedule, 0, 100000); + silc_protocol_execute(protocol, client->schedule, 0, 1); } break; case 3: diff --git a/lib/silcclient/silcclient.h b/lib/silcclient/silcclient.h index d87dff84..5750bb20 100644 --- a/lib/silcclient/silcclient.h +++ b/lib/silcclient/silcclient.h @@ -527,7 +527,8 @@ typedef struct { message to a specific connection. `conn', however, may be NULL. The `type' indicates the type of the message sent by the library. The application can for example filter the message according the - type. */ + type. The variable argument list is arguments to the formatted + message that `msg' may be. */ void (*say)(SilcClient client, SilcClientConnection conn, SilcClientMessageType type, char *msg, ...); diff --git a/lib/silccore/Makefile.am b/lib/silccore/Makefile.am index afefc362..f01af8d6 100644 --- a/lib/silccore/Makefile.am +++ b/lib/silccore/Makefile.am @@ -47,6 +47,6 @@ include_HEADERS = \ silcattrs.h endif -EXTRA_DIST = *.h +EXTRA_DIST = *.h tests include $(top_srcdir)/Makefile.defines.in diff --git a/lib/silccore/silcauth.c b/lib/silccore/silcauth.c index 38a1a961..d42dd66f 100644 --- a/lib/silccore/silcauth.c +++ b/lib/silccore/silcauth.c @@ -216,14 +216,8 @@ silc_auth_public_key_encode_data(SilcPublicKey public_key, SILC_STR_UI_XNSTRING(pk, pk_len), SILC_STR_END); - ret = silc_memdup(buf->data, buf->len); - if (!ret) - return NULL; - - if (ret_len) - *ret_len = buf->len; + ret = silc_buffer_steal(buf, ret_len); - silc_buffer_clear(buf); silc_buffer_free(buf); silc_free(id_data); silc_free(pk); diff --git a/lib/silccrypt/pkcs1.c b/lib/silccrypt/pkcs1.c index 6e5a6a4a..9b596d9b 100644 --- a/lib/silccrypt/pkcs1.c +++ b/lib/silccrypt/pkcs1.c @@ -317,7 +317,7 @@ SILC_PKCS_API_ENCRYPT(pkcs1) SilcMPInt mp_tmp; SilcMPInt mp_dst; unsigned char *padded; - SilcUInt32 padded_len, len = key->bits / 8; + SilcUInt32 padded_len, len = (key->bits + 7) / 8; /* Pad data */ if (!RSA_FormatBlock(&padded, &padded_len, len, @@ -326,8 +326,6 @@ SILC_PKCS_API_ENCRYPT(pkcs1) silc_mp_init(&mp_tmp); silc_mp_init(&mp_dst); - silc_mp_set_ui(&mp_tmp, 0); - silc_mp_set_ui(&mp_dst, 0); /* Data to MP */ silc_mp_bin2mp(padded, padded_len, &mp_tmp); @@ -357,8 +355,6 @@ SILC_PKCS_API_DECRYPT(pkcs1) silc_mp_init(&mp_tmp); silc_mp_init(&mp_dst); - silc_mp_set_ui(&mp_tmp, 0); - silc_mp_set_ui(&mp_dst, 0); /* Data to MP */ silc_mp_bin2mp(src, src_len, &mp_tmp); @@ -367,7 +363,7 @@ SILC_PKCS_API_DECRYPT(pkcs1) rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n); /* MP to data */ - padded = silc_mp_mp2bin(&mp_dst, key->bits / 8, &padded_len); + padded = silc_mp_mp2bin(&mp_dst, (key->bits + 7) / 8, &padded_len); /* Unpad data */ unpadded = RSA_DecodeOneBlock(padded, padded_len, 0, @@ -401,7 +397,7 @@ SILC_PKCS_API_SIGN(pkcs1) SilcMPInt mp_dst; unsigned char *padded; SilcUInt32 padded_len; - SilcUInt32 len = key->bits / 8; + SilcUInt32 len = (key->bits + 7) / 8; /* Pad data */ if (!RSA_FormatBlock(&padded, &padded_len, len, RSA_BlockPrivate, @@ -410,8 +406,6 @@ SILC_PKCS_API_SIGN(pkcs1) silc_mp_init(&mp_tmp); silc_mp_init(&mp_dst); - silc_mp_set_ui(&mp_tmp, 0); - silc_mp_set_ui(&mp_dst, 0); /* Data to MP */ silc_mp_bin2mp(padded, len, &mp_tmp); @@ -438,12 +432,10 @@ SILC_PKCS_API_VERIFY(pkcs1) SilcMPInt mp_tmp2; SilcMPInt mp_dst; unsigned char *verify, *unpadded; - SilcUInt32 verify_len, len = key->bits / 8; + SilcUInt32 verify_len, len = (key->bits + 7) / 8; silc_mp_init(&mp_tmp2); silc_mp_init(&mp_dst); - silc_mp_set_ui(&mp_tmp2, 0); - silc_mp_set_ui(&mp_dst, 0); /* Format the signature into MP int */ silc_mp_bin2mp(signature, signature_len, &mp_tmp2); diff --git a/lib/silccrypt/rsa.c b/lib/silccrypt/rsa.c index 202ccf3f..51725932 100644 --- a/lib/silccrypt/rsa.c +++ b/lib/silccrypt/rsa.c @@ -146,7 +146,7 @@ SILC_PKCS_API_GET_PUBLIC_KEY(rsa) unsigned char tmp[4]; e = silc_mp_mp2bin(&key->e, 0, &e_len); - n = silc_mp_mp2bin(&key->n, key->bits / 8, &n_len); + n = silc_mp_mp2bin(&key->n, (key->bits + 7) / 8, &n_len); *ret_len = e_len + 4 + n_len + 4; ret = silc_calloc(*ret_len, sizeof(unsigned char)); @@ -185,7 +185,7 @@ SILC_PKCS_API_GET_PRIVATE_KEY(rsa) unsigned char tmp[4]; e = silc_mp_mp2bin(&key->e, 0, &e_len); - n = silc_mp_mp2bin(&key->n, key->bits / 8, &n_len); + n = silc_mp_mp2bin(&key->n, (key->bits + 7) / 8, &n_len); d = silc_mp_mp2bin(&key->d, 0, &d_len); *ret_len = e_len + 4 + n_len + 4 + d_len + 4; @@ -259,7 +259,7 @@ SILC_PKCS_API_SET_PUBLIC_KEY(rsa) silc_mp_bin2mp(key_data + 4 + e_len + 4, n_len, &key->n); - key->bits = n_len * 8; + key->bits = silc_mp_sizeinbase(&key->n, 2); key->pub_set = TRUE; return key->bits; @@ -323,7 +323,7 @@ SILC_PKCS_API_SET_PRIVATE_KEY(rsa) silc_mp_bin2mp(key_data + 4 + e_len + 4 + n_len + 4, d_len, &key->d); - key->bits = n_len * 8; + key->bits = silc_mp_sizeinbase(&key->n, 2); key->prv_set = TRUE; key->pub_set = TRUE; @@ -338,20 +338,15 @@ SILC_PKCS_API_CONTEXT_LEN(rsa) SILC_PKCS_API_ENCRYPT(rsa) { RsaKey *key = (RsaKey *)context; - int i, tmplen; + int tmplen; SilcMPInt mp_tmp; SilcMPInt mp_dst; silc_mp_init(&mp_tmp); silc_mp_init(&mp_dst); - silc_mp_set_ui(&mp_tmp, 0); - silc_mp_set_ui(&mp_dst, 0); /* Format the data into MP int */ - for (i = 0; i < src_len; i++) { - silc_mp_mul_2exp(&mp_tmp, &mp_tmp, 8); - silc_mp_add_ui(&mp_tmp, &mp_tmp, src[i]); - } + silc_mp_bin2mp(src, src_len, &mp_tmp); /* Encrypt */ rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->e, &key->n); @@ -359,10 +354,7 @@ SILC_PKCS_API_ENCRYPT(rsa) tmplen = (key->bits + 7) / 8; /* Format the MP int back into data */ - for (i = tmplen; i > 0; i--) { - dst[i - 1] = (unsigned char)(silc_mp_get_ui(&mp_dst) & 0xff); - silc_mp_div_2exp(&mp_dst, &mp_dst, 8); - } + silc_mp_mp2bin_noalloc(&mp_dst, dst, tmplen); *dst_len = tmplen; silc_mp_uninit(&mp_tmp); @@ -374,20 +366,15 @@ SILC_PKCS_API_ENCRYPT(rsa) SILC_PKCS_API_DECRYPT(rsa) { RsaKey *key = (RsaKey *)context; - int i, tmplen; + int tmplen; SilcMPInt mp_tmp; SilcMPInt mp_dst; silc_mp_init(&mp_tmp); silc_mp_init(&mp_dst); - silc_mp_set_ui(&mp_tmp, 0); - silc_mp_set_ui(&mp_dst, 0); /* Format the data into MP int */ - for (i = 0; i < src_len; i++) { - silc_mp_mul_2exp(&mp_tmp, &mp_tmp, 8); - silc_mp_add_ui(&mp_tmp, &mp_tmp, src[i]); - } + silc_mp_bin2mp(src, src_len, &mp_tmp); /* Decrypt */ rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n); @@ -395,10 +382,7 @@ SILC_PKCS_API_DECRYPT(rsa) tmplen = (key->bits + 7) / 8; /* Format the MP int back into data */ - for (i = tmplen; i > 0; i--) { - dst[i - 1] = (unsigned char)(silc_mp_get_ui(&mp_dst) & 0xff); - silc_mp_div_2exp(&mp_dst, &mp_dst, 8); - } + silc_mp_mp2bin_noalloc(&mp_dst, dst, tmplen); *dst_len = tmplen; silc_mp_uninit(&mp_tmp); @@ -410,20 +394,15 @@ SILC_PKCS_API_DECRYPT(rsa) SILC_PKCS_API_SIGN(rsa) { RsaKey *key = (RsaKey *)context; - int i, tmplen; + int tmplen; SilcMPInt mp_tmp; SilcMPInt mp_dst; silc_mp_init(&mp_tmp); silc_mp_init(&mp_dst); - silc_mp_set_ui(&mp_tmp, 0); - silc_mp_set_ui(&mp_dst, 0); /* Format the data into MP int */ - for (i = 0; i < src_len; i++) { - silc_mp_mul_2exp(&mp_tmp, &mp_tmp, 8); - silc_mp_add_ui(&mp_tmp, &mp_tmp, src[i]); - } + silc_mp_bin2mp(src, src_len, &mp_tmp); /* Sign */ rsa_en_de_crypt(&mp_dst, &mp_tmp, &key->d, &key->n); @@ -431,10 +410,7 @@ SILC_PKCS_API_SIGN(rsa) tmplen = (key->bits + 7) / 8; /* Format the MP int back into data */ - for (i = tmplen; i > 0; i--) { - dst[i - 1] = (unsigned char)(silc_mp_get_ui(&mp_dst) & 0xff); - silc_mp_div_2exp(&mp_dst, &mp_dst, 8); - } + silc_mp_mp2bin_noalloc(&mp_dst, dst, tmplen); *dst_len = tmplen; silc_mp_uninit(&mp_tmp); @@ -446,31 +422,22 @@ SILC_PKCS_API_SIGN(rsa) SILC_PKCS_API_VERIFY(rsa) { RsaKey *key = (RsaKey *)context; - int i, ret; + int ret; SilcMPInt mp_tmp, mp_tmp2; SilcMPInt mp_dst; silc_mp_init(&mp_tmp); silc_mp_init(&mp_tmp2); silc_mp_init(&mp_dst); - silc_mp_set_ui(&mp_tmp, 0); - silc_mp_set_ui(&mp_tmp2, 0); - silc_mp_set_ui(&mp_dst, 0); /* Format the signature into MP int */ - for (i = 0; i < signature_len; i++) { - silc_mp_mul_2exp(&mp_tmp2, &mp_tmp2, 8); - silc_mp_add_ui(&mp_tmp2, &mp_tmp2, signature[i]); - } + silc_mp_bin2mp(signature, signature_len, &mp_tmp2); /* Verify */ rsa_en_de_crypt(&mp_dst, &mp_tmp2, &key->e, &key->n); /* Format the data into MP int */ - for (i = 0; i < data_len; i++) { - silc_mp_mul_2exp(&mp_tmp, &mp_tmp, 8); - silc_mp_add_ui(&mp_tmp, &mp_tmp, data[i]); - } + silc_mp_bin2mp(data, data_len, &mp_tmp); ret = TRUE; diff --git a/lib/silccrypt/silcpkcs.c b/lib/silccrypt/silcpkcs.c index 4deddfd9..83a16d00 100644 --- a/lib/silccrypt/silcpkcs.c +++ b/lib/silccrypt/silcpkcs.c @@ -687,8 +687,9 @@ silc_pkcs_public_key_encode(SilcPublicKey public_key, SilcUInt32 *len) SilcBuffer buf; unsigned char *ret; - buf = silc_buffer_alloc(public_key->len + 4); - silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf)); + buf = silc_buffer_alloc_size(public_key->len + 4); + if (!buf) + return NULL; silc_buffer_format(buf, SILC_STR_UI_INT(public_key->len), @@ -699,13 +700,9 @@ silc_pkcs_public_key_encode(SilcPublicKey public_key, SilcUInt32 *len) SILC_STR_UI_XNSTRING(public_key->pk, public_key->pk_len), SILC_STR_END); - if (len) - *len = public_key->len + 4; - ret = silc_calloc(buf->len, sizeof(*ret)); - memcpy(ret, buf->data, buf->len); + ret = silc_buffer_steal(buf, len); silc_buffer_free(buf); - return ret; } @@ -721,8 +718,9 @@ silc_pkcs_public_key_data_encode(unsigned char *pk, SilcUInt32 pk_len, SilcUInt32 totlen; totlen = 2 + strlen(pkcs) + 2 + strlen(identifier) + pk_len; - buf = silc_buffer_alloc(totlen + 4); - silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf)); + buf = silc_buffer_alloc_size(totlen + 4); + if (!buf) + return NULL; silc_buffer_format(buf, SILC_STR_UI_INT(totlen), @@ -732,13 +730,9 @@ silc_pkcs_public_key_data_encode(unsigned char *pk, SilcUInt32 pk_len, SILC_STR_UI32_STRING(identifier), SILC_STR_UI_XNSTRING(pk, pk_len), SILC_STR_END); - if (len) - *len = totlen + 4; - ret = silc_calloc(buf->len, sizeof(*ret)); - memcpy(ret, buf->data, buf->len); + ret = silc_buffer_steal(buf, len); silc_buffer_free(buf); - return ret; } @@ -748,40 +742,34 @@ silc_pkcs_public_key_data_encode(unsigned char *pk, SilcUInt32 pk_len, bool silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len, SilcPublicKey *public_key) { - SilcBuffer buf; + SilcBufferStruct buf; SilcPKCS alg; SilcUInt16 pkcs_len, identifier_len; SilcUInt32 totlen, key_len; unsigned char *pkcs_name = NULL, *ident = NULL, *key_data = NULL; int ret; - buf = silc_buffer_alloc(data_len); - silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf)); - silc_buffer_put(buf, data, data_len); + silc_buffer_set(&buf, data, data_len); /* Get length */ - ret = silc_buffer_unformat(buf, + ret = silc_buffer_unformat(&buf, SILC_STR_UI_INT(&totlen), SILC_STR_END); - if (ret == -1) { - silc_buffer_free(buf); + if (ret == -1) return FALSE; - } #if 1 /* Backwards support, remove! */ if (totlen == data_len) totlen -= 4; #endif - if (totlen + 4 != data_len) { - silc_buffer_free(buf); + if (totlen + 4 != data_len) return FALSE; - } /* Get algorithm name and identifier */ - silc_buffer_pull(buf, 4); + silc_buffer_pull(&buf, 4); ret = - silc_buffer_unformat(buf, + silc_buffer_unformat(&buf, SILC_STR_UI16_NSTRING_ALLOC(&pkcs_name, &pkcs_len), SILC_STR_UI16_NSTRING_ALLOC(&ident, &identifier_len), SILC_STR_END); @@ -807,9 +795,9 @@ bool silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len, } /* Get key data. We assume that rest of the buffer is key data. */ - silc_buffer_pull(buf, 2 + pkcs_len + 2 + identifier_len); - key_len = buf->len; - ret = silc_buffer_unformat(buf, + silc_buffer_pull(&buf, 2 + pkcs_len + 2 + identifier_len); + key_len = buf.len; + ret = silc_buffer_unformat(&buf, SILC_STR_UI_XNSTRING_ALLOC(&key_data, key_len), SILC_STR_END); if (ret == -1) @@ -835,17 +823,12 @@ bool silc_pkcs_public_key_decode(unsigned char *data, SilcUInt32 data_len, (*public_key)->pk_type = SILC_SKE_PK_TYPE_SILC; } - silc_buffer_free(buf); return TRUE; err: - if (pkcs_name) - silc_free(pkcs_name); - if (ident) - silc_free(ident); - if (key_data) - silc_free(key_data); - silc_buffer_free(buf); + silc_free(pkcs_name); + silc_free(ident); + silc_free(key_data); return FALSE; } @@ -971,8 +954,9 @@ silc_pkcs_private_key_encode(SilcPrivateKey private_key, SilcUInt32 *len) SilcUInt32 totlen; totlen = 2 + strlen(private_key->name) + private_key->prv_len; - buf = silc_buffer_alloc(totlen); - silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf)); + buf = silc_buffer_alloc_size(totlen); + if (!buf) + return NULL; silc_buffer_format(buf, SILC_STR_UI_SHORT(strlen(private_key->name)), @@ -980,14 +964,9 @@ silc_pkcs_private_key_encode(SilcPrivateKey private_key, SilcUInt32 *len) SILC_STR_UI_XNSTRING(private_key->prv, private_key->prv_len), SILC_STR_END); - if (len) - *len = totlen; - ret = silc_calloc(buf->len, sizeof(*ret)); - memcpy(ret, buf->data, buf->len); - silc_buffer_clear(buf); + ret = silc_buffer_steal(buf, len); silc_buffer_free(buf); - return ret; } @@ -1002,22 +981,18 @@ silc_pkcs_private_key_data_encode(unsigned char *prv, SilcUInt32 prv_len, SilcUInt32 totlen; totlen = 2 + strlen(pkcs) + prv_len; - buf = silc_buffer_alloc(totlen); - silc_buffer_pull_tail(buf, totlen); + buf = silc_buffer_alloc_size(totlen); + if (!buf) + return NULL; silc_buffer_format(buf, SILC_STR_UI_SHORT(strlen(pkcs)), SILC_STR_UI32_STRING(pkcs), SILC_STR_UI_XNSTRING(prv, prv_len), SILC_STR_END); - if (len) - *len = totlen; - ret = silc_calloc(buf->len, sizeof(*ret)); - memcpy(ret, buf->data, buf->len); - silc_buffer_clear(buf); + ret = silc_buffer_steal(buf, len); silc_buffer_free(buf); - return ret; } @@ -1027,20 +1002,18 @@ silc_pkcs_private_key_data_encode(unsigned char *prv, SilcUInt32 prv_len, bool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len, SilcPrivateKey *private_key) { - SilcBuffer buf; + SilcBufferStruct buf; SilcPKCS alg; SilcUInt16 pkcs_len; SilcUInt32 key_len; unsigned char *pkcs_name = NULL, *key_data = NULL; int ret; - buf = silc_buffer_alloc(data_len); - silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf)); - silc_buffer_put(buf, data, data_len); + silc_buffer_set(&buf, data, data_len); /* Get algorithm name and identifier */ ret = - silc_buffer_unformat(buf, + silc_buffer_unformat(&buf, SILC_STR_UI16_NSTRING_ALLOC(&pkcs_name, &pkcs_len), SILC_STR_END); if (ret == -1) { @@ -1048,7 +1021,7 @@ bool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len, goto err; } - if (pkcs_len < 1 || pkcs_len > buf->truelen) { + if (pkcs_len < 1 || pkcs_len > buf.truelen) { SILC_LOG_DEBUG(("Malformed private key buffer")); goto err; } @@ -1060,9 +1033,9 @@ bool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len, } /* Get key data. We assume that rest of the buffer is key data. */ - silc_buffer_pull(buf, 2 + pkcs_len); - key_len = buf->len; - ret = silc_buffer_unformat(buf, + silc_buffer_pull(&buf, 2 + pkcs_len); + key_len = buf.len; + ret = silc_buffer_unformat(&buf, SILC_STR_UI_XNSTRING_ALLOC(&key_data, key_len), SILC_STR_END); if (ret == -1) @@ -1087,17 +1060,11 @@ bool silc_pkcs_private_key_decode(unsigned char *data, SilcUInt32 data_len, (*private_key)->prv_len = key_len; } - silc_buffer_clear(buf); - silc_buffer_free(buf); return TRUE; err: - if (pkcs_name) - silc_free(pkcs_name); - if (key_data) - silc_free(key_data); - silc_buffer_clear(buf); - silc_buffer_free(buf); + silc_free(pkcs_name); + silc_free(key_data); return FALSE; } @@ -1110,20 +1077,24 @@ static bool silc_pkcs_save_public_key_internal(const char *filename, { SilcBuffer buf; SilcUInt32 len; + unsigned char *tmp = NULL; switch(encoding) { case SILC_PKCS_FILE_BIN: break; case SILC_PKCS_FILE_PEM: - data = silc_pem_encode_file(data, data_len); + tmp = data = silc_pem_encode_file(data, data_len); data_len = strlen(data); break; } len = data_len + (strlen(SILC_PKCS_PUBLIC_KEYFILE_BEGIN) + strlen(SILC_PKCS_PUBLIC_KEYFILE_END)); - buf = silc_buffer_alloc(len); - silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf)); + buf = silc_buffer_alloc_size(len); + if (!buf) { + silc_free(tmp); + return FALSE; + } silc_buffer_format(buf, SILC_STR_UI32_STRING(SILC_PKCS_PUBLIC_KEYFILE_BEGIN), @@ -1133,10 +1104,12 @@ static bool silc_pkcs_save_public_key_internal(const char *filename, /* Save into file */ if (silc_file_writefile(filename, buf->data, buf->len)) { + silc_free(tmp); silc_buffer_free(buf); return FALSE; } + silc_free(tmp); silc_buffer_free(buf); return TRUE; } diff --git a/lib/silccrypt/silcrng.c b/lib/silccrypt/silcrng.c index 2686c74a..48a3e001 100644 --- a/lib/silccrypt/silcrng.c +++ b/lib/silccrypt/silcrng.c @@ -554,7 +554,7 @@ SilcUInt16 silc_rng_get_rn16(SilcRng rng) SilcUInt32 silc_rng_get_rn32(SilcRng rng) { unsigned char rn[4]; - SilcUInt16 num; + SilcUInt32 num; rn[0] = silc_rng_get_byte(rng); rn[1] = silc_rng_get_byte(rng); diff --git a/lib/silcmath/silcmp.h b/lib/silcmath/silcmp.h index da72aa91..ba18ae35 100644 --- a/lib/silcmath/silcmp.h +++ b/lib/silcmath/silcmp.h @@ -106,10 +106,16 @@ size_t silc_mp_size(SilcMPInt *mp); * * DESCRIPTION * - * Return the size of the integer in base `base'. Note that this size - * is probably only an approximation. However, it is guaranteed that - * the returned size is always at least the size of the integer, however, - * it may be larger. + * Return the size of the integer in base `base'. + * + * NOTES + * + * For any other base but 2 this function usually returns only an + * approximated size in the base. It is however guaranteed that the + * the returned size is always at least the size of the integer or + * larger. + * + * For base 2 this returns the exact bit-size of the integer. * ***/ size_t silc_mp_sizeinbase(SilcMPInt *mp, int base); @@ -167,6 +173,11 @@ void silc_mp_set_si(SilcMPInt *dst, SilcInt32 si); * Set `dst' integer from string `str' of base `base'. The `dst' must * already be initialized. * + * NOTES + * + * For base 2 the string must be in ASCII bit presentation, not in + * binary. Use the silc_mp_bin2mp to decode binary into integer. + * ***/ void silc_mp_set_str(SilcMPInt *dst, const char *str, int base); @@ -195,6 +206,11 @@ SilcUInt32 silc_mp_get_ui(SilcMPInt *mp); * must already have space allocated. The function returns the same * as `str' or NULL on error. * + * NOTES + * + * For base 2 the returned string is in ASCII bit presentation, not + * in binary. Use the silc_mp_mp2bin to encode integer into binary. + * ***/ char *silc_mp_get_str(char *str, SilcMPInt *mp, int base); diff --git a/lib/silcske/silcske.c b/lib/silcske/silcske.c index 2fd4e010..e0012121 100644 --- a/lib/silcske/silcske.c +++ b/lib/silcske/silcske.c @@ -201,17 +201,15 @@ SilcSKEStatus silc_ske_initiator_start(SilcSKE ske, SilcRng rng, if (status != SILC_SKE_STATUS_OK) return status; - /* Take a copy of the payload buffer for future use. It is used to - compute the HASH value. */ - ske->start_payload_copy = silc_buffer_copy(payload_buf); - ske->start_payload = start_payload; - /* Send the packet. */ if (ske->callbacks->send_packet) (*ske->callbacks->send_packet)(ske, payload_buf, SILC_PACKET_KEY_EXCHANGE, ske->callbacks->context); - silc_buffer_free(payload_buf); + /* Save the the payload buffer for future use. It is later used to + compute the HASH value. */ + ske->start_payload_copy = payload_buf; + ske->start_payload = start_payload; return status; } @@ -427,10 +425,9 @@ SilcSKEStatus silc_ske_initiator_phase_2(SilcSKE ske, ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR; return ske->status; } - payload->sign_data = silc_calloc(sign_len, sizeof(unsigned char)); - memcpy(payload->sign_data, sign, sign_len); - memset(sign, 0, sizeof(sign)); + payload->sign_data = silc_memdup(sign, sign_len); payload->sign_len = sign_len; + memset(sign, 0, sizeof(sign)); } status = silc_ske_payload_ke_encode(ske, payload, &payload_buf); @@ -514,8 +511,7 @@ static void silc_ske_initiator_finish_final(SilcSKE ske, if (status != SILC_SKE_STATUS_OK) goto err; - ske->hash = silc_calloc(hash_len, sizeof(unsigned char)); - memcpy(ske->hash, hash, hash_len); + ske->hash = silc_memdup(hash, hash_len); ske->hash_len = hash_len; SILC_LOG_DEBUG(("Verifying signature (HASH)")); @@ -627,8 +623,8 @@ SilcSKEStatus silc_ske_initiator_finish(SilcSKE ske, ske->users++; (*ske->callbacks->verify_key)(ske, payload->pk_data, payload->pk_len, - payload->pk_type, ske->callbacks->context, - silc_ske_initiator_finish_final, NULL); + payload->pk_type, ske->callbacks->context, + silc_ske_initiator_finish_final, NULL); /* We will continue to the final state after the public key has been verified by the caller. */ @@ -726,8 +722,7 @@ SilcSKEStatus silc_ske_responder_start(SilcSKE ske, SilcRng rng, err: if (remote_payload) silc_ske_payload_start_free(remote_payload); - if (payload) - silc_free(payload); + silc_free(payload); if (status == SILC_SKE_STATUS_OK) return SILC_SKE_STATUS_ERROR; @@ -1056,8 +1051,7 @@ SilcSKEStatus silc_ske_responder_finish(SilcSKE ske, if (status != SILC_SKE_STATUS_OK) goto err; - ske->hash = silc_calloc(hash_len, sizeof(unsigned char)); - memcpy(ske->hash, hash, hash_len); + ske->hash = silc_memdup(hash, hash_len); ske->hash_len = hash_len; SILC_LOG_DEBUG(("Signing HASH value")); @@ -1070,10 +1064,9 @@ SilcSKEStatus silc_ske_responder_finish(SilcSKE ske, status = SILC_SKE_STATUS_SIGNATURE_ERROR; goto err; } - ske->ke2_payload->sign_data = silc_calloc(sign_len, sizeof(unsigned char)); - memcpy(ske->ke2_payload->sign_data, sign, sign_len); - memset(sign, 0, sizeof(sign)); + ske->ke2_payload->sign_data = silc_memdup(sign, sign_len); ske->ke2_payload->sign_len = sign_len; + memset(sign, 0, sizeof(sign)); } ske->ke2_payload->pk_type = pk_type; @@ -1112,23 +1105,18 @@ SilcSKEStatus silc_ske_responder_finish(SilcSKE ske, SilcSKEStatus silc_ske_end(SilcSKE ske) { - SilcBuffer packet; + SilcBufferStruct packet; + unsigned char data[4]; SILC_LOG_DEBUG(("Start")); - packet = silc_buffer_alloc_size(4); - if (!packet) - return SILC_SKE_STATUS_OUT_OF_MEMORY; - silc_buffer_format(packet, - SILC_STR_UI_INT((SilcUInt32)SILC_SKE_STATUS_OK), - SILC_STR_END); + SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, data); + silc_buffer_set(&packet, data, 4); if (ske->callbacks->send_packet) - (*ske->callbacks->send_packet)(ske, packet, SILC_PACKET_SUCCESS, + (*ske->callbacks->send_packet)(ske, &packet, SILC_PACKET_SUCCESS, ske->callbacks->context); - silc_buffer_free(packet); - return SILC_SKE_STATUS_OK; } @@ -1138,26 +1126,21 @@ SilcSKEStatus silc_ske_end(SilcSKE ske) SilcSKEStatus silc_ske_abort(SilcSKE ske, SilcSKEStatus status) { - SilcBuffer packet; + SilcBufferStruct packet; + unsigned char data[4]; SILC_LOG_DEBUG(("Start")); if (status > SILC_SKE_STATUS_INVALID_COOKIE) status = SILC_SKE_STATUS_BAD_PAYLOAD; - packet = silc_buffer_alloc_size(4); - if (!packet) - return SILC_SKE_STATUS_OUT_OF_MEMORY; - silc_buffer_format(packet, - SILC_STR_UI_INT((SilcUInt32)status), - SILC_STR_END); + SILC_PUT32_MSB((SilcUInt32)status, data); + silc_buffer_set(&packet, data, 4); if (ske->callbacks->send_packet) - (*ske->callbacks->send_packet)(ske, packet, SILC_PACKET_FAILURE, + (*ske->callbacks->send_packet)(ske, &packet, SILC_PACKET_FAILURE, ske->callbacks->context); - silc_buffer_free(packet); - return SILC_SKE_STATUS_OK; } diff --git a/lib/silcutil/silcbuffer.h b/lib/silcutil/silcbuffer.h index b8463044..149adc1d 100644 --- a/lib/silcutil/silcbuffer.h +++ b/lib/silcutil/silcbuffer.h @@ -210,13 +210,43 @@ void silc_buffer_free(SilcBuffer sb) { if (sb) { #if defined(SILC_DEBUG) - memset(sb->head, 'F', sb->truelen); + if (sb->head) + memset(sb->head, 'F', sb->truelen); #endif silc_free(sb->head); silc_free(sb); } } +/****f* silcutil/SilcBufferAPI/silc_buffer_steal + * + * SYNOPSIS + * + * static inline + * unsigned char *silc_buffer_steal(SilcBuffer sb, SilcUInt32 *data_len); + * + * DESCRIPTION + * + * Steals the data from the buffer `sb'. This returns pointer to the + * start of the buffer and the true length of that buffer. The `sb' + * cannot be used anymore after calling this function because the + * data buffer was stolen. The `sb' must be freed with silc_buffer_free. + * The caller is responsible of freeing the stolen data buffer with + * silc_free. + * + ***/ + +static inline +unsigned char *silc_buffer_steal(SilcBuffer sb, SilcUInt32 *data_len) +{ + unsigned char *buf = sb->head; + if (data_len) + *data_len = sb->truelen; + sb->head = sb->data = sb->tail = sb->end = NULL; + sb->len = sb->truelen = 0; + return buf; +} + /****f* silcutil/SilcBufferAPI/silc_buffer_set * * SYNOPSIS diff --git a/lib/silcutil/silcbuffmt.c b/lib/silcutil/silcbuffmt.c index 4fffb7c3..a189c290 100644 --- a/lib/silcutil/silcbuffmt.c +++ b/lib/silcutil/silcbuffmt.c @@ -532,9 +532,12 @@ int silc_buffer_strformat(SilcBuffer dst, ...) goto ok; dst->head = silc_realloc(dst->head, sizeof(*dst->head) * - (strlen(string) + len)); + (strlen(string) + len + 1)); + if (!dst->head) + return -1; memcpy(dst->head + len, string, strlen(string)); len += strlen(string); + dst->head[len] = '\0'; } SILC_LOG_DEBUG(("Error occured while formatting buffer")); @@ -543,9 +546,9 @@ int silc_buffer_strformat(SilcBuffer dst, ...) ok: dst->end = dst->head + len; - dst->tail = dst->data = dst->end; - dst->len = 0; - dst->truelen = len; + dst->data = dst->head; + dst->tail = dst->end; + dst->len = dst->truelen = len; va_end(va); return len; diff --git a/lib/silcutil/silcconfig.c b/lib/silcutil/silcconfig.c index 1f3e4699..2066f957 100644 --- a/lib/silcutil/silcconfig.c +++ b/lib/silcutil/silcconfig.c @@ -2,9 +2,9 @@ silcconfig.c - Author: Johnny Mnemonic + Author: Giovanni Giacobbi - Copyright (C) 1997 - 2002 Pekka Riikonen + Copyright (C) 2002 - 2003 Giovanni Giacobbi 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 @@ -172,7 +172,8 @@ static SilcConfigOption *silc_config_find_option(SilcConfigEntity ent, } return NULL; } -/* ... */ +/* Converts a string in the type specified. returns a dynamically + * allocated pointer. */ static void *silc_config_marshall(SilcConfigType type, const char *val) { void *pt; @@ -578,7 +579,7 @@ static int silc_config_main_internal(SilcConfigEntity ent) } else { void *pt; - int ret; + int ret = 0; /* very important in case of no cb */ if (*(*p)++ != '=') return SILC_CONFIG_EEXPECTEDEQUAL; @@ -594,15 +595,17 @@ static int silc_config_main_internal(SilcConfigEntity ent) pt = silc_config_marshall(thisopt->type, buf); if (!pt) return SILC_CONFIG_EINVALIDTEXT; - if (thisopt->cb) { + if (thisopt->cb) ret = thisopt->cb(thisopt->type, thisopt->name, file->line, pt, thisopt->context); - if (ret) { - SILC_CONFIG_DEBUG(("Callback refused the value [ret=%d]", ret)); - return ret; - } - } + + /* since we have to free "pt" both on failure and on success, we + assume that ret == 0 if we didn't actually call any cb. */ silc_free(pt); + if (ret) { + SILC_CONFIG_DEBUG(("Callback refused the value [ret=%d]", ret)); + return ret; + } } continue; diff --git a/lib/silcutil/silcconfig.h b/lib/silcutil/silcconfig.h index 91225867..4d45aa86 100644 --- a/lib/silcutil/silcconfig.h +++ b/lib/silcutil/silcconfig.h @@ -2,9 +2,9 @@ silcconfig.h - Author: Johnny Mnemonic + Author: Giovanni Giacobbi - Copyright (C) 1997 - 2002 Pekka Riikonen + Copyright (C) 2002 - 2003 Giovanni Giacobbi 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 diff --git a/lib/silcutil/silclog.c b/lib/silcutil/silclog.c index 14d31d54..736edb03 100644 --- a/lib/silcutil/silclog.c +++ b/lib/silcutil/silclog.c @@ -2,7 +2,7 @@ silclog.c - Author: Johnny Mnemonic + Author: Giovanni Giacobbi Copyright (C) 1997 - 2002 Pekka Riikonen diff --git a/lib/silcutil/silclog.h b/lib/silcutil/silclog.h index 60b2f637..337c882e 100644 --- a/lib/silcutil/silclog.h +++ b/lib/silcutil/silclog.h @@ -2,7 +2,7 @@ silclog.h - Author: Johnny Mnemonic + Author: Giovanni Giacobbi Copyright (C) 1997 - 2002 Pekka Riikonen diff --git a/lib/silcutil/silcschedule.c b/lib/silcutil/silcschedule.c index e0f658b0..a474d165 100644 --- a/lib/silcutil/silcschedule.c +++ b/lib/silcutil/silcschedule.c @@ -399,12 +399,13 @@ static void silc_schedule_dispatch_nontimeout(SilcSchedule schedule) task = schedule->generic_queue->task; while(1) { - /* Validity of the task is checked always before and after + /* Validity of the task and fd is checked always before and after execution beacuse the task might have been unregistered in the callback function, ie. it is not valid anymore. */ /* Is the task ready for reading */ - if (task->valid && schedule->fd_list[i].revents & SILC_TASK_READ) { + if (task->valid && schedule->fd_list[i].revents & SILC_TASK_READ && + fd == schedule->fd_list[i].fd) { silc_mutex_unlock(schedule->generic_queue->lock); SILC_SCHEDULE_UNLOCK(schedule); task->callback(schedule, schedule->app_context, @@ -414,7 +415,8 @@ static void silc_schedule_dispatch_nontimeout(SilcSchedule schedule) } /* Is the task ready for writing */ - if (task->valid && schedule->fd_list[i].revents & SILC_TASK_WRITE) { + if (task->valid && schedule->fd_list[i].revents & SILC_TASK_WRITE && + fd == schedule->fd_list[i].fd) { silc_mutex_unlock(schedule->generic_queue->lock); SILC_SCHEDULE_UNLOCK(schedule); task->callback(schedule, schedule->app_context, @@ -718,9 +720,6 @@ SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd, if (!schedule->valid) return NULL; - SILC_LOG_DEBUG(("Registering new task, fd=%d type=%d priority=%d", fd, - type, priority)); - queue = SILC_SCHEDULE_GET_QUEUE(type); /* If the task is generic task, we check whether this task has already @@ -729,6 +728,9 @@ SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd, if (type == SILC_TASK_GENERIC) { silc_mutex_lock(queue->lock); + SILC_LOG_DEBUG(("Registering new task, fd=%d type=%d priority=%d", fd, + type, priority)); + if (queue->task) { SilcTask task = queue->task; while(1) { @@ -754,6 +756,12 @@ SilcTask silc_schedule_task_add(SilcSchedule schedule, SilcUInt32 fd, } newtask = silc_calloc(1, sizeof(*newtask)); + if (!newtask) + return NULL; + + SILC_LOG_DEBUG(("Registering new task %p, fd=%d type=%d priority=%d", + newtask, fd, type, priority)); + newtask->fd = fd; newtask->context = context; newtask->callback = callback; @@ -1223,7 +1231,7 @@ static int silc_schedule_task_remove(SilcTaskQueue queue, SilcTask task) return TRUE; } - SILC_LOG_DEBUG(("Removing task")); + SILC_LOG_DEBUG(("Removing task %p", task)); /* Unregister the task */ old = first; diff --git a/lib/silcutil/silctypes.h b/lib/silcutil/silctypes.h index b123cea8..c763f8fa 100644 --- a/lib/silcutil/silctypes.h +++ b/lib/silcutil/silctypes.h @@ -216,8 +216,8 @@ typedef signed long SilcInt64; typedef unsigned long long SilcUInt64; typedef signed long long SilcInt64; #else -typedef SilcUInt32 SilcUInt64; /* XXX Use Windows's own 64 bit types */ -typedef SilcInt32 SilcInt64; +typedef unsigned __int64 SilcUInt64; +typedef signed __int64 SilcInt64; #endif #else typedef SilcUInt32 SilcUInt64; @@ -245,9 +245,9 @@ typedef SilcUInt32 * void *; /* Macros */ -#define GET_WORD(cp) ((SilcUInt32)(SilcUInt8)(cp)[0]) << 24 \ - | ((SilcUInt32)(SilcUInt8)(cp)[1] << 16) \ - | ((SilcUInt32)(SilcUInt8)(cp)[2] << 8) \ +#define SILC_GET_WORD(cp) ((SilcUInt32)(SilcUInt8)(cp)[0]) << 24 \ + | ((SilcUInt32)(SilcUInt8)(cp)[1] << 16) \ + | ((SilcUInt32)(SilcUInt8)(cp)[2] << 8) \ | ((SilcUInt32)(SilcUInt8)(cp)[3]) /****d* silcutil/SILCTypes/SILC_GET16_MSB @@ -302,10 +302,10 @@ do { \ * * SOURCE */ -#define SILC_GET64_MSB(l, cp) \ -do { \ - (l) = ((((SilcUInt64)GET_WORD((cp))) << 32) | \ - ((SilcUInt64)GET_WORD((cp) + 4))); \ +#define SILC_GET64_MSB(l, cp) \ +do { \ + (l) = ((((SilcUInt64)SILC_GET_WORD((cp))) << 32) | \ + ((SilcUInt64)SILC_GET_WORD((cp) + 4))); \ } while(0) /***/ @@ -455,4 +455,40 @@ do { \ } while(0) /***/ +/****d* silcutil/SILCTypes/SILC_SWAB_16 + * + * NAME + * + * #define SILC_SWAB_16 ... + * + * DESCRIPTION + * + * Swabs 16-bit unsigned integer byte order. + * + * SOURCE + */ +#define SILC_SWAB_16(l) \ + ((SilcUInt16)(((SilcUInt16)(l) & (SilcUInt16)0x00FFU) << 8) | \ + (((SilcUInt16)(l) & (SilcUInt16)0xFF00U) >> 8)) +/***/ + +/****d* silcutil/SILCTypes/SILC_SWAB_32 + * + * NAME + * + * #define SILC_SWAB_32 ... + * + * DESCRIPTION + * + * Swabs 32-bit unsigned integer byte order. + * + * SOURCE + */ +#define SILC_SWAB_32(l) \ + ((SilcUInt32)(((SilcUInt32)(l) & (SilcUInt32)0x000000FFUL) << 24) | \ + (((SilcUInt32)(l) & (SilcUInt32)0x0000FF00UL) << 8) | \ + (((SilcUInt32)(l) & (SilcUInt32)0x00FF0000UL) >> 8) | \ + (((SilcUInt32)(l) & (SilcUInt32)0xFF000000UL) >> 24)) +/***/ + #endif /* SILCTYPES_H */ diff --git a/lib/silcutil/unix/silcunixsockconn.c b/lib/silcutil/unix/silcunixsockconn.c index 4d14ac5f..26d9dd73 100644 --- a/lib/silcutil/unix/silcunixsockconn.c +++ b/lib/silcutil/unix/silcunixsockconn.c @@ -74,8 +74,9 @@ SILC_TASK_CALLBACK(silc_socket_read_qos) { SilcSocketConnection sock = context; sock->qos->applied = TRUE; - silc_schedule_set_listen_fd(sock->qos->schedule, sock->sock, - (SILC_TASK_READ | SILC_TASK_WRITE), TRUE); + if (sock->users > 1) + silc_schedule_set_listen_fd(sock->qos->schedule, sock->sock, + (SILC_TASK_READ | SILC_TASK_WRITE), TRUE); sock->qos->applied = FALSE; silc_socket_free(sock); } diff --git a/prepare b/prepare index e0ba0efe..e126805b 100755 --- a/prepare +++ b/prepare @@ -37,7 +37,7 @@ # SILC Distribution versions. Set here or give the version on the command # line as argument. # -SILC_VERSION=0.9.7 # Base version +SILC_VERSION=0.9.8 # Base version ############################################################################# diff --git a/scripts/stripspaces.tcl b/scripts/stripspaces.tcl index 0e629665..01bac320 100755 --- a/scripts/stripspaces.tcl +++ b/scripts/stripspaces.tcl @@ -2,9 +2,9 @@ # # stripspaces.tcl - strip trailing spaces from source files # -# Author: Johnny Mnemonic +# Author: Giovanni Giacobbi # -# Copyright (C) 2002 Johnny Mnemonic +# Copyright (C) 2002 - 2003 Giovanni Giacobbi # # 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 diff --git a/tutorial/Makefile.defines_int.in b/tutorial/Makefile.defines_int.in index 03ee3ff3..252e825a 100644 --- a/tutorial/Makefile.defines_int.in +++ b/tutorial/Makefile.defines_int.in @@ -17,7 +17,7 @@ silc_install_prefix=@prefix@ SILC_COMMON_LIBS= @LIBS@ -L$(silc_install_prefix)/lib \ - -L/usr/local/silc/lib -lsilc -lsilcclient + -L/usr/local/silc/lib -lsilc -lsilcclient -lsilc SILC_CFLAGS=@CFLAGS@ CC=@CC@ LIBTOOL = @LIBTOOL@ -- 2.24.0