Merge branch 'vici-ruby'
Adds a ruby gem for the VICI protocol, along with some documentation improvements and some minor fixes to vici and swanctl.
This commit is contained in:
@@ -17,6 +17,11 @@ strongswan-5.2.1
|
|||||||
- The new ext-auth plugin calls an external script to implement custom IKE_SA
|
- The new ext-auth plugin calls an external script to implement custom IKE_SA
|
||||||
authorization logic, courtesy of Vyronas Tsingaras.
|
authorization logic, courtesy of Vyronas Tsingaras.
|
||||||
|
|
||||||
|
- For the vici plugin a ruby gem has been added to allow ruby applications
|
||||||
|
to control or monitor the IKE daemon. The vici documentation has been updated
|
||||||
|
to include a description of the available operations and some simple examples
|
||||||
|
using both the libvici C interface and the ruby gem.
|
||||||
|
|
||||||
|
|
||||||
strongswan-5.2.0
|
strongswan-5.2.0
|
||||||
----------------
|
----------------
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ ARG_WITH_SET([capabilities], [no], [set capability dropping library. Cur
|
|||||||
ARG_WITH_SET([mpz_powm_sec], [yes], [use the more side-channel resistant mpz_powm_sec in libgmp, if available])
|
ARG_WITH_SET([mpz_powm_sec], [yes], [use the more side-channel resistant mpz_powm_sec in libgmp, if available])
|
||||||
ARG_WITH_SET([dev-headers], [no], [install strongSwan development headers to directory.])
|
ARG_WITH_SET([dev-headers], [no], [install strongSwan development headers to directory.])
|
||||||
ARG_WITH_SET([printf-hooks], [auto], [force the use of a specific printf hook implementation (auto, builtin, glibc, vstr).])
|
ARG_WITH_SET([printf-hooks], [auto], [force the use of a specific printf hook implementation (auto, builtin, glibc, vstr).])
|
||||||
|
ARG_WITH_SET([rubygemdir], ["gem environment gemdir"], [path to install ruby gems to])
|
||||||
|
|
||||||
if test -n "$PKG_CONFIG"; then
|
if test -n "$PKG_CONFIG"; then
|
||||||
systemdsystemunitdir_default=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
|
systemdsystemunitdir_default=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
|
||||||
@@ -285,6 +286,7 @@ ARG_ENABL_SET([integrity-test], [enable integrity testing of libstrongswan and p
|
|||||||
ARG_DISBL_SET([load-warning], [disable the charon plugin load option warning in starter.])
|
ARG_DISBL_SET([load-warning], [disable the charon plugin load option warning in starter.])
|
||||||
ARG_ENABL_SET([mediation], [enable IKEv2 Mediation Extension.])
|
ARG_ENABL_SET([mediation], [enable IKEv2 Mediation Extension.])
|
||||||
ARG_ENABL_SET([unwind-backtraces],[use libunwind to create backtraces for memory leaks and segfaults.])
|
ARG_ENABL_SET([unwind-backtraces],[use libunwind to create backtraces for memory leaks and segfaults.])
|
||||||
|
ARG_ENABL_SET([ruby-gems], [enable installation of provided ruby gems.])
|
||||||
# compile options
|
# compile options
|
||||||
ARG_ENABL_SET([coverage], [enable lcov coverage report generation.])
|
ARG_ENABL_SET([coverage], [enable lcov coverage report generation.])
|
||||||
ARG_ENABL_SET([leak-detective], [enable malloc hooks to find memory leaks.])
|
ARG_ENABL_SET([leak-detective], [enable malloc hooks to find memory leaks.])
|
||||||
@@ -1152,6 +1154,17 @@ if test x$coverage = xtrue; then
|
|||||||
CFLAGS="${CFLAGS} -g -O0"
|
CFLAGS="${CFLAGS} -g -O0"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test x$ruby_gems = xtrue; then
|
||||||
|
AC_PATH_PROG([GEM], [gem], [], [$PATH:/bin:/usr/bin:/usr/local/bin])
|
||||||
|
if test x$GEM = x; then
|
||||||
|
AC_MSG_ERROR(RubyGems package manager not found)
|
||||||
|
fi
|
||||||
|
if test "x$rubygemdir" = "xgem environment gemdir"; then
|
||||||
|
rubygemdir=$($GEM environment gemdir)
|
||||||
|
fi
|
||||||
|
AC_SUBST(RUBYGEMDIR, "$rubygemdir")
|
||||||
|
fi
|
||||||
|
|
||||||
# ===============================================
|
# ===============================================
|
||||||
# collect plugin list for strongSwan components
|
# collect plugin list for strongSwan components
|
||||||
# ===============================================
|
# ===============================================
|
||||||
@@ -1511,6 +1524,7 @@ AM_CONDITIONAL(USE_SWANCTL, test x$swanctl = xtrue)
|
|||||||
AM_CONDITIONAL(USE_SVC, test x$svc = xtrue)
|
AM_CONDITIONAL(USE_SVC, test x$svc = xtrue)
|
||||||
AM_CONDITIONAL(USE_SYSTEMD, test x$systemd = xtrue)
|
AM_CONDITIONAL(USE_SYSTEMD, test x$systemd = xtrue)
|
||||||
AM_CONDITIONAL(USE_LEGACY_SYSTEMD, test -n "$systemdsystemunitdir" -a "x$systemdsystemunitdir" != xno)
|
AM_CONDITIONAL(USE_LEGACY_SYSTEMD, test -n "$systemdsystemunitdir" -a "x$systemdsystemunitdir" != xno)
|
||||||
|
AM_CONDITIONAL(USE_RUBY_GEMS, test x$ruby_gems = xtrue)
|
||||||
|
|
||||||
# ========================
|
# ========================
|
||||||
# set global definitions
|
# set global definitions
|
||||||
@@ -1713,6 +1727,7 @@ AC_CONFIG_FILES([
|
|||||||
src/libcharon/plugins/maemo/Makefile
|
src/libcharon/plugins/maemo/Makefile
|
||||||
src/libcharon/plugins/stroke/Makefile
|
src/libcharon/plugins/stroke/Makefile
|
||||||
src/libcharon/plugins/vici/Makefile
|
src/libcharon/plugins/vici/Makefile
|
||||||
|
src/libcharon/plugins/vici/ruby/Makefile
|
||||||
src/libcharon/plugins/updown/Makefile
|
src/libcharon/plugins/updown/Makefile
|
||||||
src/libcharon/plugins/dhcp/Makefile
|
src/libcharon/plugins/dhcp/Makefile
|
||||||
src/libcharon/plugins/unit_tester/Makefile
|
src/libcharon/plugins/unit_tester/Makefile
|
||||||
|
|||||||
@@ -67,3 +67,10 @@ vici_tests_LDFLAGS = @COVERAGE_LDFLAGS@
|
|||||||
vici_tests_LDADD = \
|
vici_tests_LDADD = \
|
||||||
$(top_builddir)/src/libstrongswan/libstrongswan.la \
|
$(top_builddir)/src/libstrongswan/libstrongswan.la \
|
||||||
$(top_builddir)/src/libstrongswan/tests/libtest.la
|
$(top_builddir)/src/libstrongswan/tests/libtest.la
|
||||||
|
|
||||||
|
|
||||||
|
SUBDIRS =
|
||||||
|
|
||||||
|
if USE_RUBY_GEMS
|
||||||
|
SUBDIRS += ruby
|
||||||
|
endif
|
||||||
|
|||||||
@@ -84,12 +84,12 @@ The message encoding consists of a sequence of elements. Each element starts
|
|||||||
with the element type, optionally followed by an element name and/or an element
|
with the element type, optionally followed by an element name and/or an element
|
||||||
value. Currently the following message element types are defined:
|
value. Currently the following message element types are defined:
|
||||||
|
|
||||||
* _SECTION_START = 0_: Begin a new section having a name
|
* _SECTION_START = 1_: Begin a new section having a name
|
||||||
* _SECTION_END = 1_: End a previously started section
|
* _SECTION_END = 2_: End a previously started section
|
||||||
* _KEY_VALUE = 2_: Define a value for a named key in the current section
|
* _KEY_VALUE = 3_: Define a value for a named key in the current section
|
||||||
* _LIST_START = 3_: Begin a named list for list items
|
* _LIST_START = 4_: Begin a named list for list items
|
||||||
* _LIST_ITEM = 4_: Define an unnamed item value in the current list
|
* _LIST_ITEM = 5_: Define an unnamed item value in the current list
|
||||||
* _LIST_END = 5_: End a previously started list
|
* _LIST_END = 6_: End a previously started list
|
||||||
|
|
||||||
Types are encoded as 8-bit values. Types having a name (SECTION_START,
|
Types are encoded as 8-bit values. Types having a name (SECTION_START,
|
||||||
KEY_VALUE and LIST_START) have an ASCII string following the type, which itself
|
KEY_VALUE and LIST_START) have an ASCII string following the type, which itself
|
||||||
@@ -103,7 +103,8 @@ the length field itself.
|
|||||||
|
|
||||||
The interpretation of any value is not defined by the message format; it can
|
The interpretation of any value is not defined by the message format; it can
|
||||||
take arbitrary blobs. The application may specify types for specific keys, such
|
take arbitrary blobs. The application may specify types for specific keys, such
|
||||||
as strings or integer representations.
|
as strings or integer representations. The vici plugin currently uses
|
||||||
|
non-null terminated strings as values only; numbers get encoded as strings.
|
||||||
|
|
||||||
### Sections ###
|
### Sections ###
|
||||||
|
|
||||||
@@ -165,6 +166,513 @@ the following C array:
|
|||||||
1,
|
1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
## Client-initiated commands ##
|
||||||
|
|
||||||
|
Based on the packet layer, VICI implements commands requested by the client
|
||||||
|
and responded to by the server using named _CMD_REQUEST_ and _CMD_RESPONSE_
|
||||||
|
packets wrapping messages. The request message may contain command arguments,
|
||||||
|
the response message the reply.
|
||||||
|
|
||||||
|
Some commands use response streaming, that is, a request triggers a series of
|
||||||
|
events to consecutively stream data to the client before the response message
|
||||||
|
completes the stream. A client must register for the appropriate event to
|
||||||
|
receive the stream, and unregister after the response has been received.
|
||||||
|
|
||||||
|
The following client issued commands with the appropriate command input and
|
||||||
|
output messages are currently defined:
|
||||||
|
|
||||||
|
### version() ###
|
||||||
|
|
||||||
|
Returns daemon and system specific version information.
|
||||||
|
|
||||||
|
{} => {
|
||||||
|
daemon = <IKE daemon name>
|
||||||
|
version = <strongSwan version>
|
||||||
|
sysname = <operating system name>
|
||||||
|
release = <operating system release>
|
||||||
|
machine = <hardware identifier>
|
||||||
|
}
|
||||||
|
|
||||||
|
### stats() ###
|
||||||
|
|
||||||
|
Returns IKE daemon statistics and load information.
|
||||||
|
|
||||||
|
{} => {
|
||||||
|
uptime = {
|
||||||
|
running = <relative uptime in human-readable form>
|
||||||
|
since = <absolute startup time>
|
||||||
|
}
|
||||||
|
workers = {
|
||||||
|
total = <total number of worker threads>
|
||||||
|
idle = <worker threads currently idle>
|
||||||
|
active = {
|
||||||
|
critical = <threads processing "critical" priority jobs>
|
||||||
|
high = <threads processing "high" priority jobs>
|
||||||
|
medium = <threads processing "medium" priority jobs>
|
||||||
|
low = <threads processing "low" priority jobs>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
queues = {
|
||||||
|
critical = <jobs queued with "critical" priority>
|
||||||
|
high = <jobs queued with "high" priority>
|
||||||
|
medium = <jobs queued with "medium" priority>
|
||||||
|
low = <jobs queued with "low" priority>
|
||||||
|
}
|
||||||
|
scheduled = <number of jobs scheduled for timed execution>
|
||||||
|
ikesas = {
|
||||||
|
total = <total number of IKE_SAs active>
|
||||||
|
half-open = <number of IKE_SAs in half-open state>
|
||||||
|
}
|
||||||
|
plugins = [
|
||||||
|
<names of loaded plugins>
|
||||||
|
]
|
||||||
|
mem = { # available if built with leak-detective or on Windows
|
||||||
|
total = <total heap memory usage in bytes>
|
||||||
|
allocs = <total heap allocation blocks>
|
||||||
|
<heap-name>* = { # on Windows only
|
||||||
|
total = <heap memory usage in bytes by this heap>
|
||||||
|
allocs = <allocated blocks for this heap>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mallinfo = { # available with mallinfo() support
|
||||||
|
sbrk = <non-mmaped space available>
|
||||||
|
mmap = <mmaped space available>
|
||||||
|
used = <total number of bytes used>
|
||||||
|
free = <available but unused bytes>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
### reload-settings() ###
|
||||||
|
|
||||||
|
Reloads _strongswan.conf_ settings and all plugins supporting configuration
|
||||||
|
reload.
|
||||||
|
|
||||||
|
{} => {
|
||||||
|
success = <yes or no>
|
||||||
|
errmsg = <error string on failure>
|
||||||
|
}
|
||||||
|
|
||||||
|
### initiate() ###
|
||||||
|
|
||||||
|
Initiates an SA while streaming _control-log_ events.
|
||||||
|
|
||||||
|
{
|
||||||
|
child = <CHILD_SA configuration name to initiate>
|
||||||
|
timeout = <timeout in seconds before returning>
|
||||||
|
loglevel = <loglevel to issue "control-log" events for>
|
||||||
|
} => {
|
||||||
|
success = <yes or no>
|
||||||
|
errmsg = <error string on failure or timeout>
|
||||||
|
}
|
||||||
|
|
||||||
|
### terminate() ###
|
||||||
|
|
||||||
|
Terminates an SA while streaming _control-log_ events.
|
||||||
|
|
||||||
|
{
|
||||||
|
child = <terminate a CHILD_SA by configuration name>
|
||||||
|
ike = <terminate an IKE_SA by configuration name>
|
||||||
|
child_id = <terminate a CHILD_SA by its reqid>
|
||||||
|
ike_id = <terminate an IKE_SA by its unique id>
|
||||||
|
timeout = <timeout in seconds before returning>
|
||||||
|
loglevel = <loglevel to issue "control-log" events for>
|
||||||
|
} => {
|
||||||
|
success = <yes or no>
|
||||||
|
errmsg = <error string on failure or timeout>
|
||||||
|
}
|
||||||
|
|
||||||
|
### install() ###
|
||||||
|
|
||||||
|
Install a trap, drop or bypass policy defined by a CHILD_SA config.
|
||||||
|
|
||||||
|
{
|
||||||
|
child = <CHILD_SA configuration name to install>
|
||||||
|
} => {
|
||||||
|
success = <yes or no>
|
||||||
|
errmsg = <error string on failure>
|
||||||
|
}
|
||||||
|
|
||||||
|
### uninstall() ###
|
||||||
|
|
||||||
|
Uninstall a trap, drop or bypass policy defined by a CHILD_SA config.
|
||||||
|
|
||||||
|
{
|
||||||
|
child = <CHILD_SA configuration name to install>
|
||||||
|
} => {
|
||||||
|
success = <yes or no>
|
||||||
|
errmsg = <error string on failure>
|
||||||
|
}
|
||||||
|
|
||||||
|
### list-sas() ###
|
||||||
|
|
||||||
|
Lists currently active IKE_SAs and associated CHILD_SAs by streaming _list-sa_
|
||||||
|
events.
|
||||||
|
|
||||||
|
{
|
||||||
|
noblock = <use non-blocking mode if key is set>
|
||||||
|
ike = <filter listed IKE_SAs by its name>
|
||||||
|
ike_id = <filter listed IKE_SA by its unique id>
|
||||||
|
} => {
|
||||||
|
# completes after streaming list-sa events
|
||||||
|
}
|
||||||
|
|
||||||
|
### list-policies() ###
|
||||||
|
|
||||||
|
List currently installed trap, drop and bypass policies by streaming
|
||||||
|
_list-policy_ events.
|
||||||
|
|
||||||
|
{
|
||||||
|
drop = <set to yes to list drop policies>
|
||||||
|
pass = <set to yes to list bypass policies>
|
||||||
|
trap = <set to yes to list trap policies>
|
||||||
|
child = <filter by CHILD_SA configuration name>
|
||||||
|
} => {
|
||||||
|
# completes after streaming list-sa events
|
||||||
|
}
|
||||||
|
|
||||||
|
### list-conns() ###
|
||||||
|
|
||||||
|
List currently loaded connections by streaming _list-conn_ events. This
|
||||||
|
call includes all connections known by the daemon, not only those loaded
|
||||||
|
over vici.
|
||||||
|
|
||||||
|
{
|
||||||
|
ike = <list connections matching a given configuration name only>
|
||||||
|
} => {
|
||||||
|
# completes after streaming list-conn events
|
||||||
|
}
|
||||||
|
|
||||||
|
### get-conns() ###
|
||||||
|
|
||||||
|
Return a list of connection names loaded exclusively over vici, not including
|
||||||
|
connections found in other backends.
|
||||||
|
|
||||||
|
{} => {
|
||||||
|
conns = [
|
||||||
|
<list of connection names>
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
### list-certs() ###
|
||||||
|
|
||||||
|
List currently loaded certificates by streaming _list-cert_ events. This
|
||||||
|
call includes all certificates known by the daemon, not only those loaded
|
||||||
|
over vici.
|
||||||
|
|
||||||
|
{
|
||||||
|
type = <certificate type to filter for, or ANY>
|
||||||
|
subject = <set to list only certificates having subject>
|
||||||
|
} => {
|
||||||
|
# completes after streaming list-cert events
|
||||||
|
}
|
||||||
|
|
||||||
|
### load-conn() ###
|
||||||
|
|
||||||
|
Load a single connection definition into the daemon. An existing connection
|
||||||
|
with the same name gets updated or replaced.
|
||||||
|
|
||||||
|
{
|
||||||
|
<IKE_SA config name> = {
|
||||||
|
# IKE configuration parameters with authentication and CHILD_SA
|
||||||
|
# subsections. Refer to swanctl.conf(5) for details.
|
||||||
|
} => {
|
||||||
|
success = <yes or no>
|
||||||
|
errmsg = <error string on failure>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
### unload-conn() ###
|
||||||
|
|
||||||
|
Unload a previously loaded connection definition by name.
|
||||||
|
|
||||||
|
{
|
||||||
|
name = <IKE_SA config name>
|
||||||
|
} => {
|
||||||
|
success = <yes or no>
|
||||||
|
errmsg = <error string on failure>
|
||||||
|
}
|
||||||
|
|
||||||
|
### load-cert() ###
|
||||||
|
|
||||||
|
Load a certificate into the daemon.
|
||||||
|
|
||||||
|
{
|
||||||
|
type = <certificate type, X509|X509CA|X509AA|X509CRL|X509AC>
|
||||||
|
data = <PEM or DER encoded certificate data>
|
||||||
|
} => {
|
||||||
|
success = <yes or no>
|
||||||
|
errmsg = <error string on failure>
|
||||||
|
}
|
||||||
|
|
||||||
|
### load-key() ###
|
||||||
|
|
||||||
|
Load a private key into the daemon.
|
||||||
|
|
||||||
|
{
|
||||||
|
type = <private key type, RSA|ECDSA>
|
||||||
|
data = <PEM or DER encoded key data>
|
||||||
|
} => {
|
||||||
|
success = <yes or no>
|
||||||
|
errmsg = <error string on failure>
|
||||||
|
}
|
||||||
|
|
||||||
|
### load-shared() ###
|
||||||
|
|
||||||
|
Load a shared IKE PSK, EAP or XAuth secret into the daemon.
|
||||||
|
|
||||||
|
{
|
||||||
|
type = <private key type, IKE|EAP|XAUTH>
|
||||||
|
data = <raw shared key data>
|
||||||
|
owners = [
|
||||||
|
<list of shared key owner identities>
|
||||||
|
]
|
||||||
|
} => {
|
||||||
|
success = <yes or no>
|
||||||
|
errmsg = <error string on failure>
|
||||||
|
}
|
||||||
|
|
||||||
|
### clear-creds() ###
|
||||||
|
|
||||||
|
Clear all loaded certificate, private key and shared key credentials. This
|
||||||
|
affects only credentials loaded over vici, but additionally flushes the
|
||||||
|
credential cache.
|
||||||
|
|
||||||
|
{} => {
|
||||||
|
success = <yes or no>
|
||||||
|
errmsg = <error string on failure>
|
||||||
|
}
|
||||||
|
|
||||||
|
### load-pool() ###
|
||||||
|
|
||||||
|
Load an in-memory virtual IP and configuration attribute pool. Existing
|
||||||
|
pools with the same name get updated, if possible.
|
||||||
|
|
||||||
|
{
|
||||||
|
<pool name> = {
|
||||||
|
addrs = <subnet of virtual IP pool addresses>
|
||||||
|
<attribute type>* = [
|
||||||
|
# attribute type is one of address, dns, nbns, dhcp, netmask,
|
||||||
|
# server, subnet, split_include, split_exclude or a numerical
|
||||||
|
# attribute type identifier.
|
||||||
|
<list of attributes for type>
|
||||||
|
]
|
||||||
|
}
|
||||||
|
} => {
|
||||||
|
success = <yes or no>
|
||||||
|
errmsg = <error string on failure>
|
||||||
|
}
|
||||||
|
|
||||||
|
### unload-pool() ###
|
||||||
|
|
||||||
|
Unload a previously loaded virtual IP and configuration attribute pool.
|
||||||
|
Unloading fails for pools with leases currently online.
|
||||||
|
|
||||||
|
{
|
||||||
|
name = <virtual IP address pool to delete>
|
||||||
|
} => {
|
||||||
|
success = <yes or no>
|
||||||
|
errmsg = <error string on failure>
|
||||||
|
}
|
||||||
|
|
||||||
|
### get-pools() ###
|
||||||
|
|
||||||
|
List the currently loaded pools.
|
||||||
|
|
||||||
|
{} => {
|
||||||
|
<pool name>* = {
|
||||||
|
base = <virtual IP pool base address>
|
||||||
|
size = <total number of addresses in the pool>
|
||||||
|
online = <number of leases online>
|
||||||
|
offline = <number of leases offline>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## Server-issued events ##
|
||||||
|
|
||||||
|
Based on the packet layer, the vici plugin raises event messages using named
|
||||||
|
EVENT packets wrapping messages. The message contains event details.
|
||||||
|
|
||||||
|
### log ###
|
||||||
|
|
||||||
|
The _log_ event is issued to registered clients for each debug log message.
|
||||||
|
This event is not associated with a command.
|
||||||
|
|
||||||
|
{
|
||||||
|
group = <subsystem identifier for debug message>
|
||||||
|
level = <log level, 0-4>
|
||||||
|
thread = <numerical thread identifier issuing the log message>
|
||||||
|
ikesa-name = <name of IKE_SA, if log is associated with any>
|
||||||
|
ikesa-uniqued = <unique identifier of IKE_A, if log associated with any>
|
||||||
|
msg = <log message text>
|
||||||
|
}
|
||||||
|
|
||||||
|
### control-log ###
|
||||||
|
|
||||||
|
The _control-log_ event is issued for log events during active _initiate_ or
|
||||||
|
_terminate_ commands. It is issued only to clients currently having such
|
||||||
|
a command active.
|
||||||
|
|
||||||
|
{
|
||||||
|
group = <subsystem identifier for debug message>
|
||||||
|
level = <log level, 0-4>
|
||||||
|
ikesa-name = <name of IKE_SA, if log associated with any>
|
||||||
|
ikesa-uniqued = <unique identifier of IKE_A, if log associated with any>
|
||||||
|
msg = <log message text>
|
||||||
|
}
|
||||||
|
|
||||||
|
### list-sa ###
|
||||||
|
|
||||||
|
The _list-sa_ event is issued to stream IKE_SAs during an active _list-sas_
|
||||||
|
command.
|
||||||
|
|
||||||
|
{
|
||||||
|
<IKE_SA config name> = {
|
||||||
|
uniqueid = <IKE_SA unique identifier>
|
||||||
|
version = <IKE version, 1 or 2>
|
||||||
|
state = <IKE_SA state name>
|
||||||
|
local-host = <local IKE endpoint address>
|
||||||
|
local-id = <local IKE identity>
|
||||||
|
remote-host = <remote IKE endpoint address>
|
||||||
|
remote-id = <remote IKE identity>
|
||||||
|
remote-xauth-id = <remote XAuth identity, if XAuth-authenticated>
|
||||||
|
remote-eap-id = <remote EAP identity, if EAP-authenticated>
|
||||||
|
initiator = <yes, if initiator of IKE_SA>
|
||||||
|
initiator-spi = <hex encoded initiator SPI / cookie>
|
||||||
|
responder-spi = <hex encoded responder SPI / cookie>
|
||||||
|
encr-alg = <IKE encryption algorithm string>
|
||||||
|
encr-keysize = <key size for encr-alg, if applicable>
|
||||||
|
integ-alg = <IKE integrity algorithm string>
|
||||||
|
integ-keysize = <key size for encr-alg, if applicable>
|
||||||
|
prf-alg = <IKE pseudo random function string>
|
||||||
|
dh-group = <IKE Diffie-Hellman group string>
|
||||||
|
established = <seconds the IKE_SA has been established>
|
||||||
|
rekey-time = <seconds before IKE_SA gets rekeyed>
|
||||||
|
reauth-time = <seconds before IKE_SA gets re-authenticated>
|
||||||
|
tasks-queued = [
|
||||||
|
<list of currently queued tasks for execution>
|
||||||
|
]
|
||||||
|
tasks-active = [
|
||||||
|
<list of tasks currently initiating actively>
|
||||||
|
]
|
||||||
|
tasks-passive = [
|
||||||
|
<list of tasks currently handling passively>
|
||||||
|
]
|
||||||
|
child-sas = {
|
||||||
|
<child-sa-name>* = {
|
||||||
|
reqid = <reqid of CHILD_SA>
|
||||||
|
state = <state string of CHILD_SA>
|
||||||
|
mode = <IPsec mode, tunnel|transport|beet>
|
||||||
|
protocol = <IPsec protocol AH|ESP>
|
||||||
|
encap = <yes if using UDP encapsulation>
|
||||||
|
spi-in = <hex encoded inbound SPI>
|
||||||
|
spi-out = <hex encoded outbound SPI>
|
||||||
|
cpi-in = <hex encoded inbound CPI, if using compression>
|
||||||
|
cpi-out = <hex encoded outbound CPI, if using compression>
|
||||||
|
encr-alg = <ESP encryption algorithm name, if any>
|
||||||
|
encr-keysize = <ESP encryption key size, if applicable>
|
||||||
|
integ-alg = <ESP or AH integrity algorithm name, if any>
|
||||||
|
integ-keysize = <ESP or AH integrity key size, if applicable>
|
||||||
|
prf-alg = <CHILD_SA pseudo random function name>
|
||||||
|
dh-group = <CHILD_SA PFS rekeying DH group name, if any>
|
||||||
|
esn = <1 if using extended sequence numbers>
|
||||||
|
bytes-in = <number of input bytes processed>
|
||||||
|
packets-in = <number of input packets processed>
|
||||||
|
use-in = <seconds since last inbound packet, if any>
|
||||||
|
bytes-out = <number of output bytes processed>
|
||||||
|
packets-out = <number of output packets processed>
|
||||||
|
use-out = <seconds since last outbound packet, if any>
|
||||||
|
rekey-time = <seconds before CHILD_SA gets rekeyed>
|
||||||
|
life-time = <seconds before CHILD_SA expires>
|
||||||
|
install-time = <seconds the CHILD_SA has been installed>
|
||||||
|
local-ts = [
|
||||||
|
<list of local traffic selectors>
|
||||||
|
]
|
||||||
|
remote-ts = [
|
||||||
|
<list of remote traffic selectors>
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
### list-policy ###
|
||||||
|
|
||||||
|
The _list-policy_ event is issued to stream installed policies during an active
|
||||||
|
_list-policies_ command.
|
||||||
|
|
||||||
|
{
|
||||||
|
<child-sa-config-name> = {
|
||||||
|
mode = <policy mode, tunnel|transport|pass|drop>
|
||||||
|
local-ts = [
|
||||||
|
<list of local traffic selectors>
|
||||||
|
]
|
||||||
|
remote-ts = [
|
||||||
|
<list of remote traffic selectors>
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
### list-conn ###
|
||||||
|
|
||||||
|
The _list-conn_ event is issued to stream loaded connection during an active
|
||||||
|
_list-conns_ command.
|
||||||
|
|
||||||
|
{
|
||||||
|
<IKE_SA connection name> = {
|
||||||
|
local_addrs = [
|
||||||
|
<list of valid local IKE endpoint addresses>
|
||||||
|
]
|
||||||
|
remote_addrs = [
|
||||||
|
<list of valid remote IKE endpoint addresses>
|
||||||
|
]
|
||||||
|
version = <IKE version as string, IKEv1|IKEv2 or 0 for any>
|
||||||
|
|
||||||
|
local*, remote* = { # multiple local and remote auth sections
|
||||||
|
class = <authentication type>
|
||||||
|
eap-type = <EAP type to authenticate if when using EAP>
|
||||||
|
eap-vendor = <EAP vendor for type, if any>
|
||||||
|
xauth = <xauth backend name>
|
||||||
|
revocation = <revocation policy>
|
||||||
|
id = <IKE identity>
|
||||||
|
aaa_id = <AAA authentication backend identity>
|
||||||
|
eap_id = <EAP identity for authentication>
|
||||||
|
xauth_id = <XAuth username for authentication>
|
||||||
|
groups = [
|
||||||
|
<group membership required to use connection>
|
||||||
|
]
|
||||||
|
certs = [
|
||||||
|
<certificates allowed for authentication>
|
||||||
|
]
|
||||||
|
cacerts = [
|
||||||
|
<CA certificates allowed for authentication>
|
||||||
|
]
|
||||||
|
}
|
||||||
|
children = {
|
||||||
|
<CHILD_SA config name>* = {
|
||||||
|
mode = <IPsec mode>
|
||||||
|
local-ts = [
|
||||||
|
<list of local traffic selectors>
|
||||||
|
]
|
||||||
|
remote-ts = [
|
||||||
|
<list of remote traffic selectors>
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
### list-cert ###
|
||||||
|
|
||||||
|
The _list-cert_ event is issued to stream loaded certificates during an active
|
||||||
|
_list-certs_ command.
|
||||||
|
|
||||||
|
{
|
||||||
|
type = <certificate type>
|
||||||
|
has_privkey = <set if a private key for the certificate is available>
|
||||||
|
data = <ASN1 encoded certificate data>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# libvici C client library #
|
# libvici C client library #
|
||||||
|
|
||||||
libvici is the reference implementation of a C client library implementing
|
libvici is the reference implementation of a C client library implementing
|
||||||
@@ -172,5 +680,177 @@ the vici protocol. It builds upon libstrongswan, but provides a stable API
|
|||||||
to implement client applications in the C programming language. libvici uses
|
to implement client applications in the C programming language. libvici uses
|
||||||
the libstrongswan thread pool to deliver event messages asynchronously.
|
the libstrongswan thread pool to deliver event messages asynchronously.
|
||||||
|
|
||||||
More information about the libvici API is available in the libvici.h header
|
## Connecting to the daemon ##
|
||||||
file.
|
|
||||||
|
This example shows how to connect to the daemon using the default URI, and
|
||||||
|
then perform proper cleanup:
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <libvici.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
vici_conn_t *conn;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
vici_init();
|
||||||
|
conn = vici_connect(NULL);
|
||||||
|
if (conn)
|
||||||
|
{
|
||||||
|
/* do stuff */
|
||||||
|
vici_disconnect(conn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = errno;
|
||||||
|
fprintf(stderr, "connecting failed: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
vici_deinit();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
## A simple client request ##
|
||||||
|
|
||||||
|
In the following example, a simple _version_ request is issued to the daemon
|
||||||
|
and the result is printed:
|
||||||
|
|
||||||
|
int get_version(vici_conn_t *conn)
|
||||||
|
{
|
||||||
|
vici_req_t *req;
|
||||||
|
vici_res_t *res;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
req = vici_begin("version");
|
||||||
|
res = vici_submit(req, conn);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
printf("%s %s (%s, %s, %s)\n",
|
||||||
|
vici_find_str(res, "", "daemon"),
|
||||||
|
vici_find_str(res, "", "version"),
|
||||||
|
vici_find_str(res, "", "sysname"),
|
||||||
|
vici_find_str(res, "", "release"),
|
||||||
|
vici_find_str(res, "", "machine"));
|
||||||
|
vici_free_res(res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = errno;
|
||||||
|
fprintf(stderr, "version request failed: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
## A request with event streaming and callback parsing ##
|
||||||
|
|
||||||
|
In this more advanced example, the _list-conns_ command is used to stream
|
||||||
|
loaded connections with the _list-conn_ event. The event message is parsed
|
||||||
|
with a simple callback to print the connection name:
|
||||||
|
|
||||||
|
int conn_cb(void *null, vici_res_t *res, char *name)
|
||||||
|
{
|
||||||
|
printf("%s\n", name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void list_cb(void *null, char *name, vici_res_t *res)
|
||||||
|
{
|
||||||
|
if (vici_parse_cb(res, conn_cb, NULL, NULL, NULL) != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "parsing failed: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int list_conns(vici_conn_t *conn)
|
||||||
|
{
|
||||||
|
vici_req_t *req;
|
||||||
|
vici_res_t *res;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (vici_register(conn, "list-conn", list_cb, NULL) == 0)
|
||||||
|
{
|
||||||
|
req = vici_begin("list-conns");
|
||||||
|
res = vici_submit(req, conn);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
vici_free_res(res);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = errno;
|
||||||
|
fprintf(stderr, "request failed: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
vici_register(conn, "list-conn", NULL, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret = errno;
|
||||||
|
fprintf(stderr, "registration failed: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
## API documentation ##
|
||||||
|
|
||||||
|
More information about the libvici API is available in the _libvici.h_ header
|
||||||
|
file or the generated Doxygen documentation.
|
||||||
|
|
||||||
|
# vici ruby gem #
|
||||||
|
|
||||||
|
The _vici ruby gem_ is a pure ruby implementation of the VICI protocol to
|
||||||
|
implement client applications. It is provided in the _ruby_ subdirectory, and
|
||||||
|
gets built and installed if strongSwan has been _./configure_'d with
|
||||||
|
_--enable-vici_ and _--enable-ruby-gems_.
|
||||||
|
|
||||||
|
The _Connection_ class from the _Vici_ module provides the high level interface,
|
||||||
|
the underlying classes are usually not required to build ruby applications
|
||||||
|
using VICI. The _Connection_ class provides methods for the supported VICI
|
||||||
|
commands and an event listening mechanism.
|
||||||
|
|
||||||
|
To represent the VICI message data tree, the gem converts the binary encoding
|
||||||
|
to ruby data types. The _Connection_ class takes and returns ruby objects for
|
||||||
|
the exchanged message data:
|
||||||
|
* Sections get encoded as Hash, containing other sections as Hash, or
|
||||||
|
* Key/Values, where the values are Strings as Hash values
|
||||||
|
* Lists get encoded as Arrays with String values
|
||||||
|
Non-String values that are not a Hash nor an Array get converted with .to_s
|
||||||
|
during encoding.
|
||||||
|
|
||||||
|
## Connecting to the daemon ##
|
||||||
|
|
||||||
|
To create a connection to the daemon, a socket must be passed to the
|
||||||
|
_Connection_ constructor. There is no default, but on Unix systems usually
|
||||||
|
a Unix socket over _/var/run/charon.vici_ is used:
|
||||||
|
|
||||||
|
require "vici"
|
||||||
|
require "socket"
|
||||||
|
|
||||||
|
v = Vici::Connection.new(UNIXSocket.new("/var/run/charon.vici"))
|
||||||
|
|
||||||
|
## A simple client request ##
|
||||||
|
|
||||||
|
An example to print the daemon version information is as simple as:
|
||||||
|
|
||||||
|
x = v.version
|
||||||
|
puts "%s %s (%s, %s, %s)" % [
|
||||||
|
x["daemon"], x["version"], x["sysname"], x["release"], x["machine"]
|
||||||
|
]
|
||||||
|
|
||||||
|
## A request with closure invocation ##
|
||||||
|
|
||||||
|
The _Connection_ class takes care of event streaming by invoking a closure
|
||||||
|
for each event. The following example lists all loaded connections using the
|
||||||
|
_list-conns_ command and implicitly the _list-conn_ event:
|
||||||
|
|
||||||
|
v.list_conns { |conn|
|
||||||
|
conn.each { |key, value|
|
||||||
|
puts key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
## API documentation ##
|
||||||
|
|
||||||
|
For more details about the ruby gem refer to the comments in the gem source
|
||||||
|
code or the generated documentation.
|
||||||
|
|||||||
@@ -438,7 +438,7 @@ void vici_free_req(vici_req_t *req)
|
|||||||
free(req);
|
free(req);
|
||||||
}
|
}
|
||||||
|
|
||||||
int vici_dump(vici_res_t *res, char *label, bool pretty, FILE *out)
|
int vici_dump(vici_res_t *res, char *label, int pretty, FILE *out)
|
||||||
{
|
{
|
||||||
if (res->message->dump(res->message, label, pretty, out))
|
if (res->message->dump(res->message, label, pretty, out))
|
||||||
{
|
{
|
||||||
@@ -754,11 +754,14 @@ void vici_init()
|
|||||||
library_init(NULL, "vici");
|
library_init(NULL, "vici");
|
||||||
if (lib->processor->get_total_threads(lib->processor) < 4)
|
if (lib->processor->get_total_threads(lib->processor) < 4)
|
||||||
{
|
{
|
||||||
|
dbg_default_set_level(0);
|
||||||
lib->processor->set_threads(lib->processor, 4);
|
lib->processor->set_threads(lib->processor, 4);
|
||||||
|
dbg_default_set_level(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vici_deinit()
|
void vici_deinit()
|
||||||
{
|
{
|
||||||
|
lib->processor->cancel(lib->processor);
|
||||||
library_deinit();
|
library_deinit();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,8 +75,6 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <utils/utils.h>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opaque vici connection contex.
|
* Opaque vici connection contex.
|
||||||
*/
|
*/
|
||||||
@@ -284,7 +282,7 @@ void vici_free_req(vici_req_t *req);
|
|||||||
* @param out FILE to dump to
|
* @param out FILE to dump to
|
||||||
* @return 0 if dumped complete message, 1 on error
|
* @return 0 if dumped complete message, 1 on error
|
||||||
*/
|
*/
|
||||||
int vici_dump(vici_res_t *res, char *label, bool pretty, FILE *out);
|
int vici_dump(vici_res_t *res, char *label, int pretty, FILE *out);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse next element from a vici response message.
|
* Parse next element from a vici response message.
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
*.gem
|
||||||
|
*.gemspec
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
vici.gemspec: $(srcdir)/vici.gemspec.in
|
||||||
|
$(AM_V_GEN) sed \
|
||||||
|
-e "s:@GEM_VERSION@:$(PACKAGE_VERSION):" \
|
||||||
|
$(srcdir)/vici.gemspec.in > $@
|
||||||
|
|
||||||
|
vici-$(PACKAGE_VERSION).gem: vici.gemspec
|
||||||
|
$(GEM) build vici.gemspec
|
||||||
|
|
||||||
|
all-local: vici-$(PACKAGE_VERSION).gem
|
||||||
|
|
||||||
|
clean-local:
|
||||||
|
rm -f vici.gemspec vici-$(PACKAGE_VERSION).gem
|
||||||
|
|
||||||
|
install-data-local: vici-$(PACKAGE_VERSION).gem
|
||||||
|
$(GEM) install --install-dir $(DESTDIR)$(RUBYGEMDIR) \
|
||||||
|
vici-$(PACKAGE_VERSION).gem
|
||||||
|
|
||||||
|
uninstall-local:
|
||||||
|
$(GEM) uninstall --install-dir $(DESTDIR)$(RUBYGEMDIR) \
|
||||||
|
--version $(PACKAGE_VERSION) vici
|
||||||
@@ -0,0 +1,569 @@
|
|||||||
|
##
|
||||||
|
# The Vici module implements a native ruby client side library for the
|
||||||
|
# strongSwan VICI protocol. The Connection class provides a high-level
|
||||||
|
# interface to issue requests or listen for events.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2014 Martin Willi
|
||||||
|
# Copyright (C) 2014 revosec AG
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
|
||||||
|
module Vici
|
||||||
|
|
||||||
|
##
|
||||||
|
# Vici specific exception all others inherit from
|
||||||
|
class Error < StandardError
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Error while parsing a vici message from the daemon
|
||||||
|
class ParseError < Error
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Error while encoding a vici message from ruby data structures
|
||||||
|
class EncodeError < Error
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Error while exchanging messages over the vici Transport layer
|
||||||
|
class TransportError < Error
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Generic vici command execution error
|
||||||
|
class CommandError < Error
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Error if an issued vici command is unknown by the daemon
|
||||||
|
class CommandUnknownError < CommandError
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Error if a command failed to execute in the daemon
|
||||||
|
class CommandExecError < CommandError
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Generic vici event handling error
|
||||||
|
class EventError < Error
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Tried to register to / unregister from an unknown vici event
|
||||||
|
class EventUnknownError < EventError
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Exception to raise from an event listening closure to stop listening
|
||||||
|
class StopEventListening < Exception
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# The Message class provides the low level encoding and decoding of vici
|
||||||
|
# protocol messages. Directly using this class is usually not required.
|
||||||
|
class Message
|
||||||
|
|
||||||
|
SECTION_START = 1
|
||||||
|
SECTION_END = 2
|
||||||
|
KEY_VALUE = 3
|
||||||
|
LIST_START = 4
|
||||||
|
LIST_ITEM = 5
|
||||||
|
LIST_END = 6
|
||||||
|
|
||||||
|
def initialize(data = "")
|
||||||
|
if data == nil
|
||||||
|
@root = Hash.new()
|
||||||
|
elsif data.is_a?(Hash)
|
||||||
|
@root = data
|
||||||
|
else
|
||||||
|
@encoded = data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Get the raw byte encoding of an on-the-wire message
|
||||||
|
def encoding
|
||||||
|
if @encoded == nil
|
||||||
|
@encoded = encode(@root)
|
||||||
|
end
|
||||||
|
@encoded
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Get the root element of the parsed ruby data structures
|
||||||
|
def root
|
||||||
|
if @root == nil
|
||||||
|
@root = parse(@encoded)
|
||||||
|
end
|
||||||
|
@root
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def encode_name(name)
|
||||||
|
[name.length].pack("c") << name
|
||||||
|
end
|
||||||
|
|
||||||
|
def encode_value(value)
|
||||||
|
if value.class != String
|
||||||
|
value = value.to_s
|
||||||
|
end
|
||||||
|
[value.length].pack("n") << value
|
||||||
|
end
|
||||||
|
|
||||||
|
def encode_kv(encoding, key, value)
|
||||||
|
encoding << KEY_VALUE << encode_name(key) << encode_value(value)
|
||||||
|
end
|
||||||
|
|
||||||
|
def encode_section(encoding, key, value)
|
||||||
|
encoding << SECTION_START << encode_name(key)
|
||||||
|
encoding << encode(value) << SECTION_END
|
||||||
|
end
|
||||||
|
|
||||||
|
def encode_list(encoding, key, value)
|
||||||
|
encoding << LIST_START << encode_name(key)
|
||||||
|
value.each do |item|
|
||||||
|
encoding << LIST_ITEM << encode_value(item)
|
||||||
|
end
|
||||||
|
encoding << LIST_END
|
||||||
|
end
|
||||||
|
|
||||||
|
def encode(node)
|
||||||
|
encoding = ""
|
||||||
|
node.each do |key, value|
|
||||||
|
case value.class
|
||||||
|
when String, Fixnum, true, false
|
||||||
|
encoding = encode_kv(encoding, key, value)
|
||||||
|
else
|
||||||
|
if value.is_a?(Hash)
|
||||||
|
encoding = encode_section(encoding, key, value)
|
||||||
|
elsif value.is_a?(Array)
|
||||||
|
encoding = encode_list(encoding, key, value)
|
||||||
|
else
|
||||||
|
encoding = encode_kv(encoding, key, value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
encoding
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_name(encoding)
|
||||||
|
len = encoding.unpack("c")[0]
|
||||||
|
name = encoding[1, len]
|
||||||
|
return encoding[(1 + len)..-1], name
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse_value(encoding)
|
||||||
|
len = encoding.unpack("n")[0]
|
||||||
|
value = encoding[2, len]
|
||||||
|
return encoding[(2 + len)..-1], value
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse(encoding)
|
||||||
|
stack = [Hash.new]
|
||||||
|
list = nil
|
||||||
|
while encoding.length != 0 do
|
||||||
|
type = encoding.unpack("c")[0]
|
||||||
|
encoding = encoding[1..-1]
|
||||||
|
case type
|
||||||
|
when SECTION_START
|
||||||
|
encoding, name = parse_name(encoding)
|
||||||
|
stack.push(stack[-1][name] = Hash.new)
|
||||||
|
when SECTION_END
|
||||||
|
if stack.length() == 1
|
||||||
|
raise ParseError, "unexpected section end"
|
||||||
|
end
|
||||||
|
stack.pop()
|
||||||
|
when KEY_VALUE
|
||||||
|
encoding, name = parse_name(encoding)
|
||||||
|
encoding, value = parse_value(encoding)
|
||||||
|
stack[-1][name] = value
|
||||||
|
when LIST_START
|
||||||
|
encoding, name = parse_name(encoding)
|
||||||
|
stack[-1][name] = []
|
||||||
|
list = name
|
||||||
|
when LIST_ITEM
|
||||||
|
raise ParseError, "unexpected list item" if list == nil
|
||||||
|
encoding, value = parse_value(encoding)
|
||||||
|
stack[-1][list].push(value)
|
||||||
|
when LIST_END
|
||||||
|
raise ParseError, "unexpected list end" if list == nil
|
||||||
|
list = nil
|
||||||
|
else
|
||||||
|
raise ParseError, "invalid type: #{type}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if stack.length() > 1
|
||||||
|
raise ParseError, "unexpected message end"
|
||||||
|
end
|
||||||
|
stack[0]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# The Transport class implements to low level segmentation of packets
|
||||||
|
# to the underlying transport stream. Directly using this class is usually
|
||||||
|
# not required.
|
||||||
|
class Transport
|
||||||
|
|
||||||
|
CMD_REQUEST = 0
|
||||||
|
CMD_RESPONSE = 1
|
||||||
|
CMD_UNKNOWN = 2
|
||||||
|
EVENT_REGISTER = 3
|
||||||
|
EVENT_UNREGISTER = 4
|
||||||
|
EVENT_CONFIRM = 5
|
||||||
|
EVENT_UNKNOWN = 6
|
||||||
|
EVENT = 7
|
||||||
|
|
||||||
|
##
|
||||||
|
# Create a transport layer using a provided socket for communication.
|
||||||
|
def initialize(socket)
|
||||||
|
@socket = socket
|
||||||
|
@events = Hash.new
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Write a packet prefixed by its length over the transport socket. Type
|
||||||
|
# specifies the message, the optional label and message get appended.
|
||||||
|
def write(type, label, message)
|
||||||
|
encoding = ""
|
||||||
|
if label
|
||||||
|
encoding << label.length << label
|
||||||
|
end
|
||||||
|
if message
|
||||||
|
encoding << message.encoding
|
||||||
|
end
|
||||||
|
@socket.send([encoding.length + 1, type].pack("Nc") + encoding, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Read a packet from the transport socket. Returns the packet type, and
|
||||||
|
# if available in the packet a label and the contained message.
|
||||||
|
def read
|
||||||
|
len = @socket.recv(4).unpack("N")[0]
|
||||||
|
encoding = @socket.recv(len)
|
||||||
|
type = encoding.unpack("c")[0]
|
||||||
|
len = 1
|
||||||
|
case type
|
||||||
|
when CMD_REQUEST, EVENT_REGISTER, EVENT_UNREGISTER, EVENT
|
||||||
|
label = encoding[2, encoding[1].unpack("c")[0]]
|
||||||
|
len += label.length + 1
|
||||||
|
when CMD_RESPONSE, CMD_UNKNOWN, EVENT_CONFIRM, EVENT_UNKNOWN
|
||||||
|
label = nil
|
||||||
|
else
|
||||||
|
raise TransportError, "invalid message: #{type}"
|
||||||
|
end
|
||||||
|
if encoding.length == len
|
||||||
|
return type, label, Message.new
|
||||||
|
end
|
||||||
|
return type, label, Message.new(encoding[len..-1])
|
||||||
|
end
|
||||||
|
|
||||||
|
def dispatch_event(name, message)
|
||||||
|
@events[name].each do |handler|
|
||||||
|
handler.call(name, message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def read_and_dispatch_event
|
||||||
|
type, label, message = read
|
||||||
|
p
|
||||||
|
if type == EVENT
|
||||||
|
dispatch_event(label, message)
|
||||||
|
else
|
||||||
|
raise TransportError, "unexpected message: #{type}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def read_and_dispatch_events
|
||||||
|
loop do
|
||||||
|
type, label, message = read
|
||||||
|
if type == EVENT
|
||||||
|
dispatch_event(label, message)
|
||||||
|
else
|
||||||
|
return type, label, message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Send a command with a given name, and optionally a message. Returns
|
||||||
|
# the reply message on success.
|
||||||
|
def request(name, message = nil)
|
||||||
|
write(CMD_REQUEST, name, message)
|
||||||
|
type, label, message = read_and_dispatch_events
|
||||||
|
case type
|
||||||
|
when CMD_RESPONSE
|
||||||
|
return message
|
||||||
|
when CMD_UNKNOWN
|
||||||
|
raise CommandUnknownError, name
|
||||||
|
else
|
||||||
|
raise CommandError, "invalid response for #{name}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Register a handler method for the given event name
|
||||||
|
def register(name, handler)
|
||||||
|
write(EVENT_REGISTER, name, nil)
|
||||||
|
type, label, message = read_and_dispatch_events
|
||||||
|
case type
|
||||||
|
when EVENT_CONFIRM
|
||||||
|
if @events.has_key?(name)
|
||||||
|
@events[name] += [handler]
|
||||||
|
else
|
||||||
|
@events[name] = [handler];
|
||||||
|
end
|
||||||
|
when EVENT_UNKNOWN
|
||||||
|
raise EventUnknownError, name
|
||||||
|
else
|
||||||
|
raise EventError, "invalid response for #{name} register"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Unregister a handler method for the given event name
|
||||||
|
def unregister(name, handler)
|
||||||
|
write(EVENT_UNREGISTER, name, nil)
|
||||||
|
type, label, message = read_and_dispatch_events
|
||||||
|
case type
|
||||||
|
when EVENT_CONFIRM
|
||||||
|
@events[name] -= [handler]
|
||||||
|
when EVENT_UNKNOWN
|
||||||
|
raise EventUnknownError, name
|
||||||
|
else
|
||||||
|
raise EventError, "invalid response for #{name} unregister"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# The Connection class provides the high-level interface to monitor, configure
|
||||||
|
# and control the IKE daemon. It takes a connected stream-oriented Socket for
|
||||||
|
# the communication with the IKE daemon.
|
||||||
|
#
|
||||||
|
# This class takes and returns ruby objects for the exchanged message data.
|
||||||
|
# * Sections get encoded as Hash, containing other sections as Hash, or
|
||||||
|
# * Key/Values, where the values are Strings as Hash values
|
||||||
|
# * Lists get encoded as Arrays with String values
|
||||||
|
# Non-String values that are not a Hash nor an Array get converted with .to_s
|
||||||
|
# during encoding.
|
||||||
|
class Connection
|
||||||
|
|
||||||
|
def initialize(socket)
|
||||||
|
@transp = Transport.new(socket)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# List matching loaded connections. The provided closure is invoked
|
||||||
|
# for each matching connection.
|
||||||
|
def list_conns(match = nil, &block)
|
||||||
|
call_with_event("list-conns", Message.new(match), "list-conn", &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# List matching active SAs. The provided closure is invoked for each
|
||||||
|
# matching SA.
|
||||||
|
def list_sas(match = nil, &block)
|
||||||
|
call_with_event("list-sas", Message.new(match), "list-sa", &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# List matching installed policies. The provided closure is invoked
|
||||||
|
# for each matching policy.
|
||||||
|
def list_policies(match, &block)
|
||||||
|
call_with_event("list-policies", Message.new(match), "list-policy",
|
||||||
|
&block)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# List matching loaded certificates. The provided closure is invoked
|
||||||
|
# for each matching certificate definition.
|
||||||
|
def list_certs(match = nil, &block)
|
||||||
|
call_with_event("list-certs", Message.new(match), "list-cert", &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Load a connection into the daemon.
|
||||||
|
def load_conn(conn)
|
||||||
|
check_success(@transp.request("load-conn", Message.new(conn)))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Unload a connection from the daemon.
|
||||||
|
def unload_conn(conn)
|
||||||
|
check_success(@transp.request("unload-conn", Message.new(conn)))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Get the names of connections managed by vici.
|
||||||
|
def get_conns()
|
||||||
|
@transp.request("get-conns").root
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Clear all loaded credentials.
|
||||||
|
def clear_creds()
|
||||||
|
check_success(@transp.request("clear-creds"))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Load a certificate into the daemon.
|
||||||
|
def load_cert(cert)
|
||||||
|
check_success(@transp.request("load-cert", Message.new(cert)))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Load a private key into the daemon.
|
||||||
|
def load_key(key)
|
||||||
|
check_success(@transp.request("load-key", Message.new(key)))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Load a shared key into the daemon.
|
||||||
|
def load_shared(shared)
|
||||||
|
check_success(@transp.request("load-shared", Message.new(shared)))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Load a virtual IP / attribute pool
|
||||||
|
def load_pool(pool)
|
||||||
|
check_success(@transp.request("load-pool", Message.new(pool)))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Unload a virtual IP / attribute pool
|
||||||
|
def unload_pool(pool)
|
||||||
|
check_success(@transp.request("unload-pool", Message.new(pool)))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Get the currently loaded pools.
|
||||||
|
def get_pools()
|
||||||
|
@transp.request("get-pools").root
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Initiate a connection. The provided closure is invoked for each log line.
|
||||||
|
def initiate(options, &block)
|
||||||
|
check_success(call_with_event("initiate", Message.new(options),
|
||||||
|
"control-log", &block))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Terminate a connection. The provided closure is invoked for each log line.
|
||||||
|
def terminate(options, &block)
|
||||||
|
check_success(call_with_event("terminate", Message.new(options),
|
||||||
|
"control-log", &block))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Install a shunt/route policy.
|
||||||
|
def install(policy)
|
||||||
|
check_success(@transp.request("install", Message.new(policy)))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Uninstall a shunt/route policy.
|
||||||
|
def uninstall(policy)
|
||||||
|
check_success(@transp.request("uninstall", Message.new(policy)))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Reload strongswan.conf settings.
|
||||||
|
def reload_settings
|
||||||
|
check_success(@transp.request("reload-settings", nil))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Get daemon statistics and information.
|
||||||
|
def stats
|
||||||
|
@transp.request("stats", nil).root
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Get daemon version information
|
||||||
|
def version
|
||||||
|
@transp.request("version", nil).root
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Listen for a set of event messages. This call is blocking, and invokes
|
||||||
|
# the passed closure for each event received. The closure receives the
|
||||||
|
# event name and the event message as argument. To stop listening, the
|
||||||
|
# closure may raise a StopEventListening exception, the only catched
|
||||||
|
# exception.
|
||||||
|
def listen_events(events, &block)
|
||||||
|
self.class.instance_eval do
|
||||||
|
define_method(:listen_event) do |label, message|
|
||||||
|
block.call(label, message.root)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
events.each do |event|
|
||||||
|
@transp.register(event, method(:listen_event))
|
||||||
|
end
|
||||||
|
begin
|
||||||
|
loop do
|
||||||
|
@transp.read_and_dispatch_event
|
||||||
|
end
|
||||||
|
rescue StopEventListening
|
||||||
|
ensure
|
||||||
|
events.each do |event|
|
||||||
|
@transp.unregister(event, method(:listen_event))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Issue a command request, but register for a specific event while the
|
||||||
|
# command is active. VICI uses this mechanism to stream potentially large
|
||||||
|
# data objects continuously. The provided closure is invoked for all
|
||||||
|
# event messages.
|
||||||
|
def call_with_event(command, request, event, &block)
|
||||||
|
self.class.instance_eval do
|
||||||
|
define_method(:call_event) do |label, message|
|
||||||
|
block.call(message.root)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@transp.register(event, method(:call_event))
|
||||||
|
begin
|
||||||
|
reply = @transp.request(command, request)
|
||||||
|
ensure
|
||||||
|
@transp.unregister(event, method(:call_event))
|
||||||
|
end
|
||||||
|
reply
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Check if the reply of a command indicates "success", otherwise raise a
|
||||||
|
# CommandExecError exception
|
||||||
|
def check_success(reply)
|
||||||
|
root = reply.root
|
||||||
|
if root["success"] != "yes"
|
||||||
|
raise CommandExecError, root["errmsg"]
|
||||||
|
end
|
||||||
|
root
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
Gem::Specification.new do |s|
|
||||||
|
s.name = "vici"
|
||||||
|
s.version = "@GEM_VERSION@"
|
||||||
|
s.authors = ["Martin Willi"]
|
||||||
|
s.email = ["[email protected]"]
|
||||||
|
s.description = %q{
|
||||||
|
The strongSwan VICI protocol allows external application to monitor,
|
||||||
|
configure and control the IKE daemon charon. This ruby gem provides a
|
||||||
|
native client side implementation of the VICI protocol, well suited to
|
||||||
|
script automated tasks in a relaible way.
|
||||||
|
}
|
||||||
|
s.summary = "Native ruby interface for strongSwan VICI"
|
||||||
|
s.homepage = "https://wiki.strongswan.org/projects/strongswan/wiki/Vici"
|
||||||
|
s.license = "MIT"
|
||||||
|
s.files = "lib/vici.rb"
|
||||||
|
end
|
||||||
@@ -270,13 +270,10 @@ CALLBACK(load_shared, vici_message_t*,
|
|||||||
CALLBACK(clear_creds, vici_message_t*,
|
CALLBACK(clear_creds, vici_message_t*,
|
||||||
private_vici_cred_t *this, char *name, u_int id, vici_message_t *message)
|
private_vici_cred_t *this, char *name, u_int id, vici_message_t *message)
|
||||||
{
|
{
|
||||||
vici_builder_t *builder;
|
|
||||||
|
|
||||||
this->creds->clear(this->creds);
|
this->creds->clear(this->creds);
|
||||||
lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
|
lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
|
||||||
|
|
||||||
builder = vici_builder_create();
|
return create_reply(NULL);
|
||||||
return builder->finalize(builder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void manage_command(private_vici_cred_t *this,
|
static void manage_command(private_vici_cred_t *this,
|
||||||
|
|||||||
@@ -267,9 +267,10 @@ static int call_command(command_t *cmd)
|
|||||||
conn = vici_connect(uri);
|
conn = vici_connect(uri);
|
||||||
if (!conn)
|
if (!conn)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
command_usage("connecting to '%s' URI failed: %s",
|
command_usage("connecting to '%s' URI failed: %s",
|
||||||
uri ?: "default", strerror(errno));
|
uri ?: "default", strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = cmd->call(conn);
|
ret = cmd->call(conn);
|
||||||
vici_disconnect(conn);
|
vici_disconnect(conn);
|
||||||
|
|||||||
@@ -71,8 +71,9 @@ static int initiate(vici_conn_t *conn)
|
|||||||
|
|
||||||
if (vici_register(conn, "control-log", log_cb, &format) != 0)
|
if (vici_register(conn, "control-log", log_cb, &format) != 0)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "registering for log failed: %s\n", strerror(errno));
|
fprintf(stderr, "registering for log failed: %s\n", strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
req = vici_begin("initiate");
|
req = vici_begin("initiate");
|
||||||
if (child)
|
if (child)
|
||||||
@@ -87,8 +88,9 @@ static int initiate(vici_conn_t *conn)
|
|||||||
res = vici_submit(req, conn);
|
res = vici_submit(req, conn);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "initiate request failed: %s\n", strerror(errno));
|
fprintf(stderr, "initiate request failed: %s\n", strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
if (format & COMMAND_FORMAT_RAW)
|
if (format & COMMAND_FORMAT_RAW)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -55,8 +55,9 @@ static int manage_policy(vici_conn_t *conn, char *label)
|
|||||||
res = vici_submit(req, conn);
|
res = vici_submit(req, conn);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "%s request failed: %s\n", label, strerror(errno));
|
fprintf(stderr, "%s request failed: %s\n", label, strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
if (format & COMMAND_FORMAT_RAW)
|
if (format & COMMAND_FORMAT_RAW)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -590,6 +590,7 @@ static int list_certs(vici_conn_t *conn)
|
|||||||
vici_res_t *res;
|
vici_res_t *res;
|
||||||
command_format_options_t format = COMMAND_FORMAT_NONE;
|
command_format_options_t format = COMMAND_FORMAT_NONE;
|
||||||
char *arg, *subject = NULL, *type = NULL;
|
char *arg, *subject = NULL, *type = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
@@ -621,9 +622,10 @@ static int list_certs(vici_conn_t *conn)
|
|||||||
}
|
}
|
||||||
if (vici_register(conn, "list-cert", list_cb, &format) != 0)
|
if (vici_register(conn, "list-cert", list_cb, &format) != 0)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "registering for certificates failed: %s\n",
|
fprintf(stderr, "registering for certificates failed: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
req = vici_begin("list-certs");
|
req = vici_begin("list-certs");
|
||||||
if (type)
|
if (type)
|
||||||
@@ -637,8 +639,9 @@ static int list_certs(vici_conn_t *conn)
|
|||||||
res = vici_submit(req, conn);
|
res = vici_submit(req, conn);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "list-certs request failed: %s\n", strerror(errno));
|
fprintf(stderr, "list-certs request failed: %s\n", strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
if (format & COMMAND_FORMAT_RAW)
|
if (format & COMMAND_FORMAT_RAW)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -183,6 +183,7 @@ static int list_conns(vici_conn_t *conn)
|
|||||||
vici_res_t *res;
|
vici_res_t *res;
|
||||||
command_format_options_t format = COMMAND_FORMAT_NONE;
|
command_format_options_t format = COMMAND_FORMAT_NONE;
|
||||||
char *arg;
|
char *arg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
@@ -205,16 +206,18 @@ static int list_conns(vici_conn_t *conn)
|
|||||||
}
|
}
|
||||||
if (vici_register(conn, "list-conn", list_cb, &format) != 0)
|
if (vici_register(conn, "list-conn", list_cb, &format) != 0)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "registering for connections failed: %s\n",
|
fprintf(stderr, "registering for connections failed: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
req = vici_begin("list-conns");
|
req = vici_begin("list-conns");
|
||||||
res = vici_submit(req, conn);
|
res = vici_submit(req, conn);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "list-conns request failed: %s\n", strerror(errno));
|
fprintf(stderr, "list-conns request failed: %s\n", strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
if (format & COMMAND_FORMAT_RAW)
|
if (format & COMMAND_FORMAT_RAW)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ static int list_pols(vici_conn_t *conn)
|
|||||||
bool trap = FALSE, drop = FALSE, pass = FALSE;
|
bool trap = FALSE, drop = FALSE, pass = FALSE;
|
||||||
command_format_options_t format = COMMAND_FORMAT_NONE;
|
command_format_options_t format = COMMAND_FORMAT_NONE;
|
||||||
char *arg, *child = NULL;
|
char *arg, *child = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
@@ -154,9 +155,10 @@ static int list_pols(vici_conn_t *conn)
|
|||||||
}
|
}
|
||||||
if (vici_register(conn, "list-policy", list_cb, &format) != 0)
|
if (vici_register(conn, "list-policy", list_cb, &format) != 0)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "registering for policies failed: %s\n",
|
fprintf(stderr, "registering for policies failed: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
req = vici_begin("list-policies");
|
req = vici_begin("list-policies");
|
||||||
if (child)
|
if (child)
|
||||||
@@ -178,8 +180,9 @@ static int list_pols(vici_conn_t *conn)
|
|||||||
res = vici_submit(req, conn);
|
res = vici_submit(req, conn);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "list-policies request failed: %s\n", strerror(errno));
|
fprintf(stderr, "list-policies request failed: %s\n", strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
if (format & COMMAND_FORMAT_RAW)
|
if (format & COMMAND_FORMAT_RAW)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,8 +68,9 @@ static int list_pools(vici_conn_t *conn)
|
|||||||
res = vici_submit(req, conn);
|
res = vici_submit(req, conn);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "get-pools request failed: %s\n", strerror(errno));
|
fprintf(stderr, "get-pools request failed: %s\n", strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
if (format & COMMAND_FORMAT_RAW)
|
if (format & COMMAND_FORMAT_RAW)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ static int list_sas(vici_conn_t *conn)
|
|||||||
bool noblock = FALSE;
|
bool noblock = FALSE;
|
||||||
command_format_options_t format = COMMAND_FORMAT_NONE;
|
command_format_options_t format = COMMAND_FORMAT_NONE;
|
||||||
char *arg, *ike = NULL;
|
char *arg, *ike = NULL;
|
||||||
int ike_id = 0;
|
int ike_id = 0, ret;
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
@@ -315,8 +315,9 @@ static int list_sas(vici_conn_t *conn)
|
|||||||
}
|
}
|
||||||
if (vici_register(conn, "list-sa", list_cb, &format) != 0)
|
if (vici_register(conn, "list-sa", list_cb, &format) != 0)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "registering for SAs failed: %s\n", strerror(errno));
|
fprintf(stderr, "registering for SAs failed: %s\n", strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
req = vici_begin("list-sas");
|
req = vici_begin("list-sas");
|
||||||
if (ike)
|
if (ike)
|
||||||
@@ -334,8 +335,9 @@ static int list_sas(vici_conn_t *conn)
|
|||||||
res = vici_submit(req, conn);
|
res = vici_submit(req, conn);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "list-sas request failed: %s\n", strerror(errno));
|
fprintf(stderr, "list-sas request failed: %s\n", strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
if (format & COMMAND_FORMAT_RAW)
|
if (format & COMMAND_FORMAT_RAW)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ static int logcmd(vici_conn_t *conn)
|
|||||||
{
|
{
|
||||||
command_format_options_t format = COMMAND_FORMAT_NONE;
|
command_format_options_t format = COMMAND_FORMAT_NONE;
|
||||||
char *arg;
|
char *arg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
@@ -73,8 +74,9 @@ static int logcmd(vici_conn_t *conn)
|
|||||||
|
|
||||||
if (vici_register(conn, "log", log_cb, &format) != 0)
|
if (vici_register(conn, "log", log_cb, &format) != 0)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "registering for log failed: %s\n", strerror(errno));
|
fprintf(stderr, "registering for log failed: %s\n", strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
wait_sigint();
|
wait_sigint();
|
||||||
|
|||||||
@@ -49,8 +49,9 @@ static int reload_settings(vici_conn_t *conn)
|
|||||||
res = vici_submit(req, conn);
|
res = vici_submit(req, conn);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "reload-settings request failed: %s\n", strerror(errno));
|
fprintf(stderr, "reload-settings request failed: %s\n", strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
if (format & COMMAND_FORMAT_RAW)
|
if (format & COMMAND_FORMAT_RAW)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ static int stats(vici_conn_t *conn)
|
|||||||
vici_res_t *res;
|
vici_res_t *res;
|
||||||
char *arg;
|
char *arg;
|
||||||
command_format_options_t format = COMMAND_FORMAT_NONE;
|
command_format_options_t format = COMMAND_FORMAT_NONE;
|
||||||
|
int ret;
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
@@ -48,8 +49,9 @@ static int stats(vici_conn_t *conn)
|
|||||||
res = vici_submit(req, conn);
|
res = vici_submit(req, conn);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "stats request failed: %s\n", strerror(errno));
|
fprintf(stderr, "stats request failed: %s\n", strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
if (format & COMMAND_FORMAT_RAW)
|
if (format & COMMAND_FORMAT_RAW)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -80,8 +80,9 @@ static int terminate(vici_conn_t *conn)
|
|||||||
|
|
||||||
if (vici_register(conn, "control-log", log_cb, &format) != 0)
|
if (vici_register(conn, "control-log", log_cb, &format) != 0)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "registering for log failed: %s\n", strerror(errno));
|
fprintf(stderr, "registering for log failed: %s\n", strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
req = vici_begin("terminate");
|
req = vici_begin("terminate");
|
||||||
if (child)
|
if (child)
|
||||||
@@ -108,8 +109,9 @@ static int terminate(vici_conn_t *conn)
|
|||||||
res = vici_submit(req, conn);
|
res = vici_submit(req, conn);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "terminate request failed: %s\n", strerror(errno));
|
fprintf(stderr, "terminate request failed: %s\n", strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
if (format & COMMAND_FORMAT_RAW)
|
if (format & COMMAND_FORMAT_RAW)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ static int version(vici_conn_t *conn)
|
|||||||
char *arg;
|
char *arg;
|
||||||
bool daemon = FALSE;
|
bool daemon = FALSE;
|
||||||
command_format_options_t format = COMMAND_FORMAT_NONE;
|
command_format_options_t format = COMMAND_FORMAT_NONE;
|
||||||
|
int ret;
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
@@ -58,8 +59,9 @@ static int version(vici_conn_t *conn)
|
|||||||
res = vici_submit(req, conn);
|
res = vici_submit(req, conn);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
|
ret = errno;
|
||||||
fprintf(stderr, "version request failed: %s\n", strerror(errno));
|
fprintf(stderr, "version request failed: %s\n", strerror(errno));
|
||||||
return errno;
|
return ret;
|
||||||
}
|
}
|
||||||
if (format & COMMAND_FORMAT_RAW)
|
if (format & COMMAND_FORMAT_RAW)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user