Added check for and create of run dir and/or basename of digest_cache (if different from run dir). Added set_locale() call based on LOCALE setting in the conf file.

git-svn-id: file:///home/mbr/svn/fwknop/trunk@177 510a4753-2344-4c79-9c09-4d669213fbeb
This commit is contained in:
Damien Stuart
2010-01-02 16:42:07 +00:00
parent d8dc9be941
commit 909ff4eaec
5 changed files with 247 additions and 24 deletions

View File

@@ -85,7 +85,7 @@ AC_HEADER_STDC
AC_HEADER_TIME
AC_HEADER_RESOLV
AC_CHECK_HEADERS([ctype.h endian.h errno.h netdb.h net/ethernet.h netinet/ether.h netinet/ip_icmp.h netinet/in.h netinet/ip.h netinet/tcp.h netinet/udp.h stdint.h stdlib.h string.h strings.h sys/byteorder.h sys/endian.h sys/ethernet.h sys/socket.h sys/stat.h sys/time.h termios.h unistd.h])
AC_CHECK_HEADERS([ctype.h endian.h errno.h locale.h netdb.h net/ethernet.h netinet/ether.h netinet/ip_icmp.h netinet/in.h netinet/ip.h netinet/tcp.h netinet/udp.h stdint.h stdlib.h string.h strings.h sys/byteorder.h sys/endian.h sys/ethernet.h sys/socket.h sys/stat.h sys/time.h termios.h unistd.h])
# Type checks.
#

View File

