From 9d79cbd71baf62a6a4465240ce17d6b19077f488 Mon Sep 17 00:00:00 2001 From: Pekka Riikonen Date: Sun, 8 Apr 2001 13:43:33 +0000 Subject: [PATCH] updates. --- CHANGES | 8 ++ Makefile.am | 11 +-- apps/silc/clientutil.c | 61 +++---------- apps/silc/clientutil.h | 2 - apps/silc/silc.c | 4 +- apps/silcd/server.c | 60 ++----------- apps/silcd/serverconfig.c | 114 +++++++++++------------- apps/silcd/serverconfig.h | 8 ++ apps/silcd/silcd.c | 183 ++++++++++++++++++++++++++++++++++---- apps/silcd/silcd.h | 12 +-- doc/example_silcd.conf | 8 ++ lib/silcutil/silcutil.c | 57 +++++++++++- lib/silcutil/silcutil.h | 2 + 13 files changed, 327 insertions(+), 203 deletions(-) diff --git a/CHANGES b/CHANGES index 05f1a0c9..b7f8a672 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +Sun Apr 8 15:30:56 EEST 2001 Pekka Riikonen + + * Made the key generation options to the silcd program. Added + -C option, equivalent to client's option. + + * Added new [ServerKeys] config section to the server. It + configures the server's public and private key. + Sun Apr 8 01:37:21 EEST 2001 Pekka Riikonen * Made preliminary `make install' work. diff --git a/Makefile.am b/Makefile.am index e51b999f..da17d191 100644 --- a/Makefile.am +++ b/Makefile.am @@ -44,19 +44,20 @@ install-dirs: -mkdir -p $(docdir) generate-server-key: - -umask 022; - -echo Generating SILC Server key into $(etcdir) - -$(sbindir)/silcd -k $(etcdir) + -$(sbindir)/silcd -C $(etcdir) sim-install: - -echo Installing SIM modules into $(modulesdir) -cp -fR $(srcdir)/lib/silcsim/modules/*.so $(modulesdir)/ doc-install: -cp -fR $(srcdir)/doc/* $(docdir)/ + -cp -fR $(srcdir)/COPYING $(docdir)/ + -cp -fR $(srcdir)/README $(docdir)/ + -cp -fR $(srcdir)/INSTALL $(docdir)/ + -cp -fR $(srcdir)/TODO $(docdir)/ etc-install: -cp -fR $(srcdir)/doc/example_silcd.conf $(etcdir)/silcd.conf -cp -fR $(srcdir)/doc/example_silc.conf $(etcdir)/silc.conf -install-data-hook: install-dirs generate-server-key sim-install doc-install +install-data-hook: install-dirs generate-server-key sim-install doc-install etc-install diff --git a/apps/silc/clientutil.c b/apps/silc/clientutil.c index 0686a64e..4070b419 100644 --- a/apps/silc/clientutil.c +++ b/apps/silc/clientutil.c @@ -124,53 +124,6 @@ int silc_get_number_of_emails() return num; } -/* Returns the username of the user. If the global variable LOGNAME - does not exists we will get the name from the password file. */ - -char *silc_get_username() -{ - char *logname = NULL; - - logname = strdup(getenv("LOGNAME")); - if (!logname) { - logname = getlogin(); - if (!logname) { - struct passwd *pw; - - pw = getpwuid(getuid()); - if (!pw) { - fprintf(stderr, "silc_get_username: %s\n", strerror(errno)); - return NULL; - } - - logname = strdup(pw->pw_name); - } - } - - return logname; -} - -/* Returns the real name of ther user. */ - -char *silc_get_real_name() -{ - char *realname = NULL; - struct passwd *pw; - - pw = getpwuid(getuid()); - if (!pw) { - fprintf(stderr, "silc_get_username: %s\n", strerror(errno)); - return NULL; - } - - if (strchr(pw->pw_gecos, ',')) - *strchr(pw->pw_gecos, ',') = 0; - - realname = strdup(pw->pw_gecos); - - return realname; -} - /* Returns time til next minute changes. Used to update the clock when needed. */ @@ -226,21 +179,27 @@ int silc_client_ask_yes_no(SilcClient client, char *prompt) void silc_client_list_ciphers() { - + char *ciphers = silc_cipher_get_supported(); + fprintf(stdout, "%s\n", ciphers); + silc_free(ciphers); } /* Lists supported (builtin) hash functions */ void silc_client_list_hash_funcs() { - + char *hash = silc_hash_get_supported(); + fprintf(stdout, "%s\n", hash); + silc_free(hash); } /* Lists supported PKCS algorithms */ void silc_client_list_pkcs() { - + char *pkcs = silc_pkcs_get_supported(); + fprintf(stdout, "%s\n", pkcs); + silc_free(pkcs); } /* Displays input prompt on command line and takes input data from user */ @@ -482,7 +441,7 @@ New pair of keys will be created. Please, answer to following questions.\n\ if (ret_prv_key) *ret_prv_key = prv_key; - printf("Public key has been save into `%s'.\n", pkfile); + printf("Public key has been saved into `%s'.\n", pkfile); printf("Private key has been saved into `%s'.\n", prvfile); printf("Press to continue...\n"); getchar(); diff --git a/apps/silc/clientutil.h b/apps/silc/clientutil.h index 38f0d9e8..9d796f34 100644 --- a/apps/silc/clientutil.h +++ b/apps/silc/clientutil.h @@ -26,8 +26,6 @@ void silc_print_to_window(WINDOW *win, char *message); void silc_print(SilcClient client, char *msg, ...); char *silc_get_mail_path(); int silc_get_number_of_emails(); -char *silc_get_username(); -char *silc_get_real_name(); int silc_client_time_til_next_min(); int silc_client_ask_yes_no(SilcClient client, char *prompt); char *silc_client_get_input(const char *prompt); diff --git a/apps/silc/silc.c b/apps/silc/silc.c index fa67c083..5a64e7c9 100644 --- a/apps/silc/silc.c +++ b/apps/silc/silc.c @@ -72,9 +72,9 @@ static char *opt_cipher = NULL; static char *opt_public_key = NULL; static char *opt_private_key = NULL; static char *opt_config_file = NULL; -static int opt_no_silcrc = FALSE; +static bool opt_no_silcrc = FALSE; -static int opt_create_keypair = FALSE; +static bool opt_create_keypair = FALSE; static char *opt_pkcs = NULL; static int opt_bits = 0; diff --git a/apps/silcd/server.c b/apps/silcd/server.c index 12769c44..87517338 100644 --- a/apps/silcd/server.c +++ b/apps/silcd/server.c @@ -120,6 +120,14 @@ int silc_server_init(SilcServer server) assert(server); assert(server->config); + /* Set public and private keys */ + server->public_key = server->config->server_keys->public_key; + server->private_key = server->config->server_keys->private_key; + if (!server->public_key || !server->private_key) { + SILC_LOG_ERROR(("Server public key and/or private key does not exist")); + return FALSE; + } + /* XXX After server is made as Silc Server Library this can be given as argument, for now this is hard coded */ server->params = silc_calloc(1, sizeof(*server->params)); @@ -152,58 +160,6 @@ int silc_server_init(SilcServer server) /* Initialize none cipher */ silc_cipher_alloc("none", &server->none_cipher); - /* XXXXX Generate RSA key pair */ - { - unsigned char *public_key; - unsigned char *private_key; - uint32 pk_len, prv_len; - struct stat st; - - if (stat("pubkey.pub", &st) < 0 && stat("privkey.prv", &st) < 0) { - - if (silc_pkcs_alloc("rsa", &server->pkcs) == FALSE) { - SILC_LOG_ERROR(("Could not create RSA key pair")); - goto err0; - } - - if (server->pkcs->pkcs->init(server->pkcs->context, - 1024, server->rng) == FALSE) { - SILC_LOG_ERROR(("Could not generate RSA key pair")); - goto err0; - } - - public_key = server->pkcs->pkcs->get_public_key(server->pkcs->context, - &pk_len); - private_key = server->pkcs->pkcs->get_private_key(server->pkcs->context, - &prv_len); - - SILC_LOG_HEXDUMP(("public key"), public_key, pk_len); - SILC_LOG_HEXDUMP(("private key"), private_key, prv_len); - - server->public_key = - silc_pkcs_public_key_alloc("rsa", "UN=root, HN=dummy", - public_key, pk_len); - server->private_key = - silc_pkcs_private_key_alloc("rsa", private_key, prv_len); - - /* XXX Save keys */ - silc_pkcs_save_public_key("pubkey.pub", server->public_key, - SILC_PKCS_FILE_PEM); - silc_pkcs_save_private_key("privkey.prv", server->private_key, NULL, - SILC_PKCS_FILE_BIN); - - memset(public_key, 0, pk_len); - memset(private_key, 0, prv_len); - silc_free(public_key); - silc_free(private_key); - } else { - silc_pkcs_load_public_key("pubkey.pub", &server->public_key, - SILC_PKCS_FILE_PEM); - silc_pkcs_load_private_key("privkey.prv", &server->private_key, - SILC_PKCS_FILE_BIN); - } - } - /* Create a listening server. Note that our server can listen on multiple ports. All listeners are created here and now. */ /* XXX Still check this whether to use server_info or listen_port. */ diff --git a/apps/silcd/serverconfig.c b/apps/silcd/serverconfig.c index f25206d6..1a9abdf3 100644 --- a/apps/silcd/serverconfig.c +++ b/apps/silcd/serverconfig.c @@ -31,6 +31,8 @@ SilcServerConfigSection silc_server_config_sections[] = { SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION, 4 }, { "[hmac]", SILC_CONFIG_SERVER_SECTION_TYPE_HMAC, 3 }, + { "[ServerKeys]", + SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_KEYS, 2 }, { "[ServerInfo]", SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO, 4 }, { "[AdminInfo]", @@ -79,6 +81,8 @@ SilcServerConfig silc_server_config_alloc(char *filename) new->filename = filename; + SILC_LOG_DEBUG(("Loading config data from `%s'", filename)); + /* Open configuration file and parse it */ config_parse = NULL; buffer = NULL; @@ -105,6 +109,7 @@ void silc_server_config_free(SilcServerConfig config) { if (config) { silc_free(config->filename); + silc_free(config->server_keys); silc_free(config->server_info); silc_free(config->admin_info); silc_free(config->listen_port); @@ -439,6 +444,54 @@ int silc_server_config_parse_lines(SilcServerConfig config, checkmask |= (1L << pc->section->type); break; + case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_KEYS: + + if (!config->server_keys) + config->server_keys = silc_calloc(1, sizeof(*config->server_keys)); + + ret = silc_config_get_token(line, &tmp); + if (ret < 0) + break; + if (ret == 0) { + fprintf(stderr, "%s:%d: Public key name not defined\n", + config->filename, pc->linenum); + break; + } + + if (!silc_pkcs_load_public_key(tmp, &config->server_keys->public_key, + SILC_PKCS_FILE_PEM)) + if (!silc_pkcs_load_public_key(tmp, &config->server_keys->public_key, + SILC_PKCS_FILE_BIN)) { + fprintf(stderr, "%s:%d: Could not load public key file `%s'\n", + config->filename, pc->linenum, tmp); + break; + } + silc_free(tmp); + + ret = silc_config_get_token(line, &tmp); + if (ret < 0) + break; + if (ret == 0) { + fprintf(stderr, "%s:%d: Private key name not defined\n", + config->filename, pc->linenum); + break; + } + + if (!silc_pkcs_load_private_key(tmp, &config->server_keys->private_key, + SILC_PKCS_FILE_BIN)) + if (!silc_pkcs_load_private_key(tmp, + &config->server_keys->private_key, + SILC_PKCS_FILE_PEM)) { + fprintf(stderr, "%s:%d: Could not load private key file `%s'\n", + config->filename, pc->linenum, tmp); + break; + } + silc_free(tmp); + + check = TRUE; + checkmask |= (1L << pc->section->type); + break; + case SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO: if (!config->server_info) @@ -1491,64 +1544,3 @@ silc_server_config_find_admin(SilcServerConfig config, return admin; } - -/* Prints out example configuration file with default built in - configuration values. */ - -void silc_server_config_print() -{ - char *buf; - - buf = "\ -#\n\ -# Automatically generated example SILCd configuration file with default\n\ -# built in values. Use this as a guide to configure your SILCd configuration\n\ -# file for your system. For detailed description of different configuration\n\ -# sections refer to silcd(8) manual page.\n\ -#\n"; - /* -# -#+blowfish -#+twofish -#+rc5 -#+rc6 -#+3des - -# -#+md5 -#+sha1 - - -+lassi.kuo.fi.ssh.com:10.2.1.6:Kuopio, Finland:1333 - - -+Mun huone:Mun servo:Pekka Riikonen:priikone@poseidon.pspt.fi - - -+10.2.1.6:10.2.1.6:1333 - - -+infologfile:silcd.log:10000 -#+warninglogfile:/var/log/silcd_warning.log:10000 -#+errorlogfile:ERROR.log:10000 -#+fatallogfile:/var/log/silcd_error.log: - - - +1:100:100:100 - +2:200:300:400 - - -+10.2.1.199:priikone:333:1 - - -+10.2.1.199:priikone:priikone:1 - - - - - - - */ - - fprintf(stdout, "%s\n", buf); -} diff --git a/apps/silcd/serverconfig.h b/apps/silcd/serverconfig.h index 0a2c7147..095b3d7b 100644 --- a/apps/silcd/serverconfig.h +++ b/apps/silcd/serverconfig.h @@ -32,6 +32,12 @@ typedef struct SilcServerConfigSectionAlgStruct { #define SILC_CONFIG_SERVER_MODNAME "builtin" } SilcServerConfigSectionAlg; +/* Holds server keys from config file */ +typedef struct { + SilcPublicKey public_key; + SilcPrivateKey private_key; +} SilcServerConfigSectionServerKeys; + /* Holds server information from config file */ typedef struct { char *server_name; @@ -162,6 +168,7 @@ typedef struct { SilcServerConfigSectionAlg *pkcs; SilcServerConfigSectionAlg *hash_func; SilcServerConfigSectionAlg *hmac; + SilcServerConfigSectionServerKeys *server_keys; SilcServerConfigSectionServerInfo *server_info; SilcServerConfigSectionAdminInfo *admin_info; SilcServerConfigSectionListenPort *listen_port; @@ -185,6 +192,7 @@ typedef enum { SILC_CONFIG_SERVER_SECTION_TYPE_PKCS, SILC_CONFIG_SERVER_SECTION_TYPE_HASH_FUNCTION, SILC_CONFIG_SERVER_SECTION_TYPE_HMAC, + SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_KEYS, SILC_CONFIG_SERVER_SECTION_TYPE_SERVER_INFO, SILC_CONFIG_SERVER_SECTION_TYPE_ADMIN_INFO, SILC_CONFIG_SERVER_SECTION_TYPE_LISTEN_PORT, diff --git a/apps/silcd/silcd.c b/apps/silcd/silcd.c index db974ec7..186deb82 100644 --- a/apps/silcd/silcd.c +++ b/apps/silcd/silcd.c @@ -29,29 +29,54 @@ #include "server_internal.h" #include "version.h" +static void silc_usage(); +static char *silc_server_create_identifier(); +static int +silc_server_create_key_pair(char *pkcs_name, int bits, char *path, + char *identifier, + SilcPublicKey *ret_pub_key, + SilcPrivateKey *ret_prv_key); + /* Long command line options */ static struct option long_opts[] = { { "config-file", 1, NULL, 'f' }, - { "generate-config-file", 0, NULL, 'c' }, { "debug", 0, NULL, 'd' }, { "help", 0, NULL, 'h' }, { "version", 0, NULL,'V' }, + + /* Key management options */ + { "create-key-pair", 1, NULL, 'C' }, + { "pkcs", 1, NULL, 10 }, + { "bits", 1, NULL, 11 }, + { NULL, 0, NULL, 0 } }; +/* Command line option variables */ +static bool opt_create_keypair = FALSE; +static char *opt_keypath = NULL; +static char *opt_pkcs = "rsa"; +static int opt_bits = 1024; + /* Prints out the usage of silc client */ -void silc_usage() +static void silc_usage() { - printf("Usage: silcd [options]\n"); - printf("Options:\n"); - printf(" -f --config-file=FILE Alternate configuration file\n"); - printf(" -c --generate-config-file Generate example configuration " - "file\n"); - printf(" -d --debug Enable debugging (no daemon)\n"); - printf(" -h --help Display this message\n"); - printf(" -V --version Display version\n"); + printf("\ +Usage: silcd [options]\n\ +\n\ + Generic Options:\n\ + -f --config-file=FILE Alternate configuration file\n\ + -d --debug Enable debugging (no daemon)\n\ + -h --help Display this message\n\ + -V --version Display version\n\ +\n\ + Key Management Options:\n\ + -C, --create-key-pair=PATH Create new public key pair\n\ + --pkcs=PKCS Set the PKCS of the public key pair\n\ + --bits=VALUE Set length of the public key pair\n\ +\n"); exit(0); } @@ -66,7 +91,7 @@ int main(int argc, char **argv) /* Parse command line arguments */ if (argc > 1) { - while ((opt = getopt_long(argc, argv, "cf:dhV", + while ((opt = getopt_long(argc, argv, "cf:dhVC:", long_opts, &option_index)) != EOF) { switch(opt) { @@ -76,21 +101,34 @@ int main(int argc, char **argv) case 'V': printf("SILCd Secure Internet Live Conferencing daemon, " "version %s\n", silc_version); - printf("(c) 1997 - 2000 Pekka Riikonen " + printf("(c) 1997 - 2001 Pekka Riikonen " "\n"); exit(0); break; - case 'c': - /* Print out example configuration file */ - silc_server_config_print(); - exit(0); - break; case 'd': silc_debug = TRUE; break; case 'f': config_file = strdup(optarg); break; + + /* + * Key management options + */ + case 'C': + opt_create_keypair = TRUE; + if (optarg) + opt_keypath = strdup(optarg); + break; + case 10: + if (optarg) + opt_pkcs = strdup(optarg); + break; + case 11: + if (optarg) + opt_bits = atoi(optarg); + break; + default: silc_usage(); break; @@ -98,6 +136,13 @@ int main(int argc, char **argv) } } + if (opt_create_keypair == TRUE) { + /* Create new key pair and exit */ + silc_server_create_key_pair(opt_pkcs, opt_bits, opt_keypath, + NULL, NULL, NULL); + exit(0); + } + /* Default configuration file */ if (!config_file) config_file = strdup(SILC_SERVER_CONFIG_FILE); @@ -135,3 +180,107 @@ int main(int argc, char **argv) fail: exit(1); } + +/* Returns identifier string for public key generation. */ + +static char *silc_server_create_identifier() +{ + char *username = NULL, *realname = NULL; + char hostname[256], email[256]; + + /* Get realname */ + realname = silc_get_real_name(); + + /* Get hostname */ + memset(hostname, 0, sizeof(hostname)); + gethostname(hostname, sizeof(hostname)); + + /* Get username (mandatory) */ + username = silc_get_username(); + if (!username) + return NULL; + + /* Create default email address, whether it is right or not */ + snprintf(email, sizeof(email), "%s@%s", username, hostname); + + return silc_pkcs_encode_identifier(username, hostname, realname, email, + NULL, NULL); +} + +/* Creates new public key and private key pair. This is used only + when user wants to create new key pair from command line. */ + +static int +silc_server_create_key_pair(char *pkcs_name, int bits, char *path, + char *identifier, + SilcPublicKey *ret_pub_key, + SilcPrivateKey *ret_prv_key) +{ + SilcPKCS pkcs; + SilcPublicKey pub_key; + SilcPrivateKey prv_key; + SilcRng rng; + unsigned char *key; + uint32 key_len; + char pkfile[256], prvfile[256]; + + if (!pkcs_name || !path) + return FALSE; + + if (!silc_pkcs_is_supported(pkcs_name)) { + fprintf(stderr, "Unsupported PKCS `%s'", pkcs_name); + return FALSE; + } + + if (!bits) + bits = 1024; + + if (!identifier) + identifier = silc_server_create_identifier(); + + rng = silc_rng_alloc(); + silc_rng_init(rng); + silc_rng_global_init(rng); + + snprintf(pkfile, sizeof(pkfile) - 1, "%s%s", path, + SILC_SERVER_PUBLIC_KEY_NAME); + snprintf(prvfile, sizeof(prvfile) - 1, "%s%s", path, + SILC_SERVER_PRIVATE_KEY_NAME); + + /* Generate keys */ + silc_pkcs_alloc(pkcs_name, &pkcs); + pkcs->pkcs->init(pkcs->context, bits, rng); + + /* Save public key into file */ + key = silc_pkcs_get_public_key(pkcs, &key_len); + pub_key = silc_pkcs_public_key_alloc(pkcs->pkcs->name, identifier, + key, key_len); + silc_pkcs_save_public_key(pkfile, pub_key, SILC_PKCS_FILE_PEM); + if (ret_pub_key) + *ret_pub_key = pub_key; + else + silc_pkcs_public_key_free(pub_key); + + memset(key, 0, sizeof(key_len)); + silc_free(key); + + /* Save private key into file */ + key = silc_pkcs_get_private_key(pkcs, &key_len); + prv_key = silc_pkcs_private_key_alloc(pkcs->pkcs->name, key, key_len); + silc_pkcs_save_private_key(prvfile, prv_key, NULL, SILC_PKCS_FILE_BIN); + if (ret_prv_key) + *ret_prv_key = prv_key; + else + silc_pkcs_private_key_free(prv_key); + + printf("Public key has been saved into `%s'\n", pkfile); + printf("Private key has been saved into `%s'\n", prvfile); + + memset(key, 0, sizeof(key_len)); + silc_free(key); + + silc_rng_free(rng); + silc_pkcs_free(pkcs); + + return TRUE; +} diff --git a/apps/silcd/silcd.h b/apps/silcd/silcd.h index 6ad45cb7..512ce94a 100644 --- a/apps/silcd/silcd.h +++ b/apps/silcd/silcd.h @@ -25,18 +25,12 @@ compilation time. Otherwise, use default. This can be overridden on command line as well. */ #ifndef SILC_SERVER_CONFIG_FILE -#define SILC_SERVER_CONFIG_FILE "/etc/silc/silcd.conf\0" +#define SILC_SERVER_CONFIG_FILE "/etc/silc/silcd.conf" #endif -void usage(); - -char file_public_key[100]; /* server public key */ -char file_private_key[100]; /* server private key */ - -#define PUBLICKEY_NAME "/silc_host_public" -#define PRIVATEKEY_NAME "/silc_host_private" +#define SILC_SERVER_PUBLIC_KEY_NAME "/silcd.pub" +#define SILC_SERVER_PRIVATE_KEY_NAME "/silcd.prv" #define SERVER_KEY_EXPIRATION_DAYS 180 -int key_expires; #endif diff --git a/doc/example_silcd.conf b/doc/example_silcd.conf index d5221b5c..a3b878a4 100644 --- a/doc/example_silcd.conf +++ b/doc/example_silcd.conf @@ -76,6 +76,14 @@ Kuopio, Finland:Test Server:Pekka Riikonen:priikone@poseidon.pspt.fi [ServerInfo] lassi.kuo.fi.ssh.com:10.2.1.6:Kuopio, Finland:706 +# +# Server keys +# +# Format: +: +# +[ServerKeys] +/etc/silc/silcd.pub:/etc/silc/silcd.prv + # # Listenning ports. # diff --git a/lib/silcutil/silcutil.c b/lib/silcutil/silcutil.c index 9407febc..2f0f69e0 100644 --- a/lib/silcutil/silcutil.c +++ b/lib/silcutil/silcutil.c @@ -77,12 +77,13 @@ int silc_file_write(const char *filename, const char *buffer, uint32 len) int fd; if ((fd = creat(filename, 0644)) == -1) { - SILC_LOG_ERROR(("Cannot open file %s for writing: %s", strerror(errno))); + SILC_LOG_ERROR(("Cannot open file %s for writing: %s", filename, + strerror(errno))); return -1; } if ((write(fd, buffer, len)) == -1) { - SILC_LOG_ERROR(("Cannot write to file %s: %s", strerror(errno))); + SILC_LOG_ERROR(("Cannot write to file %s: %s", filename, strerror(errno))); return -1; } @@ -100,12 +101,13 @@ int silc_file_write_mode(const char *filename, const char *buffer, int fd; if ((fd = creat(filename, mode)) == -1) { - SILC_LOG_ERROR(("Cannot open file %s for writing: %s", strerror(errno))); + SILC_LOG_ERROR(("Cannot open file %s for writing: %s", filename, + strerror(errno))); return -1; } if ((write(fd, buffer, len)) == -1) { - SILC_LOG_ERROR(("Cannot write to file %s: %s", strerror(errno))); + SILC_LOG_ERROR(("Cannot write to file %s: %s", filename, strerror(errno))); return -1; } @@ -694,3 +696,50 @@ int silc_string_match(const char *string1, const char *string2) return ret; } + +/* Returns the username of the user. If the global variable LOGNAME + does not exists we will get the name from the password file. */ + +char *silc_get_username() +{ + char *logname = NULL; + + logname = strdup(getenv("LOGNAME")); + if (!logname) { + logname = getlogin(); + if (!logname) { + struct passwd *pw; + + pw = getpwuid(getuid()); + if (!pw) { + fprintf(stderr, "silc_get_username: %s\n", strerror(errno)); + return NULL; + } + + logname = strdup(pw->pw_name); + } + } + + return logname; +} + +/* Returns the real name of ther user. */ + +char *silc_get_real_name() +{ + char *realname = NULL; + struct passwd *pw; + + pw = getpwuid(getuid()); + if (!pw) { + fprintf(stderr, "silc_get_username: %s\n", strerror(errno)); + return NULL; + } + + if (strchr(pw->pw_gecos, ',')) + *strchr(pw->pw_gecos, ',') = 0; + + realname = strdup(pw->pw_gecos); + + return realname; +} diff --git a/lib/silcutil/silcutil.h b/lib/silcutil/silcutil.h index b6e7f92d..ef610aed 100644 --- a/lib/silcutil/silcutil.h +++ b/lib/silcutil/silcutil.h @@ -48,5 +48,7 @@ int silc_string_compare(char *string1, char *string2); char *silc_string_regexify(const char *string); int silc_string_regex_match(const char *regex, const char *string); int silc_string_match(const char *string1, const char *string2); +char *silc_get_username(); +char *silc_get_real_name(); #endif -- 2.24.0