5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 2001 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
22 #include "chat-protocols.h"
26 #include "servers-setup.h"
27 #include "channels-setup.h"
28 #include "silc-servers.h"
29 #include "silc-channels.h"
30 #include "silc-queries.h"
31 #include "silc-nicklist.h"
32 #include "version_internal.h"
38 #include "fe-common/core/printtext.h"
39 #include "fe-common/core/fe-channels.h"
40 #include "fe-common/core/keyboard.h"
41 #include "fe-common/silc/module-formats.h"
43 /* Command line option variables */
44 static bool opt_create_keypair = FALSE;
45 static bool opt_list_ciphers = FALSE;
46 static bool opt_list_hash = FALSE;
47 static bool opt_list_hmac = FALSE;
48 static bool opt_list_pkcs = FALSE;
49 static bool opt_version = FALSE;
50 static char *opt_debug = FALSE;
51 static char *opt_pkcs = NULL;
52 static char *opt_keyfile = NULL;
53 static int opt_bits = 0;
57 SilcClient silc_client = NULL;
58 SilcClientConfig silc_config = NULL;
59 extern SilcClientOperations ops;
60 extern bool silc_debug;
61 extern bool silc_debug_hexdump;
63 /* SIM (SILC Module) table */
64 SilcSimContext **sims = NULL;
65 uint32 sims_count = 0;
68 static int my_silc_scheduler(void)
70 silc_client_run_one(silc_client);
74 static CHATNET_REC *create_chatnet(void)
76 return g_malloc0(sizeof(CHATNET_REC));
79 static SERVER_SETUP_REC *create_server_setup(void)
81 return g_malloc0(sizeof(SERVER_SETUP_REC));
84 static CHANNEL_SETUP_REC *create_channel_setup(void)
86 return g_malloc0(sizeof(CHANNEL_SETUP_REC));
89 static SERVER_CONNECT_REC *create_server_connect(void)
91 return g_malloc0(sizeof(SILC_SERVER_CONNECT_REC));
94 static void destroy_server_connect(SERVER_CONNECT_REC *conn)
99 /* Checks user information and saves them to the config file it they
100 do not exist there already. */
102 static void silc_init_userinfo(void)
104 const char *set, *nick, *user_name;
107 /* check if nick/username/realname wasn't read from setup.. */
108 set = settings_get_str("real_name");
109 if (set == NULL || *set == '\0') {
110 str = g_getenv("SILCNAME");
112 str = g_getenv("IRCNAME");
113 settings_set_str("real_name",
114 str != NULL ? str : g_get_real_name());
118 user_name = settings_get_str("user_name");
119 if (user_name == NULL || *user_name == '\0') {
120 str = g_getenv("SILCUSER");
122 str = g_getenv("IRCUSER");
123 settings_set_str("user_name",
124 str != NULL ? str : g_get_user_name());
126 user_name = settings_get_str("user_name");
130 nick = settings_get_str("nick");
131 if (nick == NULL || *nick == '\0') {
132 str = g_getenv("SILCNICK");
134 str = g_getenv("IRCNICK");
135 settings_set_str("nick", str != NULL ? str : user_name);
137 nick = settings_get_str("nick");
141 set = settings_get_str("alternate_nick");
142 if (set == NULL || *set == '\0') {
143 if (strlen(nick) < 9)
144 str = g_strconcat(nick, "_", NULL);
146 str = g_strdup(nick);
147 str[strlen(str)-1] = '_';
149 settings_set_str("alternate_nick", str);
154 set = settings_get_str("hostname");
155 if (set == NULL || *set == '\0') {
156 str = g_getenv("SILCHOST");
158 str = g_getenv("IRCHOST");
160 settings_set_str("hostname", str);
166 static bool silc_log_misc(SilcLogType type, char *message, void *context)
168 fprintf(stderr, "%s\n", message);
172 static void silc_nickname_format_parse(const char *nickname,
175 silc_parse_userfqdn(nickname, ret_nickname, NULL);
178 /* Finalize init. Init finish signal calls this. */
180 void silc_core_init_finish(SERVER_REC *server)
182 CHAT_PROTOCOL_REC *rec;
183 SilcClientParams params;
185 if (opt_create_keypair == TRUE) {
186 /* Create new key pair and exit */
187 silc_cipher_register_default();
188 silc_pkcs_register_default();
189 silc_hash_register_default();
190 silc_hmac_register_default();
191 silc_client_create_key_pair(opt_pkcs, opt_bits,
192 NULL, NULL, NULL, NULL, NULL);
198 silc_cipher_register_default();
199 silc_pkcs_register_default();
200 silc_hash_register_default();
201 silc_hmac_register_default();
202 silc_client_show_key(opt_keyfile);
206 if (opt_list_ciphers) {
207 silc_cipher_register_default();
208 silc_client_list_ciphers();
213 silc_hash_register_default();
214 silc_client_list_hash_funcs();
219 silc_hmac_register_default();
220 silc_client_list_hmacs();
225 silc_pkcs_register_default();
226 silc_client_list_pkcs();
231 printf("SILC Secure Internet Live Conferencing, version %s "
232 "(base: SILC Toolkit %s)\n", silc_dist_version, silc_version);
233 printf("(c) 1997 - 2001 Pekka Riikonen <priikone@silcnet.org>\n");
239 silc_debug_hexdump = TRUE;
240 silc_log_set_debug_string(opt_debug);
241 silc_log_set_callback(SILC_LOG_INFO, silc_log_misc, NULL);
242 silc_log_set_callback(SILC_LOG_WARNING, silc_log_misc, NULL);
243 silc_log_set_callback(SILC_LOG_ERROR, silc_log_misc, NULL);
244 silc_log_set_callback(SILC_LOG_FATAL, silc_log_misc, NULL);
247 "Run-time debugging is not enabled. To enable it recompile\n"
248 "the client with --enable-debug configuration option.\n");
252 /* Do some irssi initializing */
253 settings_add_bool("server", "skip_motd", FALSE);
254 settings_add_str("server", "alternate_nick", NULL);
256 /* Initialize the auto_addr variables Is "server" the best choice for
257 * this? No existing category seems to apply.
259 settings_add_bool("server", "use_auto_addr", FALSE);
260 settings_add_str("server", "auto_bind_ip", "");
261 settings_add_str("server", "auto_public_ip", "");
262 settings_add_int("server", "auto_bind_port", 0);
264 silc_init_userinfo();
266 /* Initialize client parameters */
267 memset(¶ms, 0, sizeof(params));
268 strcat(params.nickname_format, "%n@%h%a");
269 params.nickname_parse = silc_nickname_format_parse;
271 /* Allocate SILC client */
272 silc_client = silc_client_alloc(&ops, ¶ms, NULL, silc_version_string);
274 /* Load local config file */
275 silc_config = silc_client_config_alloc(SILC_CLIENT_HOME_CONFIG_FILE);
277 /* Get user information */
278 silc_client->username = g_strdup(settings_get_str("user_name"));
279 silc_client->nickname = g_strdup(settings_get_str("nick"));
280 silc_client->hostname = silc_net_localhost();
281 silc_client->realname = g_strdup(settings_get_str("real_name"));
283 /* Register all configured ciphers, PKCS and hash functions. */
285 silc_config->client = silc_client;
286 if (!silc_client_config_register_ciphers(silc_config))
287 silc_cipher_register_default();
288 if (!silc_client_config_register_pkcs(silc_config))
289 silc_pkcs_register_default();
290 if (!silc_client_config_register_hashfuncs(silc_config))
291 silc_hash_register_default();
292 if (!silc_client_config_register_hmacs(silc_config))
293 silc_hmac_register_default();
295 /* Register default ciphers, pkcs, hash funtions and hmacs. */
296 silc_cipher_register_default();
297 silc_pkcs_register_default();
298 silc_hash_register_default();
299 silc_hmac_register_default();
302 /* Check ~/.silc directory and public and private keys */
303 if (silc_client_check_silc_dir() == FALSE) {
308 /* Load public and private key */
309 if (silc_client_load_keys(silc_client) == FALSE) {
314 /* Initialize the SILC client */
315 if (!silc_client_init(silc_client)) {
320 /* Register SILC to the irssi */
321 rec = g_new0(CHAT_PROTOCOL_REC, 1);
323 rec->fullname = "Secure Internet Live Conferencing";
324 rec->chatnet = "silcnet";
325 rec->create_chatnet = create_chatnet;
326 rec->create_server_setup = create_server_setup;
327 rec->create_channel_setup = create_channel_setup;
328 rec->create_server_connect = create_server_connect;
329 rec->destroy_server_connect = destroy_server_connect;
330 rec->server_connect = (SERVER_REC *(*) (SERVER_CONNECT_REC *))
332 rec->channel_create = (CHANNEL_REC *(*) (SERVER_REC *, const char *, int))
334 rec->query_create = (QUERY_REC *(*) (const char *, const char *, int))
337 chat_protocol_register(rec);
341 silc_channels_init();
344 idletag = g_timeout_add(5, (GSourceFunc) my_silc_scheduler, NULL);
347 /* Init SILC. Called from src/fe-text/silc.c */
349 void silc_core_init(void)
351 static struct poptOption options[] = {
352 { "create-key-pair", 'C', POPT_ARG_NONE, &opt_create_keypair, 0,
353 "Create new public key pair", NULL },
354 { "pkcs", 0, POPT_ARG_STRING, &opt_pkcs, 0,
355 "Set the PKCS of the public key pair", "PKCS" },
356 { "bits", 0, POPT_ARG_INT, &opt_bits, 0,
357 "Set the length of the public key pair", "VALUE" },
358 { "show-key", 'S', POPT_ARG_STRING, &opt_keyfile, 0,
359 "Show the contents of the public key", "FILE" },
360 { "list-ciphers", 'C', POPT_ARG_NONE, &opt_list_ciphers, 0,
361 "List supported ciphers", NULL },
362 { "list-hash-funcs", 'H', POPT_ARG_NONE, &opt_list_hash, 0,
363 "List supported hash functions", NULL },
364 { "list-hmacs", 'H', POPT_ARG_NONE, &opt_list_hmac, 0,
365 "List supported HMACs", NULL },
366 { "list-pkcs", 'P', POPT_ARG_NONE, &opt_list_pkcs, 0,
367 "List supported PKCSs", NULL },
368 { "debug", 'd', POPT_ARG_STRING, &opt_debug, 0,
369 "Enable debugging", "STRING" },
370 { "version", 'V', POPT_ARG_NONE, &opt_version, 0,
371 "Show version", NULL },
372 { NULL, '\0', 0, NULL }
375 signal_add("irssi init finished", (SIGNAL_FUNC) silc_core_init_finish);
377 args_register(options);
380 /* Deinit SILC. Called from src/fe-text/silc.c */
382 void silc_core_deinit(void)
385 signal_emit("chat protocol deinit", 1,
386 chat_protocol_find("SILC"));
388 silc_server_deinit();
389 silc_channels_deinit();
390 silc_queries_deinit();
392 chat_protocol_unregister("SILC");
394 g_source_remove(idletag);
397 g_free(silc_client->username);
398 g_free(silc_client->realname);
399 silc_client_free(silc_client);