starter: Remove main parts of pluto support (invoke, whack).

This commit is contained in:
Tobias Brunner 2012-05-14 17:33:03 +02:00
parent 95e41fb80a
commit 041e763b77
7 changed files with 57 additions and 976 deletions

View File

@ -4,8 +4,8 @@ include $(CLEAR_VARS)
# copy-n-paste from Makefile.am (update for LEX/YACC)
LOCAL_SRC_FILES := \
parser.c lexer.c ipsec-parser.h netkey.c args.h netkey.h \
starterwhack.c starterwhack.h starterstroke.c invokepluto.c confread.c \
starterstroke.h invokepluto.h confread.h args.c \
starterstroke.c confread.c \
starterstroke.h confread.h args.c \
keywords.c files.h keywords.h cmp.c starter.c cmp.h invokecharon.c \
invokecharon.h klips.c klips.h

View File

@ -1,8 +1,8 @@
ipsec_PROGRAMS = starter
starter_SOURCES = \
parser.y lexer.l ipsec-parser.h netkey.c args.h netkey.h \
starterwhack.c starterwhack.h starterstroke.c invokepluto.c confread.c \
starterstroke.h invokepluto.h confread.h args.c \
starterstroke.c confread.c \
starterstroke.h confread.h args.c \
keywords.c files.h keywords.h cmp.c starter.c cmp.h invokecharon.c \
invokecharon.h klips.c klips.h

View File

