5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 1997 - 2002 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; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
23 #include "net-nonblock.h"
24 #include "net-sendbuffer.h"
34 #include "channels-setup.h"
36 #include "silc-servers.h"
37 #include "silc-channels.h"
38 #include "silc-queries.h"
39 #include "silc-nicklist.h"
40 #include "window-item-def.h"
42 #include "fe-common/core/printtext.h"
43 #include "fe-common/core/keyboard.h"
47 /* Lists supported ciphers */
49 void silc_client_list_ciphers()
51 char *ciphers = silc_cipher_get_supported();
52 fprintf(stdout, "%s\n", ciphers);
56 /* Lists supported hash functions */
58 void silc_client_list_hash_funcs()
60 char *hash = silc_hash_get_supported();
61 fprintf(stdout, "%s\n", hash);
65 /* Lists supported hash functions */
67 void silc_client_list_hmacs()
69 char *hash = silc_hmac_get_supported();
70 fprintf(stdout, "%s\n", hash);
74 /* Lists supported PKCS algorithms */
76 void silc_client_list_pkcs()
78 char *pkcs = silc_pkcs_get_supported();
79 fprintf(stdout, "%s\n", pkcs);
83 /* This checks stats for various SILC files and directories. First it
84 checks if ~/.silc directory exist and is owned by the correct user. If
85 it doesn't exist, it will create the directory. After that it checks if
86 user's Public and Private key files exists and that they aren't expired.
87 If they doesn't exist or they are expired, they will be (re)created
90 int silc_client_check_silc_dir()
92 char filename[256], file_public_key[256], file_private_key[256];
93 char servfilename[256], clientfilename[256], friendsfilename[256];
96 time_t curtime, modtime;
98 SILC_LOG_DEBUG(("Checking ~./silc directory"));
100 memset(filename, 0, sizeof(filename));
101 memset(file_public_key, 0, sizeof(file_public_key));
102 memset(file_private_key, 0, sizeof(file_private_key));
104 pw = getpwuid(getuid());
106 fprintf(stderr, "silc: %s\n", strerror(errno));
110 /* We'll take home path from /etc/passwd file to be sure. */
111 snprintf(filename, sizeof(filename) - 1, "%s/", get_irssi_dir());
112 snprintf(servfilename, sizeof(servfilename) - 1, "%s/serverkeys",
114 snprintf(clientfilename, sizeof(clientfilename) - 1, "%s/clientkeys",
116 snprintf(friendsfilename, sizeof(friendsfilename) - 1, "%s/friends",
120 * Check ~/.silc directory
122 if ((stat(filename, &st)) == -1) {
123 /* If dir doesn't exist */
124 if (errno == ENOENT) {
125 if (pw->pw_uid == geteuid()) {
126 if ((mkdir(filename, 0755)) == -1) {
127 fprintf(stderr, "Couldn't create `%s' directory\n", filename);
131 fprintf(stderr, "Couldn't create `%s' directory due to a wrong uid!\n",
136 fprintf(stderr, "%s\n", strerror(errno));
141 /* Check the owner of the dir */
142 if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
143 fprintf(stderr, "You don't seem to own `%s' directory\n",
149 /* Check the permissions of the dir */
150 if ((st.st_mode & 0777) != 0755) {
151 if ((chmod(filename, 0755)) == -1) {
152 fprintf(stderr, "Permissions for `%s' directory must be 0755\n",
161 * Check ~./silc/serverkeys directory
163 if ((stat(servfilename, &st)) == -1) {
164 /* If dir doesn't exist */
165 if (errno == ENOENT) {
166 if (pw->pw_uid == geteuid()) {
167 if ((mkdir(servfilename, 0755)) == -1) {
168 fprintf(stderr, "Couldn't create `%s' directory\n", servfilename);
172 fprintf(stderr, "Couldn't create `%s' directory due to a wrong uid!\n",
177 fprintf(stderr, "%s\n", strerror(errno));
183 * Check ~./silc/clientkeys directory
185 if ((stat(clientfilename, &st)) == -1) {
186 /* If dir doesn't exist */
187 if (errno == ENOENT) {
188 if (pw->pw_uid == geteuid()) {
189 if ((mkdir(clientfilename, 0755)) == -1) {
190 fprintf(stderr, "Couldn't create `%s' directory\n", clientfilename);
194 fprintf(stderr, "Couldn't create `%s' directory due to a wrong uid!\n",
199 fprintf(stderr, "%s\n", strerror(errno));
205 * Check ~./silc/friends directory
207 if ((stat(friendsfilename, &st)) == -1) {
208 /* If dir doesn't exist */
209 if (errno == ENOENT) {
210 if (pw->pw_uid == geteuid()) {
211 if ((mkdir(friendsfilename, 0755)) == -1) {
212 fprintf(stderr, "Couldn't create `%s' directory\n", friendsfilename);
216 fprintf(stderr, "Couldn't create `%s' directory due to a wrong uid!\n",
221 fprintf(stderr, "%s\n", strerror(errno));
227 * Check Public and Private keys
229 snprintf(file_public_key, sizeof(file_public_key) - 1, "%s%s",
230 filename, SILC_CLIENT_PUBLIC_KEY_NAME);
231 snprintf(file_private_key, sizeof(file_private_key) - 1, "%s%s",
232 filename, SILC_CLIENT_PRIVATE_KEY_NAME);
234 if ((stat(file_public_key, &st)) == -1) {
235 /* If file doesn't exist */
236 if (errno == ENOENT) {
237 fprintf(stdout, "Running SILC for the first time\n");
238 silc_create_key_pair(SILC_CLIENT_DEF_PKCS,
239 SILC_CLIENT_DEF_PKCS_LEN,
240 file_public_key, file_private_key, NULL,
241 NULL, NULL, NULL, NULL, FALSE);
242 printf("Press <Enter> to continue...\n");
245 fprintf(stderr, "%s\n", strerror(errno));
250 /* Check the owner of the public key */
251 if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
252 fprintf(stderr, "You don't seem to own your public key!?\n");
256 if ((stat(file_private_key, &st)) == -1) {
257 /* If file doesn't exist */
258 if (errno == ENOENT) {
259 fprintf(stdout, "Your private key doesn't exist\n");
260 silc_create_key_pair(SILC_CLIENT_DEF_PKCS,
261 SILC_CLIENT_DEF_PKCS_LEN,
262 file_public_key, file_private_key, NULL,
263 NULL, NULL, NULL, NULL, FALSE);
264 printf("Press <Enter> to continue...\n");
267 fprintf(stderr, "%s\n", strerror(errno));
272 /* Check the owner of the private key */
273 if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
274 fprintf(stderr, "You don't seem to own your private key!?\n");
278 /* Check the permissions for the private key */
279 if ((st.st_mode & 0777) != 0600) {
280 fprintf(stderr, "Wrong permissions in your private key file `%s'!\n"
281 "Trying to change them ... ", file_private_key);
282 if ((chmod(file_private_key, 0600)) == -1) {
284 "Failed to change permissions for private key file!\n"
285 "Permissions for your private key file must be 0600.\n");
288 fprintf(stderr, "Done.\n\n");
291 /* See if the key has expired. */
292 modtime = st.st_mtime; /* last modified */
293 curtime = time(0) - modtime;
295 /* 86400 is seconds in a day. */
296 if (curtime >= (86400 * SILC_CLIENT_KEY_EXPIRES)) {
300 "----------------------------------------------------\n"
301 "Your private key has expired and needs to be\n"
302 "recreated. Would you like to create a new key pair\n"
303 "now? If you answer Yes, the new key will expire in\n"
304 "%d days from today. If you answer No, the old key\n"
305 "will expire again in %d days from today.\n"
306 "----------------------------------------------------\n",
307 SILC_CLIENT_KEY_EXPIRES, SILC_CLIENT_KEY_EXPIRES);
309 answer = silc_get_input("Would you like to create a new key pair "
310 "([y]/n)?: ", FALSE);
311 if (!answer || answer[0] == 'Y' || answer[0] == 'y') {
312 silc_create_key_pair(SILC_CLIENT_DEF_PKCS,
313 SILC_CLIENT_DEF_PKCS_LEN,
314 file_public_key, file_private_key, NULL,
315 NULL, NULL, NULL, NULL, FALSE);
316 printf("Press <Enter> to continue...\n");
321 utim.actime = time(NULL);
322 utim.modtime = time(NULL);
323 utime(file_private_key, &utim);
332 /* Loads public and private key from files. */
334 int silc_client_load_keys(SilcClient client)
336 char pub[256], prv[256];
340 SILC_LOG_DEBUG(("Loading public and private keys"));
342 pw = getpwuid(getuid());
346 memset(prv, 0, sizeof(prv));
347 snprintf(prv, sizeof(prv) - 1, "%s/%s",
348 get_irssi_dir(), SILC_CLIENT_PRIVATE_KEY_NAME);
350 memset(pub, 0, sizeof(pub));
351 snprintf(pub, sizeof(pub) - 1, "%s/%s",
352 get_irssi_dir(), SILC_CLIENT_PUBLIC_KEY_NAME);
354 /* Try loading first with "" passphrase, for those that didn't set
355 passphrase for private key, and only if that fails let it prompt
357 ret = silc_load_key_pair(pub, prv, "", &client->pkcs, &client->public_key,
358 &client->private_key);
360 ret = silc_load_key_pair(pub, prv, NULL, &client->pkcs,
361 &client->public_key, &client->private_key);