From: Pekka Riikonen Date: Sun, 5 Oct 2008 14:45:59 +0000 (+0300) Subject: Merge commit 'origin/silc.1.1.branch' X-Git-Url: http://git.silcnet.org/gitweb/?p=silc.git;a=commitdiff_plain;h=805fddcf6431e784f9f77114782a90c9d12f9cbe;hp=faa97fdb56d0b85042a5d0149b73ce7022f04398 Merge commit 'origin/silc.1.1.branch' Conflicts: CHANGES TODO apps/Makefile.ad apps/autodist/CHANGES apps/autodist/autodist.in apps/autodist/doc/autodist.1.in apps/autodist/doc/autodist.texi apps/silcd/command.c apps/silcd/server.c apps/silcd/server_backup.c apps/silcd/server_query.c configure.ad distdir/autodist distdir/pre-dist-client distdir/pre-dist-toolkit includes/silc.h.in includes/silcversion.h.in lib/Makefile.ad lib/configure.ad lib/contrib/Makefile.ad lib/silcasn1/silcasn1.c lib/silcasn1/silcasn1_decode.c lib/silcasn1/silcasn1_encode.c lib/silcclient/client.h lib/silcclient/client_entry.c lib/silcclient/silcclient.h lib/silccore/silcpacket.c lib/silccrypt/Makefile.ad lib/silccrypt/aes.c lib/silccrypt/aes_x86.asm lib/silccrypt/aes_x86_64.asm lib/silccrypt/ciphers.h lib/silccrypt/configure.ad lib/silccrypt/rijndael_internal.h lib/silccrypt/silccipher.c lib/silccrypt/silcpk.c lib/silccrypt/silcpkcs.c lib/silccrypt/silcpkcs1.c lib/silcmath/configure.ad lib/silcsim/Makefile.ad lib/silcske/silcconnauth.c lib/silcske/silcske.c lib/silcskr/silcskr.c lib/silcutil/silcatomic.h lib/silcutil/silcbuffer.h lib/silcutil/silcbuffmt.c lib/silcutil/silcconfig.c lib/silcutil/silcdlist.h lib/silcutil/silcfdstream.c lib/silcutil/silcfsm.c lib/silcutil/silclist.h lib/silcutil/silclog.c lib/silcutil/silcmime.c lib/silcutil/silcmutex.h lib/silcutil/silcnet.h lib/silcutil/silcschedule.c lib/silcutil/silcschedule.h lib/silcutil/silcschedule_i.h lib/silcutil/silcsocketstream.c lib/silcutil/silcsocketstream_i.h lib/silcutil/silcstack.c lib/silcutil/silcstack.h lib/silcutil/silcstringprep.c lib/silcutil/silctime.c lib/silcutil/silctypes.h lib/silcutil/silcutil.c lib/silcutil/stacktrace.c lib/silcutil/tests/test_silcschedule.c lib/silcutil/tests/test_silctime.c lib/silcutil/unix/silcunixnet.c lib/silcutil/unix/silcunixschedule.c lib/silcutil/unix/silcunixsocketstream.c lib/silcutil/unix/silcunixthread.c lib/silcutil/win32/silcwin32schedule.c win32/libsilc/libsilc.def --- diff --git a/CHANGES b/CHANGES index c5f1ab51..dfaf9cad 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,185 @@ +Thu Mar 13 13:31:35 EET 2008 Pekka Riikonen + + * Fixed silcd crash in NEW_CLIENT packet handling when nickname + is not present in the packet. Affected files are + apps/silcd/packet_receive.c. + +Fri Feb 22 16:12:27 EET 2008 Pekka Riikonen + + * Fixed partial encryption in CTR mode in AES. Change does not + affect interoperability in SILC due to the way CTR is used in + SILC. But, fixed anyway. Affected files are + lib/silccrypt/aes.c and rijndael_internal.h. + +Tue Jan 8 09:41:57 EET 2008 Pekka Riikonen + + * Fixed printable fingerprint bufferoverlfow, RedHat bug 372021. + Affected file is lib/silcutil/silcutil.c. + +Sun Dec 30 14:00:46 EET 2007 Pekka Riikonen + + * Fixed unix signal delivery in SILC scheduler. Affected file + is lib/silcutil/unix/silcunixschedule.c. + +Sun Nov 18 16:43:04 CET 2007 Jochen Eisinger + + * Add -avoid-version and -rpath flags when compiling the plugin. + Affected file is apps/irssi/src/fe-common/silc/Makefile.in + +Thu Nov 15 18:03:53 EET 2007 Pekka Riikonen + + * Reprocess JOIN command synchronously after resolving channel + user list. Affected file is lib/silcclient/command_reply.c. + + * In JOIN command reply check if the channel key is already + saved. If it is we have received new key from server while + resolving user and must not save the old key. Affected file + is lib/silcclient/command_reply.c. + + * Remove all channel keys and hmacs after giving LEAVE command. + Affected file is lib/silcclient/command_reply.c. + +Tue Nov 13 18:24:56 EET 2007 Pekka Riikonen + + * Added missing channel unreferencing in CMODE, CUMODE, + TOPIC, INVITE, BAN and KICK command replies. Affected + file is lib/silcclient/command_reply.c. + +Sun Nov 11 23:04:54 EET 2007 Pekka Riikonen + + * Free stream data and abort ongoing protocols correctly + for primary router connections receiving end of stream. + Affected file is apps/silcd/server.c. + +Sun Nov 11 16:02:12 EET 2007 Pekka Riikonen + + * SILC Server 1.1 Beta4. + +Sun Nov 11 14:15:48 EET 2007 Pekka Riikonen + + * SILC Toolkit 1.1.5. + +Sun Nov 11 11:22:35 EET 2007 Pekka Riikonen + + * Fixed connection authentication with public keys to use + correct public key as responder. Affected file is + lib/silcske/silcconnauth.c. + + * Fixed public key authentication in server. Affected file is + apps/silcd/serverconfig.c. + + * Fixed OPER and SILCOPER public key authentication. Affected + file is apps/silcd/server.c. + + * Fixed prefer_passphrase_auth flag in server. Fixed + disconnection of unauthenticated connection. Affected file is + apps/silcd/server.c. + + * Fixed client resuming in server. Affected file is + apps/silcd/packet_receive.c. + + * Fixed IDENTIFY and WHOWAS command reply to correctly update + client entries (fixes a crash). Affected file is + apps/silcd/command_reply.c. + +Tue Nov 6 16:39:20 EET 2007 Pekka Riikonen + + * SILC Client 1.1.3. + +Mon Nov 5 23:07:58 EET 2007 Pekka Riikonen + + * Zero tail of CTR mode IV in IV Included mode. Change does + not cause compatibility issues. Affected file is + lib/silcske/silcske.c. + +Mon Nov 5 22:24:25 EET 2007 Pekka Riikonen + + * SILC Toolkit 1.1.4. + + * Fixed CTR mode rekey. Affected file is lib/silcske/silcske.c. + + * Rewrote the IV Included CTR mode encryption/decryption in + packet engine. Affected file is lib/silccore/silcpacket.c. + +Sun Nov 4 15:20:25 EET 2007 Pekka Riikonen + + * Removed module_path and module options from the server + config file format. Affected file is apps/silcd/serverconfig.c. + + * Fixed non-IPv6 compilation error. Affected file is + lib/silcutil/unix/silcunixnet.c. + +Sat Nov 3 23:23:38 EET 2007 Pekka Riikonen + + * Do not free packet engine before uninitializing scheduler. + Do not disconnct already disconnected streams. Affected + files are in apps/silcd/. + + * Fixed setting correct ID for re-encrypted channel messages + in router-to-router connections. Affected file is + apps/silcd/packet_send.c. + +Sun Sep 30 15:16:18 EEST 2007 Pekka Riikonen + + * Fixed channel private key deleting when deleting the channel. + Affected file is lib/silcclient/client_channel.c. + +Sun Sep 9 17:52:49 EEST 2007 Pekka Riikonen + + * SILC Toolkit 1.1.3. + + * Fixed possible buffer overflows from SILC Config code. + Patch from J�r�my Bobbio. Affected file is + lib/silcutil/silcconfig.c. + +Sun Aug 26 12:28:49 EEST 2007 Pekka Riikonen + + * Fixed TIMEOUT handling in user info resolving during JOINing, + fixes crash. Affected file is lib/silcclient/client_notify.c. + + * Fixed mandatory UN and HN SILC public key identifier checking + (both must be present). Affected file is + lib/silccrypt/silcpk.c. + +Tue Aug 7 20:56:06 EEST 2007 Pekka Riikonen + + * Fixed alignment issues with 64-bit CPUs. Affected files + are lib/silcutil/silcschedule.c and unix/silcunixschedule.c. + + * Added "There are now xx nick's" to "are xx nicks". Affected + file is apps/irssi/src/fe-common/silc/module-formats.c. + +Sat Aug 4 18:37:22 EEST 2007 Pekka Riikonen + + * Fixed USERS command user mode handling (integer overflow). + Affected file is lib/silcclient/command_reply.c. + +Thu Jul 19 21:08:49 EEST 2007 Pekka Riikonen + + * Fixed big-endian issues from aes implementation. Affected + files are lib/silccrypt/aes.c. + + * Fixed lib/silcutil/silcatomic.h compilation on IA64. Patch + from J�r�my Bobbio. + + * Fixed public key identifier parsing to check lengths + correctly. Affected file is lib/silccrypt/silcpk.c. + +Wed Jul 4 08:06:38 EEST 2007 Pekka Riikonen + + * SILC Toolkit 1.1.2. + + * SILC Client 1.1.2. + +Mon Jul 2 17:28:47 CEST 2007 Pekka Riikonen + + * In silc_client_free check that scheduler is allocated before + trying to free it. Affected file is lib/silcclient/client.c. + + * Fixed buffer overflow in NICK_CHANGE notify. The destination + buffer for old nickname was too small. Affected file is + lib/silclient/client_notify.c. + Sun Jul 1 19:15:15 EEST 2007 Pekka Riikonen * SILC Server 1.1 Beta1. @@ -61,7 +243,7 @@ Mon Jun 18 23:47:22 EEST 2007 Pekka Riikonen * Use SILC_VERIFY to assert that silc_rwlock_wrlock can be called only once per thread on Unix. Affected file is lib/silcutil/unix/silcunixthread.c. Added same for mutex - as well. Documented same on the API in + as well. Documented same on the API in lib/silcutil/silcmutex.h. * Fixed USERS command reply write-lock unlocking. Affected file @@ -84,7 +266,7 @@ Thu Jun 14 21:15:31 CEST 2007 Jochen Eisinger apps/irssi/src/core/modules-load.c * Don't delete hilight entry (because it's just a pointer, not a - copy). Affected file is + copy). Affected file is apps/irssi/src/fe-common/silc/fe-silc-messages.c Mon Jun 11 22:10:17 EEST 2007 Pekka Riikonen @@ -135,7 +317,7 @@ Thu Jun 7 21:25:31 EEST 2007 Pekka Riikonen Wed Jun 6 18:33:05 EEST 2007 Pekka Riikonen - * Added notify callback to silc_schedule_init which can be used to + * Added notify callback to silc_schedule_init which can be used to set a notify callback for scheduler which is called when task is added to scheduler or deleted from scheduler. Affected file is lib/silcutil/silcschedule.[ch]. @@ -144,7 +326,7 @@ Wed Jun 6 18:33:05 EEST 2007 Pekka Riikonen was very short. Affected file is lib/silcutil/silcschedule.c. * Rewrote the SILC scheduler handling in SILC Client to not poll - every few msecs but to use the new notify callback. Affected + every few msecs but to use the new notify callback. Affected file is apps/irssi/src/silc/core/silc-core.c. * Fixed SFTP client library read buffer size which was too small. @@ -320,7 +502,7 @@ Fri May 18 18:10:36 EEST 2007 Pekka Riikonen better. Affected file is lib/silccilent/client_entry.c. * Added "foo#2 appears as foo" support to SILC Client when user - leaves or quits and one formatted nickname remain. Affected file + leaves or quits and one formatted nickname remain. Affected file is apps/irssi/src/silc/core/client_ops.c. * Send SilcChannelEntry to application in SILC_NOTIFY_TYPE_SIGNOFF. @@ -382,7 +564,7 @@ Wed May 16 09:34:10 EEST 2007 Pekka Riikonen Tue May 15 23:55:41 EEST 2007 Pekka Riikonen * Added SILC_VERIFY macro which is equivalent to SILC_ASSERT - but is compiled always in. Affected file is + but is compiled always in. Affected file is lib/silcutil/silclog.h. * Use SILC_VERIFY in FSM macros instead of SILC_ASSERT which is @@ -461,7 +643,7 @@ Wed May 9 19:51:28 EEST 2007 Pekka Riikonen on WIN32. Affected files are lib/silcutil/silclog_i.h and silclog.c. - * Rewrote WIN32 SILC Scheduler. It now handles non-blocking file + * Rewrote WIN32 SILC Scheduler. It now handles non-blocking file descriptors and sockets better. Though, room for optimization remains. Affected file is lib/silcutil/win32/silcwin32schedule.c. @@ -1353,7 +1535,7 @@ Sun Apr 3 14:58:53 EEST 2005 Pekka Riikonen file silcd/packet_receive.c. * Added getrusage() to take noise in SILC RNG. A patch by - Mika Boström. Affected files are configure.in.pre, + Mika Bostr�m. Affected files are configure.in.pre, includes/silcincludes.h.in, lib/silccrypt/silcrng.c. Sat Apr 2 18:09:30 EEST 2005 Pekka Riikonen @@ -1523,7 +1705,7 @@ Wed Nov 24 18:24:05 CET 2004 Pekka Riikonen Tue Nov 23 16:54:35 CET 2004 Pekka Riikonen * Fixed Win32 scheduler to not stuck anymore. A patch from - Juha Räsänen. Affected file is + Juha R�s�nen. Affected file is lib/silcutil/win32/silcwin32schedule.c. * Fixed QoS parsing for connection blocks in server. Affected @@ -1621,7 +1803,7 @@ Sat Feb 28 16:25:09 EET 2004 Pekka Riikonen on the channel. Affected file lib/silcclient/client_channel.c. * The channel private key used to decrypt message is now - delivered to the application in the 'channel_messageÃ' client + delivered to the application in the 'channel_message�' client operation. Affected files are lib/silcclient/silcclient.h and client_channel.c. @@ -2507,7 +2689,7 @@ Tue Dec 17 10:05:00 CET 2002 Pekka Riikonen Aldous . * Added better implementation using CriticalSection of - SilcMutex on WIN32. A patch by Mikko Lähteenmäki + SilcMutex on WIN32. A patch by Mikko L�hteenm�ki . * Added some Winsock WIN32 compatiblity defines into @@ -2878,7 +3060,7 @@ Sun Nov 24 18:26:42 EET 2002 Pekka Riikonen notifys in Irssi SILC Client. Affected file is irssi/src/silc/core/client_ops.c. Bug #82. - * Applied Ville Räsänen's manual page and --mandir bugfix + * Applied Ville R�s�nen's manual page and --mandir bugfix patch. Affected files are configure.in.pre and Makefile.am.pre. Bug #88. @@ -3057,8 +3239,8 @@ Thu Nov 7 10:05:28 CET 2002 Pekka Riikonen Wed Nov 6 17:18:13 EET 2002 Pekka Riikonen - * Fixed manual page installation patch by Ville Räsänen. - USERS help page fix patch by Ville Räsänen + * Fixed manual page installation patch by Ville R�s�nen. + USERS help page fix patch by Ville R�s�nen * Changed the silc_client_command_call interface to make the command call simpler for the application. The library @@ -3104,7 +3286,7 @@ Sun Nov 3 17:59:15 EET 2002 Pekka Riikonen was missing altogether. Affected file silcd/command_reply.c. Bug #44. -Sun Nov 3 00:42:05 EET 2002 Mika Boström +Sun Nov 3 00:42:05 EET 2002 Mika Bostr�m * Added man-pages for silc(1), silcd(8) and silcd.conf(5). Included yodl sources for each of these. Also modified @@ -3305,7 +3487,7 @@ Sun Oct 20 14:12:24 CEST 2002 Pekka Riikonen Sat Oct 19 13:32:15 CEST 2002 Pekka Riikonen * ROBODoc documented lib/silcutil/silcbuffer.h and - lib/silcutil/silcdlist.h. Patch by Ville Räsänen + lib/silcutil/silcdlist.h. Patch by Ville R�s�nen . Fri Oct 18 10:51:04 EEST 2002 Pekka Riikonen @@ -3557,7 +3739,7 @@ Sun Sep 15 12:25:10 EEST 2002 Pekka Riikonen file lib/silcutil/silcutil.[ch]. * Added STATS command to client library and Irssi SILC client. - Patch provided by Ville Räsänen . + Patch provided by Ville R�s�nen . Wed Sep 11 09:22:00 CEST 2002 Pekka Riikonen @@ -3779,7 +3961,7 @@ Fri Jun 28 11:53:25 CEST 2002 Pekka Riikonen Thu Jun 27 20:07:27 EEST 2002 Pekka Riikonen * Buffer overflow with CUMODE command's mode->mode character - conversion. Reported by Ville Räsänen. Affected file + conversion. Reported by Ville R�s�nen. Affected file lib/silcutil/silcutil.c. Thu Jun 27 16:54:33 EEST 2002 Pekka Riikonen @@ -3867,7 +4049,7 @@ Tue Jun 25 18:47:39 EEST 2002 Pekka Riikonen * Fixed a bug in version string parsing which could crash the program with specially formatted version string. - Bug reported and patch provided by Ville Räsänen. Affected + Bug reported and patch provided by Ville R�s�nen. Affected file lib/silcutil/silcutil.c. * Handle the disconnection immediately when DISCONNECT @@ -7679,7 +7861,7 @@ Thu Sep 6 12:47:37 EEST 2001 Pekka Riikonen Added function silc_client_nickname_format to the file lib/silcclient/idlist.c. It performs the nickname formatting. - Added new field `hostname´ to the SilcClientEntry context. + Added new field `hostname� to the SilcClientEntry context. It holds the hostname of the client. Affected file is lib/silcclient/idlist.h. @@ -11050,7 +11232,7 @@ Wed Feb 21 14:17:04 EET 2001 Pekka Riikonen * Fixed buffer overflow from lib/silcclient/command.c in USERS command parsing. -Wed Feb 21 12:44:00 EET 2001 Mika Boström +Wed Feb 21 12:44:00 EET 2001 Mika Bostr�m * Changed all SilcConfigServer* and silc_config_server* to SilcServerConfig* and silc_server_config*, respectively. diff --git a/Makefile.ad b/Makefile.ad index e7dacff6..7dd0be5a 100644 --- a/Makefile.ad +++ b/Makefile.ad @@ -45,7 +45,7 @@ EXTRA_DIST = \ #endif SILC_DIST_CLIENT #ifdef SILC_DIST_SILC libtoolfix \ - CHANGES CREDITS + CREDITS #endif SILC_DIST_SILC #ifdef SILC_DIST_SILC diff --git a/TODO b/TODO index e24199ce..e6950f06 100644 --- a/TODO +++ b/TODO @@ -19,7 +19,7 @@ lib/silccore o All payload encoding routines should take SilcStack as argument. - o Remove SilcCommandCb from silccommand.h. + o Remove SilcCommandCb from silccommand.h. (***DONE) o All payload test routines into lib/silccore/tests/. @@ -27,6 +27,10 @@ lib/silccore lib/silcclient, The Client Library ================================== + o LIST command should take server name as argument, a server name whose + channels to list. This way it is possible to list channels from + any server in internet, eg. /LIST example.com. + o UDP SILC connection support to SILC server o Giving WHOIS for nick that doesn't exist should remove any same @@ -41,11 +45,6 @@ lib/silcclient, The Client Library never joined the channel if this happens. What to do if message is received from user that hasn't been resolved/joined? - o Add the SilcStream (socket stream) from the SilcPacketStream and - SilcSocket from the socket stream to SilcClientConnection for easier - access to them for programmers. Currently these have to be digged up - from the packet stream. - o Connection option that attemps to connect to remot host with various different mechanisms: UDP 706, TCP 706, TCP 80, TCP 443, UDP 7706 and TCP 7706. This is the so called hole punching mechanism. @@ -62,6 +61,11 @@ lib/silcclient, The Client Library o Ability to recover from rekey errors, at least try to. + o Add the SilcStream (socket stream) from the SilcPacketStream and + SilcSocket from the socket stream to SilcClientConnection for easier + access to them for programmers. Currently these have to be digged up + from the packet stream. (***DONE) + SFTP Library, lib/silcsftp/ =========================== @@ -155,6 +159,14 @@ lib/silcserver o Reference count all Silc*Entry structures. + o All channel names in any command (where appropriate) must be allowed to + be in format channel@server so that the server can be connected to do + the command for the channel. Change protocol if it doesn't allow it. + + o All nicknames in any command (where appropriate) must be allowed to be + in format nick@server so that the server can be connected to do the + command for the nickname. Change protocol if it doesn't allow it. + Some issues that must be kept in mind from 1.0 and 1.1 silcd's: o The server and router software MUST work out of the box. After diff --git a/apps/silcd/Makefile.am b/apps/silcd/Makefile.am index b15b1d4a..4a104650 100644 --- a/apps/silcd/Makefile.am +++ b/apps/silcd/Makefile.am @@ -39,7 +39,7 @@ silcd_SOURCES = \ LIBS = $(SILC_COMMON_LIBS) LDADD = -EXTRA_DIST = *.h +EXTRA_DIST = silc-server.spec *.h install-dirs-server: -mkdir -p $(docdir) diff --git a/apps/silcd/command.c b/apps/silcd/command.c index 12b5ce26..2bd8198e 100644 --- a/apps/silcd/command.c +++ b/apps/silcd/command.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2007 Pekka Riikonen + Copyright (C) 1997 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1051,7 +1051,8 @@ SILC_SERVER_CMD_FUNC(invite) SilcBuffer list, tmp2; SilcBufferStruct alist; unsigned char *tmp, *atype = NULL; - SilcUInt32 len, type, len2; + SilcUInt32 len, len2, ttype; + void *type; SilcUInt16 argc = 0, ident = silc_command_get_ident(cmd->payload); SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_INVITE, cmd, 1, 4); @@ -1163,7 +1164,7 @@ SILC_SERVER_CMD_FUNC(invite) tmp = silc_argument_get_arg_type(cmd->args, 2, &len); silc_hash_table_list(channel->invite_list, &htl); while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) { - if (type == 3 && !memcmp(tmp2->data, tmp, len)) { + if (SILC_PTR_TO_32(type) == 3 && !memcmp(tmp2->data, tmp, len)) { tmp = NULL; break; } @@ -1252,7 +1253,8 @@ SILC_SERVER_CMD_FUNC(invite) silc_hash_table_list(channel->invite_list, &htl); while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) list = silc_argument_payload_encode_one(list, tmp2->data, - silc_buffer_len(tmp2), type); + silc_buffer_len(tmp2), + SILC_PTR_TO_32(type)); silc_hash_table_list_reset(&htl); } @@ -1287,21 +1289,21 @@ SILC_SERVER_CMD_FUNC(invite) /* Send invite list back only if the list was modified, or no arguments was given. */ - type = 0; + ttype = 0; argc = silc_argument_get_arg_num(cmd->args); if (argc == 1) - type = 1; + ttype = 1; if (silc_argument_get_arg_type(cmd->args, 3, &len)) - type = 1; + ttype = 1; /* Send command reply */ tmp = silc_argument_get_arg_type(cmd->args, 1, &len); silc_server_send_command_reply(server, cmd->sock, SILC_COMMAND_INVITE, SILC_STATUS_OK, 0, ident, 2, 2, tmp, len, - 3, type && list ? + 3, ttype && list ? list->data : NULL, - type && list ? silc_buffer_len(list) : 0); + ttype && list ? silc_buffer_len(list) : 0); silc_buffer_free(list); out: @@ -1470,13 +1472,19 @@ SILC_SERVER_CMD_FUNC(kill) /* Do normal signoff for the destination client */ sock = remote_client->connection; + + if (sock) + silc_packet_stream_ref(sock); + silc_server_remove_from_channels(server, NULL, remote_client, TRUE, (char *)"Killed", TRUE, TRUE); - silc_server_free_client_data(server, NULL, remote_client, TRUE, - comment ? comment : - (unsigned char *)"Killed"); - if (sock) + silc_server_free_sock_user_data(server, sock, comment ? comment : + (unsigned char *)"Killed"); + if (sock) { + silc_packet_set_context(sock, NULL); silc_server_close_connection(server, sock); + silc_packet_stream_unref(sock); + } } else { /* Router operator killing */ @@ -1556,12 +1564,13 @@ SILC_SERVER_CMD_FUNC(info) char info_string[256]; memset(info_string, 0, sizeof(info_string)); - snprintf(info_string, sizeof(info_string), - "location: %s server: %s admin: %s <%s>", - server->config->server_info->location, - server->config->server_info->server_type, - server->config->server_info->admin, - server->config->server_info->email); + silc_snprintf(info_string, sizeof(info_string), + "location: %s server: %s admin: %s <%s> version: %s", + server->config->server_info->location, + server->config->server_info->server_type, + server->config->server_info->admin, + server->config->server_info->email, + silc_dist_version); server_info = info_string; entry = server->id_entry; @@ -1828,6 +1837,7 @@ static void silc_server_command_join_channel(SilcServer server, SilcBuffer user_list, mode_list, invite_list, ban_list; SilcUInt16 ident = silc_command_get_ident(cmd->payload); char check[512], check2[512]; + void *plen; SilcBool founder = FALSE; SilcBool resolve; SilcBuffer fkey = NULL, chpklist = NULL; @@ -2144,10 +2154,11 @@ 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)) + while (silc_hash_table_get(&htl, (void *)&plen, (void *)&reply)) invite_list = silc_argument_payload_encode_one(invite_list, reply->data, - silc_buffer_len(reply), tmp_len); + silc_buffer_len(reply), + SILC_PTR_TO_32(plen)); silc_hash_table_list_reset(&htl); } @@ -2163,10 +2174,11 @@ 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)) + while (silc_hash_table_get(&htl, (void *)&plen, (void *)&reply)) ban_list = silc_argument_payload_encode_one(ban_list, reply->data, - silc_buffer_len(reply), tmp_len); + silc_buffer_len(reply), + SILC_PTR_TO_32(plen)); silc_hash_table_list_reset(&htl); } @@ -2819,7 +2831,7 @@ SILC_SERVER_CMD_FUNC(umode) SilcServer server = cmd->server; SilcClientEntry client = silc_packet_get_context(cmd->sock); unsigned char *tmp_mask, m[4]; - SilcUInt32 mask = 0; + SilcUInt32 mask = 0, tmp_len; SilcUInt16 ident = silc_command_get_ident(cmd->payload); SilcBool set_mask = FALSE; @@ -2829,8 +2841,8 @@ SILC_SERVER_CMD_FUNC(umode) SILC_SERVER_COMMAND_CHECK(SILC_COMMAND_UMODE, cmd, 1, 2); /* Get the client's mode mask */ - tmp_mask = silc_argument_get_arg_type(cmd->args, 2, NULL); - if (tmp_mask) { + tmp_mask = silc_argument_get_arg_type(cmd->args, 2, &tmp_len); + if (tmp_mask && tmp_len == 4) { SILC_GET32_MSB(mask, tmp_mask); set_mask = TRUE; } @@ -2943,7 +2955,7 @@ SILC_SERVER_CMD_FUNC(cmode) /* Get the channel mode mask */ tmp_mask = silc_argument_get_arg_type(cmd->args, 2, &tmp_len); - if (tmp_mask) { + if (tmp_mask && tmp_len == 4) { SILC_GET32_MSB(mode_mask, tmp_mask); set_mask = TRUE; } @@ -4370,8 +4382,10 @@ SILC_SERVER_CMD_FUNC(watch) pk = silc_argument_get_next_arg(pkargs, &type, &pk_len); while (pk) { - if (!silc_public_key_payload_decode(pk, pk_len, &public_key)) + if (!silc_public_key_payload_decode(pk, pk_len, &public_key)) { + pk = silc_argument_get_next_arg(pkargs, &type, &pk_len); continue; + } if (type == 0x03) type = 0x00; @@ -4598,7 +4612,7 @@ SILC_SERVER_CMD_FUNC(ban) SilcUInt32 id_len, len, len2; SilcArgumentPayload args; SilcHashTableList htl; - SilcUInt32 type; + void *type; SilcUInt16 argc = 0, ident = silc_command_get_ident(cmd->payload); SilcBufferStruct blist; @@ -4707,7 +4721,8 @@ SILC_SERVER_CMD_FUNC(ban) silc_hash_table_list(channel->ban_list, &htl); while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) list = silc_argument_payload_encode_one(list, tmp2->data, - silc_buffer_len(tmp2), type); + silc_buffer_len(tmp2), + SILC_PTR_TO_32(type)); silc_hash_table_list_reset(&htl); } diff --git a/apps/silcd/command_reply.c b/apps/silcd/command_reply.c index 97aedf0e..0b1645ec 100644 --- a/apps/silcd/command_reply.c +++ b/apps/silcd/command_reply.c @@ -152,6 +152,7 @@ silc_server_command_process_error(SilcServerCommandReplyContext cmd, silc_server_remove_from_channels(server, NULL, client, TRUE, NULL, TRUE, FALSE); + silc_dlist_del(server->expired_clients, client); silc_idlist_del_data(client); silc_idlist_del_client(server->global_list, client); } @@ -515,7 +516,7 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd) if (!nickname) { SILC_LOG_ERROR(("Malformed nickname '%s' received in WHOWAS reply " "from %s", - hostname ? hostname : "", nick)); + nick, hostname ? hostname : "")); return FALSE; } @@ -533,22 +534,24 @@ silc_server_command_reply_whowas_save(SilcServerCommandReplyContext cmd) client->servername = servername[0] ? strdup(servername) : NULL; client->data.status |= SILC_IDLIST_STATUS_RESOLVED; client->data.status &= ~SILC_IDLIST_STATUS_RESOLVING; + client->data.status &= ~SILC_IDLIST_STATUS_REGISTERED; - /* Remove the old cache entry and create a new one */ - silc_idcache_del_by_context(global ? server->global_list->clients : - server->local_list->clients, client, NULL); - silc_idcache_add(global ? server->global_list->clients : - server->local_list->clients, nickname, client->id, - client); + /* Update cache entry */ + silc_idcache_update_by_context(global ? server->global_list->clients : + server->local_list->clients, client, NULL, + nickname, TRUE); } /* If client is global and is not on any channel then add that we'll expire the entry after a while. */ if (global) { - silc_idlist_find_client_by_id(server->global_list, client->id, - FALSE, &cache); - if (!silc_hash_table_count(client->channels)) + client = silc_idlist_find_client_by_id(server->global_list, client->id, + FALSE, &cache); + if (client && !silc_hash_table_count(client->channels)) { + client->data.created = silc_time(); + silc_dlist_del(server->expired_clients, client); silc_dlist_add(server->expired_clients, client); + } } return TRUE; @@ -675,17 +678,13 @@ silc_server_command_reply_identify_save(SilcServerCommandReplyContext cmd) return FALSE; } - /* Remove the old cache entry */ - silc_idcache_del_by_context(global ? server->global_list->clients : - server->local_list->clients, client, NULL); - silc_free(client->nickname); client->nickname = strdup(nick); - /* Add new cache entry */ - silc_idcache_add(global ? server->global_list->clients : - server->local_list->clients, name, client->id, - client); + /* Update the context */ + silc_idcache_update_by_context(global ? server->global_list->clients : + server->local_list->clients, client, + NULL, name, TRUE); } if (info) { diff --git a/apps/silcd/idlist.c b/apps/silcd/idlist.c index e302b6e6..1c75d718 100644 --- a/apps/silcd/idlist.c +++ b/apps/silcd/idlist.c @@ -55,8 +55,6 @@ void silc_idlist_del_data(void *entry) if (idata->hash) silc_hash_free(idata->hash); - if (idata->public_key) - silc_pkcs_public_key_free(idata->public_key); idata->hash = NULL; idata->public_key = NULL; @@ -328,7 +326,7 @@ silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username, int ret; ret = silc_parse_userfqdn(username, u, sizeof(u), h, sizeof(h)); - if (!u) + if (!ret) return NULL; if (!silc_identifier_verify(u, strlen(u), SILC_STRING_UTF8, 128)) return NULL; @@ -338,6 +336,8 @@ silc_idlist_add_client(SilcIDList id_list, char *nickname, char *username, } client = silc_calloc(1, sizeof(*client)); + if (!client) + return NULL; client->nickname = nickname; client->username = username ? strdup(username) : NULL; client->userinfo = userinfo; diff --git a/apps/silcd/idlist.h b/apps/silcd/idlist.h index 25705a98..7b9c2ad1 100644 --- a/apps/silcd/idlist.h +++ b/apps/silcd/idlist.h @@ -554,6 +554,7 @@ typedef struct { const char *hostname; const char *ip; SilcUInt16 port; + SilcConnectionType conn_type; } *SilcUnknownEntry; /* Prototypes */ diff --git a/apps/silcd/packet_receive.c b/apps/silcd/packet_receive.c index 9b990ff8..73424a68 100644 --- a/apps/silcd/packet_receive.c +++ b/apps/silcd/packet_receive.c @@ -356,6 +356,8 @@ static void silc_server_notify_process(SilcServer server, client->mode = 0; client->router = NULL; client->connection = NULL; + client->data.created = silc_time(); + silc_dlist_del(server->expired_clients, client); silc_dlist_add(server->expired_clients, client); break; @@ -1263,6 +1265,7 @@ static void silc_server_notify_process(SilcServer server, silc_server_del_from_watcher_list(server, client); /* Remove the client */ + silc_dlist_del(server->expired_clients, client); silc_idlist_del_data(client); silc_idlist_del_client(local ? server->local_list : server->global_list, client); @@ -1504,6 +1507,8 @@ static void silc_server_notify_process(SilcServer server, client->mode = 0; client->router = NULL; client->connection = NULL; + client->data.created = silc_time(); + silc_dlist_del(server->expired_clients, client); silc_dlist_add(server->expired_clients, client); break; } @@ -1664,6 +1669,7 @@ static void silc_server_notify_process(SilcServer server, silc_server_remove_from_channels(server, NULL, client, TRUE, NULL, TRUE, FALSE); + silc_dlist_del(server->expired_clients, client); silc_idlist_del_data(client); silc_idlist_del_client(server->global_list, client); } @@ -2145,7 +2151,7 @@ SilcClientEntry silc_server_new_client(SilcServer server, if (silc_buffer_unformat(buffer, SILC_STR_UI16_NSTRING_ALLOC(&nickname, &nickname_len), - SILC_STR_END)) { + SILC_STR_END) >= 0) { if (nickname_len > 128) { nickname_len = 128; nickname[nickname_len - 1] = '\0'; @@ -3433,6 +3439,8 @@ void silc_server_resume_client(SilcServer server, SilcPublicKey public_key; const char *cipher, *hostname, *ip; + SILC_LOG_DEBUG(("Resuming client")); + silc_socket_stream_get_info(silc_packet_stream_get_stream(sock), NULL, &hostname, &ip, NULL); @@ -3696,6 +3704,7 @@ void silc_server_resume_client(SilcServer server, /* Take new keys and stuff into use in the old entry */ silc_idlist_del_data(detached_client); silc_idlist_add_data(detached_client, idata); + idata->public_key = NULL; if (detached_client->data.public_key) { /* Add the resumed client's public key back to repository. */ @@ -3712,6 +3721,7 @@ void silc_server_resume_client(SilcServer server, detached_client->data.status &= ~SILC_IDLIST_STATUS_RESUME_RES; detached_client->mode &= ~SILC_UMODE_DETACHED; server->stat.my_detached--; + silc_dlist_del(server->expired_clients, detached_client); /* We are finished - reset resuming client */ detached_client->resuming_client = NULL; @@ -3729,6 +3739,7 @@ void silc_server_resume_client(SilcServer server, silc_server_remove_from_channels(server, NULL, client, FALSE, NULL, FALSE, FALSE); silc_server_del_from_watcher_list(server, client); + silc_dlist_del(server->expired_clients, client); if (!silc_idlist_del_client(server->local_list, client)) silc_idlist_del_client(server->global_list, client); client = detached_client; @@ -3807,14 +3818,17 @@ void silc_server_resume_client(SilcServer server, silc_buffer_free(nidp); } - /* Add the client again to the ID cache to get it to correct list */ - if (!silc_idcache_del_by_context(server->local_list->clients, client, - NULL)) - silc_idcache_del_by_context(server->global_list->clients, client, NULL); - silc_free(client->id); - *client->id = client_id; - silc_idcache_add(server->local_list->clients, nicknamec, - client->id, client); + /* Update entry */ + if (!silc_idcache_update_by_context(server->local_list->clients, client, + &client_id, NULL, FALSE)) + silc_idcache_update_by_context(server->global_list->clients, client, + &client_id, NULL, FALSE); + + /* Move entry to local list if it is in global list */ + if (silc_idcache_find_by_context(server->global_list->clients, client, + &id_cache)) + silc_idcache_move(server->global_list->clients, + server->local_list->clients, id_cache); /* Send some nice info to the client */ silc_server_send_connect_notifys(server, sock, client); @@ -3975,15 +3989,18 @@ void silc_server_resume_client(SilcServer server, server_entry->server_type == SILC_ROUTER) local = FALSE; - /* Change the client to correct list. */ - if (!silc_idcache_del_by_context(server->local_list->clients, - detached_client, NULL)) - silc_idcache_del_by_context(server->global_list->clients, - detached_client, NULL); - silc_idcache_add(local && server->server_type == SILC_ROUTER ? - server->local_list->clients : - server->global_list->clients, nicknamec, - detached_client->id, detached_client); + /* Move entry to correct list */ + if (local && server->server_type == SILC_ROUTER) { + if (silc_idcache_find_by_context(server->global_list->clients, + detached_client, &id_cache)) + silc_idcache_move(server->global_list->clients, + server->local_list->clients, id_cache); + } else { + if (silc_idcache_find_by_context(server->local_list->clients, + detached_client, &id_cache)) + silc_idcache_move(server->local_list->clients, + server->global_list->clients, id_cache); + } /* Change the owner of the client */ detached_client->router = server_entry; diff --git a/apps/silcd/packet_send.c b/apps/silcd/packet_send.c index 7e19280e..efc334cd 100644 --- a/apps/silcd/packet_send.c +++ b/apps/silcd/packet_send.c @@ -295,7 +295,7 @@ void silc_server_packet_send_to_channel(SilcServer server, int k; /* This doesn't send channel message packets */ - assert(type != SILC_PACKET_CHANNEL_MESSAGE); + SILC_ASSERT(type != SILC_PACKET_CHANNEL_MESSAGE); /* If there are global users in the channel we will send the message first to our router for further routing. */ @@ -399,6 +399,8 @@ void silc_server_packet_send_to_channel(SilcServer server, static SilcBool silc_server_packet_relay_to_channel_encrypt(SilcServer server, SilcPacketStream sender, + void *sender_id, + SilcIdType sender_type, SilcChannelEntry channel, unsigned char *data, unsigned int data_len) @@ -451,8 +453,9 @@ silc_server_packet_relay_to_channel_encrypt(SilcServer server, memcpy(iv, data + (data_len - iv_len - mac_len), iv_len); - src_id.type = SILC_ID_SERVER; - src_id.u.server_id = *((SilcServerEntry)idata)->id; + SILC_ASSERT(sender_type == SILC_ID_CLIENT); + src_id.type = SILC_ID_CLIENT; + src_id.u.client_id = *((SilcClientID *)sender_id); dst_id.type = SILC_ID_CHANNEL; dst_id.u.channel_id = *channel->id; @@ -502,6 +505,7 @@ void silc_server_packet_relay_to_channel(SilcServer server, channel key. If the channel key does not exist, then we know we don't have a single local user on the channel. */ if (!silc_server_packet_relay_to_channel_encrypt(server, sender_sock, + sender_id, sender_type, channel, data, data_len)) return; @@ -767,6 +771,10 @@ void silc_server_send_notify(SilcServer server, va_start(ap, argc); packet = silc_notify_payload_encode(type, argc, ap); + if (!packet) { + va_end(ap); + return; + } silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY, broadcast ? SILC_PACKET_FLAG_BROADCAST : 0, packet->data, silc_buffer_len(packet)); @@ -797,9 +805,10 @@ void silc_server_send_notify_args(SilcServer server, SilcBuffer packet; packet = silc_notify_payload_encode_args(type, argc, args); - silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY, - broadcast ? SILC_PACKET_FLAG_BROADCAST : 0, - packet->data, silc_buffer_len(packet)); + if (packet) + silc_server_packet_send(server, sock, SILC_PACKET_NOTIFY, + broadcast ? SILC_PACKET_FLAG_BROADCAST : 0, + packet->data, silc_buffer_len(packet)); silc_buffer_free(packet); } @@ -817,10 +826,11 @@ void silc_server_send_notify_channel_change(SilcServer server, idp1 = silc_id_payload_encode((void *)old_id, SILC_ID_CHANNEL); idp2 = silc_id_payload_encode((void *)new_id, SILC_ID_CHANNEL); - silc_server_send_notify(server, sock, broadcast, - SILC_NOTIFY_TYPE_CHANNEL_CHANGE, - 2, idp1->data, silc_buffer_len(idp1), - idp2->data, silc_buffer_len(idp2)); + if (idp1 && idp2) + silc_server_send_notify(server, sock, broadcast, + SILC_NOTIFY_TYPE_CHANNEL_CHANGE, + 2, idp1->data, silc_buffer_len(idp1), + idp2->data, silc_buffer_len(idp2)); silc_buffer_free(idp1); silc_buffer_free(idp2); } @@ -840,11 +850,12 @@ void silc_server_send_notify_nick_change(SilcServer server, idp1 = silc_id_payload_encode((void *)old_id, SILC_ID_CLIENT); idp2 = silc_id_payload_encode((void *)new_id, SILC_ID_CLIENT); - silc_server_send_notify(server, sock, broadcast, - SILC_NOTIFY_TYPE_NICK_CHANGE, - 3, idp1->data, silc_buffer_len(idp1), - idp2->data, silc_buffer_len(idp2), - nickname, nickname ? strlen(nickname) : 0); + if (idp1 && idp2) + silc_server_send_notify(server, sock, broadcast, + SILC_NOTIFY_TYPE_NICK_CHANGE, + 3, idp1->data, silc_buffer_len(idp1), + idp2->data, silc_buffer_len(idp2), + nickname, nickname ? strlen(nickname) : 0); silc_buffer_free(idp1); silc_buffer_free(idp2); } @@ -862,9 +873,11 @@ void silc_server_send_notify_join(SilcServer server, idp1 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT); idp2 = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL); - silc_server_send_notify(server, sock, broadcast, SILC_NOTIFY_TYPE_JOIN, - 2, idp1->data, silc_buffer_len(idp1), - idp2->data, silc_buffer_len(idp2)); + + if (idp1 && idp2) + silc_server_send_notify(server, sock, broadcast, SILC_NOTIFY_TYPE_JOIN, + 2, idp1->data, silc_buffer_len(idp1), + idp2->data, silc_buffer_len(idp2)); silc_buffer_free(idp1); silc_buffer_free(idp2); } @@ -881,9 +894,10 @@ void silc_server_send_notify_leave(SilcServer server, SilcBuffer idp; idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT); - silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id, - SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_LEAVE, - 1, idp->data, silc_buffer_len(idp)); + if (idp) + silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id, + SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_LEAVE, + 1, idp->data, silc_buffer_len(idp)); silc_buffer_free(idp); } @@ -906,6 +920,8 @@ void silc_server_send_notify_cmode(SilcServer server, unsigned char mode[4], ulimit[4]; idp = silc_id_payload_encode((void *)id, id_type); + if (!idp) + return; SILC_PUT32_MSB(mode_mask, mode); if (founder_key) fkey = silc_public_key_payload_encode(founder_key); @@ -951,6 +967,8 @@ void silc_server_send_notify_cumode(SilcServer server, idp1 = silc_id_payload_encode((void *)id, id_type); idp2 = silc_id_payload_encode((void *)target, SILC_ID_CLIENT); + if (!idp1 || !idp2) + return; SILC_PUT32_MSB(mode_mask, mode); if (founder_key) fkey = silc_public_key_payload_encode(founder_key); @@ -982,10 +1000,11 @@ void silc_server_send_notify_signoff(SilcServer server, SilcBuffer idp; idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT); - silc_server_send_notify(server, sock, broadcast, - SILC_NOTIFY_TYPE_SIGNOFF, - message ? 2 : 1, idp->data, silc_buffer_len(idp), - message, message ? strlen(message): 0); + if (idp) + silc_server_send_notify(server, sock, broadcast, + SILC_NOTIFY_TYPE_SIGNOFF, + message ? 2 : 1, idp->data, silc_buffer_len(idp), + message, message ? strlen(message): 0); silc_buffer_free(idp); } @@ -1004,12 +1023,13 @@ void silc_server_send_notify_topic_set(SilcServer server, SilcBuffer idp; idp = silc_id_payload_encode(id, id_type); - silc_server_send_notify_dest(server, sock, broadcast, - (void *)channel->id, SILC_ID_CHANNEL, - SILC_NOTIFY_TYPE_TOPIC_SET, - topic ? 2 : 1, - idp->data, silc_buffer_len(idp), - topic, topic ? strlen(topic) : 0); + if (idp) + silc_server_send_notify_dest(server, sock, broadcast, + (void *)channel->id, SILC_ID_CHANNEL, + SILC_NOTIFY_TYPE_TOPIC_SET, + topic ? 2 : 1, + idp->data, silc_buffer_len(idp), + topic, topic ? strlen(topic) : 0); silc_buffer_free(idp); } @@ -1031,11 +1051,13 @@ void silc_server_send_notify_kicked(SilcServer server, idp1 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT); idp2 = silc_id_payload_encode((void *)kicker, SILC_ID_CLIENT); - silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id, - SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_KICKED, 3, - idp1->data, silc_buffer_len(idp1), - comment, comment ? strlen(comment) : 0, - idp2->data, silc_buffer_len(idp2)); + + if (idp1 && idp2) + silc_server_send_notify_dest(server, sock, broadcast, (void *)channel->id, + SILC_ID_CHANNEL, SILC_NOTIFY_TYPE_KICKED, 3, + idp1->data, silc_buffer_len(idp1), + comment, comment ? strlen(comment) : 0, + idp2->data, silc_buffer_len(idp2)); silc_buffer_free(idp1); silc_buffer_free(idp2); } @@ -1056,11 +1078,13 @@ void silc_server_send_notify_killed(SilcServer server, idp1 = silc_id_payload_encode(client_id, SILC_ID_CLIENT); idp2 = silc_id_payload_encode(killer, killer_type); - silc_server_send_notify_dest(server, sock, broadcast, (void *)client_id, - SILC_ID_CLIENT, SILC_NOTIFY_TYPE_KILLED, - 3, idp1->data, silc_buffer_len(idp1), - comment, comment ? strlen(comment) : 0, - idp2->data, silc_buffer_len(idp2)); + + if (idp1 && idp2) + silc_server_send_notify_dest(server, sock, broadcast, (void *)client_id, + SILC_ID_CLIENT, SILC_NOTIFY_TYPE_KILLED, + 3, idp1->data, silc_buffer_len(idp1), + comment, comment ? strlen(comment) : 0, + idp2->data, silc_buffer_len(idp2)); silc_buffer_free(idp1); silc_buffer_free(idp2); } @@ -1081,10 +1105,11 @@ void silc_server_send_notify_umode(SilcServer server, idp = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT); SILC_PUT32_MSB(mode_mask, mode); - silc_server_send_notify(server, sock, broadcast, - SILC_NOTIFY_TYPE_UMODE_CHANGE, 2, - idp->data, silc_buffer_len(idp), - mode, 4); + if (idp) + silc_server_send_notify(server, sock, broadcast, + SILC_NOTIFY_TYPE_UMODE_CHANGE, 2, + idp->data, silc_buffer_len(idp), + mode, 4); silc_buffer_free(idp); } @@ -1102,12 +1127,14 @@ void silc_server_send_notify_ban(SilcServer server, SilcBuffer idp; idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL); - silc_server_send_notify(server, sock, broadcast, - SILC_NOTIFY_TYPE_BAN, 3, - idp->data, silc_buffer_len(idp), - action ? action : NULL, action ? 1 : 0, - list ? list->data : NULL, - list ? silc_buffer_len(list) : 0); + + if (idp) + silc_server_send_notify(server, sock, broadcast, + SILC_NOTIFY_TYPE_BAN, 3, + idp->data, silc_buffer_len(idp), + action ? action : NULL, action ? 1 : 0, + list ? list->data : NULL, + list ? silc_buffer_len(list) : 0); silc_buffer_free(idp); } @@ -1128,14 +1155,17 @@ void silc_server_send_notify_invite(SilcServer server, idp = silc_id_payload_encode((void *)channel->id, SILC_ID_CHANNEL); idp2 = silc_id_payload_encode((void *)client_id, SILC_ID_CLIENT); - silc_server_send_notify(server, sock, broadcast, - SILC_NOTIFY_TYPE_INVITE, 5, - idp->data, silc_buffer_len(idp), - channel->channel_name, strlen(channel->channel_name), - idp2->data, silc_buffer_len(idp2), - action ? action : NULL, action ? 1 : 0, - list ? list->data : NULL, - list ? silc_buffer_len(list) : 0); + + if (idp && idp2) + silc_server_send_notify(server, sock, broadcast, + SILC_NOTIFY_TYPE_INVITE, 5, + idp->data, silc_buffer_len(idp), + channel->channel_name, + strlen(channel->channel_name), + idp2->data, silc_buffer_len(idp2), + action ? action : NULL, action ? 1 : 0, + list ? list->data : NULL, + list ? silc_buffer_len(list) : 0); silc_buffer_free(idp); silc_buffer_free(idp2); } @@ -1155,6 +1185,8 @@ void silc_server_send_notify_watch(SilcServer server, unsigned char mode[4], n[2]; idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT); + if (!idp) + return; SILC_PUT16_MSB(type, n); SILC_PUT32_MSB(client->mode, mode); if (public_key) @@ -1188,6 +1220,10 @@ void silc_server_send_notify_dest(SilcServer server, va_start(ap, argc); packet = silc_notify_payload_encode(type, argc, ap); + if (!packet) { + va_end(ap); + return; + } silc_server_packet_send_dest(server, sock, SILC_PACKET_NOTIFY, broadcast ? SILC_PACKET_FLAG_BROADCAST : 0, dest_id, dest_id_type, @@ -1228,10 +1264,11 @@ void silc_server_send_notify_to_channel(SilcServer server, va_start(ap, argc); packet = silc_notify_payload_encode(type, argc, ap); - silc_server_packet_send_to_channel(server, sender, channel, - SILC_PACKET_NOTIFY, route_notify, - send_to_clients, - packet->data, silc_buffer_len(packet)); + if (packet) + silc_server_packet_send_to_channel(server, sender, channel, + SILC_PACKET_NOTIFY, route_notify, + send_to_clients, + packet->data, silc_buffer_len(packet)); silc_buffer_free(packet); va_end(ap); } @@ -1273,6 +1310,10 @@ void silc_server_send_notify_on_channels(SilcServer server, va_start(ap, argc); packet = silc_notify_payload_encode(type, argc, ap); + if (!packet) { + va_end(ap); + return; + } data = packet->data; data_len = silc_buffer_len(packet); @@ -1366,9 +1407,10 @@ void silc_server_send_new_id(SilcServer server, SILC_LOG_DEBUG(("Sending new ID")); idp = silc_id_payload_encode(id, id_type); - silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, - broadcast ? SILC_PACKET_FLAG_BROADCAST : 0, - idp->data, silc_buffer_len(idp)); + if (idp) + silc_server_packet_send(server, sock, SILC_PACKET_NEW_ID, + broadcast ? SILC_PACKET_FLAG_BROADCAST : 0, + idp->data, silc_buffer_len(idp)); silc_buffer_free(idp); } @@ -1397,10 +1439,10 @@ void silc_server_send_new_channel(SilcServer server, /* Encode the channel payload */ packet = silc_channel_payload_encode(channel_name, name_len, cid, channel_id_len, mode); - - silc_server_packet_send(server, sock, SILC_PACKET_NEW_CHANNEL, - broadcast ? SILC_PACKET_FLAG_BROADCAST : 0, - packet->data, silc_buffer_len(packet)); + if (packet) + silc_server_packet_send(server, sock, SILC_PACKET_NEW_CHANNEL, + broadcast ? SILC_PACKET_FLAG_BROADCAST : 0, + packet->data, silc_buffer_len(packet)); silc_buffer_free(packet); } @@ -1438,10 +1480,11 @@ void silc_server_send_channel_key(SilcServer server, tmp_len = strlen(cipher); packet = silc_channel_key_payload_encode(cid_len, cid, tmp_len, cipher, channel->key_len / 8, channel->key); - silc_server_packet_send_to_channel(server, sender, channel, - SILC_PACKET_CHANNEL_KEY, - route, TRUE, packet->data, - silc_buffer_len(packet)); + if (packet) + silc_server_packet_send_to_channel(server, sender, channel, + SILC_PACKET_CHANNEL_KEY, + route, TRUE, packet->data, + silc_buffer_len(packet)); silc_buffer_free(packet); } @@ -1463,8 +1506,9 @@ void silc_server_send_command(SilcServer server, va_start(ap, argc); packet = silc_command_payload_encode_vap(command, ident, argc, ap); - silc_server_packet_send(server, sock, SILC_PACKET_COMMAND, 0, - packet->data, silc_buffer_len(packet)); + if (packet) + silc_server_packet_send(server, sock, SILC_PACKET_COMMAND, 0, + packet->data, silc_buffer_len(packet)); silc_buffer_free(packet); va_end(ap); } @@ -1490,8 +1534,9 @@ void silc_server_send_command_reply(SilcServer server, packet = silc_command_reply_payload_encode_vap(command, status, error, ident, argc, ap); - silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0, - packet->data, silc_buffer_len(packet)); + if (packet) + silc_server_packet_send(server, sock, SILC_PACKET_COMMAND_REPLY, 0, + packet->data, silc_buffer_len(packet)); silc_buffer_free(packet); va_end(ap); } @@ -1519,9 +1564,10 @@ void silc_server_send_dest_command_reply(SilcServer server, packet = silc_command_reply_payload_encode_vap(command, status, error, ident, argc, ap); - silc_server_packet_send_dest(server, sock, SILC_PACKET_COMMAND_REPLY, 0, - dst_id, dst_id_type, packet->data, - silc_buffer_len(packet)); + if (packet) + silc_server_packet_send_dest(server, sock, SILC_PACKET_COMMAND_REPLY, 0, + dst_id, dst_id_type, packet->data, + silc_buffer_len(packet)); silc_buffer_free(packet); va_end(ap); } @@ -1536,6 +1582,9 @@ void silc_server_send_connection_auth_request(SilcServer server, SilcBuffer packet; packet = silc_buffer_alloc(4); + if (!packet) + return; + silc_buffer_pull_tail(packet, silc_buffer_truelen(packet)); silc_buffer_format(packet, SILC_STR_UI_SHORT(conn_type), @@ -1709,8 +1758,9 @@ void silc_server_send_opers_notify(SilcServer server, va_start(ap, argc); packet = silc_notify_payload_encode(type, argc, ap); - silc_server_send_opers(server, SILC_PACKET_NOTIFY, 0, - route, local, packet->data, silc_buffer_len(packet)); + if (packet) + silc_server_send_opers(server, SILC_PACKET_NOTIFY, 0, + route, local, packet->data, silc_buffer_len(packet)); silc_buffer_free(packet); va_end(ap); } diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 46fccfc0..f03581bc 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2007 Pekka Riikonen + Copyright (C) 1997 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -103,12 +103,13 @@ static SilcBool silc_server_packet_receive(SilcPacketEngine engine, !(idata->status & SILC_IDLIST_STATUS_REGISTERED)) && packet->type != SILC_PACKET_NEW_CLIENT && packet->type != SILC_PACKET_NEW_SERVER && + packet->type != SILC_PACKET_RESUME_CLIENT && packet->type != SILC_PACKET_CONNECTION_AUTH_REQUEST && packet->type != SILC_PACKET_DISCONNECT) return FALSE; - /* NEW_CLIENT and NEW_SERVER are accepted only without source ID - and for unregistered connection. */ + /* NEW_CLIENT and NEW_SERVER are accepted only without source ID and + for unregistered connection. */ if (packet->src_id && (packet->type == SILC_PACKET_NEW_CLIENT || packet->type == SILC_PACKET_NEW_SERVER) && (idata->status & SILC_IDLIST_STATUS_REGISTERED)) @@ -130,7 +131,8 @@ static SilcBool silc_server_packet_receive(SilcPacketEngine engine, silc_id_str2id(packet->src_id, packet->src_id_len, packet->src_id_type, &client_id, sizeof(client_id))) { if (!SILC_ID_CLIENT_COMPARE(client->id, &client_id)) { - SILC_LOG_DEBUG(("Packet source is not same as sender")); + SILC_LOG_DEBUG(("Packet source is not same as sender, packet %s", + silc_get_packet_name(packet->type))); return FALSE; } } @@ -192,14 +194,17 @@ static void silc_server_packet_eos(SilcPacketEngine engine, SilcServer server = callback_context; SilcIDListData idata = silc_packet_get_context(stream); - SILC_LOG_DEBUG(("End of stream received")); + SILC_LOG_DEBUG(("End of stream received, sock %p", stream)); if (!idata) return; if (server->router_conn && server->router_conn->sock == stream && !server->router && server->standalone) { + if (idata->sconn && idata->sconn->callback) + (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context); silc_server_create_connections(server); + silc_server_free_sock_user_data(server, stream, NULL); } else { /* If backup disconnected then mark that resuming will not be allowed */ if (server->server_type == SILC_ROUTER && !server->backup_router && @@ -209,6 +214,8 @@ static void silc_server_packet_eos(SilcPacketEngine engine, server->backup_closed = TRUE; } + if (idata->sconn && idata->sconn->callback) + (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context); silc_server_free_sock_user_data(server, stream, NULL); } @@ -236,6 +243,8 @@ SILC_TASK_CALLBACK(silc_server_packet_error_timeout) server->backup_closed = TRUE; } + if (idata->sconn && idata->sconn->callback) + (*idata->sconn->callback)(server, NULL, idata->sconn->callback_context); silc_server_free_sock_user_data(server, stream, NULL); } @@ -256,6 +265,8 @@ static void silc_server_packet_error(SilcPacketEngine engine, const char *ip; SilcUInt16 port; + SILC_LOG_DEBUG(("Packet error, sock %p", stream)); + if (!idata || !sock) return; @@ -266,6 +277,9 @@ static void silc_server_packet_error(SilcPacketEngine engine, SILC_CONNTYPE_STRING(idata->conn_type), silc_packet_error_string(error))); + if (!silc_packet_stream_is_valid(stream)) + return; + silc_schedule_task_add_timeout(server->schedule, silc_server_packet_error_timeout, stream, 0, 0); @@ -666,6 +680,10 @@ void silc_server_free(SilcServer server) } } + silc_schedule_task_del_by_context(server->schedule, server); + silc_schedule_uninit(server->schedule); + server->schedule = NULL; + silc_idcache_free(server->local_list->clients); silc_idcache_free(server->local_list->servers); silc_idcache_free(server->local_list->channels); @@ -915,15 +933,18 @@ SilcBool silc_server_init(SilcServer server) } } + if (server->server_type != SILC_ROUTER) { + server->stat.servers = 1; + server->stat.cell_servers = 1; + } else { + server->stat.routers = 1; + } /* If we are normal server we'll retrieve network statisticial information once in a while from the router. */ if (server->server_type != SILC_ROUTER) silc_schedule_task_add_timeout(server->schedule, silc_server_get_stats, server, 10, 0); - if (server->server_type == SILC_ROUTER) - server->stat.routers++; - /* Start packet engine */ server->packet_engine = silc_packet_engine_start(server->rng, server->server_type == SILC_ROUTER, @@ -1202,6 +1223,9 @@ void silc_server_stop(SilcServer server) while ((ps = silc_dlist_get(list))) { SilcIDListData idata = silc_packet_get_context(ps); + if (!silc_packet_stream_is_valid(ps)) + continue; + if (idata) idata->status &= ~SILC_IDLIST_STATUS_DISABLED; @@ -1227,6 +1251,8 @@ void silc_server_stop(SilcServer server) silc_server_connect_router); silc_schedule_task_del_by_callback(server->schedule, silc_server_connect_to_router_retry); + silc_schedule_task_del_by_callback(server->schedule, + silc_server_connect_to_router); silc_schedule_stop(server->schedule); @@ -1246,13 +1272,12 @@ SILC_TASK_CALLBACK(silc_server_purge_expired_clients) silc_dlist_start(server->expired_clients); while ((client = silc_dlist_get(server->expired_clients))) { - if (client->data.status & SILC_IDLIST_STATUS_REGISTERED) continue; /* For unregistered clients the created timestamp is actually unregistered timestamp. Make sure client remains in history at least 500 seconds. */ - if (curtime - client->data.created < 500) + if (client->data.created && curtime - client->data.created < 500) continue; id_list = (client->data.status & SILC_IDLIST_STATUS_LOCAL ? @@ -1275,6 +1300,8 @@ SILC_TASK_CALLBACK(silc_server_purge_expired_clients) void silc_server_connection_free(SilcServerConnection sconn) { + if (!sconn) + return; SILC_LOG_DEBUG(("Free connection %p", sconn)); silc_dlist_del(sconn->server->conns, sconn); silc_server_config_unref(&sconn->conn); @@ -1306,7 +1333,8 @@ void silc_server_create_connection(SilcServer server, sconn->no_conf = dynamic; sconn->server = server; - SILC_LOG_DEBUG(("Created connection %p", sconn)); + SILC_LOG_DEBUG(("Created connection %p to %s:%d", sconn, + remote_host, port)); silc_schedule_task_add_timeout(server->schedule, silc_server_connect_router, sconn, 0, 0); @@ -1330,19 +1358,26 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, SilcID remote_id; const char *ip; - SILC_LOG_DEBUG(("Connection authentication completed")); + SILC_LOG_DEBUG(("Connection %p authentication completed, entry %p", + sconn, entry)); - sconn->op = NULL; + entry->op = NULL; if (success == FALSE) { /* Authentication failed */ - /* XXX retry connecting */ - silc_server_disconnect_remote(server, sconn->sock, - SILC_STATUS_ERR_AUTH_FAILED, NULL); + /* Try reconnecting if configuration wants it */ + if (!sconn->no_reconnect) { + silc_schedule_task_add_timeout(server->schedule, + silc_server_connect_to_router_retry, + sconn, 1, 0); + silc_dlist_del(server->conns, sconn); + return; + } + if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); + silc_server_free_sock_user_data(server, sconn->sock, NULL); return; } @@ -1368,11 +1403,16 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); - silc_free(entry); + silc_server_free_sock_user_data(server, sconn->sock, NULL); return; } + /* Statistics */ + server->stat.my_servers++; + if (server->server_type == SILC_ROUTER) + server->stat.servers++; + SILC_LOG_DEBUG(("my_servers %d", server->stat.my_servers)); + silc_idlist_add_data(id_entry, (SilcIDListData)entry); break; @@ -1392,8 +1432,7 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); - silc_free(entry); + silc_server_free_sock_user_data(server, sconn->sock, NULL); return; } @@ -1427,12 +1466,18 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_ID_SERVER), NULL, sconn->sock); if (!id_entry) { - silc_server_disconnect_remote(server, sconn->sock, - SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); + /* Try reconnecting if configuration wants it */ + if (!sconn->no_reconnect) { + silc_schedule_task_add_timeout(server->schedule, + silc_server_connect_to_router_retry, + sconn, 1, 0); + silc_dlist_del(server->conns, sconn); + return; + } + if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); - silc_free(entry); + silc_server_free_sock_user_data(server, sconn->sock, NULL); return; } @@ -1442,6 +1487,13 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, idata->status |= (SILC_IDLIST_STATUS_REGISTERED | SILC_IDLIST_STATUS_LOCAL); idata->sconn = sconn; + idata->sconn->callback = NULL; + + /* Statistics */ + server->stat.my_routers++; + if (server->server_type == SILC_ROUTER) + server->stat.routers++; + SILC_LOG_DEBUG(("my_routers %d", server->stat.my_routers)); if (!sconn->backup) { /* Mark this router our primary router if we're still standalone */ @@ -1480,8 +1532,9 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, silc_server_backup_add(server, server->id_entry, ip, sconn->remote_port, TRUE); } + } #if 0 - } else { + else { /* We already have primary router. Disconnect this connection */ SILC_LOG_DEBUG(("We already have primary router, disconnect")); silc_idlist_del_server(server->global_list, id_entry); @@ -1489,11 +1542,12 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); - silc_free(entry); + silc_server_free_sock_user_data(server, sconn->sock, NULL); + silc_server_disconnect_remote(server, sconn->sock, + SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); return; -#endif /* 0 */ } +#endif /* 0 */ } else { /* Add this server to be our backup router */ id_entry->server_type = SILC_BACKUP_ROUTER; @@ -1508,8 +1562,7 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_AUTH_FAILED, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); - silc_free(entry); + silc_server_free_sock_user_data(server, sconn->sock, NULL); return; } @@ -1528,7 +1581,6 @@ silc_server_ke_auth_compl(SilcConnAuth connauth, SilcBool success, /* Set the entry as packet stream context */ silc_packet_set_context(sconn->sock, id_entry); - out: /* Call the completion callback to indicate that we've connected to the router */ if (sconn && sconn->callback) @@ -1550,9 +1602,9 @@ static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status, { SilcPacketStream sock = context; SilcUnknownEntry entry = silc_packet_get_context(sock); - SilcServerConnection sconn = silc_ske_get_context(ske); - SilcServer server = entry->server; - SilcServerConfigRouter *conn = sconn->conn.ref_ptr; + SilcServerConnection sconn; + SilcServer server; + SilcServerConfigRouter *conn; SilcAuthMethod auth_meth = SILC_AUTH_NONE; void *auth_data = NULL; SilcUInt32 auth_data_len = 0; @@ -1561,20 +1613,31 @@ static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status, SilcHmac hmac_send, hmac_receive; SilcHash hash; - sconn->op = NULL; + server = entry->server; + sconn = entry->data.sconn; + conn = sconn->conn.ref_ptr; + entry->op = NULL; + + SILC_LOG_DEBUG(("Connection %p, SKE completed, entry %p", sconn, entry)); if (status != SILC_SKE_STATUS_OK) { /* SKE failed */ SILC_LOG_ERROR(("Error (%s) during Key Exchange protocol with %s (%s)", silc_ske_map_status(status), entry->hostname, entry->ip)); - - /* XXX retry connecting */ silc_ske_free(ske); - silc_server_disconnect_remote(server, sconn->sock, - SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); + + /* Try reconnecting if configuration wants it */ + if (!sconn->no_reconnect) { + silc_schedule_task_add_timeout(server->schedule, + silc_server_connect_to_router_retry, + sconn, 1, 0); + silc_dlist_del(server->conns, sconn); + return; + } + if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); + silc_server_free_sock_user_data(server, sconn->sock, NULL); return; } @@ -1583,16 +1646,23 @@ static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status, /* Set the keys into use. The data will be encrypted after this. */ if (!silc_ske_set_keys(ske, keymat, prop, &send_key, &receive_key, &hmac_send, &hmac_receive, &hash)) { + silc_ske_free(ske); - /* XXX retry connecting */ + /* Try reconnecting if configuration wants it */ + if (!sconn->no_reconnect) { + silc_schedule_task_add_timeout(server->schedule, + silc_server_connect_to_router_retry, + sconn, 1, 0); + silc_dlist_del(server->conns, sconn); + return; + } /* Error setting keys */ - silc_ske_free(ske); silc_server_disconnect_remote(server, sconn->sock, SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); + silc_server_free_sock_user_data(server, sconn->sock, NULL); return; } silc_packet_set_keys(sconn->sock, send_key, receive_key, hmac_send, @@ -1603,15 +1673,23 @@ static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status, connauth = silc_connauth_alloc(server->schedule, ske, server->config->conn_auth_timeout); if (!connauth) { - /* XXX retry connecting */ + silc_ske_free(ske); + + /* Try reconnecting if configuration wants it */ + if (!sconn->no_reconnect) { + silc_schedule_task_add_timeout(server->schedule, + silc_server_connect_to_router_retry, + sconn, 1, 0); + silc_dlist_del(server->conns, sconn); + return; + } /** Error allocating auth protocol */ - silc_ske_free(ske); silc_server_disconnect_remote(server, sconn->sock, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); + silc_server_free_sock_user_data(server, sconn->sock, NULL); return; } @@ -1635,7 +1713,7 @@ static void silc_server_ke_completed(SilcSKE ske, SilcSKEStatus status, entry->data.rekey = rekey; /* Start connection authentication */ - sconn->op = + entry->op = silc_connauth_initiator(connauth, server->server_type == SILC_SERVER ? SILC_CONN_SERVER : SILC_CONN_ROUTER, auth_meth, auth_data, auth_data_len, @@ -1663,6 +1741,16 @@ void silc_server_start_key_exchange(SilcServerConnection sconn) if (!sconn->sock) { SILC_LOG_ERROR(("Cannot connect: cannot create packet stream")); silc_stream_destroy(sconn->stream); + + /* Try reconnecting if configuration wants it */ + if (!sconn->no_reconnect) { + silc_schedule_task_add_timeout(server->schedule, + silc_server_connect_to_router_retry, + sconn, 1, 0); + silc_dlist_del(server->conns, sconn); + return; + } + if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); silc_server_connection_free(sconn); @@ -1674,6 +1762,16 @@ void silc_server_start_key_exchange(SilcServerConnection sconn) if (!silc_packet_set_ids(sconn->sock, SILC_ID_SERVER, server->id, 0, NULL)) { silc_packet_stream_destroy(sconn->sock); + + /* Try reconnecting if configuration wants it */ + if (!sconn->no_reconnect) { + silc_schedule_task_add_timeout(server->schedule, + silc_server_connect_to_router_retry, + sconn, 1, 0); + silc_dlist_del(server->conns, sconn); + return; + } + if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); silc_server_connection_free(sconn); @@ -1684,12 +1782,27 @@ void silc_server_start_key_exchange(SilcServerConnection sconn) entry = silc_calloc(1, sizeof(*entry)); if (!entry) { silc_packet_stream_destroy(sconn->sock); + + /* Try reconnecting if configuration wants it */ + if (!sconn->no_reconnect) { + silc_schedule_task_add_timeout(server->schedule, + silc_server_connect_to_router_retry, + sconn, 1, 0); + silc_dlist_del(server->conns, sconn); + return; + } + + if (sconn->callback) + (*sconn->callback)(server, NULL, sconn->callback_context); silc_server_connection_free(sconn); return; } entry->server = server; + entry->data.sconn = sconn; silc_packet_set_context(sconn->sock, entry); + SILC_LOG_DEBUG(("Created unknown connection %p", entry)); + /* Set Key Exchange flags from configuration, but fall back to global settings too. */ memset(¶ms, 0, sizeof(params)); @@ -1698,12 +1811,22 @@ void silc_server_start_key_exchange(SilcServerConnection sconn) params.flags |= SILC_SKE_SP_FLAG_PFS; /* Start SILC Key Exchange protocol */ - SILC_LOG_DEBUG(("Starting key exchange protocol")); + SILC_LOG_DEBUG(("Starting key exchange protocol, connection %p", sconn)); ske = silc_ske_alloc(server->rng, server->schedule, server->repository, server->public_key, server->private_key, sconn); if (!ske) { silc_free(entry); silc_packet_stream_destroy(sconn->sock); + + /* Try reconnecting if configuration wants it */ + if (!sconn->no_reconnect) { + silc_schedule_task_add_timeout(server->schedule, + silc_server_connect_to_router_retry, + sconn, 1, 0); + silc_dlist_del(server->conns, sconn); + return; + } + if (sconn->callback) (*sconn->callback)(server, NULL, sconn->callback_context); silc_server_connection_free(sconn); @@ -1715,7 +1838,7 @@ void silc_server_start_key_exchange(SilcServerConnection sconn) /* Start key exchange protocol */ params.version = silc_version_string; params.timeout_secs = server->config->key_exchange_timeout; - sconn->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL); + entry->op = silc_ske_initiator(ske, sconn->sock, ¶ms, NULL); } /* Timeout callback that will be called to retry connecting to remote @@ -1748,7 +1871,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router_retry) /* If we've reached max retry count, give up. */ if ((sconn->retry_count > param->reconnect_count) && - !param->reconnect_keep_trying) { + sconn->no_reconnect) { SILC_LOG_ERROR(("Could not connect, giving up")); if (sconn->callback) @@ -1782,7 +1905,7 @@ static void silc_server_connection_established(SilcNetStatus status, switch (status) { case SILC_NET_OK: - SILC_LOG_DEBUG(("Connection to %s:%d established", + SILC_LOG_DEBUG(("Connection %p to %s:%d established", sconn, sconn->remote_host, sconn->remote_port)); /* Continue with key exchange protocol */ @@ -1795,10 +1918,16 @@ static void silc_server_connection_established(SilcNetStatus status, SILC_LOG_ERROR(("Could not connect to %s:%d: %s", sconn->remote_host, sconn->remote_port, silc_net_get_error_string(status))); - - if (sconn->callback) - (*sconn->callback)(server, NULL, sconn->callback_context); - silc_server_connection_free(sconn); + if (!sconn->no_reconnect) { + silc_schedule_task_add_timeout(sconn->server->schedule, + silc_server_connect_to_router_retry, + sconn, 1, 0); + silc_dlist_del(server->conns, sconn); + } else { + if (sconn->callback) + (*sconn->callback)(server, NULL, sconn->callback_context); + silc_server_connection_free(sconn); + } break; default: @@ -1849,6 +1978,8 @@ SILC_TASK_CALLBACK(silc_server_connect_router) SILC_LOG_INFO(("Unconfigured %s connection %s:%d, cannot connect", (sconn->backup ? "backup router" : "router"), sconn->remote_host, sconn->remote_port)); + if (sconn->callback) + (*sconn->callback)(server, NULL, sconn->callback_context); silc_server_connection_free(sconn); return; } @@ -1865,6 +1996,8 @@ SILC_TASK_CALLBACK(silc_server_connect_router) if (!sconn->op) { SILC_LOG_ERROR(("Could not connect to router %s:%d", sconn->remote_host, sconn->remote_port)); + if (sconn->callback) + (*sconn->callback)(server, NULL, sconn->callback_context); silc_server_connection_free(sconn); return; } @@ -1883,6 +2016,7 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router) SilcServer server = context; SilcServerConnection sconn; SilcServerConfigRouter *ptr; + SilcServerConfigConnParams *param; /* Don't connect if we are shutting down. */ if (server->server_shutdown) @@ -1958,6 +2092,8 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router) } } + param = (ptr->param ? ptr->param : &server->config->param); + /* Allocate connection object for hold connection specific stuff. */ sconn = silc_calloc(1, sizeof(*sconn)); if (!sconn) @@ -1970,9 +2106,9 @@ SILC_TASK_CALLBACK(silc_server_connect_to_router) sconn->backup_replace_ip = strdup(ptr->backup_replace_ip); sconn->backup_replace_port = ptr->backup_replace_port; } + sconn->no_reconnect = param->reconnect_keep_trying == FALSE; SILC_LOG_DEBUG(("Created connection %p", sconn)); - if (!server->router_conn && !sconn->backup) server->router_conn = sconn; @@ -2022,7 +2158,16 @@ silc_server_accept_get_auth(SilcConnAuth connauth, if (cconfig->publickeys) *repository = server->repository; - entry->data.conn_type = conn_type; + if (cconfig->publickeys) { + if (server->config->prefer_passphrase_auth) { + *repository = NULL; + } else { + *passphrase = NULL; + *passphrase_len = 0; + } + } + + entry->conn_type = conn_type; return TRUE; } @@ -2043,7 +2188,16 @@ silc_server_accept_get_auth(SilcConnAuth connauth, if (sconfig->publickeys) *repository = server->repository; - entry->data.conn_type = conn_type; + if (sconfig->publickeys) { + if (server->config->prefer_passphrase_auth) { + *repository = NULL; + } else { + *passphrase = NULL; + *passphrase_len = 0; + } + } + + entry->conn_type = conn_type; return TRUE; } @@ -2058,7 +2212,16 @@ silc_server_accept_get_auth(SilcConnAuth connauth, if (rconfig->publickeys) *repository = server->repository; - entry->data.conn_type = conn_type; + if (rconfig->publickeys) { + if (server->config->prefer_passphrase_auth) { + *repository = NULL; + } else { + *passphrase = NULL; + *passphrase_len = 0; + } + } + + entry->conn_type = conn_type; return TRUE; } @@ -2092,19 +2255,23 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, server->stat.auth_failures++; silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); goto out; } SILC_LOG_DEBUG(("Checking whether connection is allowed")); - switch (entry->data.conn_type) { + switch (entry->conn_type) { case SILC_CONN_CLIENT: { SilcClientEntry client; SilcServerConfigClient *conn = entry->cconfig.ref_ptr; /* Verify whether this connection is after all allowed to connect */ - if (!silc_server_connection_allowed(server, sock, entry->data.conn_type, + if (!silc_server_connection_allowed(server, sock, entry->conn_type, &server->config->param, conn->param, silc_connauth_get_ske(connauth))) { @@ -2130,6 +2297,10 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_PERM_DENIED, "We do not have connection to backup " "router established, try later"); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); server->stat.auth_failures++; /* From here on, wait 20 seconds for the backup router to appear. */ @@ -2154,9 +2325,14 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, server->stat.auth_failures++; silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED, NULL); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); goto out; } entry->data.status |= SILC_IDLIST_STATUS_LOCAL; + entry->data.conn_type = SILC_CONN_CLIENT; /* Statistics */ server->stat.my_clients++; @@ -2184,6 +2360,7 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, } /* Add public key to repository */ + SILC_LOG_DEBUG(("Add client public key to repository")); if (!silc_server_get_public_key_by_client(server, client, NULL)) silc_skr_add_public_key_simple(server->repository, entry->data.public_key, @@ -2210,7 +2387,7 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, and we do not have connection to primary router, do not allow the connection. */ if (server->server_type == SILC_BACKUP_ROUTER && - entry->data.conn_type == SILC_CONN_SERVER && + entry->conn_type == SILC_CONN_SERVER && !SILC_PRIMARY_ROUTE(server)) { SILC_LOG_INFO(("Will not accept server connection because we do " "not have primary router connection established")); @@ -2218,17 +2395,24 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_PERM_DENIED, "We do not have connection to primary " "router established, try later"); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); server->stat.auth_failures++; goto out; } - if (entry->data.conn_type == SILC_CONN_ROUTER) { + if (entry->conn_type == SILC_CONN_ROUTER) { /* Verify whether this connection is after all allowed to connect */ if (!silc_server_connection_allowed(server, sock, - entry->data.conn_type, + entry->conn_type, &server->config->param, rconn ? rconn->param : NULL, silc_connauth_get_ske(connauth))) { + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); server->stat.auth_failures++; goto out; } @@ -2257,10 +2441,10 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, } } - if (entry->data.conn_type == SILC_CONN_SERVER) { + if (entry->conn_type == SILC_CONN_SERVER) { /* Verify whether this connection is after all allowed to connect */ if (!silc_server_connection_allowed(server, sock, - entry->data.conn_type, + entry->conn_type, &server->config->param, srvconn ? srvconn->param : NULL, silc_connauth_get_ske(connauth))) { @@ -2305,6 +2489,10 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_STATUS_ERR_PERM_DENIED, "We do not have connection to backup " "router established, try later"); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); server->stat.auth_failures++; /* From here on, wait 20 seconds for the backup router to appear. */ @@ -2316,11 +2504,11 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, } SILC_LOG_DEBUG(("Remote host is %s", - entry->data.conn_type == SILC_CONN_SERVER ? + entry->conn_type == SILC_CONN_SERVER ? "server" : (backup_router ? "backup router" : "router"))); SILC_LOG_INFO(("Connection %s (%s) is %s", entry->hostname, - entry->ip, entry->data.conn_type == SILC_CONN_SERVER ? + entry->ip, entry->conn_type == SILC_CONN_SERVER ? "server" : (backup_router ? "backup router" : "router"))); @@ -2329,15 +2517,15 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, server. We mark ourselves as router for this server if we really are router. */ new_server = - silc_idlist_add_server((entry->data.conn_type == SILC_CONN_SERVER ? + silc_idlist_add_server((entry->conn_type == SILC_CONN_SERVER ? server->local_list : (backup_router ? server->local_list : server->global_list)), NULL, - (entry->data.conn_type == SILC_CONN_SERVER ? + (entry->conn_type == SILC_CONN_SERVER ? SILC_SERVER : SILC_ROUTER), NULL, - (entry->data.conn_type == SILC_CONN_SERVER ? + (entry->conn_type == SILC_CONN_SERVER ? server->id_entry : (backup_router ? server->id_entry : NULL)), sock); @@ -2345,10 +2533,15 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, SILC_LOG_ERROR(("Could not add new server to cache")); silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_AUTH_FAILED, NULL); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); server->stat.auth_failures++; goto out; } entry->data.status |= SILC_IDLIST_STATUS_LOCAL; + entry->data.conn_type = entry->conn_type; id_entry = (void *)new_server; @@ -2413,6 +2606,7 @@ silc_server_accept_auth_compl(SilcConnAuth connauth, SilcBool success, sconn->remote_port = port; silc_dlist_add(server->conns, sconn); idata->sconn = sconn; + idata->sconn->callback = NULL; idata->last_receive = time(NULL); /* Add the common data structure to the ID entry. */ @@ -2467,6 +2661,10 @@ silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status, silc_ske_free(ske); silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); return; } @@ -2479,6 +2677,7 @@ silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status, silc_ske_free(ske); silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_KEY_EXCHANGE_FAILED, NULL); + silc_server_free_sock_user_data(server, sock, NULL); return; } silc_packet_set_keys(sock, send_key, receive_key, hmac_send, @@ -2489,6 +2688,8 @@ silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status, pk = silc_pkcs_public_key_encode(idata->public_key, &pk_len); silc_hash_make(server->sha1hash, pk, pk_len, idata->fingerprint); + silc_hash_alloc(silc_hash_get_name(prop->hash), &idata->hash); + SILC_LOG_DEBUG(("Starting connection authentication")); server->stat.auth_attempts++; @@ -2499,6 +2700,10 @@ silc_server_accept_completed(SilcSKE ske, SilcSKEStatus status, silc_ske_free(ske); silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); + silc_server_config_unref(&entry->cconfig); + silc_server_config_unref(&entry->sconfig); + silc_server_config_unref(&entry->rconfig); + silc_server_free_sock_user_data(server, sock, NULL); return; } @@ -2558,6 +2763,8 @@ static void silc_server_accept_new_connection(SilcNetStatus status, } server->stat.conn_num++; + SILC_LOG_DEBUG(("Created packet stream %p", packet_stream)); + /* Set source ID to packet stream */ if (!silc_packet_set_ids(packet_stream, SILC_ID_SERVER, server->id, 0, NULL)) { @@ -2577,6 +2784,7 @@ static void silc_server_accept_new_connection(SilcNetStatus status, silc_server_disconnect_remote(server, packet_stream, SILC_STATUS_ERR_BANNED_FROM_SERVER, deny->reason); + silc_server_free_sock_user_data(server, packet_stream, NULL); return; } @@ -2595,6 +2803,7 @@ static void silc_server_accept_new_connection(SilcNetStatus status, server->stat.conn_failures++; silc_server_disconnect_remote(server, packet_stream, SILC_STATUS_ERR_BANNED_FROM_SERVER, NULL); + silc_server_free_sock_user_data(server, packet_stream, NULL); return; } @@ -2604,6 +2813,7 @@ static void silc_server_accept_new_connection(SilcNetStatus status, server->stat.conn_failures++; silc_server_disconnect_remote(server, packet_stream, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); + silc_server_free_sock_user_data(server, packet_stream, NULL); return; } entry->hostname = hostname; @@ -2611,8 +2821,11 @@ static void silc_server_accept_new_connection(SilcNetStatus status, entry->port = port; entry->server = server; entry->data.conn_type = SILC_CONN_UNKNOWN; + entry->data.status |= SILC_IDLIST_STATUS_LOCAL; silc_packet_set_context(packet_stream, entry); + SILC_LOG_DEBUG(("Created unknown connection %p", entry)); + silc_server_config_ref(&entry->cconfig, server->config, cconfig); silc_server_config_ref(&entry->sconfig, server->config, sconfig); silc_server_config_ref(&entry->rconfig, server->config, rconfig); @@ -2639,6 +2852,7 @@ static void silc_server_accept_new_connection(SilcNetStatus status, server->stat.conn_failures++; silc_server_disconnect_remote(server, packet_stream, SILC_STATUS_ERR_RESOURCE_LIMIT, NULL); + silc_server_free_sock_user_data(server, packet_stream, NULL); return; } silc_ske_set_callbacks(ske, silc_server_verify_key, @@ -2761,9 +2975,9 @@ static void silc_server_rekey(SilcServer server, SilcPacketStream sock, SilcIDListData idata = silc_packet_get_context(sock); SilcSKE ske; - SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s]", + SILC_LOG_DEBUG(("Executing rekey protocol with %s:%d [%s], sock %p", idata->sconn->remote_host, idata->sconn->remote_port, - SILC_CONNTYPE_STRING(idata->conn_type))); + SILC_CONNTYPE_STRING(idata->conn_type), sock)); /* Allocate SKE */ ske = silc_ske_alloc(server->rng, server->schedule, NULL, @@ -2788,7 +3002,7 @@ static void silc_server_rekey(SilcServer server, SilcPacketStream sock, SILC_TASK_CALLBACK(silc_server_close_connection_final) { - silc_packet_stream_destroy(context); + silc_packet_stream_unref(context); } /* Closes connection to socket connection */ @@ -2801,6 +3015,7 @@ void silc_server_close_connection(SilcServer server, const char *hostname; SilcUInt16 port; + if (!silc_packet_stream_is_valid(sock)) memset(tmp, 0, sizeof(tmp)); // silc_socket_get_error(sock, tmp, sizeof(tmp)); silc_socket_stream_get_info(silc_packet_stream_get_stream(sock), @@ -2816,6 +3031,11 @@ void silc_server_close_connection(SilcServer server, idata->sconn = NULL; } + /* Take a reference and then destroy the stream. The last reference + is released later in a timeout callback. */ + silc_packet_stream_ref(sock); + silc_packet_stream_destroy(sock); + /* Close connection with timeout */ server->stat.conn_num--; silc_schedule_task_del_by_all(server->schedule, 0, @@ -2839,7 +3059,7 @@ void silc_server_disconnect_remote(SilcServer server, if (!sock) return; - SILC_LOG_DEBUG(("Disconnecting remote host")); + SILC_LOG_DEBUG(("Disconnecting remote host, sock %p", sock)); va_start(ap, status); cp = va_arg(ap, char *); @@ -2907,8 +3127,10 @@ void silc_server_free_client_data(SilcServer server, SILC_OPER_STATS_UPDATE(client, router, SILC_UMODE_ROUTER_OPERATOR); silc_schedule_task_del_by_context(server->schedule, client); - if (client->data.sconn) + if (client->data.sconn) { silc_server_connection_free(client->data.sconn); + client->data.sconn = NULL; + } /* We will not delete the client entry right away. We will take it into history (for WHOWAS command) for 5 minutes, unless we're @@ -2919,6 +3141,7 @@ void silc_server_free_client_data(SilcServer server, client->router = NULL; client->connection = NULL; client->data.created = silc_time(); + silc_dlist_del(server->expired_clients, client); silc_dlist_add(server->expired_clients, client); } else { /* Delete directly since we're shutting down server */ @@ -2936,16 +3159,21 @@ void silc_server_free_sock_user_data(SilcServer server, SilcPacketStream sock, const char *signoff_message) { - SilcIDListData idata = silc_packet_get_context(sock); + SilcIDListData idata; const char *ip; SilcUInt16 port; - SILC_LOG_DEBUG(("Start")); + if (!sock) + return; + SILC_LOG_DEBUG(("Start, sock %p", sock)); + + idata = silc_packet_get_context(sock); if (!idata) return; - silc_schedule_task_del_by_context(server->schedule, sock); + silc_schedule_task_del_by_all(server->schedule, 0, silc_server_do_rekey, + sock); /* Cancel active protocols */ if (idata) { @@ -3033,7 +3261,7 @@ void silc_server_free_sock_user_data(SilcServer server, /* We'll need to constantly try to reconnect to the primary router so that we'll see when it comes back online. */ - silc_server_create_connection(server, FALSE, FALSE, ip, port, + silc_server_create_connection(server, TRUE, FALSE, ip, port, silc_server_backup_connected, NULL); } @@ -3128,8 +3356,10 @@ void silc_server_free_sock_user_data(SilcServer server, } server->backup_noswitch = FALSE; - if (idata->sconn) + if (idata->sconn) { silc_server_connection_free(idata->sconn); + idata->sconn = NULL; + } /* Statistics */ if (idata->conn_type == SILC_CONN_SERVER) { @@ -3173,10 +3403,18 @@ void silc_server_free_sock_user_data(SilcServer server, { SilcUnknownEntry entry = (SilcUnknownEntry)idata; - SILC_LOG_DEBUG(("Freeing unknown connection data")); + SILC_LOG_DEBUG(("Freeing unknown connection data %p", entry)); + + if (idata->sconn) { + if (server->router_conn == idata->sconn) { + if (!server->no_reconnect) + silc_server_create_connections(server); + server->router_conn = NULL; + } - if (idata->sconn) silc_server_connection_free(idata->sconn); + idata->sconn = NULL; + } silc_idlist_del_data(idata); silc_free(entry); silc_packet_set_context(sock, NULL); @@ -3849,6 +4087,7 @@ static void silc_server_announce_get_servers(SilcServer server, SilcIDCacheEntry id_cache; SilcServerEntry entry; SilcBuffer idp; + void *tmp; /* Go through all clients in the list */ if (silc_idcache_get_all(id_list->servers, &list)) { @@ -3865,11 +4104,14 @@ static void silc_server_announce_get_servers(SilcServer server, idp = silc_id_payload_encode(entry->id, SILC_ID_SERVER); - *servers = silc_buffer_realloc(*servers, - (*servers ? - silc_buffer_truelen((*servers)) + - silc_buffer_len(idp) : - silc_buffer_len(idp))); + tmp = silc_buffer_realloc(*servers, + (*servers ? + silc_buffer_truelen((*servers)) + + silc_buffer_len(idp) : + silc_buffer_len(idp))); + if (!tmp) + return; + *servers = tmp; silc_buffer_pull_tail(*servers, ((*servers)->end - (*servers)->data)); silc_buffer_put(*servers, idp->data, silc_buffer_len(idp)); silc_buffer_pull(*servers, silc_buffer_len(idp)); @@ -3943,6 +4185,7 @@ static void silc_server_announce_get_clients(SilcServer server, SilcBuffer idp; SilcBuffer tmp; unsigned char mode[4]; + void *tmp2; /* Go through all clients in the list */ if (silc_idcache_get_all(id_list->clients, &list)) { @@ -3961,12 +4204,17 @@ static void silc_server_announce_get_clients(SilcServer server, silc_id_render(client->id, SILC_ID_CLIENT))); idp = silc_id_payload_encode(client->id, SILC_ID_CLIENT); + if (!idp) + return; - *clients = silc_buffer_realloc(*clients, - (*clients ? - silc_buffer_truelen((*clients)) + - silc_buffer_len(idp) : - silc_buffer_len(idp))); + tmp2 = silc_buffer_realloc(*clients, + (*clients ? + silc_buffer_truelen((*clients)) + + silc_buffer_len(idp) : + silc_buffer_len(idp))); + if (!tmp2) + return; + *clients = tmp2; silc_buffer_pull_tail(*clients, ((*clients)->end - (*clients)->data)); silc_buffer_put(*clients, idp->data, silc_buffer_len(idp)); silc_buffer_pull(*clients, silc_buffer_len(idp)); @@ -3976,11 +4224,14 @@ static void silc_server_announce_get_clients(SilcServer server, silc_server_announce_encode_notify(SILC_NOTIFY_TYPE_UMODE_CHANGE, 2, idp->data, silc_buffer_len(idp), mode, 4); - *umodes = silc_buffer_realloc(*umodes, - (*umodes ? - silc_buffer_truelen((*umodes)) + - silc_buffer_len(tmp) : - silc_buffer_len(tmp))); + tmp2 = silc_buffer_realloc(*umodes, + (*umodes ? + silc_buffer_truelen((*umodes)) + + silc_buffer_len(tmp) : + silc_buffer_len(tmp))); + if (!tmp2) + return; + *umodes = tmp2; silc_buffer_pull_tail(*umodes, ((*umodes)->end - (*umodes)->data)); silc_buffer_put(*umodes, tmp->data, silc_buffer_len(tmp)); silc_buffer_pull(*umodes, silc_buffer_len(tmp)); @@ -4067,6 +4318,7 @@ void silc_server_announce_get_inviteban(SilcServer server, { SilcBuffer list, idp, idp2, tmp2; SilcUInt32 type; + void *ptype; SilcHashTableList htl; const unsigned char a[1] = { 0x03 }; @@ -4078,9 +4330,10 @@ void silc_server_announce_get_inviteban(SilcServer server, type = silc_hash_table_count(channel->invite_list); SILC_PUT16_MSB(type, list->data); silc_hash_table_list(channel->invite_list, &htl); - while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) - list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2), - type); + while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) + list = silc_argument_payload_encode_one(list, tmp2->data, + silc_buffer_len(tmp2), + SILC_PTR_TO_32(ptype)); silc_hash_table_list_reset(&htl); idp2 = silc_id_payload_encode(server->id, SILC_ID_SERVER); @@ -4102,9 +4355,10 @@ void silc_server_announce_get_inviteban(SilcServer server, type = silc_hash_table_count(channel->ban_list); SILC_PUT16_MSB(type, list->data); silc_hash_table_list(channel->ban_list, &htl); - while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) - list = silc_argument_payload_encode_one(list, tmp2->data, silc_buffer_len(tmp2), - type); + while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) + list = silc_argument_payload_encode_one(list, tmp2->data, + silc_buffer_len(tmp2), + SILC_PTR_TO_32(ptype)); silc_hash_table_list_reset(&htl); *ban = @@ -4133,6 +4387,7 @@ void silc_server_announce_get_channel_users(SilcServer server, int len; unsigned char mode[4], ulimit[4]; char *hmac; + void *tmp2; SILC_LOG_DEBUG(("Start")); @@ -4169,10 +4424,13 @@ void silc_server_announce_get_channel_users(SilcServer server, SILC_CHANNEL_MODE_ULIMIT ? sizeof(ulimit) : 0)); len = silc_buffer_len(tmp); - *channel_modes = + tmp2 = silc_buffer_realloc(*channel_modes, (*channel_modes ? silc_buffer_truelen((*channel_modes)) + len : len)); + if (!tmp2) + return; + *channel_modes = tmp2; silc_buffer_pull_tail(*channel_modes, ((*channel_modes)->end - (*channel_modes)->data)); @@ -4197,10 +4455,13 @@ void silc_server_announce_get_channel_users(SilcServer server, chidp->data, silc_buffer_len(chidp)); len = silc_buffer_len(tmp); - *channel_users = + tmp2 = silc_buffer_realloc(*channel_users, (*channel_users ? silc_buffer_truelen((*channel_users)) + len : len)); + if (!tmp2) + return; + *channel_users = tmp2; silc_buffer_pull_tail(*channel_users, ((*channel_users)->end - (*channel_users)->data)); @@ -4222,11 +4483,14 @@ void silc_server_announce_get_channel_users(SilcServer server, fkey ? fkey->data : NULL, fkey ? silc_buffer_len(fkey) : 0); len = silc_buffer_len(tmp); - *channel_users_modes = + tmp2 = silc_buffer_realloc(*channel_users_modes, (*channel_users_modes ? silc_buffer_truelen((*channel_users_modes)) + len : len)); + if (!tmp2) + return; + *channel_users_modes = tmp2; silc_buffer_pull_tail(*channel_users_modes, ((*channel_users_modes)->end - (*channel_users_modes)->data)); @@ -4268,6 +4532,7 @@ void silc_server_announce_get_channels(SilcServer server, SilcUInt16 name_len; int len; int i = *channel_users_modes_c; + void *tmp; SilcBool announce; SILC_LOG_DEBUG(("Start")); @@ -4291,11 +4556,15 @@ void silc_server_announce_get_channels(SilcServer server, if (announce) { len = 4 + name_len + id_len + 4; - *channels = + tmp = silc_buffer_realloc(*channels, (*channels ? silc_buffer_truelen((*channels)) + len : len)); + if (!tmp) + break; + *channels = tmp; + silc_buffer_pull_tail(*channels, ((*channels)->end - (*channels)->data)); silc_buffer_format(*channels, @@ -4316,15 +4585,23 @@ void silc_server_announce_get_channels(SilcServer server, if (announce) { /* Channel user modes */ - *channel_users_modes = silc_realloc(*channel_users_modes, - sizeof(**channel_users_modes) * - (i + 1)); + tmp = silc_realloc(*channel_users_modes, + sizeof(**channel_users_modes) * (i + 1)); + if (!tmp) + break; + *channel_users_modes = tmp; (*channel_users_modes)[i] = NULL; - *channel_modes = silc_realloc(*channel_modes, - sizeof(**channel_modes) * (i + 1)); + tmp = silc_realloc(*channel_modes, + sizeof(**channel_modes) * (i + 1)); + if (!tmp) + break; + *channel_modes = tmp; (*channel_modes)[i] = NULL; - *channel_ids = silc_realloc(*channel_ids, - sizeof(**channel_ids) * (i + 1)); + tmp = silc_realloc(*channel_ids, + sizeof(**channel_ids) * (i + 1)); + if (!tmp) + break; + *channel_ids = tmp; (*channel_ids)[i] = NULL; silc_server_announce_get_channel_users(server, channel, &(*channel_modes)[i], @@ -4333,18 +4610,27 @@ void silc_server_announce_get_channels(SilcServer server, (*channel_ids)[i] = channel->id; /* Channel's topic */ - *channel_topics = silc_realloc(*channel_topics, - sizeof(**channel_topics) * (i + 1)); + tmp = silc_realloc(*channel_topics, + sizeof(**channel_topics) * (i + 1)); + if (!tmp) + break; + *channel_topics = tmp; (*channel_topics)[i] = NULL; silc_server_announce_get_channel_topic(server, channel, &(*channel_topics)[i]); /* Channel's invite and ban list */ - *channel_invites = silc_realloc(*channel_invites, - sizeof(**channel_invites) * (i + 1)); + tmp = silc_realloc(*channel_invites, + sizeof(**channel_invites) * (i + 1)); + if (!tmp) + break; + *channel_invites = tmp; (*channel_invites)[i] = NULL; - *channel_bans = silc_realloc(*channel_bans, - sizeof(**channel_bans) * (i + 1)); + tmp = silc_realloc(*channel_bans, + sizeof(**channel_bans) * (i + 1)); + if (!tmp) + break; + *channel_bans = tmp; (*channel_bans)[i] = NULL; silc_server_announce_get_inviteban(server, channel, &(*channel_invites)[i], diff --git a/apps/silcd/server_backup.c b/apps/silcd/server_backup.c index e460c95d..8f5140c1 100644 --- a/apps/silcd/server_backup.c +++ b/apps/silcd/server_backup.c @@ -786,11 +786,16 @@ SILC_TASK_CALLBACK(silc_server_backup_connected_again) SilcServer server = app_context; SilcServerConfigRouter *primary; + SILC_LOG_DEBUG(("Reconnecting")); + + if (server->server_shutdown) + return; + primary = silc_server_config_get_primary_router(server); if (primary) { if (!silc_server_find_socket_by_host(server, SILC_CONN_ROUTER, primary->host, primary->port)) - silc_server_create_connection(server, FALSE, FALSE, + silc_server_create_connection(server, TRUE, FALSE, primary->host, primary->port, silc_server_backup_connected, context); @@ -810,6 +815,7 @@ void silc_server_backup_connected(SilcServer server, if (!server_entry) { /* Try again */ + SILC_LOG_DEBUG(("Connecting failed")); silc_schedule_task_add_timeout(server->schedule, silc_server_backup_connected_again, context, 5, 0); @@ -840,7 +846,7 @@ SILC_TASK_CALLBACK(silc_server_backup_connect_primary_again) if (primary) { if (!silc_server_find_socket_by_host(server, SILC_CONN_ROUTER, primary->host, primary->port)) - silc_server_create_connection(server, FALSE, FALSE, + silc_server_create_connection(server, TRUE, FALSE, primary->host, primary->port, silc_server_backup_connect_primary, context); @@ -1040,7 +1046,7 @@ SILC_TASK_CALLBACK(silc_server_protocol_backup) SILC_LOG_DEBUG(("Received START (session %d), reconnect to router", ctx->session)); silc_packet_stream_ref(ctx->sock); - silc_server_create_connection(server, FALSE, FALSE, + silc_server_create_connection(server, TRUE, FALSE, primary->host, primary->port, silc_server_backup_connect_primary, ctx->sock); diff --git a/apps/silcd/server_query.c b/apps/silcd/server_query.c index cd5103a4..59eda802 100644 --- a/apps/silcd/server_query.c +++ b/apps/silcd/server_query.c @@ -397,11 +397,11 @@ void silc_server_query_send_router_reply(void *context, void *reply) returned error. */ if (query->nick_server[0] && !query->dynamic_retry && !silc_server_num_sockets_by_remote(server, query->nick_server, - query->nick_server, 1334, type)) { + query->nick_server, 706, type)) { SILC_LOG_DEBUG(("Retry query by connecting to %s:%d", query->nick_server, 706)); silc_server_create_connection(server, FALSE, TRUE, query->nick_server, - 1334, silc_server_query_connected, + 706, silc_server_query_connected, query); query->dynamic_retry = TRUE; query->resolved = FALSE; @@ -1516,6 +1516,7 @@ void silc_server_query_send_reply(SilcServer server, SilcUInt16 ident = silc_command_get_ident(cmd->payload); SilcStatus status; unsigned char *tmp; + char *tmp2; SilcUInt32 len; SilcBuffer idp; int i, k, valid_count; @@ -1642,8 +1643,8 @@ void silc_server_query_send_reply(SilcServer server, hsock = entry->connection; silc_strncat(uh, sizeof(uh), "@", 1); silc_socket_stream_get_info(silc_packet_stream_get_stream(hsock), - NULL, (const char **)&tmp, NULL, NULL); - silc_strncat(uh, sizeof(uh), tmp, strlen(tmp)); + NULL, (const char **)&tmp2, NULL, NULL); + silc_strncat(uh, sizeof(uh), tmp2, strlen(tmp2)); } if (idata->conn_type == SILC_CONN_CLIENT) @@ -1733,9 +1734,9 @@ void silc_server_query_send_reply(SilcServer server, hsock = entry->connection; silc_strncat(uh, sizeof(uh), "@", 1); silc_socket_stream_get_info(silc_packet_stream_get_stream(hsock), - NULL, (const char **)&tmp, + NULL, (const char **)&tmp2, NULL, NULL); - silc_strncat(uh, sizeof(uh), tmp, strlen(tmp)); + silc_strncat(uh, sizeof(uh), tmp2, strlen(tmp2)); } silc_server_send_command_reply(server, cmd->sock, query->querycmd, diff --git a/apps/silcd/server_util.c b/apps/silcd/server_util.c index 19ea23e6..74ce18ba 100644 --- a/apps/silcd/server_util.c +++ b/apps/silcd/server_util.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2005, 2007 Pekka Riikonen + Copyright (C) 1997 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -228,6 +228,8 @@ SilcBool silc_server_remove_clients_by_server(SilcServer server, client->mode = 0; client->router = NULL; client->connection = NULL; + client->data.created = silc_time(); + silc_dlist_del(server->expired_clients, client); silc_dlist_add(server->expired_clients, client); } else { silc_idlist_del_data(client); @@ -289,6 +291,8 @@ SilcBool silc_server_remove_clients_by_server(SilcServer server, client->mode = 0; client->router = NULL; client->connection = NULL; + client->data.created = silc_time(); + silc_dlist_del(server->expired_clients, client); silc_dlist_add(server->expired_clients, client); } else { silc_idlist_del_data(client); @@ -997,7 +1001,7 @@ SilcUInt32 silc_server_num_sockets_by_ip(SilcServer server, const char *ip, silc_dlist_start(server->conns); while ((conn = silc_dlist_get(server->conns))) { - if (!conn->sock) + if (!conn->sock || !silc_packet_stream_is_valid(conn->sock)) continue; silc_socket_stream_get_info(silc_packet_stream_get_stream(conn->sock), NULL, NULL, &ipaddr, NULL); @@ -1023,7 +1027,7 @@ silc_server_find_socket_by_host(SilcServer server, silc_dlist_start(server->conns); while ((conn = silc_dlist_get(server->conns))) { - if (!conn->sock) + if (!conn->sock || !silc_packet_stream_is_valid(conn->sock)) continue; idata = silc_packet_get_context(conn->sock); silc_socket_stream_get_info(silc_packet_stream_get_stream(conn->sock), @@ -1112,6 +1116,13 @@ SilcPublicKey silc_server_get_public_key(SilcServer server, silc_skr_find(server->repository, server->schedule, find, find_callback, &public_key); +#ifdef SILC_DEBUG + if (public_key) + SILC_LOG_DEBUG(("Found public key")); + else + SILC_LOG_DEBUG(("Public key not found")); +#endif /* SILC_DEBUG */ + return public_key; } @@ -1188,6 +1199,7 @@ SilcBool silc_server_connection_allowed(SilcServer server, silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_BAD_VERSION, "You support too old protocol version"); + silc_server_free_sock_user_data(server, sock, NULL); return FALSE; } @@ -1199,6 +1211,7 @@ SilcBool silc_server_connection_allowed(SilcServer server, silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_BAD_VERSION, "You support too old software version"); + silc_server_free_sock_user_data(server, sock, NULL); return FALSE; } @@ -1210,6 +1223,7 @@ SilcBool silc_server_connection_allowed(SilcServer server, silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_BAD_VERSION, "Your software is not supported"); + silc_server_free_sock_user_data(server, sock, NULL); return FALSE; } } @@ -1229,6 +1243,7 @@ SilcBool silc_server_connection_allowed(SilcServer server, silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_RESOURCE_LIMIT, "Server is full, try again later"); + silc_server_free_sock_user_data(server, sock, NULL); return FALSE; } @@ -1240,6 +1255,7 @@ SilcBool silc_server_connection_allowed(SilcServer server, silc_server_disconnect_remote(server, sock, SILC_STATUS_ERR_RESOURCE_LIMIT, "Too many connections from your host"); + silc_server_free_sock_user_data(server, sock, NULL); return FALSE; } @@ -1531,8 +1547,17 @@ void silc_server_kill_client(SilcServer server, if (remote_client->connection) { /* Remove locally conneted client */ SilcPacketStream sock = remote_client->connection; - silc_server_free_client_data(server, sock, remote_client, FALSE, NULL); - silc_server_close_connection(server, sock); + + if (sock) + silc_packet_stream_ref(sock); + + silc_server_free_sock_user_data(server, sock, NULL); + + if (sock) { + silc_packet_set_context(sock, NULL); + silc_server_close_connection(server, sock); + silc_packet_stream_unref(sock); + } } else { /* Update statistics */ server->stat.clients--; @@ -1554,6 +1579,7 @@ void silc_server_kill_client(SilcServer server, } /* Remove remote client */ + silc_dlist_del(server->expired_clients, remote_client); silc_idlist_del_data(remote_client); if (!silc_idlist_del_client(server->global_list, remote_client)) { /* Remove this client from watcher list if it is */ @@ -1746,10 +1772,11 @@ SilcBool silc_server_inviteban_match(SilcServer server, SilcHashTable list, SilcUInt8 type, void *check) { unsigned char *tmp = NULL; - SilcUInt32 len = 0, t; + SilcUInt32 len = 0; SilcHashTableList htl; SilcBuffer entry, idp = NULL, pkp = NULL; SilcBool ret = FALSE; + void *t; SILC_LOG_DEBUG(("Matching invite/ban")); @@ -1779,13 +1806,14 @@ SilcBool silc_server_inviteban_match(SilcServer server, SilcHashTable list, /* Compare the list */ silc_hash_table_list(list, &htl); while (silc_hash_table_get(&htl, (void *)&t, (void *)&entry)) { - if (type == t) { + if (type == SILC_PTR_TO_32(t)) { if (type == 1) { if (silc_string_match(entry->data, tmp)) { ret = TRUE; break; } - } else if (!memcmp(entry->data, tmp, len)) { + } else if (silc_buffer_len(entry) == len && + !memcmp(entry->data, tmp, len)) { ret = TRUE; break; } @@ -1809,6 +1837,7 @@ SilcBool silc_server_inviteban_process(SilcServer server, { unsigned char *tmp; SilcUInt32 type, len; + void *ptype; SilcBuffer tmp2; SilcHashTableList htl; @@ -1835,8 +1864,9 @@ SilcBool silc_server_inviteban_process(SilcServer server, /* Check if the string is added already */ silc_hash_table_list(list, &htl); - while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) { - if (type == 1 && silc_string_match(tmp2->data, tmp)) { + while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) { + if (SILC_PTR_TO_32(ptype) == 1 && + silc_string_match(tmp2->data, tmp)) { tmp = NULL; break; } @@ -1866,8 +1896,8 @@ SilcBool silc_server_inviteban_process(SilcServer server, /* Check if the public key is in the list already */ silc_hash_table_list(list, &htl); - while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) { - if (type == 2 && !memcmp(tmp2->data, tmp, len)) { + while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) { + if (SILC_PTR_TO_32(ptype) == 2 && !memcmp(tmp2->data, tmp, len)) { tmp = NULL; break; } @@ -1886,8 +1916,8 @@ SilcBool silc_server_inviteban_process(SilcServer server, /* Check if the ID is in the list already */ silc_hash_table_list(list, &htl); - while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) { - if (type == 3 && !memcmp(tmp2->data, tmp, len)) { + while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) { + if (SILC_PTR_TO_32(ptype) == 3 && !memcmp(tmp2->data, tmp, len)) { tmp = NULL; break; } @@ -1925,8 +1955,9 @@ SilcBool silc_server_inviteban_process(SilcServer server, /* Delete from the list */ silc_hash_table_list(list, &htl); - while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) { - if (type == 1 && silc_string_match(tmp2->data, tmp)) { + while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) { + if (SILC_PTR_TO_32(ptype) == 1 && + silc_string_match(tmp2->data, tmp)) { silc_hash_table_del_by_context(list, (void *)1, tmp2); break; } @@ -1946,8 +1977,8 @@ SilcBool silc_server_inviteban_process(SilcServer server, /* Delete from the invite list */ silc_hash_table_list(list, &htl); - while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) { - if (type == 2 && !memcmp(tmp2->data, tmp, len)) { + while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) { + if (SILC_PTR_TO_32(ptype) == 2 && !memcmp(tmp2->data, tmp, len)) { silc_hash_table_del_by_context(list, (void *)2, tmp2); break; } @@ -1959,8 +1990,8 @@ SilcBool silc_server_inviteban_process(SilcServer server, /* Delete from the invite list */ silc_hash_table_list(list, &htl); - while (silc_hash_table_get(&htl, (void *)&type, (void *)&tmp2)) { - if (type == 3 && !memcmp(tmp2->data, tmp, len)) { + while (silc_hash_table_get(&htl, (void *)&ptype, (void *)&tmp2)) { + if (SILC_PTR_TO_32(ptype) == 3 && !memcmp(tmp2->data, tmp, len)) { silc_hash_table_del_by_context(list, (void *)3, tmp2); break; } @@ -2090,6 +2121,8 @@ SilcBuffer silc_server_get_channel_pk_list(SilcServer server, silc_hash_table_list(channel->channel_pubkeys, &htl); while (silc_hash_table_get(&htl, NULL, (void *)&pk)) { pkp = silc_public_key_payload_encode(pk); + if (!pkp) + continue; list = silc_argument_payload_encode_one(list, pkp->data, silc_buffer_len(pkp), announce ? 0x03 : diff --git a/apps/silcd/serverconfig.c b/apps/silcd/serverconfig.c index fca40453..30d76af3 100644 --- a/apps/silcd/serverconfig.c +++ b/apps/silcd/serverconfig.c @@ -183,8 +183,8 @@ static SilcBool my_parse_authdata(SilcAuthMethod auth_meth, const char *p, return TRUE; } -static SilcBool my_parse_publickeydir(const char *dirname, void **auth_data, - SilcSKRKeyUsage usage) +static int my_parse_publickeydir(const char *dirname, void **auth_data, + SilcSKRKeyUsage usage) { int total = 0; struct dirent *get_file; @@ -193,7 +193,7 @@ static SilcBool my_parse_publickeydir(const char *dirname, void **auth_data, if (!(dp = opendir(dirname))) { SILC_SERVER_LOG_ERROR(("Error while parsing config file: " "Could not open directory \"%s\"", dirname)); - return FALSE; + return -1; } /* errors are not considered fatal */ @@ -216,14 +216,14 @@ static SilcBool my_parse_publickeydir(const char *dirname, void **auth_data, SILC_SERVER_LOG_ERROR(("Error stating file %s: %s", buf, strerror(errno))); } else if (S_ISREG(check_file.st_mode)) { - my_parse_authdata(SILC_AUTH_PUBLIC_KEY, buf, auth_data, NULL, - usage, NULL); - total++; + if (my_parse_authdata(SILC_AUTH_PUBLIC_KEY, buf, auth_data, NULL, + usage, NULL)) + total++; } } SILC_LOG_DEBUG(("Tried to load %d public keys in \"%s\"", total, dirname)); - return TRUE; + return total; } /* Callbacks */ @@ -233,11 +233,7 @@ SILC_CONFIG_CALLBACK(fetch_generic) SilcServerConfig config = (SilcServerConfig) context; int got_errno = 0; - if (!strcmp(name, "module_path")) { - CONFIG_IS_DOUBLE(config->module_path); - config->module_path = (*(char *)val ? strdup((char *) val) : NULL); - } - else if (!strcmp(name, "prefer_passphrase_auth")) { + if (!strcmp(name, "prefer_passphrase_auth")) { config->prefer_passphrase_auth = *(SilcBool *)val; } else if (!strcmp(name, "require_reverse_lookup")) { @@ -380,10 +376,6 @@ SILC_CONFIG_CALLBACK(fetch_cipher) CONFIG_IS_DOUBLE(tmp->name); tmp->name = strdup((char *) val); } - else if (!strcmp(name, "module")) { - CONFIG_IS_DOUBLE(tmp->module); - tmp->module = (*(char *)val ? strdup((char *) val) : NULL); - } else if (!strcmp(name, "keylength")) { tmp->key_length = *(SilcUInt32 *)val; } @@ -396,7 +388,6 @@ SILC_CONFIG_CALLBACK(fetch_cipher) got_err: silc_free(tmp->name); - silc_free(tmp->module); silc_free(tmp); config->tmp = NULL; return got_errno; @@ -428,10 +419,6 @@ SILC_CONFIG_CALLBACK(fetch_hash) CONFIG_IS_DOUBLE(tmp->name); tmp->name = strdup((char *) val); } - else if (!strcmp(name, "module")) { - CONFIG_IS_DOUBLE(tmp->module); - tmp->module = (*(char *)val ? strdup((char *) val) : NULL); - } else if (!strcmp(name, "blocklength")) { tmp->block_length = *(int *)val; } @@ -444,7 +431,6 @@ SILC_CONFIG_CALLBACK(fetch_hash) got_err: silc_free(tmp->name); - silc_free(tmp->module); silc_free(tmp); config->tmp = NULL; return got_errno; @@ -654,10 +640,11 @@ SILC_CONFIG_CALLBACK(fetch_serverinfo) /* Check the private key file permissions. */ if ((stat(file_tmp, &st)) != -1) { - if ((st.st_mode & 0777) != 0600) { + if (((st.st_mode & 0777) != 0600) && + ((st.st_mode & 0777) != 0640)) { SILC_SERVER_LOG_ERROR(("Wrong permissions in private key " "file \"%s\". The permissions must be " - "0600.", file_tmp)); + "0600 or 0640.", file_tmp)); return SILC_CONFIG_ESILENT; } } @@ -881,18 +868,22 @@ SILC_CONFIG_CALLBACK(fetch_client) else if (!strcmp(name, "publickey")) { if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, (void *)&config->server->repository, NULL, + SILC_SKR_USAGE_AUTH | SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } + tmp->publickeys = TRUE; } else if (!strcmp(name, "publickeydir")) { - if (!my_parse_publickeydir((char *) val, - (void *)&config->server->repository, - SILC_SKR_USAGE_KEY_AGREEMENT)) { + if (my_parse_publickeydir((char *) val, + (void *)&config->server->repository, + SILC_SKR_USAGE_AUTH | + SILC_SKR_USAGE_KEY_AGREEMENT) < 0) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } + tmp->publickeys = TRUE; } else if (!strcmp(name, "params")) { CONFIG_IS_DOUBLE(tmp->param); @@ -960,6 +951,7 @@ SILC_CONFIG_CALLBACK(fetch_admin) got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } + tmp->publickeys = TRUE; } else return SILC_CONFIG_EINTERNAL; @@ -1057,10 +1049,12 @@ SILC_CONFIG_CALLBACK(fetch_server) CONFIG_IS_DOUBLE(tmp->publickeys); if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, (void *)&config->server->repository, NULL, + SILC_SKR_USAGE_AUTH | SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } + tmp->publickeys = TRUE; } else if (!strcmp(name, "params")) { CONFIG_IS_DOUBLE(tmp->param); @@ -1134,10 +1128,12 @@ SILC_CONFIG_CALLBACK(fetch_router) CONFIG_IS_DOUBLE(tmp->publickeys); if (!my_parse_authdata(SILC_AUTH_PUBLIC_KEY, (char *) val, (void *)&config->server->repository, NULL, + SILC_SKR_USAGE_AUTH | SILC_SKR_USAGE_KEY_AGREEMENT, NULL)) { got_errno = SILC_CONFIG_EPRINTLINE; goto got_err; } + tmp->publickeys = TRUE; } else if (!strcmp(name, "params")) { CONFIG_IS_DOUBLE(tmp->param); @@ -1188,7 +1184,6 @@ SILC_CONFIG_CALLBACK(fetch_router) /* known config options tables */ static const SilcConfigTable table_general[] = { - { "module_path", SILC_CONFIG_ARG_STRE, fetch_generic, NULL }, { "prefer_passphrase_auth", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL }, { "require_reverse_lookup", SILC_CONFIG_ARG_TOGGLE, fetch_generic, NULL }, { "connections_max", SILC_CONFIG_ARG_INT, fetch_generic, NULL }, @@ -1225,7 +1220,6 @@ static const SilcConfigTable table_general[] = { static const SilcConfigTable table_cipher[] = { { "name", SILC_CONFIG_ARG_STR, fetch_cipher, NULL }, - { "module", SILC_CONFIG_ARG_STRE, fetch_cipher, NULL }, { "keylength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL }, { "blocklength", SILC_CONFIG_ARG_INT, fetch_cipher, NULL }, { 0, 0, 0, 0 } @@ -1233,7 +1227,6 @@ static const SilcConfigTable table_cipher[] = { static const SilcConfigTable table_hash[] = { { "name", SILC_CONFIG_ARG_STR, fetch_hash, NULL }, - { "module", SILC_CONFIG_ARG_STRE, fetch_hash, NULL }, { "blocklength", SILC_CONFIG_ARG_INT, fetch_hash, NULL }, { "digestlength", SILC_CONFIG_ARG_INT, fetch_hash, NULL }, { 0, 0, 0, 0 } @@ -1612,7 +1605,6 @@ void silc_server_config_destroy(SilcServerConfig config) SILC_LOG_DEBUG(("Freeing config context")); /* Destroy general config stuff */ - silc_free(config->module_path); silc_free(config->debug_string); silc_free(config->param.version_protocol); silc_free(config->param.version_software); @@ -1666,12 +1658,10 @@ void silc_server_config_destroy(SilcServerConfig config) SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigCipher, config->cipher) silc_free(di->name); - silc_free(di->module); silc_free(di); } SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHash, config->hash) silc_free(di->name); - silc_free(di->module); silc_free(di); } SILC_SERVER_CONFIG_LIST_DESTROY(SilcServerConfigHmac, config->hmac) diff --git a/apps/silcd/silc-server.spec.in b/apps/silcd/silc-server.spec.in new file mode 100644 index 00000000..060ea61e --- /dev/null +++ b/apps/silcd/silc-server.spec.in @@ -0,0 +1,51 @@ +Summary: SILC Server +Name: silc-server +Version: SILC_VERSION +Release: SILC_RELEASE +License: GPL +Group: Applications/Communications +URL: http://silcnet.org/ +Source0: silc-server-%{version}.tar.gz +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot +BuildRequires: silc-toolkit-devel +Requires: silc-toolkit >= 1.1 + +%description +SILC (Secure Internet Live Conferencing) is a protocol which provides +secure conferencing services on the Internet over insecure channel. + +%prep +%setup -q + +%build +%configure --prefix=%{_prefix} \ + --mandir=%{_mandir} \ + --infodir=%{_infodir} \ + --bindir=%{_bindir} \ + --sbindir=%{_sbindir} \ + --datadir=%{_datadir} \ + --enable-ipv6 +make -j4 + +%install +rm -rf $RPM_BUILD_ROOT +make DESTDIR=$RPM_BUILD_ROOT install +mv $RPM_BUILD_ROOT/%{_datadir}/doc/silc-server \ + $RPM_BUILD_ROOT/%{_datadir}/doc/silc-server-%version + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr (755,root,root,755) +%{_sbindir}/* +%defattr (644,root,root,755) +%{_sysconfdir}/silcd.conf +%{_sysconfdir}/silcalgs.conf +%{_mandir}/man5/* +%{_mandir}/man8/* +%doc %{_datadir}/doc + +%changelog +* Sun Nov 18 2007 - Pekka Riikonen +- Initial version diff --git a/apps/silcd/silcd.c b/apps/silcd/silcd.c index 14e3657f..d367328c 100644 --- a/apps/silcd/silcd.c +++ b/apps/silcd/silcd.c @@ -245,9 +245,7 @@ SILC_TASK_CALLBACK(got_hup) SILC_TASK_CALLBACK(stop_server) { - /* Stop scheduler, the program will stop eventually after noticing - that the scheduler is down. */ - silc_schedule_stop(silcd->schedule); + silc_server_stop(silcd); } /* Dump server statistics into a file into /tmp directory */ @@ -747,15 +745,14 @@ int main(int argc, char **argv) silc_file_writefile(pidfile, buf, strlen(buf)); } - silc_server_drop_privs(silcd); } + silc_server_drop_privs(silcd); /* Run the server. When this returns the server has been stopped and we will exit. */ silc_server_run(silcd); - /* Stop the server and free it. */ - silc_server_stop(silcd); + /* Free server */ silc_server_config_destroy(silcd->config); silc_server_free(silcd); diff --git a/config.guess b/config.guess deleted file mode 100755 index 951383e3..00000000 --- a/config.guess +++ /dev/null @@ -1,1516 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, -# Inc. - -timestamp='2007-05-17' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:SunOS:5.*:* | ix86xen:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - *:Interix*:[3456]*) - case ${UNAME_MACHINE} in - x86) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - EM64T | authenticamd) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; - esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit ;; - xtensa:Linux:*:*) - echo xtensa-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^LIBC/{ - s: ::g - p - }'`" - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} - exit ;; - SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} - exit ;; - SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/configure.ad b/configure.ad index c85bab2a..08bc3915 100644 --- a/configure.ad +++ b/configure.ad @@ -134,6 +134,75 @@ __SILC_PACKAGE_VERSION="#define __SILC_TOOLKIT_VERSION SILC_VERSION($maj,$min,$b #endif SILC_DIST_TOOLKIT +## +## Required dependencies +## + +compile_libs=true +LIBSUBDIR=lib +LDFLAGS="-L\$(silc_top_srcdir)/lib $LDFLAGS" + +# SILC Runtime Toolkit checking +AC_ARG_WITH(srt-includes, + [ --with-srt-includes=DIR SILC Runtime Toolkit includes [search in DIR]], + [ac_srt_includes="$withval"], [ac_srt_includes="no"]) +AC_ARG_WITH(srt-libs, + [ --with-srt-libs=DIR SILC Runtime Toolkit libraries [search in DIR]], + [ac_srt_libs="$withval"], [ac_srt_libs="no"]) + +if test -n "$with_srt_includes" || test -n "$with_srt_libs"; then + # Manually provided libs + if test "$ac_srt_includes" != "no"; then + SILC_LIB_INCLUDES="-I$ac_srt_includes" + fi + if test "$ac_srt_libs" != "no"; then + LDFLAGS="-L$ac_srt_libs $LDFLAGS" + fi + + # Check libs to link against + f=`$EGREP __SILC_HAVE_PTHREAD $ac_srt_includes/silc.h` + if test -n "$f"; then + LIBS="$LIBS -lpthread" + has_threads=true + fi +else + # pkg-config check + PKG_CHECK_MODULES(SRT, [srt >= 1.2]) + LIBS="$SRT_LIBS $LIBS" + CFLAGS="$CFLAGS $SRT_CFLAGS" +fi + +# SILC Crypto Toolkit checking +AC_ARG_WITH(sct-includes, + [ --with-sct-includes=DIR SILC Crypto Toolkit includes [search in DIR]], + [ac_sct_includes="$withval"], [ac_sct_includes="no"]) +AC_ARG_WITH(sct-libs, + [ --with-sct-libs=DIR SILC Crypto Toolkit libraries [search in DIR]], + [ac_sct_libs="$withval"], [ac_sct_libs="no"]) + +if test -n "$with_sct_includes" || test -n "$with_sct_libs"; then + # Manually provided libs + if test "$ac_sct_includes" != "no"; then + SILC_LIB_INCLUDES="-I$ac_sct_includes" + fi + if test "$ac_sct_libs" != "no"; then + LDFLAGS="-L$ac_sct_libs $LDFLAGS" + fi + + # Check libs to link against + f=`$EGREP __SILC_HAVE_PTHREAD $ac_sct_includes/silc.h` + if test -n "$f"; then + LIBS="$LIBS -lpthread" + has_threads=true + fi +else + # pkg-config check + PKG_CHECK_MODULES(SCT, [sct >= 1.2]) + LIBS="$SCT_LIBS $LIBS" + CFLAGS="$CFLAGS $SCT_CFLAGS" +fi + + ## ## Detect CPU ## @@ -461,70 +530,6 @@ AM_CONDITIONAL(SILC_NO_ASM, test x$want_asm = xfalse) ## With/without checkings ## -compile_libs=true -LIBSUBDIR=lib -LDFLAGS="-L\$(silc_top_srcdir)/lib $LDFLAGS" - -# SILC Runtime Toolkit checking -AC_ARG_WITH(srt-includes, - [ --with-srt-includes=DIR SILC Runtime Toolkit includes [search in DIR]], - [ac_srt_includes="$withval"], [ac_srt_includes="no"]) -AC_ARG_WITH(srt-libs, - [ --with-srt-libs=DIR SILC Runtime Toolkit libraries [search in DIR]], - [ac_srt_libs="$withval"], [ac_srt_libs="no"]) - -if test -n "$with_srt_includes" || test -n "$with_srt_libs"; then - # Manually provided libs - if test "$ac_srt_includes" != "no"; then - SILC_LIB_INCLUDES="-I$ac_srt_includes" - fi - if test "$ac_srt_libs" != "no"; then - LDFLAGS="-L$ac_srt_libs $LDFLAGS" - fi - - # Check libs to link against - f=`$EGREP __SILC_HAVE_PTHREAD $ac_srt_includes/silc.h` - if test -n "$f"; then - LIBS="$LIBS -lpthread" - has_threads=true - fi -else - # pkg-config check - PKG_CHECK_MODULES(SRT, [srt >= 1.2]) - LIBS="$SRT_LIBS $LIBS" - CFLAGS="$CFLAGS $SRT_CFLAGS" -fi - -# SILC Crypto Toolkit checking -AC_ARG_WITH(sct-includes, - [ --with-sct-includes=DIR SILC Crypto Toolkit includes [search in DIR]], - [ac_sct_includes="$withval"], [ac_sct_includes="no"]) -AC_ARG_WITH(sct-libs, - [ --with-sct-libs=DIR SILC Crypto Toolkit libraries [search in DIR]], - [ac_sct_libs="$withval"], [ac_sct_libs="no"]) - -if test -n "$with_sct_includes" || test -n "$with_sct_libs"; then - # Manually provided libs - if test "$ac_sct_includes" != "no"; then - SILC_LIB_INCLUDES="-I$ac_sct_includes" - fi - if test "$ac_sct_libs" != "no"; then - LDFLAGS="-L$ac_sct_libs $LDFLAGS" - fi - - # Check libs to link against - f=`$EGREP __SILC_HAVE_PTHREAD $ac_sct_includes/silc.h` - if test -n "$f"; then - LIBS="$LIBS -lpthread" - has_threads=true - fi -else - # pkg-config check - PKG_CHECK_MODULES(SCT, [sct >= 1.2]) - LIBS="$SCT_LIBS $LIBS" - CFLAGS="$CFLAGS $SCT_CFLAGS" -fi - #ifndef SILC_DIST_TOOLKIT # SILC Protocol Toolkit checking AC_ARG_WITH(silc-includes, @@ -599,9 +604,6 @@ SILC_LIB_INCLUDES="$SILC_LIB_INCLUDES -I$SILC_TOP_SRCDIR/lib/silcclient" #ifdef SILC_DIST_SERVERLIB SILC_LIB_INCLUDES="$SILC_LIB_INCLUDES -I$SILC_TOP_SRCDIR/lib/silcserver" #endif SILC_DIST_SERVERLIB -#ifdef SILC_DIST_HTTP -SILC_LIB_INCLUDES="$SILC_LIB_INCLUDES -I$SILC_TOP_SRCDIR/lib/silchttp" -#endif SILC_DIST_HTTP #ifdef SILC_DIST_VCARD SILC_LIB_INCLUDES="$SILC_LIB_INCLUDES -I$SILC_TOP_SRCDIR/lib/silcvcard" #endif SILC_DIST_VCARD @@ -859,15 +861,6 @@ lib/silcserver/tests/Makefile ) #endif SILC_DIST_SERVERLIB -#ifdef SILC_DIST_HTTP -AC_CONFIG_FILES( -lib/silchttp/Makefile -#ifdef SILC_DIST_INPLACE -lib/silchttp/tests/Makefile -#endif SILC_DIST_INPLACE -) -#endif SILC_DIST_HTTP - #ifdef SILC_DIST_VCARD AC_CONFIG_FILES( lib/silcvcard/Makefile diff --git a/distdir/post-dist b/distdir/post-dist index c026866e..8323ec7e 100644 --- a/distdir/post-dist +++ b/distdir/post-dist @@ -6,9 +6,9 @@ package=$3 distdir=$4 if test -f $distdir.tar.gz; then - md5sum $distdir.tar.gz > $distdir.tar.gz.md5 + sha512sum $distdir.tar.gz > $distdir.tar.gz.sum fi if test -f $distdir.tar.bz2; then - md5sum $distdir.tar.bz2 > $distdir.tar.bz2.md5 + sha512sum $distdir.tar.bz2 > $distdir.tar.bz2.sum fi diff --git a/distdir/pre-dist-client b/distdir/pre-dist-client index bf3ffb3d..bb08d2ac 100644 --- a/distdir/pre-dist-client +++ b/distdir/pre-dist-client @@ -7,7 +7,7 @@ distdir=$4 release=$5 if test -z $release; then - release="0.fc7" + release="0.fc8" fi sed -e "s/SILC_VERSION/$dist_version/" -e "s/SILC_RELEASE/$release/" \ diff --git a/distdir/pre-dist-server b/distdir/pre-dist-server new file mode 100644 index 00000000..575160db --- /dev/null +++ b/distdir/pre-dist-server @@ -0,0 +1,19 @@ +#!/bin/sh + +distribution=$1 +dist_version=$2 +package=$3 +distdir=$4 +release=$5 + +if test -z $release; then + release="0.fc8" +fi + +sed -e "s/SILC_VERSION/$dist_version/" -e "s/SILC_RELEASE/$release/" \ + apps/silcd/silc-server.spec.in > apps/silcd/silc-server.spec + +cd doc +make dist-hook +cd .. + diff --git a/distdir/pre-dist-toolkit b/distdir/pre-dist-toolkit index 12d05fd4..0cecb64a 100644 --- a/distdir/pre-dist-toolkit +++ b/distdir/pre-dist-toolkit @@ -7,7 +7,7 @@ distdir=$4 release=$5 if test -z $release; then - release="0.fc7" + release="0.fc8" fi sed -e "s/SILC_VERSION/$dist_version/" -e "s/SILC_RELEASE/$release/" \ diff --git a/distdir/server b/distdir/server index 4734b305..a35f7587 100644 --- a/distdir/server +++ b/distdir/server @@ -4,10 +4,9 @@ bug-report silc-devel@lists.silcnet.org inherit common define SILC_DIST_SERVER -#define SILC_DIST_SERVERLIB -define SILC_DIST_HTTP undef SILC_DIST_SFTP undef SILC_DIST_VCARD +pre-dist-hook distdir/pre-dist-server post-process-dist-hook distdir/post-process-dist post-dist-hook distdir/post-dist diff --git a/distdir/toolkit b/distdir/toolkit index ddbb2732..cb054865 100644 --- a/distdir/toolkit +++ b/distdir/toolkit @@ -15,7 +15,6 @@ license-header distdir/GPL-header distdir/TOOLKIT-header # Distdefs define SILC_DIST_TOOLKIT define SILC_DIST_CLIENTLIB -define SILC_DIST_HTTP # Includes include README.CVS diff --git a/doc/example_silcd.conf.in b/doc/example_silcd.conf.in index e337dc0a..32bb7be4 100644 --- a/doc/example_silcd.conf.in +++ b/doc/example_silcd.conf.in @@ -32,11 +32,6 @@ Include "@ETCDIR@/silcalgs.conf"; # for different connections. # General { - # This is the default path where to search modules. If omitted - # built-in modules will be used. Built-in modules will also be - # used if a module file cannot be located. - module_path = "@MODULESDIR@"; - # If both passphrase and public key authentication is set for a # connection the public key authentication is the preferred one # to use. Set this to `true' to prefer passphrase authentication @@ -79,6 +74,17 @@ General { # with ConnectionParams. keepalive_secs = 300; + # Dynamic router connections. If this is set for normal SILC server + # the connection to primary router is not created untill it is actually + # needed. Giving for example /WHOIS foobar@silcnet.org would then + # create connection to the primary router to resolve user foobar. + # On the other hand giving /WHOIS foobar would try to search the + # user foobar locally, without creating the connection. Note that + # giving /JOIN foobar will also created the connection as current + # SILC Server version supports only global channels (all JOINs require + # connection to router, if one is configured). + #dynamic_server = true; + # Default reconnection parameters defines how the server reconnect # to the remote if the connection was lost. The reconnection phase # use so called exponential backoff algorithm; The reconnect @@ -184,10 +190,12 @@ ServerInfo { # # Primary listener. Specify the IP address and the port to bind - # the server. + # the server. The public_ip can be used to specify the public IP + # if the server is behind NAT. # Primary { ip = "10.2.1.6"; + # public_ip = "11.1.1.1"; port = 706; }; diff --git a/doc/examples/silcd.prv b/doc/examples/silcd.prv index 71cadd08..63dceea9 100644 Binary files a/doc/examples/silcd.prv and b/doc/examples/silcd.prv differ diff --git a/doc/examples/silcd.pub b/doc/examples/silcd.pub index 057cf1e0..96dd2a64 100644 --- a/doc/examples/silcd.pub +++ b/doc/examples/silcd.pub @@ -1,7 +1,9 @@ -----BEGIN SILC PUBLIC KEY----- -AAAA5wADcnNhAFBVTj1wcmlpa29uZSwgSE49c2lsYy5yYWtldHRpLm5ldCwgUk49UGVra2E -gUmlpa29uZW4sIEU9cHJpaWtvbmVAc2lsYy5yYWtldHRpLm5ldAAAAAQAAAB/AAAAgCVP8Q -JzCCCC3DUhJlTNABfFqvBIe+BheiAtpHc5D5+2dHqzoAQy99gTFlRGfnnqLvcz1YzYPjVEn -+mbVEL6jddJZ2C1YwqzCGa5lG6dr4Un5QSU/uSgFoMY8wRjmfB1Cp/7/CgEFb20JeD/cS6s -Tl86ElyTwi+NIwPMFePjlBkx +AAABawADcnNhAFpVTj1wcmlpa29uZSwgSE49bG9jYWxob3N0LmxvY2FsZG9tYWluLCBSTj1 +QZWtrYSBSaWlrb25lbiwgRT1wcmlpa29uZUBsb2NhbGhvc3QubG9jYWxkb21haW4AAAAC// +0AAAEAUAkEHrwD2RtMuyT/dtG/kyjz9lGS9zCPruDk8J4XhRpWTv6qL7PGM6Dd2m/+6REVf +5zweY9JKzs3XU+lS1RL0WkCtNVmA1nUPrmKfztvhjQkVLj5zlZGAFmIAq5aLQqwJIf8xquy +qgcJ0eF2cahnCONb+d2IImik2hMfffQkcGL2kMr7UQ+kJBM/mAeoIDQr/78b+vgWPBdTLsI +7vhjLPyHXIBDYGawU8/oN4HYm2sSn+nqpmWtD41Z7GtuwQGivUGhAuAWeasG4RX1zQaNwTg +a4Hm+do3sUuSczPawPcyA/2npp8SO2eTsLUPsWChI8kv6StBdLd/YUaig8EZN6YQ== -----END SILC PUBLIC KEY----- diff --git a/doc/silcalgs.conf b/doc/silcalgs.conf index 928e1316..b083bb8c 100644 --- a/doc/silcalgs.conf +++ b/doc/silcalgs.conf @@ -13,57 +13,56 @@ # # Configured ciphers # -# The "name" is unique name to the cipher. The "module" option can be either -# absolute or relative to the "module_path", and it defines where the cipher -# module is found. If omitted the built-in cipher is used. The "keylength" -# defines the length of the key (bytes), and the "blocklength" defines the -# block size of the cipher (bytes). +# The "name" is unique name to the cipher. The "keylength" defines the +# length of the key (bytes), and the "blocklength" defines the block size +# of the cipher (bytes). # +cipher { + name = "aes-256-ctr"; + keylength = 32; + blocklength = 16; +}; cipher { name = "aes-256-cbc"; - module = "aes.sim.so"; keylength = 32; blocklength = 16; }; +cipher { + name = "aes-192-ctr"; + keylength = 24; + blocklength = 16; +}; cipher { name = "aes-192-cbc"; - module = "aes.sim.so"; keylength = 24; blocklength = 16; }; +cipher { + name = "aes-128-ctr"; + keylength = 16; + blocklength = 16; +}; cipher { name = "aes-128-cbc"; - module = "aes.sim.so"; keylength = 16; blocklength = 16; }; cipher { name = "twofish-256-cbc"; - module = "twofish.sim.so"; keylength = 32; blocklength = 16; }; cipher { name = "twofish-192-cbc"; - module = "twofish.sim.so"; keylength = 24; blocklength = 16; }; cipher { name = "twofish-128-cbc"; - module = "twofish.sim.so"; keylength = 16; blocklength = 16; }; -# "none" cipher should not be used -#cipher { -# name = "none"; -# module = "none.sim.so"; -# keylength = 0; -# blocklength = 0; -#}; - # # Configured hash functions # @@ -116,6 +115,6 @@ hmac { # # Configured PKCS # -PKCS { - name = "rsa"; +PKCS { + name = "rsa"; }; diff --git a/doc/silcd.conf.yo b/doc/silcd.conf.yo index a78ed964..34a38cd5 100644 --- a/doc/silcd.conf.yo +++ b/doc/silcd.conf.yo @@ -21,15 +21,20 @@ nsect(SECTION: General) em(General) section contains global settings for the silcd. -bf(module_path) -quote(Defines where SIM modules are located. If definition is omitted, -built-in modules will be used. Also, if a module can not be located, a built-in -module will be used in its place. The argument is a path to the directory the -modules are in, for example bf("/usr/local/silc/modules").) +bf(dynamic_server) +quote(Dynamic router connections. If this is set for normal SILC server +the connection to primary router is not created untill it is actually +needed. Giving for example em(/WHOIS foobar@silcnet.org) would then +create connection to the primary router to resolve user foobar. +On the other hand giving em(/WHOIS foobar) would try to search the +user foobar locally, without creating the connection. Note that +giving em(/JOIN foobar) will also created the connection as current +SILC Server version supports only global channels (all JOINs require +connection to router, if one is configured).) bf(prefer_passphrase_auth) -quote(If both public key and passphrase authentication are set for a -connection, public key authentication is by default preferred. Setting this +quote(If both public key and passphrase authentication are set for a +connection, public key authentication is by default preferred. Setting this value to em(true) causes silcd to prefer passphrase authentication in these cases.) @@ -44,7 +49,7 @@ connections are refused.) bf(connections_max_per_host) quote(Maximum number of incoming connections from any single host. This -setting can be overridden on a connection-specific basis with +setting can be overridden on a connection-specific basis with em(ConnectionParams).) bf(version_protocol) @@ -71,13 +76,13 @@ bf(key_exchange_rekey) quote(Defines the interval, in seconds, how often the session key will be regenerated. This setting only applies to the connection initiator, as rekey is always performed by the initiating party. Setting has effect only when -the server acts as an initiator, and can be overridden with +the server acts as an initiator, and can be overridden with em(ConnectionParams).) bf(key_exchange_pfs) quote(Boolean value to determine, whether key-exchange is performed with Perfect Forward Secrecy (PFS) or without. If set to em(true), the rekey -process will be somewhat slower, but more secure since the key is +process will be somewhat slower, but more secure since the key is entirely regenerated. Can be overridden with em(ConnectionParams).) bf(key_exchange_timeout) @@ -121,11 +126,11 @@ bf(qos_bytes_limit) quote(Limits incoming SILC data to the specified number of bytes per second.) bf(qos_limit_sec) -quote(This value defines the timeout, in seconds, for the delay of received +quote(This value defines the timeout, in seconds, for the delay of received data in case it was left in a QoS queue.) bf(qos_limit_usec) -quote(This value defines the timeout, in microseconds, for the delay of +quote(This value defines the timeout, in microseconds, for the delay of received data for received data in case it was left in a QoS queue.) nsect(SECTION: ServerInfo) @@ -222,7 +227,7 @@ nsubsect(SUBSECTION: Errors) nsubsect(SUBSECTION: Fatals) Each of these subsections has the same attributes, em(File) and em(Size). Different levels of problems are logged to their respective channels -(em(Info), em(Warnings), em(Errors), em(Fatals)), depending on their need +(em(Info), em(Warnings), em(Errors), em(Fatals)), depending on their need of attention. bf(File) @@ -236,19 +241,19 @@ size within given limit.) nsect(SECTION: ConnectionParams) This section defines connection parameters. Each connection may have its own -set of em(ConnectionParams) but having one is in no way mandatory. If no -separate parameters have been assigned, the defaults and the ones from +set of em(ConnectionParams) but having one is in no way mandatory. If no +separate parameters have been assigned, the defaults and the ones from em(General) section will be used. A silcd configuration may have any number of em(ConnectionParams) sections. bf(name) -quote(This is a unique name that separates bf(this) particular -em(ConnectionParams) section from all the others. It is also the name with -which settings are referred to a given set of parameters. This field is +quote(This is a unique name that separates bf(this) particular +em(ConnectionParams) section from all the others. It is also the name with +which settings are referred to a given set of parameters. This field is mandatory.) bf(connections_max) -quote(Limits how many concurrent connections are allowed. Any further +quote(Limits how many concurrent connections are allowed. Any further connections are simply refused. Note that this setting can not override the figure given in em(General) section.) @@ -293,7 +298,7 @@ quote(Exactly the same as in em(General) section.) bf(anonymous) quote(This boolean setting has meaning only to client connections. If set to -em(true), client connections using this em(ConnectionParams) block will have +em(true), client connections using this em(ConnectionParams) block will have their username and host scrambled. The client will also have an anonymous mode set to it.) @@ -322,7 +327,7 @@ must supply a connection password. bf(Host) quote(An address or wildcarded set of addresses, either in numeric IP-address -fashion or as hostnames. For example em("10.1.*") or +fashion or as hostnames. For example em("10.1.*") or em("*.mydomain.domain.org").) bf(Passphrase) @@ -410,7 +415,7 @@ nsect(SECTION: Admin) This section defines configured administration connections. bf(Host) -quote(Either FQDN or a strict IP-address to the origin of connection. +quote(Either FQDN or a strict IP-address to the origin of connection. This field is optional.) bf(User) @@ -427,7 +432,7 @@ quote(Path to administrator's public key file. If both em(Passphrase) and em(PublicKey) are defined, either one can be used.) nsect(SECTION: Deny) -This section defines denied incoming connections. They apply equally to both +This section defines denied incoming connections. They apply equally to both client and server connections, so make sure you know what you add here. Each em(Deny) section covers one instance of denied connection(s). There may be any number of em(Deny) sections. diff --git a/lib/Makefile.ad b/lib/Makefile.ad index df5d76eb..9312320c 100644 --- a/lib/Makefile.ad +++ b/lib/Makefile.ad @@ -22,9 +22,6 @@ SILCLIB_DIRS = \ silccore \ silcapputil \ silcske \ -#ifdef SILC_DIST_HTTP - silchttp \ -#endif SILC_DIST_HTTP #ifdef SILC_DIST_SFTP silcsftp \ #endif SILC_DIST_SFTP diff --git a/lib/silcapputil/silcidcache.c b/lib/silcapputil/silcidcache.c index d189e932..f549b770 100644 --- a/lib/silcapputil/silcidcache.c +++ b/lib/silcapputil/silcidcache.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2000 - 2007 Pekka Riikonen + Copyright (C) 2000 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -142,9 +142,8 @@ silc_idcache_add(SilcIDCache cache, char *name, void *id, void *context) if (id) { /* See if this entry is added already to cache */ if (silc_idcache_find_by_id_one(cache, id, NULL)) { - SILC_LOG_ERROR(("Attempted to add same ID twice to ID Cache, id %s", + SILC_LOG_DEBUG(("Attempted to add same ID twice to ID Cache, id %s", silc_id_render(id, cache->id_type))); - SILC_ASSERT(FALSE); goto err; } } diff --git a/lib/silcclient/client.c b/lib/silcclient/client.c index fa139d2e..449fc375 100644 --- a/lib/silcclient/client.c +++ b/lib/silcclient/client.c @@ -54,7 +54,7 @@ static void silc_client_connection_finished(SilcFSMThread fsm, SilcClient client = silc_fsm_get_state_context(fsm); /* Signal client that we have finished */ - silc_atomic_sub_int16(&client->internal->conns, 1); + silc_atomic_sub_int32(&client->internal->conns, 1); client->internal->connection_closed = TRUE; SILC_FSM_EVENT_SIGNAL(&client->internal->wait_event); @@ -536,7 +536,7 @@ SILC_FSM_STATE(silc_client_st_run) /* A connection finished */ SILC_LOG_DEBUG(("Event: connection closed")); client->internal->connection_closed = FALSE; - if (silc_atomic_get_int16(&client->internal->conns) == 0 && + if (silc_atomic_get_int32(&client->internal->conns) == 0 && client->internal->stop) SILC_FSM_EVENT_SIGNAL(&client->internal->wait_event); return SILC_FSM_CONTINUE; @@ -545,7 +545,7 @@ SILC_FSM_STATE(silc_client_st_run) if (client->internal->stop) { /* Stop client libarry. If we have running connections, wait until they finish first. */ - if (silc_atomic_get_int16(&client->internal->conns) == 0) { + if (silc_atomic_get_int32(&client->internal->conns) == 0) { SILC_LOG_DEBUG(("Event: stop")); silc_fsm_next(fsm, silc_client_st_stop); } @@ -681,7 +681,7 @@ silc_client_add_connection(SilcClient client, silc_fsm_start(thread, silc_client_connection_st_start); SILC_LOG_DEBUG(("New connection %p", conn)); - silc_atomic_add_int16(&client->internal->conns, 1); + silc_atomic_add_int32(&client->internal->conns, 1); return conn; } @@ -945,7 +945,7 @@ SilcClient silc_client_alloc(SilcClientOperations *ops, nickname_format[sizeof(new_client->internal-> params->nickname_format) - 1] = 0; - silc_atomic_init16(&new_client->internal->conns, 0); + silc_atomic_init32(&new_client->internal->conns, 0); return new_client; } @@ -954,7 +954,8 @@ SilcClient silc_client_alloc(SilcClientOperations *ops, void silc_client_free(SilcClient client) { - silc_schedule_uninit(client->schedule); + if (client->schedule) + silc_schedule_uninit(client->schedule); if (client->rng) silc_rng_free(client->rng); @@ -962,10 +963,13 @@ void silc_client_free(SilcClient client) if (!client->internal->params->dont_register_crypto_library) silc_crypto_uninit(); - silc_packet_engine_stop(client->internal->packet_engine); - silc_dlist_uninit(client->internal->ftp_sessions); - silc_atomic_uninit16(&client->internal->conns); - silc_mutex_free(client->internal->lock); + if (client->internal->packet_engine) + silc_packet_engine_stop(client->internal->packet_engine); + if (client->internal->ftp_sessions) + silc_dlist_uninit(client->internal->ftp_sessions); + if (client->internal->lock) + silc_mutex_free(client->internal->lock); + silc_atomic_uninit32(&client->internal->conns); silc_free(client->username); silc_free(client->hostname); silc_free(client->realname); diff --git a/lib/silcclient/client.h b/lib/silcclient/client.h index e008e44f..d66808dc 100644 --- a/lib/silcclient/client.h +++ b/lib/silcclient/client.h @@ -53,14 +53,17 @@ typedef struct SilcClientEntryInternalStruct { SilcUInt32 key_len; /* Key data length */ SilcClientKeyAgreement ke; /* Current key agreement context or NULL */ + SilcAtomic32 refcnt; /* Reference counter */ + SilcAtomic32 deleted; /* Flag indicating whether the client object is + already scheduled for deletion */ + SilcUInt16 resolve_cmd_ident; /* Command identifier when resolving */ + /* Flags */ unsigned int valid : 1; /* FALSE if this entry is not valid. Entry without nickname is not valid. */ unsigned int generated : 1; /* TRUE if library generated `key' */ unsigned int prv_resp : 1; /* TRUE if we are responder when using private message keys. */ - SilcUInt16 resolve_cmd_ident; /* Command identifier when resolving */ - SilcAtomic16 refcnt; /* Reference counter */ } SilcClientEntryInternal; /* Internal channel entry context */ @@ -81,20 +84,23 @@ typedef struct SilcChannelEntryInternalStruct { SilcHmac hmac; /* Current HMAC */ unsigned char iv[SILC_CIPHER_MAX_IV_SIZE]; /* Current IV */ + SilcAtomic32 refcnt; /* Reference counter */ + SilcAtomic32 deleted; /* Flag indicating whether the + channel object is already + scheduled for deletion */ SilcUInt16 resolve_cmd_ident; /* Channel information resolving identifier. This is used when resolving users, and other stuff that relates to the channel. Not used for the channel resolving itself. */ - SilcAtomic16 refcnt; /* Reference counter */ } SilcChannelEntryInternal; /* Internal server entry context */ typedef struct SilcServerEntryInternalStruct { SilcRwLock lock; /* Read/write lock */ SilcUInt16 resolve_cmd_ident; /* Resolving identifier */ - SilcAtomic8 refcnt; /* Reference counter */ + SilcAtomic32 refcnt; /* Reference counter */ } SilcServerEntryInternal; #endif /* CLIENT_H */ diff --git a/lib/silcclient/client_channel.c b/lib/silcclient/client_channel.c index 2075d807..7dd4f0a6 100644 --- a/lib/silcclient/client_channel.c +++ b/lib/silcclient/client_channel.c @@ -650,8 +650,14 @@ SilcBool silc_client_del_channel_private_keys(SilcClient client, } channel->internal.curr_key = NULL; - channel->cipher = silc_cipher_get_name(channel->internal.send_key); - channel->hmac = silc_hmac_get_name(channel->internal.hmac); + if (channel->internal.send_key) + channel->cipher = silc_cipher_get_name(channel->internal.send_key); + else + channel->cipher = NULL; + if (channel->internal.hmac) + channel->hmac = silc_hmac_get_name(channel->internal.hmac); + else + channel->hmac = NULL; silc_dlist_uninit(channel->internal.private_keys); channel->internal.private_keys = NULL; diff --git a/lib/silcclient/client_entry.c b/lib/silcclient/client_entry.c index 32f272ec..017f8f8a 100644 --- a/lib/silcclient/client_entry.c +++ b/lib/silcclient/client_entry.c @@ -785,7 +785,8 @@ SilcClientEntry silc_client_add_client(SilcClient client, return NULL; silc_rwlock_alloc(&client_entry->internal.lock); - silc_atomic_init16(&client_entry->internal.refcnt, 0); + silc_atomic_init32(&client_entry->internal.refcnt, 0); + silc_atomic_init32(&client_entry->internal.deleted, 1); client_entry->id = *id; client_entry->mode = mode; client_entry->realname = userinfo ? strdup(userinfo) : NULL; @@ -989,7 +990,8 @@ void silc_client_del_client_entry(SilcClient client, silc_client_ftp_session_free_client(client, client_entry); if (client_entry->internal.ke) silc_client_abort_key_agreement(client, conn, client_entry); - silc_atomic_uninit16(&client_entry->internal.refcnt); + silc_atomic_uninit32(&client_entry->internal.deleted); + silc_atomic_uninit32(&client_entry->internal.refcnt); silc_rwlock_free(client_entry->internal.lock); silc_free(client_entry); } @@ -999,30 +1001,18 @@ void silc_client_del_client_entry(SilcClient client, SilcBool silc_client_del_client(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry) { - SilcBool ret; - if (!client_entry) return FALSE; - if (silc_atomic_sub_int16(&client_entry->internal.refcnt, 1) > 0) - return FALSE; - - SILC_LOG_DEBUG(("Deleting client %p", client_entry)); - - silc_mutex_lock(conn->internal->lock); - ret = silc_idcache_del_by_context(conn->internal->client_cache, - client_entry, NULL); - silc_mutex_unlock(conn->internal->lock); + SILC_LOG_DEBUG(("Marking client entry %p deleted")); - if (ret) { - /* Remove from channels */ - silc_client_remove_from_channels(client, conn, client_entry); - - /* Free the client entry data */ - silc_client_del_client_entry(client, conn, client_entry); + if (silc_atomic_sub_int32(&client_entry->internal.deleted, 1) != 0) { + SILC_LOG_DEBUG(("Client entry %p already marked deleted")); + return FALSE; } - return ret; + silc_client_unref_client(client, conn, client_entry); + return TRUE; } /* Internal routine used to find client by ID and if not found this creates @@ -1066,10 +1056,10 @@ SilcClientEntry silc_client_ref_client(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry) { - silc_atomic_add_int16(&client_entry->internal.refcnt, 1); + silc_atomic_add_int32(&client_entry->internal.refcnt, 1); SILC_LOG_DEBUG(("Client %p refcnt %d->%d", client_entry, - silc_atomic_get_int16(&client_entry->internal.refcnt) - 1, - silc_atomic_get_int16(&client_entry->internal.refcnt))); + silc_atomic_get_int32(&client_entry->internal.refcnt) - 1, + silc_atomic_get_int32(&client_entry->internal.refcnt))); return client_entry; } @@ -1078,11 +1068,32 @@ SilcClientEntry silc_client_ref_client(SilcClient client, void silc_client_unref_client(SilcClient client, SilcClientConnection conn, SilcClientEntry client_entry) { - if (client_entry) { - SILC_LOG_DEBUG(("Client %p refcnt %d->%d", client_entry, - silc_atomic_get_int16(&client_entry->internal.refcnt), - silc_atomic_get_int16(&client_entry->internal.refcnt) - 1)); - silc_client_del_client(client, conn, client_entry); + SilcBool ret; + + if (!client_entry) + return; + + SILC_LOG_DEBUG(("Client %p refcnt %d->%d", client_entry, + silc_atomic_get_int32(&client_entry->internal.refcnt), + silc_atomic_get_int32(&client_entry->internal.refcnt) - 1)); + + if (silc_atomic_sub_int32(&client_entry->internal.refcnt, 1) > 0) + return; + + SILC_LOG_DEBUG(("Deleting client %p (%d)", client_entry, + silc_atomic_get_int32(&client_entry->internal.deleted))); + + silc_mutex_lock(conn->internal->lock); + ret = silc_idcache_del_by_context(conn->internal->client_cache, + client_entry, NULL); + silc_mutex_unlock(conn->internal->lock); + + if (ret) { + /* Remove from channels */ + silc_client_remove_from_channels(client, conn, client_entry); + + /* Free the client entry data */ + silc_client_del_client_entry(client, conn, client_entry); } } @@ -1275,6 +1286,7 @@ SilcClientEntry silc_client_nickname_format(SilcClient client, } newnick[off] = 0; + memset(client_entry->nickname, 0, sizeof(client_entry->nickname)); memcpy(client_entry->nickname, newnick, strlen(newnick)); silc_client_list_free(client, conn, clients); @@ -1619,7 +1631,8 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, return NULL; silc_rwlock_alloc(&channel->internal.lock); - silc_atomic_init16(&channel->internal.refcnt, 0); + silc_atomic_init32(&channel->internal.refcnt, 0); + silc_atomic_init32(&channel->internal.deleted, 1); channel->id = *channel_id; channel->mode = mode; @@ -1632,7 +1645,7 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, if (!channel->channel_name) { silc_rwlock_free(channel->internal.lock); - silc_atomic_uninit16(&channel->internal.refcnt); + silc_atomic_uninit32(&channel->internal.refcnt); silc_free(channel); return NULL; } @@ -1641,7 +1654,7 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, NULL, NULL, NULL, TRUE); if (!channel->user_list) { silc_rwlock_free(channel->internal.lock); - silc_atomic_uninit16(&channel->internal.refcnt); + silc_atomic_uninit32(&channel->internal.refcnt); silc_free(channel->channel_name); silc_free(channel); return NULL; @@ -1652,7 +1665,7 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, SILC_STRING_UTF8, 256, NULL); if (!channel_namec) { silc_rwlock_free(channel->internal.lock); - silc_atomic_uninit16(&channel->internal.refcnt); + silc_atomic_uninit32(&channel->internal.refcnt); silc_free(channel->channel_name); silc_hash_table_free(channel->user_list); silc_free(channel); @@ -1665,7 +1678,7 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, if (!silc_idcache_add(conn->internal->channel_cache, channel_namec, &channel->id, channel)) { silc_rwlock_free(channel->internal.lock); - silc_atomic_uninit16(&channel->internal.refcnt); + silc_atomic_uninit32(&channel->internal.refcnt); silc_free(channel_namec); silc_free(channel->channel_name); silc_hash_table_free(channel->user_list); @@ -1687,67 +1700,21 @@ SilcChannelEntry silc_client_add_channel(SilcClient client, SilcBool silc_client_del_channel(SilcClient client, SilcClientConnection conn, SilcChannelEntry channel) { - SilcIDCacheEntry id_cache; - SilcBool ret = TRUE; - SilcCipher key; - SilcHmac hmac; - char *namec; if (!channel) return FALSE; - if (silc_atomic_sub_int16(&channel->internal.refcnt, 1) > 0) - return FALSE; - - SILC_LOG_DEBUG(("Deleting channel %p", channel)); + SILC_LOG_DEBUG(("Marking channel entry %p deleted")); - silc_mutex_lock(conn->internal->lock); - if (silc_idcache_find_by_context(conn->internal->channel_cache, channel, - &id_cache)) { - namec = id_cache->name; - ret = silc_idcache_del_by_context(conn->internal->channel_cache, - channel, NULL); - silc_free(namec); - } - silc_mutex_unlock(conn->internal->lock); - if (!ret) + if (silc_atomic_sub_int32(&channel->internal.deleted, 1) != 0) { + SILC_LOG_DEBUG(("Channel entry %p already marked deleted")); return FALSE; - - silc_client_empty_channel(client, conn, channel); silc_client_del_channel_private_keys(client, conn, channel); - silc_hash_table_free(channel->user_list); - silc_free(channel->channel_name); - silc_free(channel->topic); - if (channel->founder_key) - silc_pkcs_public_key_free(channel->founder_key); - if (channel->internal.send_key) - silc_cipher_free(channel->internal.send_key); - if (channel->internal.receive_key) - silc_cipher_free(channel->internal.receive_key); - if (channel->internal.hmac) - silc_hmac_free(channel->internal.hmac); - if (channel->internal.old_channel_keys) { - silc_dlist_start(channel->internal.old_channel_keys); - while ((key = silc_dlist_get(channel->internal.old_channel_keys))) - silc_cipher_free(key); - silc_dlist_uninit(channel->internal.old_channel_keys); } - if (channel->internal.old_hmacs) { - silc_dlist_start(channel->internal.old_hmacs); - while ((hmac = silc_dlist_get(channel->internal.old_hmacs))) - silc_hmac_free(hmac); - silc_dlist_uninit(channel->internal.old_hmacs); - } - if (channel->channel_pubkeys) - silc_argument_list_free(channel->channel_pubkeys, - SILC_ARGUMENT_PUBLIC_KEY); - silc_atomic_uninit16(&channel->internal.refcnt); - silc_rwlock_free(channel->internal.lock); - silc_schedule_task_del_by_context(conn->client->schedule, channel); - silc_free(channel); - return ret; + silc_client_unref_channel(client, conn, channel); + return TRUE; } /* Replaces the channel ID of the `channel' to `new_id'. Returns FALSE @@ -1799,10 +1766,10 @@ SilcChannelEntry silc_client_ref_channel(SilcClient client, SilcClientConnection conn, SilcChannelEntry channel_entry) { - silc_atomic_add_int16(&channel_entry->internal.refcnt, 1); + silc_atomic_add_int32(&channel_entry->internal.refcnt, 1); SILC_LOG_DEBUG(("Channel %p refcnt %d->%d", channel_entry, - silc_atomic_get_int16(&channel_entry->internal.refcnt) - 1, - silc_atomic_get_int16(&channel_entry->internal.refcnt))); + silc_atomic_get_int32(&channel_entry->internal.refcnt) - 1, + silc_atomic_get_int32(&channel_entry->internal.refcnt))); return channel_entry; } @@ -1811,13 +1778,71 @@ SilcChannelEntry silc_client_ref_channel(SilcClient client, void silc_client_unref_channel(SilcClient client, SilcClientConnection conn, SilcChannelEntry channel_entry) { - if (channel_entry) { - SILC_LOG_DEBUG(("Channel %p refcnt %d->%d", channel_entry, - silc_atomic_get_int16(&channel_entry->internal.refcnt), - silc_atomic_get_int16(&channel_entry->internal.refcnt) - - 1)); - silc_client_del_channel(client, conn, channel_entry); + SilcIDCacheEntry id_cache; + SilcBool ret = TRUE; + SilcCipher key; + SilcHmac hmac; + char *namec; + + if (!channel_entry) + return; + + SILC_LOG_DEBUG(("Channel %p refcnt %d->%d", channel_entry, + silc_atomic_get_int32(&channel_entry->internal.refcnt), + silc_atomic_get_int32(&channel_entry->internal.refcnt) + - 1)); + + if (silc_atomic_sub_int32(&channel_entry->internal.refcnt, 1) > 0) + return; + + SILC_LOG_DEBUG(("Deleting channel %p", channel_entry)); + + silc_mutex_lock(conn->internal->lock); + if (silc_idcache_find_by_context(conn->internal->channel_cache, channel_entry, + &id_cache)) { + namec = id_cache->name; + ret = silc_idcache_del_by_context(conn->internal->channel_cache, + channel_entry, NULL); + silc_free(namec); } + silc_mutex_unlock(conn->internal->lock); + + if (!ret) + return; + + silc_client_empty_channel(client, conn, channel_entry); + silc_client_del_channel_private_keys(client, conn, channel_entry); + silc_hash_table_free(channel_entry->user_list); + silc_free(channel_entry->channel_name); + silc_free(channel_entry->topic); + if (channel_entry->founder_key) + silc_pkcs_public_key_free(channel_entry->founder_key); + if (channel_entry->internal.send_key) + silc_cipher_free(channel_entry->internal.send_key); + if (channel_entry->internal.receive_key) + silc_cipher_free(channel_entry->internal.receive_key); + if (channel_entry->internal.hmac) + silc_hmac_free(channel_entry->internal.hmac); + if (channel_entry->internal.old_channel_keys) { + silc_dlist_start(channel_entry->internal.old_channel_keys); + while ((key = silc_dlist_get(channel_entry->internal.old_channel_keys))) + silc_cipher_free(key); + silc_dlist_uninit(channel_entry->internal.old_channel_keys); + } + if (channel_entry->internal.old_hmacs) { + silc_dlist_start(channel_entry->internal.old_hmacs); + while ((hmac = silc_dlist_get(channel_entry->internal.old_hmacs))) + silc_hmac_free(hmac); + silc_dlist_uninit(channel_entry->internal.old_hmacs); + } + if (channel_entry->channel_pubkeys) + silc_argument_list_free(channel_entry->channel_pubkeys, + SILC_ARGUMENT_PUBLIC_KEY); + silc_atomic_uninit32(&channel_entry->internal.deleted); + silc_atomic_uninit32(&channel_entry->internal.refcnt); + silc_rwlock_free(channel_entry->internal.lock); + silc_schedule_task_del_by_context(conn->client->schedule, channel_entry); + silc_free(channel_entry); } /* Free channel entry list */ @@ -2052,7 +2077,7 @@ SilcServerEntry silc_client_add_server(SilcClient client, return NULL; silc_rwlock_alloc(&server_entry->internal.lock); - silc_atomic_init8(&server_entry->internal.refcnt, 0); + silc_atomic_init32(&server_entry->internal.refcnt, 0); server_entry->id = *server_id; if (server_name) server_entry->server_name = strdup(server_name); @@ -2104,7 +2129,7 @@ SilcBool silc_client_del_server(SilcClient client, SilcClientConnection conn, if (!server) return FALSE; - if (silc_atomic_sub_int8(&server->internal.refcnt, 1) > 0) + if (silc_atomic_sub_int32(&server->internal.refcnt, 1) > 0) return FALSE; SILC_LOG_DEBUG(("Deleting server %p", server)); @@ -2123,7 +2148,7 @@ SilcBool silc_client_del_server(SilcClient client, SilcClientConnection conn, silc_free(server->server_info); if (server->public_key) silc_pkcs_public_key_free(server->public_key); - silc_atomic_uninit8(&server->internal.refcnt); + silc_atomic_uninit32(&server->internal.refcnt); silc_rwlock_free(server->internal.lock); silc_free(server); @@ -2191,10 +2216,10 @@ SilcServerEntry silc_client_ref_server(SilcClient client, SilcClientConnection conn, SilcServerEntry server_entry) { - silc_atomic_add_int8(&server_entry->internal.refcnt, 1); + silc_atomic_add_int32(&server_entry->internal.refcnt, 1); SILC_LOG_DEBUG(("Server %p refcnt %d->%d", server_entry, - silc_atomic_get_int8(&server_entry->internal.refcnt) - 1, - silc_atomic_get_int8(&server_entry->internal.refcnt))); + silc_atomic_get_int32(&server_entry->internal.refcnt) - 1, + silc_atomic_get_int32(&server_entry->internal.refcnt))); return server_entry; } @@ -2205,8 +2230,8 @@ void silc_client_unref_server(SilcClient client, SilcClientConnection conn, { if (server_entry) { SILC_LOG_DEBUG(("Server %p refcnt %d->%d", server_entry, - silc_atomic_get_int8(&server_entry->internal.refcnt), - silc_atomic_get_int8(&server_entry->internal.refcnt) + silc_atomic_get_int32(&server_entry->internal.refcnt), + silc_atomic_get_int32(&server_entry->internal.refcnt) - 1)); silc_client_del_server(client, conn, server_entry); } diff --git a/lib/silcclient/client_internal.h b/lib/silcclient/client_internal.h index fd04fa3b..a2971820 100644 --- a/lib/silcclient/client_internal.h +++ b/lib/silcclient/client_internal.h @@ -108,7 +108,7 @@ struct SilcClientInternalStruct { char *silc_client_version; /* Version set by application */ SilcClientRunning running; /* Running/Stopped callback */ void *running_context; /* Context for runnign callback */ - SilcAtomic16 conns; /* Number of connections in client */ + SilcAtomic32 conns; /* Number of connections in client */ SilcUInt16 next_session_id; /* Next FTP session ID */ /* Events */ diff --git a/lib/silcclient/client_notify.c b/lib/silcclient/client_notify.c index e1c96913..2ccb574c 100644 --- a/lib/silcclient/client_notify.c +++ b/lib/silcclient/client_notify.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2007 Pekka Riikonen + Copyright (C) 1997 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -298,8 +298,14 @@ SILC_FSM_STATE(silc_client_notify_invite) /* Get the channel entry */ channel = silc_client_get_channel_by_id(client, conn, &id.u.channel_id); - if (!channel) - goto out; + if (!channel) { + /** Resolve channel */ + SILC_FSM_CALL(silc_client_get_channel_by_id_resolve( + client, conn, &id.u.channel_id, + silc_client_notify_resolved, + notify)); + /* NOT REACHED */ + } /* If channel is being resolved handle notify after resolving */ if (channel->internal.resolve_cmd_ident) { diff --git a/lib/silcclient/client_register.c b/lib/silcclient/client_register.c index 72f10c1d..efbeaa24 100644 --- a/lib/silcclient/client_register.c +++ b/lib/silcclient/client_register.c @@ -591,25 +591,26 @@ SILC_FSM_STATE(silc_client_st_resume_completed) &conn->local_entry->id); /* Call JOIN command replies for all joined channel */ - silc_idcache_get_all(conn->internal->channel_cache, &channels); - silc_list_start(channels); - while ((entry = silc_list_get(channels))) { - SilcHashTableList htl; - const char *cipher, *hmac; - - channel = entry->context; - cipher = (channel->internal.send_key ? - silc_cipher_get_name(channel->internal.send_key) : NULL); - hmac = (channel->internal.hmac ? - silc_hmac_get_name(channel->internal.hmac) : NULL); - silc_hash_table_list(channel->user_list, &htl); - silc_client_resume_command_callback(client, conn, SILC_COMMAND_JOIN, - channel->channel_name, channel, - channel->mode, &htl, channel->topic, - cipher, hmac, channel->founder_key, - channel->channel_pubkeys, - channel->user_limit); - silc_hash_table_list_reset(&htl); + if (silc_idcache_get_all(conn->internal->channel_cache, &channels)) { + silc_list_start(channels); + while ((entry = silc_list_get(channels))) { + SilcHashTableList htl; + const char *cipher, *hmac; + + channel = entry->context; + cipher = (channel->internal.send_key ? + silc_cipher_get_name(channel->internal.send_key) : NULL); + hmac = (channel->internal.hmac ? + silc_hmac_get_name(channel->internal.hmac) : NULL); + silc_hash_table_list(channel->user_list, &htl); + silc_client_resume_command_callback(client, conn, SILC_COMMAND_JOIN, + channel->channel_name, channel, + channel->mode, &htl, channel->topic, + cipher, hmac, channel->founder_key, + channel->channel_pubkeys, + channel->user_limit); + silc_hash_table_list_reset(&htl); + } } conn->internal->registering = FALSE; diff --git a/lib/silcclient/command.c b/lib/silcclient/command.c index a50ab523..b5827f22 100644 --- a/lib/silcclient/command.c +++ b/lib/silcclient/command.c @@ -411,6 +411,7 @@ SilcUInt16 silc_client_command_call(SilcClient client, SilcUInt32 argc = 0; unsigned char **argv = NULL; SilcUInt32 *argv_lens = NULL, *argv_types = NULL; + SilcUInt16 cmd_ident; SilcClientCommand command; SilcClientCommandContext cmd; char *arg; @@ -480,7 +481,7 @@ SilcUInt16 silc_client_command_call(SilcClient client, cmd->argv = argv; cmd->argv_lens = argv_lens; cmd->argv_types = argv_types; - cmd->cmd_ident = silc_client_cmd_ident(conn); + cmd_ident = cmd->cmd_ident = silc_client_cmd_ident(conn); cmd->called = TRUE; cmd->verbose = TRUE; silc_list_init(cmd->reply_callbacks, @@ -492,7 +493,7 @@ SilcUInt16 silc_client_command_call(SilcClient client, silc_client_command_destructor, NULL, FALSE); silc_fsm_start_sync(&cmd->thread, command->command); - return cmd->cmd_ident; + return cmd_ident; } /* Generic function to send any command. The arguments must be sent already diff --git a/lib/silcclient/command_reply.c b/lib/silcclient/command_reply.c index bf80d064..ede88753 100644 --- a/lib/silcclient/command_reply.c +++ b/lib/silcclient/command_reply.c @@ -118,6 +118,7 @@ static void silc_client_command_process_error(SilcClientCommandContext cmd, client_entry = silc_client_get_client_by_id(client, conn, &id.u.client_id); if (client_entry) { silc_client_remove_from_channels(client, conn, client_entry); + client_entry->internal.valid = FALSE; silc_client_del_client(client, conn, client_entry); silc_client_unref_client(client, conn, client_entry); } @@ -947,6 +948,7 @@ SILC_FSM_STATE(silc_client_command_reply_kill) /* Remove the client */ if (client_entry) { silc_client_remove_from_channels(client, conn, client_entry); + client_entry->internal.valid = FALSE; silc_client_del_client(client, conn, client_entry); silc_client_unref_client(client, conn, client_entry); } diff --git a/lib/silccore/silccommand.h b/lib/silccore/silccommand.h index eb0d176e..059797e5 100644 --- a/lib/silccore/silccommand.h +++ b/lib/silccore/silccommand.h @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2006 Pekka Riikonen + Copyright (C) 1997 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -30,23 +30,6 @@ #ifndef SILCCOMMAND_H #define SILCCOMMAND_H -/****f* silccore/SilcCommandAPI/SilcCommandCb - * - * SYNOPSIS - * - * typedef void (*SilcCommandCb)(void *context, void *context2); - * - * DESCRIPTION - * - * Command function callback. The actual command function pointer. - * This is generic command callback that the application may choose to - * use with its command routines. However, none of the generic - * routines depend on this callback so application may freely define - * their own command callback if desired. - * - ***/ -typedef void (*SilcCommandCb)(void *context, void *context2); - /****s* silccore/SilcCommandAPI/SilcCommandPayload * * NAME diff --git a/lib/silccore/silcpacket.c b/lib/silccore/silcpacket.c index d2696bbe..26f721f5 100644 --- a/lib/silccore/silcpacket.c +++ b/lib/silccore/silcpacket.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2007 Pekka Riikonen + Copyright (C) 1997 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -40,7 +40,7 @@ struct SilcPacketEngineStruct { SilcMutex lock; /* Engine lock */ SilcRng rng; /* RNG for engine */ SilcHashTable contexts; /* Per scheduler contexts */ - SilcPacketCallbacks *callbacks; /* Packet callbacks */ + const SilcPacketCallbacks *callbacks; /* Packet callbacks */ void *callback_context; /* Context for callbacks */ SilcList streams; /* All streams in engine */ SilcList packet_pool; /* Free list for received packets */ @@ -51,7 +51,7 @@ struct SilcPacketEngineStruct { /* Packet processor context */ typedef struct SilcPacketProcessStruct { SilcPacketType *types; /* Packets to process */ - SilcPacketCallbacks *callbacks; /* Callbacks or NULL */ + const SilcPacketCallbacks *callbacks; /* Callbacks or NULL */ void *callback_context; SilcInt32 priority; /* Priority */ } *SilcPacketProcess; @@ -81,7 +81,7 @@ struct SilcPacketStreamStruct { unsigned char *dst_id; /* Destination ID */ SilcUInt32 send_psn; /* Sending sequence */ SilcUInt32 receive_psn; /* Receiving sequence */ - SilcAtomic8 refcnt; /* Reference counter */ + SilcAtomic32 refcnt; /* Reference counter */ SilcUInt8 sid; /* Security ID, set if IV included */ unsigned int src_id_len : 6; unsigned int src_id_type : 2; @@ -336,7 +336,6 @@ static inline SilcBool silc_packet_stream_read(SilcPacketStream ps, silc_mutex_unlock(ps->lock); if (ret == -1) { /* Cannot read now, do it later. */ - silc_buffer_pull(inbuf, silc_buffer_len(inbuf)); return FALSE; } @@ -394,7 +393,6 @@ static inline SilcBool silc_packet_stream_read(SilcPacketStream ps, if (ret == -1) { /* Cannot read now, do it later. */ - silc_buffer_pull(inbuf, silc_buffer_len(inbuf)); return FALSE; } @@ -542,7 +540,7 @@ static void silc_packet_engine_context_destr(void *key, void *context, SilcPacketEngine silc_packet_engine_start(SilcRng rng, SilcBool router, - SilcPacketCallbacks *callbacks, + const SilcPacketCallbacks *callbacks, void *callback_context) { SilcPacketEngine engine; @@ -624,7 +622,7 @@ void silc_packet_engine_stop(SilcPacketEngine engine) silc_free(engine); } -static const char *packet_error[] = { +static const char * const packet_error[] = { "Cannot read from stream", "Cannot write to stream", "Packet MAC failed", @@ -698,7 +696,7 @@ SilcPacketStream silc_packet_stream_create(SilcPacketEngine engine, return NULL; ps->stream = stream; - silc_atomic_init8(&ps->refcnt, 1); + silc_atomic_init32(&ps->refcnt, 1); silc_mutex_alloc(&ps->lock); /* Allocate out buffer */ @@ -724,8 +722,8 @@ SilcPacketStream silc_packet_stream_create(SilcPacketEngine engine, (void *)&ps->sc)) { ps->sc = silc_calloc(1, sizeof(*ps->sc)); if (!ps->sc) { - silc_packet_stream_destroy(ps); silc_mutex_unlock(engine->lock); + silc_packet_stream_destroy(ps); return NULL; } ps->sc->engine = engine; @@ -736,8 +734,8 @@ SilcPacketStream silc_packet_stream_create(SilcPacketEngine engine, if (!inbuf) { silc_free(ps->sc); ps->sc = NULL; - silc_packet_stream_destroy(ps); silc_mutex_unlock(engine->lock); + silc_packet_stream_destroy(ps); return NULL; } silc_buffer_reset(inbuf); @@ -747,8 +745,8 @@ SilcPacketStream silc_packet_stream_create(SilcPacketEngine engine, silc_buffer_free(inbuf); silc_free(ps->sc); ps->sc = NULL; - silc_packet_stream_destroy(ps); silc_mutex_unlock(engine->lock); + silc_packet_stream_destroy(ps); return NULL; } silc_dlist_add(ps->sc->inbufs, inbuf); @@ -759,8 +757,8 @@ SilcPacketStream silc_packet_stream_create(SilcPacketEngine engine, silc_dlist_del(ps->sc->inbufs, inbuf); silc_free(ps->sc); ps->sc = NULL; - silc_packet_stream_destroy(ps); silc_mutex_unlock(engine->lock); + silc_packet_stream_destroy(ps); return NULL; } } @@ -819,7 +817,7 @@ SilcPacketStream silc_packet_stream_add_remote(SilcPacketStream stream, return NULL; ps->sc = stream->sc; - silc_atomic_init8(&ps->refcnt, 1); + silc_atomic_init32(&ps->refcnt, 1); silc_mutex_alloc(&ps->lock); /* Set the UDP packet stream as underlaying stream */ @@ -887,7 +885,9 @@ void silc_packet_stream_destroy(SilcPacketStream stream) if (!stream) return; - if (silc_atomic_sub_int8(&stream->refcnt, 1) > 0) { + if (silc_atomic_sub_int32(&stream->refcnt, 1) > 0) { + if (stream->destroyed) + return; stream->destroyed = TRUE; SILC_LOG_DEBUG(("Marking packet stream %p destroyed", stream)); @@ -902,17 +902,18 @@ void silc_packet_stream_destroy(SilcPacketStream stream) if (!stream->udp) { /* Delete from engine */ - engine = stream->sc->engine; - silc_mutex_lock(engine->lock); - silc_list_del(engine->streams, stream); - - /* Remove per scheduler context, if it is not used anymore */ if (stream->sc) { + engine = stream->sc->engine; + silc_mutex_lock(engine->lock); + silc_list_del(engine->streams, stream); + + /* Remove per scheduler context, if it is not used anymore */ stream->sc->stream_count--; if (!stream->sc->stream_count) silc_hash_table_del(engine->contexts, stream->sc->schedule); + + silc_mutex_unlock(engine->lock); } - silc_mutex_unlock(engine->lock); /* Destroy the underlaying stream */ if (stream->stream) @@ -972,7 +973,7 @@ void silc_packet_stream_destroy(SilcPacketStream stream) silc_free(stream->src_id); silc_free(stream->dst_id); - silc_atomic_uninit8(&stream->refcnt); + silc_atomic_uninit32(&stream->refcnt); silc_mutex_free(stream->lock); silc_free(stream); } @@ -1001,7 +1002,7 @@ void silc_packet_stream_set_iv_included(SilcPacketStream stream) /* Links `callbacks' to `stream' for specified packet types */ static SilcBool silc_packet_stream_link_va(SilcPacketStream stream, - SilcPacketCallbacks *callbacks, + const SilcPacketCallbacks *callbacks, void *callback_context, int priority, va_list ap) { @@ -1030,6 +1031,7 @@ static SilcBool silc_packet_stream_link_va(SilcPacketStream stream, stream->process = silc_dlist_init(); if (!stream->process) { silc_mutex_unlock(stream->lock); + silc_free(p); return FALSE; } } @@ -1079,7 +1081,7 @@ static SilcBool silc_packet_stream_link_va(SilcPacketStream stream, /* Links `callbacks' to `stream' for specified packet types */ SilcBool silc_packet_stream_link(SilcPacketStream stream, - SilcPacketCallbacks *callbacks, + const SilcPacketCallbacks *callbacks, void *callback_context, int priority, ...) { @@ -1097,7 +1099,7 @@ SilcBool silc_packet_stream_link(SilcPacketStream stream, /* Unlinks `callbacks' from `stream'. */ void silc_packet_stream_unlink(SilcPacketStream stream, - SilcPacketCallbacks *callbacks, + const SilcPacketCallbacks *callbacks, void *callback_context) { SilcPacketProcess p; @@ -1153,10 +1155,10 @@ SilcBool silc_packet_get_sender(SilcPacket packet, void silc_packet_stream_ref(SilcPacketStream stream) { - silc_atomic_add_int8(&stream->refcnt, 1); + silc_atomic_add_int32(&stream->refcnt, 1); SILC_LOG_DEBUG(("Stream %p, refcnt %d->%d", stream, - silc_atomic_get_int8(&stream->refcnt) - 1, - silc_atomic_get_int8(&stream->refcnt))); + silc_atomic_get_int32(&stream->refcnt) - 1, + silc_atomic_get_int32(&stream->refcnt))); } /* Unreference packet stream */ @@ -1164,11 +1166,11 @@ void silc_packet_stream_ref(SilcPacketStream stream) void silc_packet_stream_unref(SilcPacketStream stream) { SILC_LOG_DEBUG(("Stream %p, refcnt %d->%d", stream, - silc_atomic_get_int8(&stream->refcnt), - silc_atomic_get_int8(&stream->refcnt) - 1)); - if (silc_atomic_sub_int8(&stream->refcnt, 1) > 0) + silc_atomic_get_int32(&stream->refcnt), + silc_atomic_get_int32(&stream->refcnt) - 1)); + if (silc_atomic_sub_int32(&stream->refcnt, 1) > 0) return; - silc_atomic_add_int8(&stream->refcnt, 1); + silc_atomic_add_int32(&stream->refcnt, 1); silc_packet_stream_destroy(stream); } @@ -1323,6 +1325,7 @@ SilcBool silc_packet_set_ids(SilcPacketStream stream, { SilcUInt32 len; unsigned char tmp[32]; + void *tmp_id; if (!src_id && !dst_id) return FALSE; @@ -1332,16 +1335,17 @@ SilcBool silc_packet_set_ids(SilcPacketStream stream, if (src_id) { SILC_LOG_DEBUG(("Setting source ID to packet stream %p", stream)); - silc_free(stream->src_id); if (!silc_id_id2str(src_id, src_id_type, tmp, sizeof(tmp), &len)) { silc_mutex_unlock(stream->lock); return FALSE; } - stream->src_id = silc_memdup(tmp, len); - if (!stream->src_id) { + tmp_id = silc_memdup(tmp, len); + if (!tmp_id) { silc_mutex_unlock(stream->lock); return FALSE; } + silc_free(stream->src_id); + stream->src_id = tmp_id; stream->src_id_type = src_id_type; stream->src_id_len = len; } @@ -1349,16 +1353,17 @@ SilcBool silc_packet_set_ids(SilcPacketStream stream, if (dst_id) { SILC_LOG_DEBUG(("Setting destination ID to packet stream %p", stream)); - silc_free(stream->dst_id); if (!silc_id_id2str(dst_id, dst_id_type, tmp, sizeof(tmp), &len)) { silc_mutex_unlock(stream->lock); return FALSE; } - stream->dst_id = silc_memdup(tmp, len); - if (!stream->dst_id) { + tmp_id = silc_memdup(tmp, len); + if (!tmp_id) { silc_mutex_unlock(stream->lock); return FALSE; } + silc_free(stream->dst_id); + stream->dst_id = tmp_id; stream->dst_id_type = dst_id_type; stream->dst_id_len = len; } @@ -2346,7 +2351,7 @@ silc_packet_wait_packet_receive(SilcPacketEngine engine, void *stream_context); /* Packet waiting callbacks */ -static SilcPacketCallbacks silc_packet_wait_cbs = +static const SilcPacketCallbacks silc_packet_wait_cbs = { silc_packet_wait_packet_receive, NULL, NULL }; @@ -2535,7 +2540,7 @@ typedef struct { } *SilcPacketWrapperStream; /* Packet wrapper callbacks */ -static SilcPacketCallbacks silc_packet_wrap_cbs = +static const SilcPacketCallbacks silc_packet_wrap_cbs = { silc_packet_wrap_packet_receive, NULL, NULL }; diff --git a/lib/silccore/silcpacket.h b/lib/silccore/silcpacket.h index 3d4ca10d..0caf10d8 100644 --- a/lib/silccore/silcpacket.h +++ b/lib/silccore/silcpacket.h @@ -361,7 +361,7 @@ typedef struct { ***/ SilcPacketEngine silc_packet_engine_start(SilcRng rng, SilcBool router, - SilcPacketCallbacks *callbacks, + const SilcPacketCallbacks *callbacks, void *callback_context); /****f* silccore/SilcPacketAPI/silc_packet_engine_stop @@ -651,7 +651,7 @@ SilcStream silc_packet_stream_get_stream(SilcPacketStream stream); * ***/ SilcBool silc_packet_stream_link(SilcPacketStream stream, - SilcPacketCallbacks *callbacks, + const SilcPacketCallbacks *callbacks, void *callback_context, int priority, ...); @@ -671,7 +671,7 @@ SilcBool silc_packet_stream_link(SilcPacketStream stream, * ***/ void silc_packet_stream_unlink(SilcPacketStream stream, - SilcPacketCallbacks *callbacks, + const SilcPacketCallbacks *callbacks, void *callback_context); /****f* silccore/SilcPacketAPI/SilcPacketWrapCoder diff --git a/lib/silcske/silcconnauth.c b/lib/silcske/silcconnauth.c index 06161b33..d44e9faf 100644 --- a/lib/silcske/silcconnauth.c +++ b/lib/silcske/silcconnauth.c @@ -704,6 +704,8 @@ SILC_FSM_STATE(silc_connauth_st_responder_authenticate_pk) connauth->auth_data, connauth->auth_data_len)); /* NOT REACHED */ + + SILC_LOG_DEBUG(("Signature is Ok")); } SILC_FSM_STATE(silc_connauth_st_responder_success) diff --git a/lib/silcske/silcske.c b/lib/silcske/silcske.c index 7331e235..fece34b6 100644 --- a/lib/silcske/silcske.c +++ b/lib/silcske/silcske.c @@ -4,7 +4,7 @@ Author: Pekka Riikonen - Copyright (C) 2000 - 2007 Pekka Riikonen + Copyright (C) 2000 - 2008 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1722,9 +1722,6 @@ SILC_FSM_STATE(silc_ske_st_initiator_phase4) silc_ske_verify_cb, ske)); /* NOT REACHED */ } - - return SILC_FSM_CONTINUE; - err: memset(hash, 'F', sizeof(hash)); silc_ske_payload_ke_free(payload); @@ -2127,15 +2124,9 @@ SILC_FSM_STATE(silc_ske_st_responder_phase2) silc_packet_free(ske->packet); ske->packet = NULL; - /* Verify the received public key and verify the signature if we are - doing mutual authentication. */ - if (ske->start_payload && - ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) { - - SILC_LOG_DEBUG(("We are doing mutual authentication")); - - if (!recv_payload->pk_data && (ske->callbacks->verify_key || - ske->repository)) { + /* Verify public key, except in rekey, when it is not sent */ + if (!ske->rekey) { + if (!recv_payload->pk_data) { /** Public key not provided */ SILC_LOG_ERROR(("Remote end did not send its public key (or " "certificate), even though we require it")); @@ -2145,8 +2136,7 @@ SILC_FSM_STATE(silc_ske_st_responder_phase2) } /* Decode the remote's public key */ - if (recv_payload->pk_data && - !silc_pkcs_public_key_alloc(recv_payload->pk_type, + if (!silc_pkcs_public_key_alloc(recv_payload->pk_type, recv_payload->pk_data, recv_payload->pk_len, &ske->prop->public_key)) { @@ -2157,39 +2147,36 @@ SILC_FSM_STATE(silc_ske_st_responder_phase2) return SILC_FSM_CONTINUE; } - if (ske->prop->public_key && (ske->callbacks->verify_key || - ske->repository)) { - SILC_LOG_DEBUG(("Verifying public key")); + SILC_LOG_DEBUG(("Verifying public key")); - /** Waiting public key verification */ - silc_fsm_next(fsm, silc_ske_st_responder_phase4); + /** Waiting public key verification */ + silc_fsm_next(fsm, silc_ske_st_responder_phase4); - /* If repository is provided, verify the key from there. */ - if (ske->repository) { - SilcSKRFind find; + /* If repository is provided, verify the key from there. */ + if (ske->repository) { + SilcSKRFind find; - find = silc_skr_find_alloc(); - if (!find) { - ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY; - silc_fsm_next(fsm, silc_ske_st_responder_error); - return SILC_FSM_CONTINUE; - } - silc_skr_find_set_pkcs_type(find, - silc_pkcs_get_type(ske->prop->public_key)); - silc_skr_find_set_public_key(find, ske->prop->public_key); - silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT); - - /* Find key from repository */ - SILC_FSM_CALL(silc_skr_find(ske->repository, - silc_fsm_get_schedule(fsm), find, - silc_ske_skr_callback, ske)); - } else { - /* Verify from application */ + find = silc_skr_find_alloc(); + if (!find) { + ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY; + silc_fsm_next(fsm, silc_ske_st_responder_error); + return SILC_FSM_CONTINUE; + } + silc_skr_find_set_pkcs_type(find, + silc_pkcs_get_type(ske->prop->public_key)); + silc_skr_find_set_public_key(find, ske->prop->public_key); + silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT); + + /* Find key from repository */ + SILC_FSM_CALL(silc_skr_find(ske->repository, + silc_fsm_get_schedule(fsm), find, + silc_ske_skr_callback, ske)); + } else { + /* Verify from application */ + if (ske->callbacks->verify_key) SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key, ske->callbacks->context, silc_ske_pk_verified, NULL)); - } - /* NOT REACHED */ } } @@ -2232,7 +2219,7 @@ SILC_FSM_STATE(silc_ske_st_responder_phase4) unsigned char hash[SILC_HASH_MAXLEN]; SilcUInt32 hash_len; - SILC_LOG_DEBUG(("Public key is authentic")); + SILC_LOG_DEBUG(("We are doing mutual authentication")); /* Compute the hash value */ status = silc_ske_make_hash(ske, hash, &hash_len, TRUE); @@ -3533,7 +3520,7 @@ SilcBool silc_ske_set_keys(SilcSKE ske, memcpy(iv + 4, keymat->receive_iv, 8); else memset(iv + 4, 0, 12); - } + } silc_cipher_set_iv(*ret_receive_key, iv); } else { diff --git a/win32/libsilc_static/libsilc_static.dsp b/win32/libsilc_static/libsilc_static.dsp index 00d6881e..99706ff9 100644 --- a/win32/libsilc_static/libsilc_static.dsp +++ b/win32/libsilc_static/libsilc_static.dsp @@ -292,10 +292,6 @@ SOURCE=..\..\lib\silccrypt\blowfish.c # End Source File # Begin Source File -SOURCE=..\..\lib\silccrypt\cast.c -# End Source File -# Begin Source File - SOURCE=..\..\lib\silccrypt\md5.c # End Source File # Begin Source File @@ -304,10 +300,6 @@ SOURCE=..\..\lib\silccrypt\none.c # End Source File # Begin Source File -SOURCE=..\..\lib\silccrypt\rc5.c -# End Source File -# Begin Source File - SOURCE=..\..\lib\silccrypt\rsa.c # End Source File # Begin Source File