X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=apps%2Firssi%2Fsrc%2Fsilc%2Fcore%2Fclientutil.c;h=836347338a3457deaa8af281f5d37ef4d6775dc1;hb=52e57c880aba9c5e89f59d962eb9af75670b76e0;hp=8f1639329813e77636874510c9b35420ee2eca08;hpb=413da0f8686910f5e627393157566ae729ca99c4;p=silc.git diff --git a/apps/irssi/src/silc/core/clientutil.c b/apps/irssi/src/silc/core/clientutil.c index 8f163932..83634733 100644 --- a/apps/irssi/src/silc/core/clientutil.c +++ b/apps/irssi/src/silc/core/clientutil.c @@ -4,12 +4,12 @@ Author: Pekka Riikonen - Copyright (C) 1997 - 2002 Pekka Riikonen + Copyright (C) 1997 - 2006 Pekka Riikonen This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -41,15 +41,40 @@ #include "fe-common/core/printtext.h" #include "fe-common/core/keyboard.h" +#include "fe-common/silc/module-formats.h" #include "core.h" +#ifdef SILC_PLUGIN +void silc_client_print_list(char *list) +{ + char **items; + int i=0; + + items = g_strsplit(list, ",", -1); + + while (items[i] != NULL) + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_CONFIG_LIST, + items[i++]); + + g_strfreev(items); +} +#endif + /* Lists supported ciphers */ void silc_client_list_ciphers() { char *ciphers = silc_cipher_get_supported(); +#ifdef SILC_PLUGIN + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_CONFIG_ALGOS, + "cipher"); + silc_client_print_list(ciphers); +#else fprintf(stdout, "%s\n", ciphers); +#endif silc_free(ciphers); } @@ -58,7 +83,14 @@ void silc_client_list_ciphers() void silc_client_list_hash_funcs() { char *hash = silc_hash_get_supported(); +#ifdef SILC_PLUGIN + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_CONFIG_ALGOS, + "hash"); + silc_client_print_list(hash); +#else fprintf(stdout, "%s\n", hash); +#endif silc_free(hash); } @@ -67,7 +99,14 @@ void silc_client_list_hash_funcs() void silc_client_list_hmacs() { char *hash = silc_hmac_get_supported(); +#ifdef SILC_PLUGIN + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_CONFIG_ALGOS, + "hmac"); + silc_client_print_list(hash); +#else fprintf(stdout, "%s\n", hash); +#endif silc_free(hash); } @@ -76,16 +115,22 @@ void silc_client_list_hmacs() void silc_client_list_pkcs() { char *pkcs = silc_pkcs_get_supported(); +#ifdef SILC_PLUGIN + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_CONFIG_ALGOS, + "pkcs"); + silc_client_print_list(pkcs); +#else fprintf(stdout, "%s\n", pkcs); +#endif silc_free(pkcs); } -/* This checks stats for various SILC files and directories. First it - checks if ~/.silc directory exist and is owned by the correct user. If +/* This checks stats for various SILC files and directories. First it + checks if ~/.silc directory exist and is owned by the correct user. If it doesn't exist, it will create the directory. After that it checks if - user's Public and Private key files exists and that they aren't expired. - If they doesn't exist or they are expired, they will be (re)created - after return. */ + user's Public and Private key files exists. If they doesn't exist they + will be created after return. */ int silc_client_check_silc_dir() { @@ -93,7 +138,6 @@ int silc_client_check_silc_dir() char servfilename[256], clientfilename[256], friendsfilename[256]; struct stat st; struct passwd *pw; - time_t curtime, modtime; SILC_LOG_DEBUG(("Checking ~./silc directory")); @@ -109,11 +153,11 @@ int silc_client_check_silc_dir() /* We'll take home path from /etc/passwd file to be sure. */ snprintf(filename, sizeof(filename) - 1, "%s/", get_irssi_dir()); - snprintf(servfilename, sizeof(servfilename) - 1, "%s/serverkeys", + snprintf(servfilename, sizeof(servfilename) - 1, "%s/serverkeys", get_irssi_dir()); - snprintf(clientfilename, sizeof(clientfilename) - 1, "%s/clientkeys", + snprintf(clientfilename, sizeof(clientfilename) - 1, "%s/clientkeys", get_irssi_dir()); - snprintf(friendsfilename, sizeof(friendsfilename) - 1, "%s/friends", + snprintf(friendsfilename, sizeof(friendsfilename) - 1, "%s/friends", get_irssi_dir()); /* @@ -137,19 +181,19 @@ int silc_client_check_silc_dir() return FALSE; } } else { - + /* Check the owner of the dir */ - if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { + if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { fprintf(stderr, "You don't seem to own `%s' directory\n", filename); return FALSE; } - + #if 0 /* Check the permissions of the dir */ if ((st.st_mode & 0777) != 0755) { if ((chmod(filename, 0755)) == -1) { - fprintf(stderr, "Permissions for `%s' directory must be 0755\n", + fprintf(stderr, "Permissions for `%s' directory must be 0755\n", filename); return FALSE; } @@ -178,7 +222,7 @@ int silc_client_check_silc_dir() return FALSE; } } - + /* * Check ~./silc/clientkeys directory */ @@ -200,7 +244,7 @@ int silc_client_check_silc_dir() return FALSE; } } - + /* * Check ~./silc/friends directory */ @@ -222,22 +266,22 @@ int silc_client_check_silc_dir() return FALSE; } } - + /* * Check Public and Private keys */ - snprintf(file_public_key, sizeof(file_public_key) - 1, "%s%s", + snprintf(file_public_key, sizeof(file_public_key) - 1, "%s%s", filename, SILC_CLIENT_PUBLIC_KEY_NAME); - snprintf(file_private_key, sizeof(file_private_key) - 1, "%s%s", + snprintf(file_private_key, sizeof(file_private_key) - 1, "%s%s", filename, SILC_CLIENT_PRIVATE_KEY_NAME); - + if ((stat(file_public_key, &st)) == -1) { /* If file doesn't exist */ if (errno == ENOENT) { fprintf(stdout, "Running SILC for the first time\n"); silc_create_key_pair(SILC_CLIENT_DEF_PKCS, SILC_CLIENT_DEF_PKCS_LEN, - file_public_key, file_private_key, NULL, + file_public_key, file_private_key, NULL, NULL, NULL, NULL, FALSE); printf("Press to continue...\n"); getchar(); @@ -246,20 +290,20 @@ int silc_client_check_silc_dir() return FALSE; } } - + /* Check the owner of the public key */ - if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { + if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { fprintf(stderr, "You don't seem to own your public key!?\n"); return FALSE; } - + if ((stat(file_private_key, &st)) == -1) { /* If file doesn't exist */ if (errno == ENOENT) { fprintf(stdout, "Your private key doesn't exist\n"); silc_create_key_pair(SILC_CLIENT_DEF_PKCS, SILC_CLIENT_DEF_PKCS_LEN, - file_public_key, file_private_key, NULL, + file_public_key, file_private_key, NULL, NULL, NULL, NULL, FALSE); printf("Press to continue...\n"); getchar(); @@ -268,69 +312,26 @@ int silc_client_check_silc_dir() return FALSE; } } - + /* Check the owner of the private key */ - if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { + if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { fprintf(stderr, "You don't seem to own your private key!?\n"); return FALSE; } - + /* Check the permissions for the private key */ if ((st.st_mode & 0777) != 0600) { fprintf(stderr, "Wrong permissions in your private key file `%s'!\n" "Trying to change them ... ", file_private_key); if ((chmod(file_private_key, 0600)) == -1) { fprintf(stderr, - "Failed to change permissions for private key file!\n" + "Failed to change permissions for private key file!\n" "Permissions for your private key file must be 0600.\n"); return FALSE; } fprintf(stderr, "Done.\n\n"); } - /* See if the key has expired. */ - modtime = st.st_mtime; /* last modified */ - curtime = time(0) - modtime; - - /* 86400 is seconds in a day. */ - if (curtime >= (86400 * SILC_CLIENT_KEY_EXPIRES)) { - char *answer; - - fprintf(stdout, - "----------------------------------------------------\n" - "Your private key has expired and needs to be\n" - "recreated. Would you like to create a new key pair\n" - "now? If you answer Yes, the new key will expire in\n" - "%d days from today. If you answer No, the old key\n" - "will expire again in %d days from today.\n" - "----------------------------------------------------\n", - SILC_CLIENT_KEY_EXPIRES, SILC_CLIENT_KEY_EXPIRES); - - answer = silc_get_input("Would you like to create a new key pair " - "(y/n)?: ", FALSE); - while (!answer) { - printf("Answer 'y' or 'n' and press Enter\n"); - answer = silc_get_input("Would you like to create a new key pair " - "(y/n)?: ", FALSE); - } - if (answer[0] == 'Y' || answer[0] == 'y') { - silc_create_key_pair(SILC_CLIENT_DEF_PKCS, - SILC_CLIENT_DEF_PKCS_LEN, - file_public_key, file_private_key, NULL, - NULL, NULL, NULL, NULL, FALSE); - printf("Press to continue...\n"); - getchar(); - } else { -#ifdef HAVE_UTIME - struct utimbuf utim; - utim.actime = time(NULL); - utim.modtime = time(NULL); - utime(file_private_key, &utim); -#endif - } - silc_free(answer); - } - return TRUE; } @@ -355,14 +356,116 @@ int silc_client_load_keys(SilcClient client) memset(pub, 0, sizeof(pub)); snprintf(pub, sizeof(pub) - 1, "%s/%s", get_irssi_dir(), SILC_CLIENT_PUBLIC_KEY_NAME); - + /* Try loading first with "" passphrase, for those that didn't set passphrase for private key, and only if that fails let it prompt for passphrase. */ - ret = silc_load_key_pair(pub, prv, "", &client->pkcs, &client->public_key, - &client->private_key); + ret = silc_load_key_pair(pub, prv, "", &irssi_pubkey, &irssi_privkey); + if (!ret) + ret = silc_load_key_pair(pub, prv, NULL, &irssi_pubkey, &irssi_privkey); + if (!ret) - ret = silc_load_key_pair(pub, prv, NULL, &client->pkcs, - &client->public_key, &client->private_key); + SILC_LOG_ERROR(("Could not load key pair")); + return ret; } + +#ifdef SILC_PLUGIN +void create_key_passphrase(const char *answer, CREATE_KEY_REC *rec) +{ + char priv_key_file[128], pub_key_file[128]; + + signal_stop(); + + if ((rec->passphrase == NULL) && (answer) && (*answer != '\0')) { + rec->passphrase = g_strdup(answer); + keyboard_entry_redirect((SIGNAL_FUNC) create_key_passphrase, + format_get_text("fe-common/silc", NULL, NULL, + NULL, SILCTXT_CONFIG_PASS_ASK2), + ENTRY_REDIRECT_FLAG_HIDDEN, rec); + return; + } + + if ((answer) && (*answer != '\0') && (rec->passphrase != NULL)) { + if (strcmp(answer, rec->passphrase)) { + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_CONFIG_PASSMISMATCH); + g_free(rec->pkcs); + g_free(rec->passphrase); + g_free(rec); + return; + } + } + + memset(priv_key_file, 0, sizeof(priv_key_file)); + memset(pub_key_file, 0, sizeof(pub_key_file)); + snprintf(priv_key_file, sizeof(priv_key_file) - 1, "%s/%s", + get_irssi_dir(), SILC_CLIENT_PRIVATE_KEY_NAME); + snprintf(pub_key_file, sizeof(pub_key_file) - 1, "%s/%s", + get_irssi_dir(), SILC_CLIENT_PUBLIC_KEY_NAME); + + if (silc_create_key_pair(rec->pkcs, rec->bits, pub_key_file, priv_key_file, + NULL, (rec->passphrase == NULL ? "" : rec->passphrase), + NULL, NULL, FALSE) == TRUE) + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_CONFIG_CREATE); + else + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_CONFIG_CREATE_FAIL); + + g_free(rec->passphrase); + g_free(rec->pkcs); + g_free(rec); +} + +void change_private_key_passphrase(const char *answer, CREATE_KEY_REC *rec) +{ + signal_stop(); + + if (rec->old == NULL) { + rec->old = g_strdup((answer == NULL ? "" : answer)); + keyboard_entry_redirect((SIGNAL_FUNC) change_private_key_passphrase, + format_get_text("fe-common/silc", NULL, NULL, + NULL, SILCTXT_CONFIG_PASS_ASK2), + ENTRY_REDIRECT_FLAG_HIDDEN, rec); + return; + } + + if ((rec->passphrase == NULL) && (answer) && (*answer != '\0')) { + rec->passphrase = g_strdup(answer); + keyboard_entry_redirect((SIGNAL_FUNC) change_private_key_passphrase, + format_get_text("fe-common/silc", NULL, NULL, + NULL, SILCTXT_CONFIG_PASS_ASK3), + ENTRY_REDIRECT_FLAG_HIDDEN, rec); + return; + } + + if ((answer) && (*answer != '\0') && (rec->passphrase != NULL)) { + if (strcmp(answer, rec->passphrase)) { + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_CONFIG_PASSMISMATCH); + g_free(rec->old); + g_free(rec->file); + g_free(rec->pkcs); + g_free(rec->passphrase); + g_free(rec); + return; + } + } + + if (silc_change_private_key_passphrase(rec->file, rec->old, + (rec->passphrase == NULL ? + "" : rec->passphrase)) == TRUE) + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_CONFIG_PASSCHANGE); + else + printformat_module("fe-common/silc", NULL, NULL, + MSGLEVEL_CRAP, SILCTXT_CONFIG_PASSCHANGE_FAIL); + g_free(rec->old); + g_free(rec->file); + g_free(rec->passphrase); + g_free(rec->pkcs); + g_free(rec); + +} +#endif