@ -1,326 +0,0 @@
/* strongSwan Pluto launcher
* 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.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <library.h>
#include <debug.h>
#include "confread.h"
#include "invokepluto.h"
#include "files.h"
#include "starterwhack.h"
static int _pluto_pid = 0;
static int _stop_requested;
pid_t
starter_pluto_pid(void)
{
return _pluto_pid;
}
void
starter_pluto_sigchild(pid_t pid, int status)
{
if (pid == _pluto_pid)
{
_pluto_pid = 0;
if (status == SS_RC_LIBSTRONGSWAN_INTEGRITY ||
status == SS_RC_DAEMON_INTEGRITY)
{
DBG1(DBG_APP, "pluto has quit: integrity test of %s failed",
(status == 64) ? "libstrongswan" : "pluto");
_stop_requested = 1;
}
else if (status == SS_RC_INITIALIZATION_FAILED)
{
DBG1(DBG_APP, "pluto has quit: initialization failed");
_stop_requested = 1;
}
if (!_stop_requested)
{
DBG1(DBG_APP, "pluto has died -- restart scheduled (%dsec)",
PLUTO_RESTART_DELAY);
alarm(PLUTO_RESTART_DELAY); // restart in 5 sec
}
unlink(PLUTO_PID_FILE);
}
}
int
starter_stop_pluto (void)
{
int i;
pid_t pid = _pluto_pid;
if (pid)
{
_stop_requested = 1;
if (starter_whack_shutdown() == 0)
{
for (i = 0; i < 400; i++)
{
usleep(20000); /* sleep for 20 ms */
if (_pluto_pid == 0)
{
DBG1(DBG_APP, "pluto stopped after %d ms", 20*(i+1));
return 0;
}
}
}
/* be more and more aggressive */
for (i = 0; i < 20 && (pid = _pluto_pid) != 0; i++)
{
if (i < 10)
{
kill(pid, SIGTERM);
}
if (i == 10)
{
kill(pid, SIGKILL);
DBG1(DBG_APP, "starter_stop_pluto(): pluto does not respond, sending KILL");
}
else
{
kill(pid, SIGKILL);
}
usleep(100000); /* sleep for 100 ms */
}
if (_pluto_pid == 0)
{
DBG1(DBG_APP, "pluto stopped after %d ms", 8000 + 100*i);
return 0;
}
DBG1(DBG_APP, "starter_stop_pluto(): can't stop pluto !!!");
return -1;
}
else
{
DBG1(DBG_APP, "stater_stop_pluto(): pluto is not started...");
}
return -1;
}
#define ADD_DEBUG(v) { \
for (l = cfg->setup.plutodebug; l && *l; l++) if (streq(*l, v)) \
arg[argc++] = "--debug-" v; \
}
int
starter_start_pluto (starter_config_t *cfg, bool no_fork, bool attach_gdb)
{
struct stat stb;
int i;
pid_t pid;
char **l;
int argc = 2;
char *arg[] = {
PLUTO_CMD, "--nofork"
, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
printf ("starter_start_pluto entered\n");
if (attach_gdb)
{
argc = 0;
arg[argc++] = "/usr/bin/gdb";
arg[argc++] = "--args";
arg[argc++] = PLUTO_CMD;
arg[argc++] = "--nofork";
}
if (cfg->setup.plutostderrlog || no_fork)
{
arg[argc++] = "--stderrlog";
}
if (cfg->setup.uniqueids)
{
arg[argc++] = "--uniqueids";
}
ADD_DEBUG("none")
ADD_DEBUG("all")
ADD_DEBUG("raw")
ADD_DEBUG("crypt")
ADD_DEBUG("parsing")
ADD_DEBUG("emitting")
ADD_DEBUG("control")
ADD_DEBUG("lifecycle")
ADD_DEBUG("klips")
ADD_DEBUG("kernel")
ADD_DEBUG("dns")
ADD_DEBUG("natt")
ADD_DEBUG("oppo")
ADD_DEBUG("controlmore")
ADD_DEBUG("private")
if (cfg->setup.crlcheckinterval > 0)
{
static char buf1[15];
arg[argc++] = "--crlcheckinterval";
snprintf(buf1, sizeof(buf1), "%d", (int)cfg->setup.crlcheckinterval);
arg[argc++] = buf1;
}
if (cfg->setup.cachecrls)
{
arg[argc++] = "--cachecrls";
}
if (cfg->setup.strictcrlpolicy)
{
arg[argc++] = "--strictcrlpolicy";
}
if (cfg->setup.nocrsend)
{
arg[argc++] = "--nocrsend";
}
if (cfg->setup.nat_traversal)
{
arg[argc++] = "--nat_traversal";
}
if (cfg->setup.force_keepalive)
{
arg[argc++] = "--force_keepalive";
}
if (cfg->setup.keep_alive)
{
static char buf2[15];
arg[argc++] = "--keep_alive";
snprintf(buf2, sizeof(buf2), "%d", (int)cfg->setup.keep_alive);
arg[argc++] = buf2;
}
if (cfg->setup.virtual_private)
{
arg[argc++] = "--virtual_private";
arg[argc++] = cfg->setup.virtual_private;
}
if (cfg->setup.pkcs11module)
{
arg[argc++] = "--pkcs11module";
arg[argc++] = cfg->setup.pkcs11module;
}
if (cfg->setup.pkcs11initargs)
{
arg[argc++] = "--pkcs11initargs";
arg[argc++] = cfg->setup.pkcs11initargs;
}
if (cfg->setup.pkcs11keepstate)
{
arg[argc++] = "--pkcs11keepstate";
}
if (cfg->setup.pkcs11proxy)
{
arg[argc++] = "--pkcs11proxy";
}
if (_pluto_pid)
{
DBG1(DBG_APP, "starter_start_pluto(): pluto already started...");
return -1;
}
else
{
unlink(PLUTO_CTL_FILE);
_stop_requested = 0;
if (cfg->setup.prepluto)
ignore_result(system(cfg->setup.prepluto));
pid = fork();
switch (pid)
{
case -1:
DBG1(DBG_APP, "can't fork(): %s", strerror(errno));
return -1;
case 0:
/* child */
if (cfg->setup.plutostderrlog)
{
int f = creat(cfg->setup.plutostderrlog, 00644);
/* redirect stderr to file */
if (f < 0)
{
DBG1(DBG_APP, "couldn't open stderr redirection file '%s'",
cfg->setup.plutostderrlog);
}
else
{
dup2(f, 2);
}
}
setsid();
closefrom(3);
sigprocmask(SIG_SETMASK, 0, NULL);
/* disable glibc's malloc checker, conflicts with leak detective */
setenv("MALLOC_CHECK_", "0", 1);
execv(arg[0], arg);
DBG1(DBG_APP, "can't execv(%s,...): %s", arg[0], strerror(errno));
exit(1);
default:
/* father */
_pluto_pid = pid;
for (i = 0; i < 500 && _pluto_pid; i++)
{
/* wait for pluto for a maximum of 500 x 20 ms = 10 s */
usleep(20000);
if (stat(PLUTO_CTL_FILE, &stb) == 0)
{
DBG1(DBG_APP, "pluto (%d) started after %d ms",
_pluto_pid, 20*(i+1));
if (cfg->setup.postpluto)
{
ignore_result(system(cfg->setup.postpluto));
}
return 0;
}
}
if (_pluto_pid)
{
/* If pluto is started but with no ctl file, stop it */
DBG1(DBG_APP, "pluto too long to start... - kill kill");
for (i = 0; i < 20 && (pid = _pluto_pid) != 0; i++)
{
if (i < 10)
{
kill(pid, SIGTERM);
}
else
{
kill(pid, SIGKILL);
}
usleep(20000); /* sleep for 20 ms */
}
}
else
{
DBG1(DBG_APP, "pluto refused to be started");
}
return -1;
}
}
return -1;
}

View File

@ -1,26 +0,0 @@
/* strongSwan pluto launcher
* 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.
*/
#ifndef _STARTER_PLUTO_H_
#define _STARTER_PLUTO_H_
#define PLUTO_RESTART_DELAY 5
extern void starter_pluto_sigchild (pid_t pid, int status);
extern pid_t starter_pluto_pid (void);
extern int starter_stop_pluto (void);
extern int starter_start_pluto (struct starter_config *cfg, bool no_fork, bool attach_gdb);
#endif /* _STARTER_PLUTO_H_ */

View File

@ -42,9 +42,7 @@
#include "confread.h"
#include "files.h"
#include "starterwhack.h"
#include "starterstroke.h"
#include "invokepluto.h"
#include "invokecharon.h"
#include "netkey.h"
#include "klips.h"
@ -54,6 +52,8 @@
#define LOG_AUTHPRIV LOG_AUTH
#endif
#define CHARON_RESTART_DELAY 5
/* logging */
static bool log_to_stderr = TRUE;
static bool log_to_syslog = TRUE;
@ -164,10 +164,6 @@ static void signal_handler(int signal)
while ((pid = waitpid(-1, &status, WNOHANG)) > 0)
{
if (pid == starter_pluto_pid())
{
name = " (Pluto)";
}
if (pid == starter_charon_pid())
{
name = " (Charon)";
@ -196,10 +192,6 @@ static void signal_handler(int signal)
{
DBG2(DBG_APP, "child %d%s has quit", pid, name?name:"");
}
if (pid == starter_pluto_pid())
{
starter_pluto_sigchild(pid, exit_status);
}
if (pid == starter_charon_pid())
{
starter_charon_sigchild(pid, exit_status);
@ -209,7 +201,6 @@ static void signal_handler(int signal)
break;
case SIGALRM:
_action_ |= FLAG_ACTION_START_PLUTO;
_action_ |= FLAG_ACTION_START_CHARON;
break;
@ -416,11 +407,10 @@ int main (int argc, char **argv)
if (lib->settings->get_bool(lib->settings, "starter.load_warning", load_warning))
{
if (lib->settings->get_str(lib->settings, "charon.load", NULL) ||
lib->settings->get_str(lib->settings, "pluto.load", NULL))
if (lib->settings->get_str(lib->settings, "charon.load", NULL))
{
DBG1(DBG_APP, "!! Your strongswan.conf contains manual plugin load options for");
DBG1(DBG_APP, "!! pluto and/or charon. This is recommended for experts only, see");
DBG1(DBG_APP, "!! Your strongswan.conf contains manual plugin load options for charon.");
DBG1(DBG_APP, "!! This is recommended for experts only, see");
DBG1(DBG_APP, "!! http://wiki.strongswan.org/projects/strongswan/wiki/PluginLoad");
}
}
@ -432,15 +422,6 @@ int main (int argc, char **argv)
exit(LSB_RC_NOT_ALLOWED);
}
if (check_pid(PLUTO_PID_FILE))
{
DBG1(DBG_APP, "pluto is already running (%s exists) -- skipping pluto start",
PLUTO_PID_FILE);
}
else
{
_action_ |= FLAG_ACTION_START_PLUTO;
}
if (check_pid(CHARON_PID_FILE))
{
DBG1(DBG_APP, "charon is already running (%s exists) -- skipping charon start",
@ -588,14 +569,10 @@ int main (int argc, char **argv)
for (;;)
{
/*
* Stop pluto/charon (if started) and exit
* Stop charon (if started) and exit
*/
if (_action_ & FLAG_ACTION_QUIT)
{
if (starter_pluto_pid())
{
starter_stop_pluto();
}
if (starter_charon_pid())
{
starter_stop_charon();
@ -614,7 +591,7 @@ int main (int argc, char **argv)
*/
if (_action_ & FLAG_ACTION_RELOAD)
{
if (starter_pluto_pid() || starter_charon_pid())
if (starter_charon_pid())
{
for (conn = cfg->conn_first; conn; conn = conn->next)
{
@ -624,10 +601,6 @@ int main (int argc, char **argv)
{
starter_stroke_del_conn(conn);
}
if (starter_pluto_pid())
{
starter_whack_del_conn(conn);
}
conn->state = STATE_TO_ADD;
}
}
@ -639,10 +612,6 @@ int main (int argc, char **argv)
{
starter_stroke_del_ca(ca);
}
if (starter_pluto_pid())
{
starter_whack_del_ca(ca);
}
ca->state = STATE_TO_ADD;
}
}
@ -661,82 +630,62 @@ int main (int argc, char **argv)
if (new_cfg && (new_cfg->err + new_cfg->non_fatal_err == 0))
{
/* Switch to new config. New conn will be loaded below */
if (!starter_cmp_pluto(cfg, new_cfg))
/* Look for new connections that are already loaded */
for (conn = cfg->conn_first; conn; conn = conn->next)
{
DBG1(DBG_APP, "Pluto has changed");
if (starter_pluto_pid())
starter_stop_pluto();
_action_ &= ~FLAG_ACTION_LISTEN;
_action_ |= FLAG_ACTION_START_PLUTO;
if (conn->state == STATE_ADDED)
{
for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
{
if (conn2->state == STATE_TO_ADD && starter_cmp_conn(conn, conn2))
{
conn->state = STATE_REPLACED;
conn2->state = STATE_ADDED;
conn2->id = conn->id;
break;
}
}
}
}
else
/* Remove conn sections that have become unused */
for (conn = cfg->conn_first; conn; conn = conn->next)
{
/* Only reload conn and ca sections if pluto is not killed */
/* Look for new connections that are already loaded */
for (conn = cfg->conn_first; conn; conn = conn->next)
if (conn->state == STATE_ADDED)
{
if (conn->state == STATE_ADDED)
if (starter_charon_pid())
{
for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next)
starter_stroke_del_conn(conn);
}
}
}
/* Look for new ca sections that are already loaded */
for (ca = cfg->ca_first; ca; ca = ca->next)
{
if (ca->state == STATE_ADDED)
{
for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
{
if (ca2->state == STATE_TO_ADD && starter_cmp_ca(ca, ca2))
{
if (conn2->state == STATE_TO_ADD && starter_cmp_conn(conn, conn2))
{
conn->state = STATE_REPLACED;
conn2->state = STATE_ADDED;
conn2->id = conn->id;
break;
}
ca->state = STATE_REPLACED;
ca2->state = STATE_ADDED;
break;
}
}
}
}
/* Remove conn sections that have become unused */
for (conn = cfg->conn_first; conn; conn = conn->next)
/* Remove ca sections that have become unused */
for (ca = cfg->ca_first; ca; ca = ca->next)
{
if (ca->state == STATE_ADDED)
{
if (conn->state == STATE_ADDED)
if (starter_charon_pid())
{
if (starter_charon_pid())
{
starter_stroke_del_conn(conn);
}
if (starter_pluto_pid())
{
starter_whack_del_conn(conn);
}
}
}
/* Look for new ca sections that are already loaded */
for (ca = cfg->ca_first; ca; ca = ca->next)
{
if (ca->state == STATE_ADDED)
{
for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next)
{
if (ca2->state == STATE_TO_ADD && starter_cmp_ca(ca, ca2))
{
ca->state = STATE_REPLACED;
ca2->state = STATE_ADDED;
break;
}
}
}
}
/* Remove ca sections that have become unused */
for (ca = cfg->ca_first; ca; ca = ca->next)
{
if (ca->state == STATE_ADDED)
{
if (starter_charon_pid())
{
starter_stroke_del_ca(ca);
}
if (starter_pluto_pid())
{
starter_whack_del_ca(ca);
}
starter_stroke_del_ca(ca);
}
}
}
@ -755,40 +704,6 @@ int main (int argc, char **argv)
last_reload = time_monotonic(NULL);
}
/*
* Start pluto
*/
if (_action_ & FLAG_ACTION_START_PLUTO)
{
if (cfg->setup.plutostart && !starter_pluto_pid())
{
DBG2(DBG_APP, "Attempting to start pluto...");
if (starter_start_pluto(cfg, no_fork, attach_gdb) == 0)
{
starter_whack_listen();
}
else
{
/* schedule next try */
alarm(PLUTO_RESTART_DELAY);
}
}
_action_ &= ~FLAG_ACTION_START_PLUTO;
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;
}
}
/*
* Start charon
*/
@ -800,29 +715,17 @@ int main (int argc, char **argv)
if (starter_start_charon(cfg, no_fork, attach_gdb))
{
/* schedule next try */
alarm(PLUTO_RESTART_DELAY);
alarm(CHARON_RESTART_DELAY);
}
starter_stroke_configure(cfg);
}
_action_ &= ~FLAG_ACTION_START_CHARON;
}
/*
* Tell pluto to reread its interfaces
*/
if (_action_ & FLAG_ACTION_LISTEN)
{
if (starter_pluto_pid())
{
starter_whack_listen();
_action_ &= ~FLAG_ACTION_LISTEN;
}
}
/*
* Add stale conn and ca sections
*/
if (starter_pluto_pid() || starter_charon_pid())
if (starter_charon_pid())
{
for (ca = cfg->ca_first; ca; ca = ca->next)
{
@ -832,10 +735,6 @@ int main (int argc, char **argv)
{
starter_stroke_add_ca(ca);
}
if (starter_pluto_pid())
{
starter_whack_add_ca(ca);
}
ca->state = STATE_ADDED;
}
}
@ -853,10 +752,6 @@ int main (int argc, char **argv)
{
starter_stroke_add_conn(cfg, conn);
}
if (starter_pluto_pid())
{
starter_whack_add_conn(conn);
}
conn->state = STATE_ADDED;
if (conn->startup == STARTUP_START)
@ -865,13 +760,6 @@ int main (int argc, char **argv)
{
starter_stroke_initiate_conn(conn);
}
if (conn->keyexchange == KEY_EXCHANGE_IKEV1)
{
if (starter_pluto_pid())
{
starter_whack_initiate_conn(conn);
}
}
}
else if (conn->startup == STARTUP_ROUTE)
{
@ -879,13 +767,6 @@ int main (int argc, char **argv)
{
starter_stroke_route_conn(conn);
}
if (conn->keyexchange == KEY_EXCHANGE_IKEV1)
{
if (starter_pluto_pid())
{
starter_whack_route_conn(conn);
}
}
}
}
}

