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:
@@ -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.
|
||||
#
|
||||
|
||||
@@ -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...
|
||||
|
||||
199
server/fwknopd.c
199
server/fwknopd.c
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user