The SILC Project

source navigation ]
identifier search ]
freetext search ]
file search ]

silc/silc/clientutil.c

  1 /*
  2 
  3   client.c
  4 
  5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
  6 
  7   Copyright (C) 1997 - 2000 Pekka Riikonen
  8 
  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.
 13   
 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.
 18 
 19 */
 20 /* $Id: clientutil.c,v 1.19 2002/02/24 11:14:43 priikone Exp $ */
 21 
 22 #include "clientincludes.h"
 23 
 24 /* Routine used to print lines to window. This can split the
 25    line neatly if a word would overlap the line. */
 26 
 27 void silc_print_to_window(WINDOW *win, char *message)
 28 {
 29   int str_len, len;
 30 
 31   str_len = strlen(message);
 32  
 33   if (str_len > COLS - 1) {
 34     /* Split overlapping words to next line */
 35     /* XXX In principal this is wrong as this modifies the original
 36        string as it replaces the last ' ' with '\n'. This could be done
 37        with little more work so that it would not replace anything. */
 38     len = COLS - 1;
 39     while (1) {
 40 
 41       while (len && message[len] != ' ')
 42         len--;
 43 
 44       if (!len)
 45         break;
 46 
 47       message[len] = '\n';
 48       len += COLS - 1;
 49       if (len > str_len)
 50         break;
 51     }
 52   }
 53 
 54   wprintw(win, "%s", message);
 55   wrefresh(win);
 56 }
 57 
 58 /* Prints message to the screen. This is used to print the messages
 59    user is typed and message that came on channels. */
 60 
 61 void silc_print(SilcClient client, char *msg, ...)
 62 {
 63   va_list vp;
 64   char message[2048];
 65   SilcClientInternal app = client->application;
 66   
 67   memset(message, 0, sizeof(message));
 68   strncat(message, "\n ", 2);
 69 
 70   va_start(vp, msg);
 71   vsprintf(message + 1, msg, vp);
 72   va_end(vp);
 73   
 74   /* Print the message */
 75   silc_print_to_window(app->screen->output_win[0], message);
 76 }
 77 
 78 /* Returns user's mail path */
 79 
 80 char *silc_get_mail_path()
 81 {
 82   char pathbuf[MAXPATHLEN];
 83   char *path;
 84 
 85 #ifndef _PATH_MAILDIR
 86 #define _PATH_MAILDIR "/var/mail"
 87 #endif
 88   
 89   path = getenv("MAIL");
 90   if (path) {
 91     strncpy(pathbuf, path, strlen(path));
 92   } else {
 93     strcpy(pathbuf, _PATH_MAILDIR);
 94     strcat(pathbuf, "/");
 95     strcat(pathbuf, silc_get_username());
 96   }
 97 
 98   return strdup(pathbuf);
 99 }