View File

@ -1,418 +0,0 @@
/* strongSwan whack functions to communicate with pluto (whack.c)
* 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.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stddef.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <library.h>
#include <debug.h>
#include <constants.h>
#include <defs.h>
#include <whack.h>
#include "starterwhack.h"
#include "confread.h"
#include "files.h"
#define ip_version(string) (strchr(string, '.') ? AF_INET : AF_INET6)
static int pack_str (char **p, char **next, char **roof)
{
const char *s = (*p==NULL) ? "" : *p; /* note: NULL becomes ""! */
size_t len = strlen(s) + 1;
if ((*roof - *next) < len)
{
return 0; /* not enough space */
}
else
{
strcpy(*next, s);
*next += len;
*p = NULL; /* don't send pointers on the wire! */
return 1;
}
}
static int send_whack_msg (whack_message_t *msg)
{
struct sockaddr_un ctl_addr;
int sock;
ssize_t len;
char *str_next, *str_roof;
ctl_addr.sun_family = AF_UNIX;
strcpy(ctl_addr.sun_path, PLUTO_CTL_FILE);
/* pack strings */
str_next = (char *)msg->string;
str_roof = (char *)&msg->string[sizeof(msg->string)];
if (!pack_str(&msg->name, &str_next, &str_roof)
|| !pack_str(&msg->left.id, &str_next, &str_roof)
|| !pack_str(&msg->left.cert, &str_next, &str_roof)
|| !pack_str(&msg->left.ca, &str_next, &str_roof)
|| !pack_str(&msg->left.groups, &str_next, &str_roof)
|| !pack_str(&msg->left.updown, &str_next, &str_roof)
|| !pack_str(&msg->left.sourceip, &str_next, &str_roof)
|| !pack_str(&msg->left.virt, &str_next, &str_roof)
|| !pack_str(&msg->right.id, &str_next, &str_roof)
|| !pack_str(&msg->right.cert, &str_next, &str_roof)
|| !pack_str(&msg->right.ca, &str_next, &str_roof)
|| !pack_str(&msg->right.groups, &str_next, &str_roof)
|| !pack_str(&msg->right.updown, &str_next, &str_roof)
|| !pack_str(&msg->right.sourceip, &str_next, &str_roof)
|| !pack_str(&msg->right.virt, &str_next, &str_roof)
|| !pack_str(&msg->keyid, &str_next, &str_roof)
|| !pack_str(&msg->myid, &str_next, &str_roof)
|| !pack_str(&msg->cacert, &str_next, &str_roof)
|| !pack_str(&msg->ldaphost, &str_next, &str_roof)
|| !pack_str(&msg->ldapbase, &str_next, &str_roof)
|| !pack_str(&msg->crluri, &str_next, &str_roof)
|| !pack_str(&msg->crluri2, &str_next, &str_roof)
|| !pack_str(&msg->ocspuri, &str_next, &str_roof)
|| !pack_str(&msg->ike, &str_next, &str_roof)
|| !pack_str(&msg->esp, &str_next, &str_roof)
|| !pack_str(&msg->sc_data, &str_next, &str_roof)
|| !pack_str(&msg->whack_lease_ip, &str_next, &str_roof)
|| !pack_str(&msg->whack_lease_id, &str_next, &str_roof)
|| !pack_str(&msg->xauth_identity, &str_next, &str_roof)
|| (str_roof - str_next < msg->keyval.len))
{
DBG1(DBG_APP, "send_wack_msg(): can't pack strings");
return -1;
}
if (msg->keyval.ptr)
{
memcpy(str_next, msg->keyval.ptr, msg->keyval.len);
}
msg->keyval.ptr = NULL;
str_next += msg->keyval.len;
len = str_next - (char *)msg;
/* connect to pluto ctl */
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0)
{
DBG1(DBG_APP, "socket() failed: %s", strerror(errno));
return -1;
}
if (connect(sock, (struct sockaddr *)&ctl_addr,
offsetof(struct sockaddr_un, sun_path) + strlen(ctl_addr.sun_path)) < 0)
{
DBG1(DBG_APP, "connect(pluto_ctl) failed: %s", strerror(errno));
close(sock);
return -1;
}
/* send message */
if (write(sock, msg, len) != len)
{
DBG1(DBG_APP, "write(pluto_ctl) failed: %s", strerror(errno));
close(sock);
return -1;
}
/* TODO: read reply */
close(sock);
return 0;
}
static void init_whack_msg(whack_message_t *msg)
{
memset(msg, 0, sizeof(whack_message_t));
msg->magic = WHACK_MAGIC;
}
static char *connection_name(starter_conn_t *conn, char *buf, size_t size)
{
/* if connection name is '%auto', create a new name like conn_xxxxx */
if (streq(conn->name, "%auto"))
{
snprintf(buf, size, "conn_%ld", conn->id);
return buf;
}
return conn->name;
}
static void set_whack_end(whack_end_t *w, starter_end_t *end, sa_family_t family)
{
w->id = end->id;
w->cert = end->cert;
w->ca = end->ca;
w->groups = end->groups;
w->host_addr = end->addr;
w->has_client = end->has_client;
w->sourceip = end->sourceip;
w->sourceip_mask = end->sourceip_mask;
if (end->sourceip && end->sourceip_mask > 0)
{
ttoaddr(end->sourceip, 0, ip_version(end->sourceip), &w->host_srcip);
w->has_srcip = !end->has_natip;
}
else
{
anyaddr(AF_INET, &w->host_srcip);
}
if (family == AF_INET6 && isanyaddr(&end->nexthop))
{
anyaddr(AF_INET6, &end->nexthop);
}
w->host_nexthop = end->nexthop;
if (w->has_client)
{
char *pos;
int len = 0;
pos = strchr(end->subnet, ',');
if (pos)
{
len = pos - end->subnet;
}
ttosubnet(end->subnet, len, ip_version(end->subnet), &w->client);
}
else
{
if (end->has_virt)
{
w->virt = end->subnet;
}
w->client.addr.u.v4.sin_family = addrtypeof(&w->host_addr);
}
w->has_client_wildcard = end->has_client_wildcard;
w->has_port_wildcard = end->has_port_wildcard;
w->has_natip = end->has_natip;
w->allow_any = end->allow_any && !end->dns_failed;
w->modecfg = end->modecfg;
w->hostaccess = end->hostaccess;
w->sendcert = end->sendcert;
w->updown = end->updown;
w->host_port = IKE_UDP_PORT;
w->port = end->port;
w->protocol = end->protocol;
if (w->port != 0)
{
int port = htons(w->port);
setportof(port, &w->host_addr);
setportof(port, &w->client.addr);
}
}
static int
starter_whack_add_pubkey (starter_conn_t *conn, starter_end_t *end
, const char *lr)
{
const char *err;
static char keyspace[1024 + 4];
char buf[ADDRTOT_BUF], name[32];
whack_message_t msg;
init_whack_msg(&msg);
connection_name(conn, name, sizeof(name));
msg.whack_key = TRUE;
msg.pubkey_alg = PUBKEY_ALG_RSA;
if (end->rsakey)
{
/* special values to ignore */
if (streq(end->rsakey, "")
|| streq(end->rsakey, "%none")
|| streq(end->rsakey, "%cert")
|| streq(end->rsakey, "0x00"))
{
return 0;
}
err = atobytes(end->rsakey, 0, keyspace, sizeof(keyspace), &msg.keyval.len);
if (err)
{
DBG1(DBG_APP, "conn %s/%s: rsakey malformed [%s]", name, lr, err);
return 1;
}
if (end->id)
{
msg.keyid = end->id;
}
else
{
addrtot(&end->addr, 0, buf, sizeof(buf));
msg.keyid = buf;
}
msg.keyval.ptr = keyspace;
return send_whack_msg(&msg);
}
return 0;
}
int starter_whack_add_conn(starter_conn_t *conn)
{
char esp_buf[256], name[32];
whack_message_t msg;
int r;
init_whack_msg(&msg);
msg.whack_connection = TRUE;
msg.name = connection_name(conn, name, sizeof(name));
msg.ikev1 = conn->keyexchange == KEY_EXCHANGE_IKEV1;
msg.addr_family = conn->addr_family;
msg.tunnel_addr_family = conn->tunnel_addr_family;
msg.sa_ike_life_seconds = conn->sa_ike_life_seconds;
msg.sa_ipsec_life_seconds = conn->sa_ipsec_life_seconds;
msg.sa_rekey_margin = conn->sa_rekey_margin;
msg.sa_rekey_fuzz = conn->sa_rekey_fuzz;
msg.sa_keying_tries = conn->sa_keying_tries;
msg.policy = conn->policy;
msg.xauth_identity = conn->xauth_identity;
msg.reqid = conn->reqid;
msg.mark_in.value = conn->mark_in.value;
msg.mark_in.mask = conn->mark_in.mask;
msg.mark_out.value = conn->mark_out.value;
msg.mark_out.mask = conn->mark_out.mask;
/*
* Make sure the IKEv2-only policy bits are unset for IKEv1 connections
*/
msg.policy &= ~POLICY_DONT_REAUTH;
msg.policy &= ~POLICY_BEET;
msg.policy &= ~POLICY_MOBIKE;
msg.policy &= ~POLICY_FORCE_ENCAP;
set_whack_end(&msg.left, &conn->left, conn->addr_family);
set_whack_end(&msg.right, &conn->right, conn->addr_family);
msg.esp = conn->esp;
msg.ike = conn->ike;
msg.pfsgroup = conn->pfsgroup;
/* taken from pluto/whack.c */
if (msg.pfsgroup)
{
snprintf(esp_buf, sizeof (esp_buf), "%s;%s"
, msg.esp ? msg.esp : ""
, msg.pfsgroup ? msg.pfsgroup : "");
msg.esp = esp_buf;
DBG2(DBG_APP, "Setting --esp=%s", msg.esp);
}
msg.dpd_delay = conn->dpd_delay;
msg.dpd_timeout = conn->dpd_timeout;
msg.dpd_action = conn->dpd_action;
/* msg.dpd_count = conn->dpd_count; not supported yet by strongSwan */
r = send_whack_msg(&msg);
if (r == 0 && (conn->policy & POLICY_PUBKEY))
{
r += starter_whack_add_pubkey (conn, &conn->left, "left");
r += starter_whack_add_pubkey (conn, &conn->right, "right");
}
return r;
}
int starter_whack_del_conn(starter_conn_t *conn)
{
char name[32];
whack_message_t msg;
init_whack_msg(&msg);
msg.whack_delete = TRUE;
msg.name = connection_name(conn, name, sizeof(name));
return send_whack_msg(&msg);
}
int starter_whack_route_conn(starter_conn_t *conn)
{
char name[32];
whack_message_t msg;
init_whack_msg(&msg);
msg.whack_route = TRUE;
msg.name = connection_name(conn, name, sizeof(name));
return send_whack_msg(&msg);
}
int starter_whack_initiate_conn(starter_conn_t *conn)
{
char name[32];
whack_message_t msg;
init_whack_msg(&msg);
msg.whack_initiate = TRUE;
msg.whack_async = TRUE;
msg.name = connection_name(conn, name, sizeof(name));
return send_whack_msg(&msg);
}
int starter_whack_listen(void)
{
whack_message_t msg;
init_whack_msg(&msg);
msg.whack_listen = TRUE;
return send_whack_msg(&msg);
}
int starter_whack_shutdown(void)
{
whack_message_t msg;
init_whack_msg(&msg);
msg.whack_shutdown = TRUE;
return send_whack_msg(&msg);
}
int starter_whack_add_ca(starter_ca_t *ca)
{
whack_message_t msg;
init_whack_msg(&msg);
msg.whack_ca = TRUE;
msg.name = ca->name;
msg.cacert = ca->cacert;
msg.ldaphost = ca->ldaphost;
msg.ldapbase = ca->ldapbase;
msg.crluri = ca->crluri;
msg.crluri2 = ca->crluri2;
msg.ocspuri = ca->ocspuri;
msg.whack_strict = ca->strict;
return send_whack_msg(&msg);
}
int starter_whack_del_ca(starter_ca_t *ca)
{
whack_message_t msg;
init_whack_msg(&msg);
msg.whack_delete = TRUE;
msg.whack_ca = TRUE;
msg.name = ca->name;
return send_whack_msg(&msg);
}

View File

@ -1,30 +0,0 @@
/* FreeS/WAN whack functions to communicate with pluto (whack.h)
* 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.
*/
#ifndef _STARTER_WHACK_H_
#define _STARTER_WHACK_H_
#include "confread.h"
extern int starter_whack_add_conn(starter_conn_t *conn);
extern int starter_whack_del_conn(starter_conn_t *conn);
extern int starter_whack_route_conn(starter_conn_t *conn);
extern int starter_whack_initiate_conn(starter_conn_t *conn);
extern int starter_whack_listen(void);
extern int starter_whack_shutdown(void);
extern int starter_whack_add_ca(starter_ca_t *ca);
extern int starter_whack_del_ca(starter_ca_t *ca);
#endif /* _STARTER_WHACK_H_ */