@@ -210,21 +210,49 @@ parse_config_file(fko_srv_options_t *opts, char *config_file)
static void
validate_options(fko_srv_options_t *opts)
{
char tmp_path[MAX_PATH_LEN];
/* If a HOSTNAME was specified in the config file, set the opts->hostname
* value to it.
*/
if(opts->config[CONF_HOSTNAME] != NULL && opts->config[CONF_HOSTNAME][0] != '\0')
strlcpy(opts->hostname, opts->config[CONF_HOSTNAME], MAX_HOSTNAME_LEN);
/* If the pid and digest cache files where not set in the config file or
* via command-line, then grab the defaults.
/* If no conf dir is set in the config file, use the default.
*/
if(opts->config[CONF_FWKNOP_CONF_DIR] == NULL)
set_config_entry(opts, CONF_FWKNOP_CONF_DIR, DEF_CONF_DIR);
/* If the pid and digest cache files where not set in the config file or
* via command-line, then grab the defaults. Start with RUN_DIR as the
* files may depend on that.
*/
if(opts->config[CONF_FWKNOP_RUN_DIR] == NULL)
set_config_entry(opts, CONF_FWKNOP_RUN_DIR, DEF_RUN_DIR);
if(opts->config[CONF_FWKNOP_PID_FILE] == NULL)
set_config_entry(opts, CONF_FWKNOP_PID_FILE, DEF_PID_FILE);
{
strlcpy(tmp_path, opts->config[CONF_FWKNOP_RUN_DIR], MAX_PATH_LEN);
if(tmp_path[strlen(tmp_path)-1] != '/')
strlcat(tmp_path, "/", MAX_PATH_LEN);
strlcat(tmp_path, DEF_PID_FILENAME, MAX_PATH_LEN);
set_config_entry(opts, CONF_FWKNOP_PID_FILE, tmp_path);
}
if(opts->config[CONF_DIGEST_FILE] == NULL)
set_config_entry(opts, CONF_DIGEST_FILE, DEF_DIGEST_CACHE);
{
strlcpy(tmp_path, opts->config[CONF_FWKNOP_RUN_DIR], MAX_PATH_LEN);
if(tmp_path[strlen(tmp_path)-1] != '/')
strlcat(tmp_path, "/", MAX_PATH_LEN);
strlcat(tmp_path, DEF_DIGEST_CACHE_FILENAME, MAX_PATH_LEN);
set_config_entry(opts, CONF_DIGEST_FILE, tmp_path);
}
/* If log facility and default identity where not set in the config file,
* fall back to defaults.
@@ -284,6 +312,11 @@ config_init(fko_srv_options_t *opts, int argc, char **argv)
if(gethostname(opts->hostname, MAX_HOSTNAME_LEN-1) < 0)
strcpy(opts->hostname, "UNKNOWN");
/* Set the conf hostname entry here in case it is not set in the conf
* file.
*/
set_config_entry(opts, CONF_HOSTNAME, opts->hostname);
/* In case this is a re-config.
*/
optind = 0;
@@ -428,7 +461,7 @@ config_init(fko_srv_options_t *opts, int argc, char **argv)
opts->status = 1;
break;
case 'v':
opts->verbose = 1;
opts->verbose++;
break;
case 'V':
fprintf(stdout, "fwknopd server %s\n", MY_VERSION);
@@ -466,10 +499,6 @@ dump_config(fko_srv_options_t *opts)
);
fprintf(stderr, "\n");
fprintf(stderr, "Hostname is set to '%s'.\n", opts->hostname);
fprintf(stderr, "\n");
}
/* Print usage message...

View File

@@ -34,6 +34,8 @@
/* Prototypes
*/
static void check_dir_path(const char *path, const char *path_name, unsigned char use_basename);
static int make_dir_path(const char *path);
static void daemonize_process(fko_srv_options_t *opts);
static int write_pid_file(fko_srv_options_t *opts);
static pid_t get_running_pid(fko_srv_options_t *opts);
@@ -44,6 +46,7 @@ main(int argc, char **argv)
fko_ctx_t ctx;
int res, last_sig, rpdb_count;
char *spa_data, *version;
char *locale;
char access_buf[MAX_LINE_LEN];
pid_t old_pid;
@@ -131,6 +134,40 @@ main(int argc, char **argv)
*/
init_logging(&opts);
#if HAVE_LOCALE_H
/* Set the locale if specified.
*/
if(opts.config[CONF_LOCALE] != NULL)
{
locale = setlocale(LC_ALL, opts.config[CONF_LOCALE]);
if(locale == NULL)
{
log_msg(LOG_ERR|LOG_STDERR,
"WARNING: Unable to set locale to %s.",
opts.config[CONF_LOCALE]
);
}
else
{
if(opts.verbose)
log_msg(LOG_ERR|LOG_STDERR,
"Locale set to %s.", opts.config[CONF_LOCALE]
);
}
}
#endif
/* Make sure we have a valid run dir and path leading to digest file
* in case it configured to be somewhere other than the run dir.
*/
check_dir_path((const char *)opts.config[CONF_FWKNOP_RUN_DIR], "Run", 0);
check_dir_path((const char *)opts.config[CONF_DIGEST_FILE], "Run", 1);
/* If we are a new process (just being started), proceed with normal
* startp. Otherwise, we are here as a result of a signal sent to an
* existing process and we want to restart.
*/
if(get_running_pid(&opts) != getpid())
{
/* If foreground mode is not set, the fork off and become a daemon.
@@ -164,8 +201,8 @@ main(int argc, char **argv)
log_msg(LOG_INFO, "Re-starting %s", MY_NAME);
}
dump_config(&opts);
/* We only support pcap capture at this point.
*/
if((strncasecmp(opts.config[CONF_AUTH_MODE], "pcap", 4)) != 0)
{
log_msg(LOG_ERR|LOG_STDERR,
@@ -174,11 +211,22 @@ main(int argc, char **argv)
exit(EXIT_FAILURE);
}
/* Initialize the digest cache (replay attack detection dbm).
*/
rpdb_count = replay_db_init(&opts);
if(opts.verbose > 1)
dump_config(&opts);
fprintf(stderr, "RPDB Count: %i\n", rpdb_count);
/* Initialize the digest cache (replay attack detection dbm)
* if so configured.
*/
if(strncasecmp(opts.config[CONF_ENABLE_DIGEST_PERSISTENCE], "Y", 1) == 0)
{
rpdb_count = replay_db_init(&opts);
if(opts.verbose)
log_msg(LOG_ERR|LOG_STDERR,
"Using Digest Cache: '%s' (entry count = %i)",
opts.config[CONF_DIGEST_FILE], rpdb_count
);
}
/* Intiate pcap capture mode...
*/
@@ -227,6 +275,145 @@ fprintf(stderr, "RPDB Count: %i\n", rpdb_count);
return(0);
}
/* Ensure the specified directory exists. If not, create it or die.
*/
static void
check_dir_path(const char *filepath, const char *fp_desc, unsigned char use_basename)
{
struct stat st;
int res;
char tmp_path[MAX_PATH_LEN];
char *ndx;
/*
* FIXME: We shouldn't use a hard-coded dir-separator here.
*/
/* But first make sure we are using an absolute path.
*/
if(*filepath != '/')
{
log_msg(LOG_ERR|LOG_STDERR,
"Configured %s directory (%s) is not an absolute path.", fp_desc, filepath
);
exit(EXIT_FAILURE);
}
/* If this is a file path that we want to use only the basename, strip
* the trailing filename here.
*/
if(use_basename && ((ndx = strrchr(filepath, '/')) != NULL))
strlcpy(tmp_path, filepath, (ndx-filepath)+1);
else
strcpy(tmp_path, filepath);
/* At this point, we should make the path is more than just "/".
* If it is not, silently return.
*/
if(strlen(tmp_path) < 2)
return;
/* Make sure we have a valid directory.
*/
res = stat(tmp_path, &st);
if(res != 0)
{
if(errno == ENOENT)
{
log_msg(LOG_WARNING|LOG_STDERR,
"%s directory: %s does not exist. Attempting to create it.", fp_desc, tmp_path
);
/* Directory does not exist, so attempt to create it.
*/
res = make_dir_path(tmp_path);
if(res != 0)
{
log_msg(LOG_ERR|LOG_STDERR,
"Unable to create %s directory: %s (error: %i)", fp_desc, tmp_path, errno
);
exit(EXIT_FAILURE);
}
log_msg(LOG_ERR|LOG_STDERR,
"Successfully created %s directory: %s", fp_desc, tmp_path
);
}
else
{
log_msg(LOG_ERR|LOG_STDERR,
"Stat of %s returned error %i", tmp_path, errno
);
exit(EXIT_FAILURE);
}
}
else
{
/* It is a file, but is it a directory?
*/
if(! S_ISDIR(st.st_mode))
{
log_msg(LOG_ERR|LOG_STDERR,
"Specified %s directory: %s is NOT a directory\n\n", fp_desc, tmp_path
);
exit(EXIT_FAILURE);
}
}
}
static int
make_dir_path(const char *run_dir)
{
struct stat st;
int res, len;
char tmp_path[MAX_PATH_LEN];
char *ndx;
strlcpy(tmp_path, run_dir, MAX_PATH_LEN);
len = strlen(tmp_path);
/* Strip any trailing dir sep char.
*/
if(tmp_path[len-1] == '/')
tmp_path[len-1] = '\0';
for(ndx = tmp_path+1; *ndx; ndx++)
{
if(*ndx == '/')
{
*ndx = '\0';
/* Stat this part of the path to see if it is a valid directory.
* If it does not exist, attempt to create it. If it does, and
* it is a directory, go on. Otherwise, any other error cause it
* to bail.
*/
if(stat(tmp_path, &st) != 0)
{
if(errno == ENOENT)
res = mkdir(tmp_path, S_IRWXU);
if(res != 0)
return res;
}
if(! S_ISDIR(st.st_mode))
{
log_msg(LOG_ERR|LOG_STDERR,
"Component: %s of %s is NOT a directory\n\n", tmp_path, run_dir
);
return(ENOTDIR);
}
*ndx = '/';
}
}
res = mkdir(tmp_path, S_IRWXU);
return(res);
}
/* Become a daemon: fork(), start a new session, chdir "/",
* and close unneeded standard filehandles.
*/

View File

@@ -32,6 +32,10 @@
#include <sys/file.h>
#include <sys/fcntl.h>
#if HAVE_LOCALE_H
#include <locale.h>
#endif
/* If the flock flags are not defined at this point, we take the liberty
* of defining them here.
*/

View File

@@ -28,6 +28,8 @@
#include "common.h"
#include <sys/stat.h>
#if HAVE_LIBPCAP
#include <pcap.h>
#endif
@@ -47,8 +49,9 @@
/* Our default config directory is based on SYSCONFDIR as set by the
* configure script.
*/
#define DEF_CONF_DIR SYSCONFDIR"/fwknop"
#define DEF_CONF_DIR SYSCONFDIR"/"PACKAGE_NAME
#endif
#define DEF_CONFIG_FILE DEF_CONF_DIR"/"MY_NAME".conf"
#define DEF_ACCESS_FILE DEF_CONF_DIR"/access.conf"
@@ -56,11 +59,11 @@
/* Our default run directory is based on LOCALSTATEDIR as set by the
* configure script. This is where we put the PID and digest cache files.
*/
#define DEF_RUN_DIR SYSRUNDIR"/run/fwknop"
#define DEF_RUN_DIR SYSRUNDIR"/run/"PACKAGE_NAME
#endif
#define DEF_PID_FILE DEF_RUN_DIR"/"MY_NAME".pid"
#define DEF_DIGEST_CACHE DEF_RUN_DIR"/digest.cache"
#define DEF_PID_FILENAME MY_NAME".pid"
#define DEF_DIGEST_CACHE_FILENAME "digest.cache"
#define DEF_INTERFACE "eth0"
@@ -154,9 +157,9 @@ enum {
//CONF_IPT_SNAT_ACCESS,
//CONF_IPT_MASQUERADE_ACCESS,
//CONF_FWKNOP_DIR,
//CONF_FWKNOP_RUN_DIR,
CONF_FWKNOP_RUN_DIR,
//CONF_FWKNOP_MOD_DIR,
//CONF_FWKNOP_CONF_DIR,
CONF_FWKNOP_CONF_DIR,
//CONF_FWKNOP_ERR_DIR,
//CONF_ACCESS_CONF,
CONF_FWKNOP_PID_FILE,
@@ -237,9 +240,9 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = {
//"IPT_SNAT_ACCESS",
//"IPT_MASQUERADE_ACCESS",
//"FWKNOP_DIR",
//"FWKNOP_RUN_DIR",
"FWKNOP_RUN_DIR",
//"FWKNOP_MOD_DIR",
//"FWKNOP_CONF_DIR",
"FWKNOP_CONF_DIR",
//"FWKNOP_ERR_DIR",
//"ACCESS_CONF",
"FWKNOP_PID_FILE",