2006-04-28 07:14:48 +00:00
|
|
|
/* strongSwan IPsec starter
|
|
|
|
* Copyright (C) 2001-2002 Mathieu Lafon - Arkoon Network Security
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
|
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* for more details.
|
|
|
|
*/
|
|
|
|
|
2013-01-22 15:13:15 +00:00
|
|
|
#define _GNU_SOURCE
|
|
|
|
|
2012-06-06 12:23:25 +00:00
|
|
|
#include <sys/select.h>
|
2006-04-28 07:14:48 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/wait.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <signal.h>
|
2012-08-14 14:59:22 +00:00
|
|
|
#include <syslog.h>
|
2006-04-28 07:14:48 +00:00
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
2008-05-08 10:58:04 +00:00
|
|
|
#include <pwd.h>
|
|
|
|
#include <grp.h>
|
2012-05-31 13:53:47 +00:00
|
|
|
#include <pthread.h>
|
2006-04-28 07:14:48 +00:00
|
|
|
|
2010-04-29 12:33:29 +00:00
|
|
|
#include <library.h>
|
2011-10-21 12:14:36 +00:00
|
|
|
#include <hydra.h>
|
2012-05-31 13:53:47 +00:00
|
|
|
#include <utils/backtrace.h>
|
|
|
|
#include <threading/thread.h>
|
2012-10-16 14:03:21 +00:00
|
|
|
#include <utils/debug.h>
|
2006-04-28 07:14:48 +00:00
|
|
|
|
|
|
|
#include "confread.h"
|
|
|
|
#include "files.h"
|
2006-05-04 07:55:42 +00:00
|
|
|
#include "starterstroke.h"
|
2006-04-28 07:16:42 +00:00
|
|
|
#include "invokecharon.h"
|
2006-04-28 07:14:48 +00:00
|
|
|
#include "netkey.h"
|
2008-11-11 09:22:00 +00:00
|
|
|
#include "klips.h"
|
2006-04-28 07:14:48 +00:00
|
|
|
#include "cmp.h"
|
|
|
|
|
2012-05-14 09:22:57 +00:00
|
|
|
#ifndef LOG_AUTHPRIV
|
|
|
|
#define LOG_AUTHPRIV LOG_AUTH
|
|
|
|
#endif
|
|
|
|
|
2012-05-14 15:33:03 +00:00
|
|
|
#define CHARON_RESTART_DELAY 5
|
|
|
|
|
2013-01-22 15:13:15 +00:00
|
|
|
static const char* cmd_default = IPSEC_DIR "/charon";
|
|
|
|
static const char* pid_file_default = IPSEC_PIDDIR "/charon.pid";
|
|
|
|
static const char* starter_pid_file_default = IPSEC_PIDDIR "/starter.pid";
|
|
|
|
|
|
|
|
char *daemon_name = NULL;
|
|
|
|
char *cmd = NULL;
|
|
|
|
char *pid_file = NULL;
|
|
|
|
char *starter_pid_file = NULL;
|
|
|
|
|
2012-05-14 09:22:57 +00:00
|
|
|
/* logging */
|
|
|
|
static bool log_to_stderr = TRUE;
|
|
|
|
static bool log_to_syslog = TRUE;
|
|
|
|
static level_t current_loglevel = 1;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* logging function for scepclient
|
|
|
|
*/
|
|
|
|
static void starter_dbg(debug_t group, level_t level, char *fmt, ...)
|
|
|
|
{
|
|
|
|
char buffer[8192];
|
|
|
|
char *current = buffer, *next;
|
|
|
|
va_list args;
|
|
|
|
|
|
|
|
if (level <= current_loglevel)
|
|
|
|
{
|
|
|
|
if (log_to_stderr)
|
|
|
|
{
|
|
|
|
va_start(args, fmt);
|
|
|
|
vfprintf(stderr, fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
}
|
|
|
|
if (log_to_syslog)
|
|
|
|
{
|
|
|
|
/* write in memory buffer first */
|
|
|
|
va_start(args, fmt);
|
|
|
|
vsnprintf(buffer, sizeof(buffer), fmt, args);
|
|
|
|
va_end(args);
|
|
|
|
|
|
|
|
/* do a syslog with every line */
|
|
|
|
while (current)
|
|
|
|
{
|
|
|
|
next = strchr(current, '\n');
|
|
|
|
if (next)
|
|
|
|
{
|
|
|
|
*(next++) = '\0';
|
|
|
|
}
|
|
|
|
syslog(LOG_INFO, "%s\n", current);
|
|
|
|
current = next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialize logging to stderr/syslog
|
|
|
|
*/
|
|
|
|
static void init_log(const char *program)
|
|
|
|
{
|
|
|
|
dbg = starter_dbg;
|
|
|
|
|
|
|
|
if (log_to_stderr)
|
|
|
|
{
|
|
|
|
setbuf(stderr, NULL);
|
|
|
|
}
|
|
|
|
if (log_to_syslog)
|
|
|
|
{
|
|
|
|
openlog(program, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_AUTHPRIV);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Deinitialize logging to syslog
|
|
|
|
*/
|
|
|
|
static void close_log()
|
|
|
|
{
|
|
|
|
if (log_to_syslog)
|
|
|
|
{
|
|
|
|
closelog();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-11-28 17:02:12 +00:00
|
|
|
/**
|
|
|
|
* Return codes defined by Linux Standard Base Core Specification 3.1
|
|
|
|
* in section 20.2. Init Script Actions
|
|
|
|
*/
|
|
|
|
#define LSB_RC_SUCCESS 0 /* success */
|
|
|
|
#define LSB_RC_FAILURE 1 /* generic or unspecified error */
|
|
|
|
#define LSB_RC_INVALID_ARGUMENT 2 /* invalid or excess argument(s) */
|
|
|
|
#define LSB_RC_NOT_IMPLEMENTED 3 /* unimplemented feature (reload) */
|
|
|
|
#define LSB_RC_NOT_ALLOWED 4 /* user had insufficient privilege */
|
|
|
|
#define LSB_RC_NOT_INSTALLED 5 /* program is not installed */
|
|
|
|
#define LSB_RC_NOT_CONFIGURED 6 /* program is not configured */
|
|
|
|
#define LSB_RC_NOT_RUNNING 7 /* program is not running */
|
|
|
|
|
2006-04-28 07:14:48 +00:00
|
|
|
#define FLAG_ACTION_START_PLUTO 0x01
|
|
|
|
#define FLAG_ACTION_UPDATE 0x02
|
|
|
|
#define FLAG_ACTION_RELOAD 0x04
|
|
|
|
#define FLAG_ACTION_QUIT 0x08
|
|
|
|
#define FLAG_ACTION_LISTEN 0x10
|
2006-04-28 07:16:42 +00:00
|
|
|
#define FLAG_ACTION_START_CHARON 0x20
|
2006-04-28 07:14:48 +00:00
|
|
|
|
|
|
|
static unsigned int _action_ = 0;
|
|
|
|
|
2012-05-31 13:53:47 +00:00
|
|
|
/**
|
|
|
|
* Handle signals in the main thread
|
|
|
|
*/
|
|
|
|
static void signal_handler(int signal)
|
2006-04-28 07:14:48 +00:00
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
switch (signal)
|
2006-05-23 08:01:49 +00:00
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
case SIGCHLD:
|
|
|
|
{
|
2009-07-17 18:33:19 +00:00
|
|
|
int status, exit_status = 0;
|
2009-04-19 19:16:09 +00:00
|
|
|
pid_t pid;
|
|
|
|
char *name = NULL;
|
|
|
|
|
|
|
|
while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
|
|
|
|
{
|
|
|
|
if (pid == starter_charon_pid())
|
2009-07-17 14:57:07 +00:00
|
|
|
{
|
2013-01-22 15:13:15 +00:00
|
|
|
if (asprintf(&name, " (%s)", daemon_name) < 0)
|
|
|
|
{
|
|
|
|
name = NULL;
|
|
|
|
}
|
2009-07-17 14:57:07 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
if (WIFSIGNALED(status))
|
2009-07-17 14:57:07 +00:00
|
|
|
{
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG2(DBG_APP, "child %d%s has been killed by sig %d\n",
|
|
|
|
pid, name?name:"", WTERMSIG(status));
|
2009-07-17 14:57:07 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
else if (WIFSTOPPED(status))
|
2009-07-17 14:57:07 +00:00
|
|
|
{
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG2(DBG_APP, "child %d%s has been stopped by sig %d\n",
|
|
|
|
pid, name?name:"", WSTOPSIG(status));
|
2009-07-17 14:57:07 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
else if (WIFEXITED(status))
|
2009-07-17 14:57:07 +00:00
|
|
|
{
|
2009-07-17 18:33:19 +00:00
|
|
|
exit_status = WEXITSTATUS(status);
|
2009-08-06 14:42:44 +00:00
|
|
|
if (exit_status >= SS_RC_FIRST && exit_status <= SS_RC_LAST)
|
2009-07-17 18:33:19 +00:00
|
|
|
{
|
|
|
|
_action_ = FLAG_ACTION_QUIT;
|
|
|
|
}
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG2(DBG_APP, "child %d%s has quit (exit code %d)\n",
|
|
|
|
pid, name?name:"", exit_status);
|
2009-07-17 14:57:07 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
else
|
2009-07-17 14:57:07 +00:00
|
|
|
{
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG2(DBG_APP, "child %d%s has quit", pid, name?name:"");
|
2009-07-17 14:57:07 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
if (pid == starter_charon_pid())
|
2009-07-17 14:57:07 +00:00
|
|
|
{
|
2009-07-17 18:33:19 +00:00
|
|
|
starter_charon_sigchild(pid, exit_status);
|
2009-07-17 14:57:07 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
2013-01-22 15:13:15 +00:00
|
|
|
|
|
|
|
if (name)
|
|
|
|
{
|
|
|
|
free(name);
|
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIGALRM:
|
|
|
|
_action_ |= FLAG_ACTION_START_CHARON;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIGHUP:
|
|
|
|
_action_ |= FLAG_ACTION_UPDATE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIGTERM:
|
|
|
|
case SIGQUIT:
|
|
|
|
case SIGINT:
|
|
|
|
_action_ |= FLAG_ACTION_QUIT;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SIGUSR1:
|
|
|
|
_action_ |= FLAG_ACTION_RELOAD;
|
|
|
|
_action_ |= FLAG_ACTION_UPDATE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG1(DBG_APP, "fsig(): unknown signal %d -- investigate", signal);
|
2009-04-19 19:16:09 +00:00
|
|
|
break;
|
2006-05-23 08:01:49 +00:00
|
|
|
}
|
2006-04-28 07:14:48 +00:00
|
|
|
}
|
|
|
|
|
2012-05-31 13:53:47 +00:00
|
|
|
/**
|
|
|
|
* Handle fatal signals raised by threads
|
|
|
|
*/
|
|
|
|
static void fatal_signal_handler(int signal)
|
|
|
|
{
|
|
|
|
backtrace_t *backtrace;
|
|
|
|
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG1(DBG_APP, "thread %u received %d", thread_current_id(), signal);
|
2012-05-31 13:53:47 +00:00
|
|
|
backtrace = backtrace_create(2);
|
|
|
|
backtrace->log(backtrace, stderr, TRUE);
|
|
|
|
backtrace->destroy(backtrace);
|
|
|
|
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG1(DBG_APP, "killing ourself, received critical signal");
|
2012-05-31 13:53:47 +00:00
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
2011-10-12 14:37:21 +00:00
|
|
|
#ifdef GENERATE_SELFCERT
|
2008-05-08 10:58:04 +00:00
|
|
|
static void generate_selfcert()
|
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
struct stat stb;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2011-10-12 14:37:21 +00:00
|
|
|
/* if ipsec.secrets file is missing then generate RSA default key pair */
|
|
|
|
if (stat(SECRETS_FILE, &stb) != 0)
|
|
|
|
{
|
|
|
|
mode_t oldmask;
|
|
|
|
FILE *f;
|
|
|
|
uid_t uid = 0;
|
|
|
|
gid_t gid = 0;
|
2008-05-08 10:58:04 +00:00
|
|
|
|
|
|
|
#ifdef IPSEC_GROUP
|
2011-10-12 14:37:21 +00:00
|
|
|
{
|
|
|
|
char buf[1024];
|
|
|
|
struct group group, *grp;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2011-10-12 14:37:21 +00:00
|
|
|
if (getgrnam_r(IPSEC_GROUP, &group, buf, sizeof(buf), &grp) == 0 && grp)
|
|
|
|
{
|
|
|
|
gid = grp->gr_gid;
|
2009-04-19 19:32:02 +00:00
|
|
|
}
|
2011-10-12 14:37:21 +00:00
|
|
|
}
|
2008-05-08 10:58:04 +00:00
|
|
|
#endif
|
|
|
|
#ifdef IPSEC_USER
|
2011-10-12 14:37:21 +00:00
|
|
|
{
|
|
|
|
char buf[1024];
|
|
|
|
struct passwd passwd, *pwp;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2011-10-12 14:37:21 +00:00
|
|
|
if (getpwnam_r(IPSEC_USER, &passwd, buf, sizeof(buf), &pwp) == 0 && pwp)
|
|
|
|
{
|
|
|
|
uid = pwp->pw_uid;
|
2009-04-19 19:32:02 +00:00
|
|
|
}
|
2011-10-12 14:37:21 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
#endif
|
2011-10-12 14:37:21 +00:00
|
|
|
setegid(gid);
|
|
|
|
seteuid(uid);
|
|
|
|
ignore_result(system("ipsec scepclient --out pkcs1 --out cert-self --quiet"));
|
|
|
|
seteuid(0);
|
|
|
|
setegid(0);
|
2009-04-19 19:16:09 +00:00
|
|
|
|
2011-10-12 14:37:21 +00:00
|
|
|
/* ipsec.secrets is root readable only */
|
|
|
|
oldmask = umask(0066);
|
2009-04-19 19:16:09 +00:00
|
|
|
|
2011-10-12 14:37:21 +00:00
|
|
|
f = fopen(SECRETS_FILE, "w");
|
|
|
|
if (f)
|
|
|
|
{
|
|
|
|
fprintf(f, "# /etc/ipsec.secrets - strongSwan IPsec secrets file\n");
|
|
|
|
fprintf(f, "\n");
|
|
|
|
fprintf(f, ": RSA myKey.der\n");
|
|
|
|
fclose(f);
|
2008-05-08 10:58:04 +00:00
|
|
|
}
|
2011-10-12 14:37:21 +00:00
|
|
|
ignore_result(chown(SECRETS_FILE, uid, gid));
|
|
|
|
umask(oldmask);
|
|
|
|
}
|
2008-05-08 10:58:04 +00:00
|
|
|
}
|
2011-10-12 14:37:21 +00:00
|
|
|
#endif /* GENERATE_SELFCERT */
|
2008-05-08 10:58:04 +00:00
|
|
|
|
2011-09-28 10:07:19 +00:00
|
|
|
static bool check_pid(char *pid_file)
|
|
|
|
{
|
|
|
|
struct stat stb;
|
|
|
|
FILE *pidfile;
|
|
|
|
|
|
|
|
if (stat(pid_file, &stb) == 0)
|
|
|
|
{
|
|
|
|
pidfile = fopen(pid_file, "r");
|
|
|
|
if (pidfile)
|
|
|
|
{
|
|
|
|
char buf[64];
|
|
|
|
pid_t pid = 0;
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
if (fread(buf, 1, sizeof(buf), pidfile))
|
|
|
|
{
|
|
|
|
buf[sizeof(buf) - 1] = '\0';
|
|
|
|
pid = atoi(buf);
|
|
|
|
}
|
|
|
|
fclose(pidfile);
|
|
|
|
if (pid && kill(pid, 0) == 0)
|
|
|
|
{ /* such a process is running */
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG1(DBG_APP, "removing pidfile '%s', process not running", pid_file);
|
2011-09-28 10:07:19 +00:00
|
|
|
unlink(pid_file);
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2013-01-22 15:13:15 +00:00
|
|
|
/* Set daemon name and adjust command and pid filenames accordingly */
|
|
|
|
static bool set_daemon_name()
|
|
|
|
{
|
|
|
|
if (!daemon_name)
|
|
|
|
{
|
|
|
|
daemon_name = "charon";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (asprintf(&cmd, IPSEC_DIR"/%s", daemon_name) < 0)
|
|
|
|
{
|
|
|
|
cmd = (char*)cmd_default;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (asprintf(&pid_file, IPSEC_PIDDIR"/%s.pid", daemon_name) < 0)
|
|
|
|
{
|
|
|
|
pid_file = (char*)pid_file_default;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (asprintf(&starter_pid_file, IPSEC_PIDDIR"/starter.%s.pid",
|
|
|
|
daemon_name) < 0)
|
|
|
|
{
|
|
|
|
starter_pid_file = (char*)starter_pid_file_default;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void cleanup()
|
|
|
|
{
|
|
|
|
if (cmd != cmd_default)
|
|
|
|
{
|
|
|
|
free(cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pid_file != pid_file_default)
|
|
|
|
{
|
|
|
|
free(pid_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (starter_pid_file != starter_pid_file_default)
|
|
|
|
{
|
|
|
|
free(starter_pid_file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-07-17 18:33:19 +00:00
|
|
|
static void usage(char *name)
|
2006-04-28 07:14:48 +00:00
|
|
|
{
|
2012-09-12 15:11:54 +00:00
|
|
|
fprintf(stderr, "Usage: starter [--nofork] [--auto-update <sec>]\n"
|
2013-01-21 20:42:08 +00:00
|
|
|
" [--debug|--debug-more|--debug-all|--nolog]\n"
|
2013-01-22 15:13:15 +00:00
|
|
|
" [--attach-gdb] [--daemon <name>]\n");
|
2009-04-19 19:16:09 +00:00
|
|
|
exit(LSB_RC_INVALID_ARGUMENT);
|
2006-04-28 07:14:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
int main (int argc, char **argv)
|
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
starter_config_t *cfg = NULL;
|
|
|
|
starter_config_t *new_cfg;
|
|
|
|
starter_conn_t *conn, *conn2;
|
|
|
|
starter_ca_t *ca, *ca2;
|
|
|
|
|
2012-05-31 13:53:47 +00:00
|
|
|
struct sigaction action;
|
2009-04-19 19:16:09 +00:00
|
|
|
struct stat stb;
|
|
|
|
|
|
|
|
int i;
|
|
|
|
int id = 1;
|
2012-06-06 12:23:25 +00:00
|
|
|
struct timespec ts;
|
2009-04-19 19:16:09 +00:00
|
|
|
unsigned long auto_update = 0;
|
|
|
|
time_t last_reload;
|
|
|
|
bool no_fork = FALSE;
|
|
|
|
bool attach_gdb = FALSE;
|
2010-07-15 04:29:26 +00:00
|
|
|
bool load_warning = FALSE;
|
2009-04-19 19:16:09 +00:00
|
|
|
|
2010-04-29 12:33:29 +00:00
|
|
|
library_init(NULL);
|
|
|
|
atexit(library_deinit);
|
|
|
|
|
2011-10-21 12:14:36 +00:00
|
|
|
libhydra_init("starter");
|
|
|
|
atexit(libhydra_deinit);
|
|
|
|
|
2009-04-19 19:16:09 +00:00
|
|
|
/* parse command line */
|
|
|
|
for (i = 1; i < argc; i++)
|
2006-04-28 07:14:48 +00:00
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
if (streq(argv[i], "--debug"))
|
|
|
|
{
|
2012-05-14 09:22:57 +00:00
|
|
|
current_loglevel = 2;
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
|
|
|
else if (streq(argv[i], "--debug-more"))
|
|
|
|
{
|
2012-05-14 09:22:57 +00:00
|
|
|
current_loglevel = 3;
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
|
|
|
else if (streq(argv[i], "--debug-all"))
|
|
|
|
{
|
2012-05-14 09:22:57 +00:00
|
|
|
current_loglevel = 4;
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
2012-09-12 15:11:54 +00:00
|
|
|
else if (streq(argv[i], "--nolog"))
|
|
|
|
{
|
|
|
|
current_loglevel = 0;
|
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
else if (streq(argv[i], "--nofork"))
|
|
|
|
{
|
|
|
|
no_fork = TRUE;
|
|
|
|
}
|
|
|
|
else if (streq(argv[i], "--attach-gdb"))
|
|
|
|
{
|
|
|
|
no_fork = TRUE;
|
|
|
|
attach_gdb = TRUE;
|
|
|
|
}
|
|
|
|
else if (streq(argv[i], "--auto-update") && i+1 < argc)
|
|
|
|
{
|
|
|
|
auto_update = atoi(argv[++i]);
|
|
|
|
if (!auto_update)
|
|
|
|
usage(argv[0]);
|
|
|
|
}
|
2013-01-22 15:13:15 +00:00
|
|
|
else if (streq(argv[i], "--daemon") && i+1 < argc)
|
|
|
|
{
|
|
|
|
daemon_name = argv[++i];
|
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
usage(argv[0]);
|
|
|
|
}
|
2006-04-28 07:14:48 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
|
2013-01-22 15:13:15 +00:00
|
|
|
if (!set_daemon_name())
|
|
|
|
{
|
|
|
|
DBG1(DBG_APP, "unable to set daemon name");
|
|
|
|
exit(LSB_RC_FAILURE);
|
|
|
|
}
|
|
|
|
|
2009-04-19 19:16:09 +00:00
|
|
|
init_log("ipsec_starter");
|
|
|
|
|
2012-06-13 10:18:25 +00:00
|
|
|
DBG1(DBG_APP, "Starting %sSwan "VERSION" IPsec [starter]...",
|
|
|
|
lib->settings->get_bool(lib->settings,
|
|
|
|
"charon.i_dont_care_about_security_and_use_aggressive_mode_psk",
|
|
|
|
FALSE) ? "weak" : "strong");
|
2009-04-19 19:16:09 +00:00
|
|
|
|
2010-07-15 04:29:26 +00:00
|
|
|
#ifdef LOAD_WARNING
|
|
|
|
load_warning = TRUE;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (lib->settings->get_bool(lib->settings, "starter.load_warning", load_warning))
|
|
|
|
{
|
2012-05-14 15:33:03 +00:00
|
|
|
if (lib->settings->get_str(lib->settings, "charon.load", NULL))
|
2010-07-15 04:29:26 +00:00
|
|
|
{
|
2012-05-14 15:33:03 +00:00
|
|
|
DBG1(DBG_APP, "!! Your strongswan.conf contains manual plugin load options for charon.");
|
|
|
|
DBG1(DBG_APP, "!! This is recommended for experts only, see");
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG1(DBG_APP, "!! http://wiki.strongswan.org/projects/strongswan/wiki/PluginLoad");
|
2010-07-15 04:29:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-19 19:16:09 +00:00
|
|
|
/* verify that we can start */
|
|
|
|
if (getuid() != 0)
|
2006-04-28 07:14:48 +00:00
|
|
|
{
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG1(DBG_APP, "permission denied (must be superuser)");
|
2013-01-22 15:13:15 +00:00
|
|
|
cleanup();
|
2009-04-19 19:16:09 +00:00
|
|
|
exit(LSB_RC_NOT_ALLOWED);
|
2006-04-28 07:14:48 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
|
2013-01-22 15:13:15 +00:00
|
|
|
if (check_pid(pid_file))
|
2006-04-28 07:14:48 +00:00
|
|
|
{
|
2013-01-22 15:13:15 +00:00
|
|
|
DBG1(DBG_APP, "%s is already running (%s exists) -- skipping daemon start",
|
|
|
|
daemon_name, pid_file);
|
2006-04-28 07:14:48 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
_action_ |= FLAG_ACTION_START_CHARON;
|
2006-05-04 07:55:42 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
if (stat(DEV_RANDOM, &stb) != 0)
|
2007-07-02 17:48:30 +00:00
|
|
|
{
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_RANDOM);
|
2013-01-22 15:13:15 +00:00
|
|
|
cleanup();
|
2009-04-19 19:16:09 +00:00
|
|
|
exit(LSB_RC_FAILURE);
|
2007-07-02 17:48:30 +00:00
|
|
|
}
|
2006-05-23 08:01:49 +00:00
|
|
|
|
2009-04-19 19:16:09 +00:00
|
|
|
if (stat(DEV_URANDOM, &stb)!= 0)
|
2008-11-11 09:22:00 +00:00
|
|
|
{
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_URANDOM);
|
2013-01-22 15:13:15 +00:00
|
|
|
cleanup();
|
2009-04-19 19:16:09 +00:00
|
|
|
exit(LSB_RC_FAILURE);
|
2008-11-11 09:22:00 +00:00
|
|
|
}
|
2006-05-23 08:01:49 +00:00
|
|
|
|
2009-04-19 19:16:09 +00:00
|
|
|
cfg = confread_load(CONFIG_FILE);
|
|
|
|
if (cfg == NULL || cfg->err > 0)
|
2006-04-28 07:14:48 +00:00
|
|
|
{
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG1(DBG_APP, "unable to start strongSwan -- fatal errors in config");
|
2009-04-19 19:16:09 +00:00
|
|
|
if (cfg)
|
2006-04-28 07:14:48 +00:00
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
confread_free(cfg);
|
2006-04-28 07:14:48 +00:00
|
|
|
}
|
2013-01-22 15:13:15 +00:00
|
|
|
cleanup();
|
2009-04-19 19:16:09 +00:00
|
|
|
exit(LSB_RC_INVALID_ARGUMENT);
|
2006-05-23 08:01:49 +00:00
|
|
|
}
|
2006-04-28 07:14:48 +00:00
|
|
|
|
2009-04-19 19:16:09 +00:00
|
|
|
/* determine if we have a native netkey IPsec stack */
|
|
|
|
if (!starter_netkey_init())
|
2006-05-23 08:01:49 +00:00
|
|
|
{
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG1(DBG_APP, "no netkey IPsec stack detected");
|
2009-04-19 19:16:09 +00:00
|
|
|
if (!starter_klips_init())
|
|
|
|
{
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG1(DBG_APP, "no KLIPS IPsec stack detected");
|
|
|
|
DBG1(DBG_APP, "no known IPsec stack detected, ignoring!");
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
2006-05-23 08:01:49 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
|
2009-08-31 15:59:00 +00:00
|
|
|
last_reload = time_monotonic(NULL);
|
2009-04-19 19:16:09 +00:00
|
|
|
|
2013-01-22 15:13:15 +00:00
|
|
|
if (check_pid(starter_pid_file))
|
2006-05-23 08:01:49 +00:00
|
|
|
{
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG1(DBG_APP, "starter is already running (%s exists) -- no fork done",
|
2013-01-22 15:13:15 +00:00
|
|
|
starter_pid_file);
|
2010-05-02 09:00:21 +00:00
|
|
|
confread_free(cfg);
|
2013-01-22 15:13:15 +00:00
|
|
|
cleanup();
|
2009-04-19 19:16:09 +00:00
|
|
|
exit(LSB_RC_SUCCESS);
|
2006-05-23 08:01:49 +00:00
|
|
|
}
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2011-10-12 14:37:21 +00:00
|
|
|
#ifdef GENERATE_SELFCERT
|
2009-04-19 19:16:09 +00:00
|
|
|
generate_selfcert();
|
2011-10-12 14:37:21 +00:00
|
|
|
#endif
|
2006-04-28 07:14:48 +00:00
|
|
|
|
2009-04-19 19:16:09 +00:00
|
|
|
/* fork if we're not debugging stuff */
|
|
|
|
if (!no_fork)
|
2006-05-23 08:01:49 +00:00
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
log_to_stderr = FALSE;
|
|
|
|
|
|
|
|
switch (fork())
|
2006-04-28 07:14:48 +00:00
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
case 0:
|
2006-05-04 07:55:42 +00:00
|
|
|
{
|
2011-10-13 08:35:41 +00:00
|
|
|
int fnull;
|
2009-04-19 19:16:09 +00:00
|
|
|
|
2012-06-04 10:55:05 +00:00
|
|
|
close_log();
|
2011-10-13 08:35:41 +00:00
|
|
|
closefrom(3);
|
|
|
|
|
|
|
|
fnull = open("/dev/null", O_RDWR);
|
2009-04-19 19:16:09 +00:00
|
|
|
if (fnull >= 0)
|
|
|
|
{
|
|
|
|
dup2(fnull, STDIN_FILENO);
|
|
|
|
dup2(fnull, STDOUT_FILENO);
|
|
|
|
dup2(fnull, STDERR_FILENO);
|
|
|
|
close(fnull);
|
|
|
|
}
|
2011-10-13 08:35:41 +00:00
|
|
|
|
2009-09-04 11:46:09 +00:00
|
|
|
setsid();
|
2012-06-04 10:55:05 +00:00
|
|
|
init_log("ipsec_starter");
|
2006-05-23 08:01:49 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
break;
|
|
|
|
case -1:
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG1(DBG_APP, "can't fork: %s", strerror(errno));
|
2009-04-19 19:16:09 +00:00
|
|
|
break;
|
|
|
|
default:
|
2010-05-02 09:00:21 +00:00
|
|
|
confread_free(cfg);
|
2013-01-22 15:13:15 +00:00
|
|
|
cleanup();
|
2009-04-19 19:16:09 +00:00
|
|
|
exit(LSB_RC_SUCCESS);
|
2006-04-28 07:14:48 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
|
|
|
|
2013-01-22 15:13:15 +00:00
|
|
|
/* save pid file in /var/run/starter[.daemon_name].pid */
|
2009-04-19 19:16:09 +00:00
|
|
|
{
|
2013-01-22 15:13:15 +00:00
|
|
|
FILE *fd = fopen(starter_pid_file, "w");
|
2009-04-19 19:16:09 +00:00
|
|
|
|
|
|
|
if (fd)
|
2006-05-23 08:01:49 +00:00
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
fprintf(fd, "%u\n", getpid());
|
|
|
|
fclose(fd);
|
2006-05-23 08:01:49 +00:00
|
|
|
}
|
|
|
|
}
|
2006-04-28 07:14:48 +00:00
|
|
|
|
2012-06-07 10:02:14 +00:00
|
|
|
/* we handle these signals only in pselect() */
|
2012-05-31 13:53:47 +00:00
|
|
|
memset(&action, 0, sizeof(action));
|
|
|
|
sigemptyset(&action.sa_mask);
|
|
|
|
sigaddset(&action.sa_mask, SIGHUP);
|
|
|
|
sigaddset(&action.sa_mask, SIGINT);
|
|
|
|
sigaddset(&action.sa_mask, SIGTERM);
|
|
|
|
sigaddset(&action.sa_mask, SIGQUIT);
|
|
|
|
sigaddset(&action.sa_mask, SIGALRM);
|
|
|
|
sigaddset(&action.sa_mask, SIGUSR1);
|
|
|
|
pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL);
|
|
|
|
|
2012-06-06 12:23:25 +00:00
|
|
|
/* install a handler for fatal signals */
|
2012-05-31 13:53:47 +00:00
|
|
|
action.sa_handler = fatal_signal_handler;
|
|
|
|
sigaction(SIGSEGV, &action, NULL);
|
|
|
|
sigaction(SIGILL, &action, NULL);
|
|
|
|
sigaction(SIGBUS, &action, NULL);
|
|
|
|
action.sa_handler = SIG_IGN;
|
|
|
|
sigaction(SIGPIPE, &action, NULL);
|
|
|
|
|
2012-06-07 10:02:14 +00:00
|
|
|
/* install main signal handler */
|
2012-05-31 13:53:47 +00:00
|
|
|
action.sa_handler = signal_handler;
|
|
|
|
sigaction(SIGHUP, &action, NULL);
|
|
|
|
sigaction(SIGINT, &action, NULL);
|
|
|
|
sigaction(SIGTERM, &action, NULL);
|
|
|
|
sigaction(SIGQUIT, &action, NULL);
|
|
|
|
sigaction(SIGALRM, &action, NULL);
|
|
|
|
sigaction(SIGUSR1, &action, NULL);
|
2012-06-07 10:02:14 +00:00
|
|
|
/* this is not blocked above as we want to receive it asynchronously */
|
|
|
|
sigaction(SIGCHLD, &action, NULL);
|
2012-05-31 13:53:47 +00:00
|
|
|
|
2012-06-07 10:02:14 +00:00
|
|
|
/* empty mask for pselect() call below */
|
2012-06-06 12:23:25 +00:00
|
|
|
sigemptyset(&action.sa_mask);
|
|
|
|
|
2009-04-19 19:16:09 +00:00
|
|
|
for (;;)
|
2006-05-23 08:01:49 +00:00
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
/*
|
2012-05-14 15:33:03 +00:00
|
|
|
* Stop charon (if started) and exit
|
2009-04-19 19:16:09 +00:00
|
|
|
*/
|
|
|
|
if (_action_ & FLAG_ACTION_QUIT)
|
2006-05-23 08:01:49 +00:00
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
if (starter_charon_pid())
|
2009-07-17 18:33:19 +00:00
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
starter_stop_charon();
|
2009-07-17 18:33:19 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
starter_netkey_cleanup();
|
|
|
|
confread_free(cfg);
|
2013-01-22 15:13:15 +00:00
|
|
|
unlink(starter_pid_file);
|
|
|
|
cleanup();
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG1(DBG_APP, "ipsec starter stopped");
|
2010-05-02 09:00:21 +00:00
|
|
|
close_log();
|
2009-04-19 19:16:09 +00:00
|
|
|
exit(LSB_RC_SUCCESS);
|
2006-05-23 08:01:49 +00:00
|
|
|
}
|
|
|
|
|
2009-04-19 19:16:09 +00:00
|
|
|
/*
|
|
|
|
* Delete all connections. Will be added below
|
|
|
|
*/
|
|
|
|
if (_action_ & FLAG_ACTION_RELOAD)
|
2006-05-23 08:01:49 +00:00
|
|
|
{
|
2012-05-14 15:33:03 +00:00
|
|
|
if (starter_charon_pid())
|
2009-04-19 19:16:09 +00:00
|
|
|
{
|
|
|
|
for (conn = cfg->conn_first; conn; conn = conn->next)
|
|
|
|
{
|
|
|
|
if (conn->state == STATE_ADDED)
|
|
|
|
{
|
|
|
|
if (starter_charon_pid())
|
|
|
|
{
|
2012-10-04 09:22:44 +00:00
|
|
|
if (conn->startup == STARTUP_ROUTE)
|
|
|
|
{
|
|
|
|
starter_stroke_unroute_conn(conn);
|
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
starter_stroke_del_conn(conn);
|
|
|
|
}
|
|
|
|
conn->state = STATE_TO_ADD;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (ca = cfg->ca_first; ca; ca = ca->next)
|
|
|
|
{
|
|
|
|
if (ca->state == STATE_ADDED)
|
|
|
|
{
|
|
|
|
if (starter_charon_pid())
|
|
|
|
{
|
|
|
|
starter_stroke_del_ca(ca);
|
|
|
|
}
|
|
|
|
ca->state = STATE_TO_ADD;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_action_ &= ~FLAG_ACTION_RELOAD;
|
2006-05-23 08:01:49 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Update configuration
|
|
|
|
*/
|
|
|
|
if (_action_ & FLAG_ACTION_UPDATE)
|
2006-04-28 07:14:48 +00:00
|
|
|
{
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG2(DBG_APP, "Reloading config...");
|
2009-04-19 19:16:09 +00:00
|
|
|
new_cfg = confread_load(CONFIG_FILE);
|
2006-04-28 07:14:48 +00:00
|
|
|
|
2012-10-08 09:23:08 +00:00
|
|
|
if (new_cfg && (new_cfg->err == 0))
|
2006-04-28 07:14:48 +00:00
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
/* Switch to new config. New conn will be loaded below */
|
|
|
|
|
2012-05-14 15:33:03 +00:00
|
|
|
/* Look for new connections that are already loaded */
|
|
|
|
for (conn = cfg->conn_first; conn; conn = conn->next)
|
|
|
|
{
|
|
|
|
if (conn->state == STATE_ADDED)
|
2009-04-19 19:16:09 +00:00
|
|
|
{
|
2012-05-14 15:33:03 +00:00
|
|
|
for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
|
2009-04-19 19:16:09 +00:00
|
|
|
{
|
2012-05-14 15:33:03 +00:00
|
|
|
if (conn2->state == STATE_TO_ADD && starter_cmp_conn(conn, conn2))
|
2009-04-19 19:16:09 +00:00
|
|
|
{
|
2012-05-14 15:33:03 +00:00
|
|
|
conn->state = STATE_REPLACED;
|
|
|
|
conn2->state = STATE_ADDED;
|
|
|
|
conn2->id = conn->id;
|
|
|
|
break;
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-05-14 15:33:03 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
|
2012-05-14 15:33:03 +00:00
|
|
|
/* Remove conn sections that have become unused */
|
|
|
|
for (conn = cfg->conn_first; conn; conn = conn->next)
|
|
|
|
{
|
|
|
|
if (conn->state == STATE_ADDED)
|
2009-04-19 19:16:09 +00:00
|
|
|
{
|
2012-05-14 15:33:03 +00:00
|
|
|
if (starter_charon_pid())
|
2009-04-19 19:16:09 +00:00
|
|
|
{
|
2012-10-04 09:22:44 +00:00
|
|
|
if (conn->startup == STARTUP_ROUTE)
|
|
|
|
{
|
|
|
|
starter_stroke_unroute_conn(conn);
|
|
|
|
}
|
2012-05-14 15:33:03 +00:00
|
|
|
starter_stroke_del_conn(conn);
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
|
|
|
}
|
2012-05-14 15:33:03 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
|
2012-05-14 15:33:03 +00:00
|
|
|
/* Look for new ca sections that are already loaded */
|
|
|
|
for (ca = cfg->ca_first; ca; ca = ca->next)
|
|
|
|
{
|
|
|
|
if (ca->state == STATE_ADDED)
|
2009-04-19 19:16:09 +00:00
|
|
|
{
|
2012-05-14 15:33:03 +00:00
|
|
|
for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
|
2009-04-19 19:16:09 +00:00
|
|
|
{
|
2012-05-14 15:33:03 +00:00
|
|
|
if (ca2->state == STATE_TO_ADD && starter_cmp_ca(ca, ca2))
|
2009-04-19 19:16:09 +00:00
|
|
|
{
|
2012-05-14 15:33:03 +00:00
|
|
|
ca->state = STATE_REPLACED;
|
|
|
|
ca2->state = STATE_ADDED;
|
|
|
|
break;
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-05-14 15:33:03 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
|
2012-05-14 15:33:03 +00:00
|
|
|
/* Remove ca sections that have become unused */
|
|
|
|
for (ca = cfg->ca_first; ca; ca = ca->next)
|
|
|
|
{
|
|
|
|
if (ca->state == STATE_ADDED)
|
2009-04-19 19:16:09 +00:00
|
|
|
{
|
2012-05-14 15:33:03 +00:00
|
|
|
if (starter_charon_pid())
|
2009-04-19 19:16:09 +00:00
|
|
|
{
|
2012-05-14 15:33:03 +00:00
|
|
|
starter_stroke_del_ca(ca);
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
confread_free(cfg);
|
|
|
|
cfg = new_cfg;
|
|
|
|
}
|
|
|
|
else
|
2006-05-23 08:01:49 +00:00
|
|
|
{
|
2012-05-14 09:22:57 +00:00
|
|
|
DBG1(DBG_APP, "can't reload config file due to errors -- keeping old one");
|
2009-04-19 19:16:09 +00:00
|
|
|
if (new_cfg)
|
|
|
|
{
|
|
|
|
confread_free(new_cfg);
|
|
|
|
}
|
2006-05-04 07:55:42 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
_action_ &= ~FLAG_ACTION_UPDATE;
|
2009-08-31 15:59:00 +00:00
|
|
|
last_reload = time_monotonic(NULL);
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
2006-04-28 07:14:48 +00:00
|
|
|
|
2009-04-19 19:16:09 +00:00
|
|
|
/*
|
2013-01-22 15:13:15 +00:00
|
|
|
* Start daemon
|
2009-04-19 19:16:09 +00:00
|
|
|
*/
|
|
|
|
if (_action_ & FLAG_ACTION_START_CHARON)
|
2006-04-28 07:16:42 +00:00
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
if (cfg->setup.charonstart && !starter_charon_pid())
|
|
|
|
{
|
2013-01-22 15:13:15 +00:00
|
|
|
DBG2(DBG_APP, "Attempting to start %s...", daemon_name);
|
2009-04-19 19:16:09 +00:00
|
|
|
if (starter_start_charon(cfg, no_fork, attach_gdb))
|
|
|
|
{
|
|
|
|
/* schedule next try */
|
2012-05-14 15:33:03 +00:00
|
|
|
alarm(CHARON_RESTART_DELAY);
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
|
|
|
starter_stroke_configure(cfg);
|
|
|
|
}
|
|
|
|
_action_ &= ~FLAG_ACTION_START_CHARON;
|
2012-09-05 14:43:34 +00:00
|
|
|
|
|
|
|
for (ca = cfg->ca_first; ca; ca = ca->next)
|
|
|
|
{
|
|
|
|
if (ca->state == STATE_ADDED)
|
|
|
|
{
|
|
|
|
ca->state = STATE_TO_ADD;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (conn = cfg->conn_first; conn; conn = conn->next)
|
|
|
|
{
|
|
|
|
if (conn->state == STATE_ADDED)
|
|
|
|
{
|
|
|
|
conn->state = STATE_TO_ADD;
|
|
|
|
}
|
|
|
|
}
|
2006-04-28 07:16:42 +00:00
|
|
|
}
|
2006-05-23 08:01:49 +00:00
|
|
|
|
2009-04-19 19:16:09 +00:00
|
|
|
/*
|
|
|
|
* Add stale conn and ca sections
|
|
|
|
*/
|
2012-05-14 15:33:03 +00:00
|
|
|
if (starter_charon_pid())
|
2006-04-28 07:14:48 +00:00
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
for (ca = cfg->ca_first; ca; ca = ca->next)
|
2006-05-04 07:55:42 +00:00
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
if (ca->state == STATE_TO_ADD)
|
|
|
|
{
|
|
|
|
if (starter_charon_pid())
|
|
|
|
{
|
|
|
|
starter_stroke_add_ca(ca);
|
|
|
|
}
|
|
|
|
ca->state = STATE_ADDED;
|
|
|
|
}
|
2006-05-23 08:01:49 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
|
|
|
|
for (conn = cfg->conn_first; conn; conn = conn->next)
|
2006-05-23 08:01:49 +00:00
|
|
|
{
|
2009-04-19 19:16:09 +00:00
|
|
|
if (conn->state == STATE_TO_ADD)
|
|
|
|
{
|
|
|
|
if (conn->id == 0)
|
|
|
|
{
|
|
|
|
/* affect new unique id */
|
|
|
|
conn->id = id++;
|
|
|
|
}
|
|
|
|
if (starter_charon_pid())
|
|
|
|
{
|
|
|
|
starter_stroke_add_conn(cfg, conn);
|
|
|
|
}
|
|
|
|
conn->state = STATE_ADDED;
|
|
|
|
|
|
|
|
if (conn->startup == STARTUP_START)
|
|
|
|
{
|
2011-11-18 09:08:18 +00:00
|
|
|
if (starter_charon_pid())
|
2009-04-19 19:16:09 +00:00
|
|
|
{
|
2011-11-18 09:08:18 +00:00
|
|
|
starter_stroke_initiate_conn(conn);
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (conn->startup == STARTUP_ROUTE)
|
|
|
|
{
|
2011-11-18 09:08:18 +00:00
|
|
|
if (starter_charon_pid())
|
2009-04-19 19:16:09 +00:00
|
|
|
{
|
2011-11-18 09:08:18 +00:00
|
|
|
starter_stroke_route_conn(conn);
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-04-28 07:16:42 +00:00
|
|
|
}
|
2006-04-28 07:14:48 +00:00
|
|
|
}
|
|
|
|
|
2009-04-19 19:16:09 +00:00
|
|
|
/*
|
|
|
|
* If auto_update activated, when to stop select
|
|
|
|
*/
|
|
|
|
if (auto_update)
|
|
|
|
{
|
2009-08-31 15:59:00 +00:00
|
|
|
time_t now = time_monotonic(NULL);
|
2006-04-28 07:14:48 +00:00
|
|
|
|
2012-06-06 12:23:25 +00:00
|
|
|
ts.tv_sec = (now < last_reload + auto_update) ?
|
|
|
|
(last_reload + auto_update - now) : 0;
|
|
|
|
ts.tv_nsec = 0;
|
2009-04-19 19:16:09 +00:00
|
|
|
}
|
2006-05-04 07:55:42 +00:00
|
|
|
|
2009-04-19 19:16:09 +00:00
|
|
|
/*
|
|
|
|
* Wait for something to happen
|
|
|
|
*/
|
2013-01-22 15:13:15 +00:00
|
|
|
if (!_action_ &&
|
|
|
|
pselect(0, NULL, NULL, NULL, auto_update ? &ts : NULL,
|
2012-06-06 12:23:25 +00:00
|
|
|
&action.sa_mask) == 0)
|
2009-04-19 19:16:09 +00:00
|
|
|
{
|
|
|
|
/* timeout -> auto_update */
|
|
|
|
_action_ |= FLAG_ACTION_UPDATE;
|
|
|
|
}
|
2006-04-28 07:14:48 +00:00
|
|
|
}
|
2009-04-19 19:16:09 +00:00
|
|
|
exit(LSB_RC_SUCCESS);
|
2006-04-28 07:14:48 +00:00
|
|
|
}
|
|
|
|
|