100 
101 /* gets the number of the user's mails, if possible */
102 
103 int silc_get_number_of_emails()
104 {
105   FILE *tl;
106   int num = 0;
107   char *filename;
108   char data[1024];
109   
110   filename = silc_get_mail_path();
111   
112   tl = fopen(filename, "r");
113   if (!tl) {
114     fprintf(stderr, "Couldn't open mail file (%s).\n", filename);
115   } else {
116     while((fscanf(tl, "%s", data)) != EOF) { 
117       if(!strcmp(data, "From:"))
118         num++;
119     }
120     
121     fclose(tl);
122   }
123   
124   return num;
125 }
126 
127 /* Returns time til next minute changes. Used to update the clock when
128    needed. */
129 
130 int silc_client_time_til_next_min()
131 {
132   time_t curtime;
133   struct tm *min;
134   
135   curtime = time(0);
136   min = localtime(&curtime);
137   
138   return 60 - min->tm_sec;
139 }
140 
141 /* Asks yes/no from user on the input line. Returns TRUE on "yes" and
142    FALSE on "no". */
143 
144 int silc_client_ask_yes_no(SilcClient client, char *prompt)
145 {
146   SilcClientInternal app = (SilcClientInternal)client->application;
147   char answer[4];
148   int ret;
149 
150  again:
151   silc_screen_input_reset(app->screen);
152 
153   /* Print prompt */
154   wattroff(app->screen->input_win, A_INVIS);
155   silc_screen_input_print_prompt(app->screen, prompt);
156 
157   /* Get string */
158   memset(answer, 0, sizeof(answer));
159   echo();
160   wgetnstr(app->screen->input_win, answer, sizeof(answer));
161   if (!strncasecmp(answer, "yes", strlen(answer)) ||
162       !strncasecmp(answer, "y", strlen(answer))) {
163     ret = TRUE;
164   } else if (!strncasecmp(answer, "no", strlen(answer)) ||
165              !strncasecmp(answer, "n", strlen(answer))) {
166     ret = FALSE;
167   } else {
168     silc_say(client, app->conn, "Type yes or no");
169     goto again;
170   }
171   noecho();
172 
173   silc_screen_input_reset(app->screen);
174 
175   return ret;
176 }
177 
178 /* Lists supported (builtin) ciphers */
179 
180 void silc_client_list_ciphers()
181 {
182   char *ciphers = silc_cipher_get_supported();
183   fprintf(stdout, "%s\n", ciphers);
184   silc_free(ciphers);
185 }
186 
187 /* Lists supported (builtin) hash functions */
188 
189 void silc_client_list_hash_funcs()
190 {
191   char *hash = silc_hash_get_supported();
192   fprintf(stdout, "%s\n", hash);
193   silc_free(hash);
194 }
195 
196 /* Lists supported PKCS algorithms */
197 
198 void silc_client_list_pkcs()
199 {
200   char *pkcs = silc_pkcs_get_supported();
201   fprintf(stdout, "%s\n", pkcs);
202   silc_free(pkcs);
203 }
204 
205 /* Displays input prompt on command line and takes input data from user */
206 
207 char *silc_client_get_input(const char *prompt)
208 {
209   char input[2048];
210   int fd;
211 
212   fd = open("/dev/tty", O_RDONLY);
213   if (fd < 0) {
214     fprintf(stderr, "silc: %s\n", strerror(errno));
215     return NULL;
216   }
217 
218   memset(input, 0, sizeof(input));
219 
220   printf("%s", prompt);
221   fflush(stdout);
222 
223   if ((read(fd, input, sizeof(input))) < 0) {
224     fprintf(stderr, "silc: %s\n", strerror(errno));
225     return NULL;
226   }
227 
228   if (strlen(input) <= 1)
229     return NULL;
230 
231   if (strchr(input, '\n'))
232     *strchr(input, '\n') = '\0';
233 
234   return strdup(input);
235 }
236 
237 /* Displays prompt on command line and takes passphrase with echo 
238    off from user. */
239 
240 char *silc_client_get_passphrase(const char *prompt)
241 {
242 #if 0
243   char input[2048];
244   char *ret;
245   int fd;
246   struct termios to;
247   struct termios to_old;
248 
249   fd = open("/dev/tty", O_RDONLY);
250   if (fd < 0) {
251     fprintf(stderr, "silc: %s\n", strerror(errno));
252     return NULL;
253   }
254 
255   signal(SIGINT, SIG_IGN);
256 
257   /* Get terminal info */
258   tcgetattr(fd, &to);
259   to_old = to;
260 
261   /* Echo OFF */
262   to.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
263   tcsetattr(fd, TCSANOW, &to);
264 
265   memset(input, 0, sizeof(input));
266 
267   printf("%s", prompt);
268   fflush(stdout);
269 
270   if ((read(fd, input, sizeof(input))) < 0) {
271     fprintf(stderr, "silc: %s\n", strerror(errno));
272     return NULL;
273   }
274 
275   if (strlen(input) <= 1) {
276     tcsetattr(fd, TCSANOW, &to_old);
277     return NULL;
278   }
279 
280   if (strchr(input, '\n'))
281     *strchr(input, '\n') = '\0';
282 
283   /* Restore old terminfo */
284   tcsetattr(fd, TCSANOW, &to_old);
285   signal(SIGINT, SIG_DFL);
286 
287   ret = silc_calloc(strlen(input), sizeof(char));
288   memcpy(ret, input, strlen(input));
289   memset(input, 0, sizeof(input));
290   return ret;
291 #else
292   return NULL;
293 #endif
294 }
295 
296 /* Returns identifier string for public key generation. */
297 
298 char *silc_client_create_identifier()
299 {
300   char *username = NULL, *realname = NULL;
301   char hostname[256], email[256];
302   
303   /* Get realname */
304   realname = silc_get_real_name();
305 
306   /* Get hostname */
307   memset(hostname, 0, sizeof(hostname));
308   gethostname(hostname, sizeof(hostname));
309 
310   /* Get username (mandatory) */
311   username = silc_get_username();
312   if (!username)
313     return NULL;
314 
315   /* Create default email address, whether it is right or not */
316   snprintf(email, sizeof(email), "%s@%s", username, hostname);
317 
318   return silc_pkcs_encode_identifier(username, hostname, realname, email,
319                                      NULL, NULL);
320 }
321 
322 /* Creates new public key and private key pair. This is used only
323    when user wants to create new key pair from command line. */
324 
325 int silc_client_create_key_pair(char *pkcs_name, int bits,
326                                 char *public_key, char *private_key,
327                                 char *identifier, 
328                                 SilcPublicKey *ret_pub_key,
329                                 SilcPrivateKey *ret_prv_key)
330 {
331   SilcPKCS pkcs;
332   SilcPublicKey pub_key;
333   SilcPrivateKey prv_key;
334   SilcRng rng;
335   unsigned char *key;
336   SilcUInt32 key_len;
337   char line[256];
338   char *pkfile = NULL, *prvfile = NULL;
339 
340   if (!pkcs_name || !public_key || !private_key)
341     printf("\
342 New pair of keys will be created.  Please, answer to following questions.\n\
343 ");
344 
345   if (!pkcs_name) {
346   again_name:
347     pkcs_name = 
348       silc_client_get_input("PKCS name (l to list names) [rsa]: ");
349     if (!pkcs_name)
350       pkcs_name = strdup("rsa");
351 
352     if (*pkcs_name == 'l' || *pkcs_name == 'L') {
353       silc_client_list_pkcs();
354       silc_free(pkcs_name);
355       goto again_name;
356     }
357   }
358 
359   if (!silc_pkcs_is_supported(pkcs_name)) {
360     fprintf(stderr, "Unknown PKCS `%s'", pkcs_name);
361     return FALSE;
362   }
363 
364   if (!bits) {
365     char *length = NULL;
366     length = 
367       silc_client_get_input("Key length in bits [1024]: ");
368     if (!length)
369       bits = 1024;
370     else
371       bits = atoi(length);
372   }
373 
374   if (!identifier) {
375     char *def = silc_client_create_identifier();
376 
377     memset(line, 0, sizeof(line));
378     if (def)
379       snprintf(line, sizeof(line), "Identifier [%s]: ", def);
380     else
381       snprintf(line, sizeof(line),
382                "Identifier (eg. UN=jon, HN=jon.dummy.com, "
383                "RN=Jon Johnson, E=jon@dummy.com): ");
384 
385     while (!identifier) {
386       identifier = silc_client_get_input(line);
387       if (!identifier && def)
388         identifier = strdup(def);
389     }
390 
391     if (def)
392       silc_free(def);
393   }
394 
395   rng = silc_rng_alloc();
396   silc_rng_init(rng);
397   silc_rng_global_init(rng);
398 
399   if (!public_key) {
400     memset(line, 0, sizeof(line));
401     snprintf(line, sizeof(line), "Public key filename [%s] ", 
402              SILC_CLIENT_PUBLIC_KEY_NAME);
403     pkfile = silc_client_get_input(line);
404     if (!pkfile)
405       pkfile = SILC_CLIENT_PUBLIC_KEY_NAME;
406   } else {
407     pkfile = public_key;
408   }
409 
410   if (!private_key) {
411     memset(line, 0, sizeof(line));
412     snprintf(line, sizeof(line), "Public key filename [%s] ", 
413              SILC_CLIENT_PRIVATE_KEY_NAME);
414     prvfile = silc_client_get_input(line);
415     if (!prvfile)
416       prvfile = SILC_CLIENT_PRIVATE_KEY_NAME;
417   } else {
418     prvfile = private_key;
419   }
420 
421   /* Generate keys */
422   silc_pkcs_alloc(pkcs_name, &pkcs);
423   pkcs->pkcs->init(pkcs->context, bits, rng);
424 
425   /* Save public key into file */
426   key = silc_pkcs_get_public_key(pkcs, &key_len);
427   pub_key = silc_pkcs_public_key_alloc(pkcs->pkcs->name, identifier,
428                                        key, key_len);
429   silc_pkcs_save_public_key(pkfile, pub_key, SILC_PKCS_FILE_PEM);
430   if (ret_pub_key)
431     *ret_pub_key = pub_key;
432 
433   memset(key, 0, sizeof(key_len));
434   silc_free(key);
435 
436   /* Save private key into file */
437   key = silc_pkcs_get_private_key(pkcs, &key_len);
438   prv_key = silc_pkcs_private_key_alloc(pkcs->pkcs->name, key, key_len);
439 
440   silc_pkcs_save_private_key(prvfile, prv_key, NULL, SILC_PKCS_FILE_BIN);
441   if (ret_prv_key)
442     *ret_prv_key = prv_key;
443 
444   printf("Public key has been saved into `%s'.\n", pkfile);
445   printf("Private key has been saved into `%s'.\n", prvfile);
446   printf("Press <Enter> to continue...\n");
447   getchar();
448 
449   memset(key, 0, sizeof(key_len));
450   silc_free(key);
451 
452   silc_rng_free(rng);
453   silc_pkcs_free(pkcs);
454 
455   return TRUE;
456 }
457 
458 /* This checks stats for various SILC files and directories. First it 
459    checks if ~/.silc directory exist and is owned by the correct user. If 
460    it doesn't exist, it will create the directory. After that it checks if
461    user's Public and Private key files exists and that they aren't expired.
462    If they doesn't exist or they are expired, they will be (re)created
463    after return. */
464 
465 int silc_client_check_silc_dir()
466 {
467   char filename[256], file_public_key[256], file_private_key[256];
468   char servfilename[256], clientfilename[256];
469   char *identifier;
470   struct stat st;
471   struct passwd *pw;
472   int firstime = FALSE;
473   time_t curtime, modtime;
474 
475   SILC_LOG_DEBUG(("Checking ~./silc directory"));
476 
477   memset(filename, 0, sizeof(filename));
478   memset(file_public_key, 0, sizeof(file_public_key));
479   memset(file_private_key, 0, sizeof(file_private_key));
480 
481   pw = getpwuid(getuid());
482   if (!pw) {
483     fprintf(stderr, "silc: %s\n", strerror(errno));
484     return FALSE;
485   }
486 
487   identifier = silc_client_create_identifier();
488 
489   /* We'll take home path from /etc/passwd file to be sure. */
490   snprintf(filename, sizeof(filename) - 1, "%s/.silc/", pw->pw_dir);
491   snprintf(servfilename, sizeof(servfilename) - 1, "%s/.silc/serverkeys", 
492            pw->pw_dir);
493   snprintf(clientfilename, sizeof(clientfilename) - 1, "%s/.silc/clientkeys", 
494            pw->pw_dir);
495 
496   /*
497    * Check ~/.silc directory
498    */
499   if ((stat(filename, &st)) == -1) {
500     /* If dir doesn't exist */
501     if (errno == ENOENT) {
502       if (pw->pw_uid == geteuid()) {
503         if ((mkdir(filename, 0755)) == -1) {
504           fprintf(stderr, "Couldn't create `%s' directory\n", filename);
505           return FALSE;
506         }
507 
508         /* Directory was created. First time running SILC */
509         firstime = TRUE;
510       } else {
511         fprintf(stderr, "Couldn't create `%s' directory due to a wrong uid!\n",
512                 filename);
513         return FALSE;
514       }
515     } else {
516       fprintf(stderr, "%s\n", strerror(errno));
517       return FALSE;
518     }
519   } else {
520     
521     /* Check the owner of the dir */
522     if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { 
523       fprintf(stderr, "You don't seem to own `%s' directory\n",
524               filename);
525       return FALSE;
526     }
527     
528     /* Check the permissions of the dir */
529     if ((st.st_mode & 0777) != 0755) {
530       if ((chmod(filename, 0755)) == -1) {
531         fprintf(stderr, "Permissions for `%s' directory must be 0755\n", 
532                 filename);
533         return FALSE;
534       }
535     }
536   }
537 
538   /*
539    * Check ~./silc/serverkeys directory
540    */
541   if ((stat(servfilename, &st)) == -1) {
542     /* If dir doesn't exist */
543     if (errno == ENOENT) {
544       if (pw->pw_uid == geteuid()) {
545         if ((mkdir(servfilename, 0755)) == -1) {
546           fprintf(stderr, "Couldn't create `%s' directory\n", servfilename);
547           return FALSE;
548         }
549       } else {
550         fprintf(stderr, "Couldn't create `%s' directory due to a wrong uid!\n",
551                 servfilename);
552         return FALSE;
553       }
554     } else {
555       fprintf(stderr, "%s\n", strerror(errno));
556       return FALSE;
557     }
558   }
559   
560   /*
561    * Check ~./silc/clientkeys directory
562    */
563   if ((stat(clientfilename, &st)) == -1) {
564     /* If dir doesn't exist */
565     if (errno == ENOENT) {
566       if (pw->pw_uid == geteuid()) {
567         if ((mkdir(clientfilename, 0755)) == -1) {
568           fprintf(stderr, "Couldn't create `%s' directory\n", clientfilename);
569           return FALSE;
570         }
571       } else {
572         fprintf(stderr, "Couldn't create `%s' directory due to a wrong uid!\n",
573                 clientfilename);
574         return FALSE;
575       }
576     } else {
577       fprintf(stderr, "%s\n", strerror(errno));
578       return FALSE;
579     }
580   }
581   
582   /*
583    * Check Public and Private keys
584    */
585   snprintf(file_public_key, sizeof(file_public_key) - 1, "%s%s", 
586            filename, SILC_CLIENT_PUBLIC_KEY_NAME);
587   snprintf(file_private_key, sizeof(file_private_key) - 1, "%s%s", 
588            filename, SILC_CLIENT_PRIVATE_KEY_NAME);
589   
590   /* If running SILC first time */
591   if (firstime) {
592     fprintf(stdout, "Running SILC for the first time\n");
593     silc_client_create_key_pair(SILC_CLIENT_DEF_PKCS, 
594                                 SILC_CLIENT_DEF_PKCS_LEN,
595                                 file_public_key, file_private_key, 
596                                 identifier, NULL, NULL);
597     return TRUE;
598   }
599   
600   if ((stat(file_public_key, &st)) == -1) {
601     /* If file doesn't exist */
602     if (errno == ENOENT) {
603       fprintf(stdout, "Your public key doesn't exist\n");
604       silc_client_create_key_pair(SILC_CLIENT_DEF_PKCS, 
605                                   SILC_CLIENT_DEF_PKCS_LEN,
606                                   file_public_key, 
607                                   file_private_key, identifier, NULL, NULL);
608     } else {
609       fprintf(stderr, "%s\n", strerror(errno));
610       return FALSE;
611     }
612   }
613 
614   if ((stat(file_private_key, &st)) == -1) {
615     /* If file doesn't exist */
616     if (errno == ENOENT) {
617       fprintf(stdout, "Your private key doesn't exist\n");
618       silc_client_create_key_pair(SILC_CLIENT_DEF_PKCS, 
619                                   SILC_CLIENT_DEF_PKCS_LEN,
620                                   file_public_key, 
621                                   file_private_key, identifier, NULL, NULL);
622     } else {
623       fprintf(stderr, "%s\n", strerror(errno));
624       return FALSE;
625     }
626   }
627     
628   /* Check the owner of the public key */
629   if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { 
630     fprintf(stderr, "You don't seem to own your public key!?\n");
631     return FALSE;
632   }
633   
634   /* Check the owner of the private key */
635   if (st.st_uid != 0 && st.st_uid != pw->pw_uid) { 
636     fprintf(stderr, "You don't seem to own your private key!?\n");
637     return FALSE;
638   }
639     
640   /* Check the permissions for the private key */
641   if ((st.st_mode & 0777) != 0600) {
642     fprintf(stderr, "Wrong permissions in your private key file `%s'!\n"
643             "Trying to change them ... ", file_private_key);
644     if ((chmod(file_private_key, 0600)) == -1) {
645       fprintf(stderr,
646               "Failed to change permissions for private key file!\n" 
647               "Permissions for your private key file must be 0600.\n");
648       return FALSE;
649     }
650     fprintf(stderr, "Done.\n\n");
651   }
652 
653   /* See if the key has expired. */
654   modtime = st.st_mtime;        /* last modified */
655   curtime = time(0) - modtime;
656     
657   /* 86400 is seconds in a day. */
658   if (curtime >= (86400 * SILC_CLIENT_KEY_EXPIRES)) {
659     fprintf(stdout, 
660             "--------------------------------------------------\n"
661             "Your private key has expired and needs to be\n" 
662             "recreated.  This will be done automatically now.\n"
663             "Your new key will expire in %d days from today.\n"
664             "--------------------------------------------------\n",
665             SILC_CLIENT_KEY_EXPIRES);
666 
667     silc_client_create_key_pair(SILC_CLIENT_DEF_PKCS, 
668                                 SILC_CLIENT_DEF_PKCS_LEN,
669                                 file_public_key, 
670                                 file_private_key, identifier, NULL, NULL);
671   }
672   
673   if (identifier)
674     silc_free(identifier);
675 
676   return TRUE;
677 }
678 
679 /* Loads public and private key from files. */
680 
681 int silc_client_load_keys(SilcClient client)
682 {
683   char filename[256];
684   struct passwd *pw;
685 
686   SILC_LOG_DEBUG(("Loading public and private keys"));
687 
688   pw = getpwuid(getuid());
689   if (!pw)
690     return FALSE;
691 
692   memset(filename, 0, sizeof(filename));
693   snprintf(filename, sizeof(filename) - 1, "%s/.silc/%s", 
694            pw->pw_dir, SILC_CLIENT_PRIVATE_KEY_NAME);
695 
696   if (silc_pkcs_load_private_key(filename, &client->private_key,
697                                  SILC_PKCS_FILE_BIN) == FALSE)
698     if (silc_pkcs_load_private_key(filename, &client->private_key,
699                                    SILC_PKCS_FILE_PEM) == FALSE)
700       return FALSE;
701 
702   memset(filename, 0, sizeof(filename));
703   snprintf(filename, sizeof(filename) - 1, "%s/.silc/%s", 
704            pw->pw_dir, SILC_CLIENT_PUBLIC_KEY_NAME);
705 
706   if (silc_pkcs_load_public_key(filename, &client->public_key,
707                                 SILC_PKCS_FILE_PEM) == FALSE)
708     if (silc_pkcs_load_public_key(filename, &client->public_key,
709                                   SILC_PKCS_FILE_BIN) == FALSE)
710       return FALSE;
711 
712   return TRUE;
713 }
714 
715 /* Dumps the public key on screen. Used from the command line option. */
716 
717 int silc_client_show_key(char *keyfile)
718 {
719   SilcPublicKey public_key;
720   SilcPublicKeyIdentifier ident;
721   char *fingerprint;
722   unsigned char *pk;
723   SilcUInt32 pk_len;
724   SilcPKCS pkcs;
725   int key_len = 0;
726 
727   if (silc_pkcs_load_public_key(keyfile, &public_key,
728                                 SILC_PKCS_FILE_PEM) == FALSE)
729     if (silc_pkcs_load_public_key(keyfile, &public_key,
730                                   SILC_PKCS_FILE_BIN) == FALSE) {
731       fprintf(stderr, "Could not load public key file `%s'\n", keyfile);
732       return FALSE;
733     }
734 
735   ident = silc_pkcs_decode_identifier(public_key->identifier);
736 
737   pk = silc_pkcs_public_key_encode(public_key, &pk_len);
738   fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
739 
740   if (silc_pkcs_alloc(public_key->name, &pkcs)) {
741     key_len = silc_pkcs_public_key_set(pkcs, public_key);
742     silc_pkcs_free(pkcs);
743   }
744 
745   printf("Public key file    : %s\n", keyfile);
746   printf("Algorithm          : %s\n", public_key->name);
747   if (key_len)
748     printf("Key length (bits)  : %d\n", key_len);
749   if (ident->realname)
750     printf("Real name          : %s\n", ident->realname);
751   if (ident->username)
752     printf("Username           : %s\n", ident->username);
753   if (ident->host)
754     printf("Hostname           : %s\n", ident->host);
755   if (ident->email)
756     printf("Email              : %s\n", ident->email);
757   if (ident->org)
758     printf("Organization       : %s\n", ident->org);
759   if (ident->country)
760     printf("Country            : %s\n", ident->country);
761   printf("Fingerprint (SHA1) : %s\n", fingerprint); 
762 
763   fflush(stdout);
764 
765   silc_free(fingerprint);
766   silc_free(pk);
767   silc_pkcs_public_key_free(public_key);
768   silc_pkcs_free_identifier(ident);
769 
770   return TRUE;
771 }
772 

This page was automatically generated by the LXR engine.
Free-text search provided by Glimpse