2014-03-11 17:36:22 +00:00
|
|
|
# The Versatile IKE Control Interface (VICI) protocol #
|
|
|
|
|
|
|
|
The vici plugin implements the server side of an IPC protocol to configure,
|
|
|
|
monitor and control the IKE daemon charon. It uses request/response and event
|
|
|
|
messages to communicate over a reliable stream based transport.
|
|
|
|
|
|
|
|
## Transport protocol ##
|
|
|
|
|
|
|
|
To provide the service, the plugin opens a listening socket using a reliable,
|
|
|
|
stream based transport. charon relies on the different stream service
|
|
|
|
abstractions provided by libstrongswan, such as TCP and UNIX sockets.
|
|
|
|
|
|
|
|
A client connects to this service to access functionality. It may send an
|
|
|
|
arbitrary number of packets over the connection before closing it.
|
|
|
|
|
|
|
|
To exchange data, the transport protocol is segmented into byte sequences.
|
2014-04-29 15:08:50 +00:00
|
|
|
Each byte sequence is prefixed by a 32-bit length header in network order,
|
|
|
|
followed by the data. The maximum segment length is currently limited to 512KB
|
|
|
|
of data, and the length field contains the length of the data only, not
|
|
|
|
including the length field itself.
|
2014-03-11 17:36:22 +00:00
|
|
|
|
|
|
|
The order of byte sequences must be strict, byte sequences must arrive in the
|
|
|
|
same order as sent.
|
|
|
|
|
|
|
|
## Packet layer ##
|
|
|
|
|
|
|
|
Within the byte sequences defined by the transport layer, both the client
|
|
|
|
and the server can exchange packets. The type of packet defines its structure
|
|
|
|
and purpose. The packet type is a 8-bit identifier, and is the first byte
|
|
|
|
in a transport layer byte sequence. The length of the packet is given by the
|
|
|
|
transport layer.
|
|
|
|
|
|
|
|
While a packet type may define the format of the wrapped data freely, currently
|
|
|
|
all types either contain a name, a message or both. The following packet types
|
|
|
|
are currently defined:
|
|
|
|
|
|
|
|
* _CMD_REQUEST = 0_: A named request message
|
|
|
|
* _CMD_RESPONSE = 1_: An unnamed response message for a request
|
|
|
|
* _CMD_UNKNOWN = 2_: An unnamed response if requested command is unknown
|
|
|
|
* _EVENT_REGISTER = 3_: A named event registration request
|
|
|
|
* _EVENT_UNREGISTER = 4_: A named event deregistration request
|
|
|
|
* _EVENT_CONFIRM = 5_: An unnamed response for successful event (de-)registration
|
|
|
|
* _EVENT_UNKNOWN = 6_: A unnamed response if event (de-)registration failed
|
|
|
|
* _EVENT = 7_: A named event message
|
|
|
|
|
|
|
|
For packets having a named type, after the packet type an 8-bit length header
|
|
|
|
of the name follows, indicating the string length in bytes of the name tag, not
|
|
|
|
including the length field itself. The name is an ASCII string that is not
|
|
|
|
null-terminated.
|
|
|
|
|
|
|
|
The rest of the packet forms the exchanged message, the length is determined
|
|
|
|
by the transport byte sequence length, subtracting the packet type and
|
|
|
|
the optional name tag in some messages.
|
|
|
|
|
|
|
|
### Commands ###
|
|
|
|
|
|
|
|
Commands are currently always requested by the client. The server replies with
|
|
|
|
a response, or with a CMD_UNKNOWN failure message to let the client know
|
|
|
|
that it does not have a handler for such a command. There is no sequence number
|
|
|
|
to associate responses to requests, so only one command can be active at
|
|
|
|
a time on a single connection.
|
|
|
|
|
|
|
|
### Events ###
|
|
|
|
|
|
|
|
To receive event messages, the client explicitly registers for events by name,
|
|
|
|
and also unregisters if it does not want to receive events of the named kind
|
|
|
|
anymore. The server confirms event registration using EVENT_CONFIRM, or
|
|
|
|
indicates that there is no such event source with EVENT_UNKNOWN.
|
|
|
|
|
|
|
|
Events may get raised at any time while registered, even during an active
|
2014-06-24 13:57:15 +00:00
|
|
|
request command. This mechanism is used to feed continuous data during a request,
|
2014-03-11 17:36:22 +00:00
|
|
|
for example.
|
|
|
|
|
|
|
|
## Message format ##
|
|
|
|
|
|
|
|
The defined packet types optionally wrap a message with additional data.
|
|
|
|
Messages are currently used in CMD_REQUEST/CMD_RESPONSE, and in EVENT packets.
|
|
|
|
A message uses a hierarchial tree of sections. Each section (or the implicit
|
|
|
|
root section) contains an arbitrary set of key/value pairs, lists and
|
|
|
|
sub-sections. The length of a message is not part of the message itself, but
|
|
|
|
the wrapping layer, usually calculated from the transport byte sequence length.
|
|
|
|
|
|
|
|
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
|
|
|
|
value. Currently the following message element types are defined:
|
|
|
|
|
2014-09-30 16:43:20 +00:00
|
|
|
* _SECTION_START = 1_: Begin a new section having a name
|
|
|
|
* _SECTION_END = 2_: End a previously started section
|
|
|
|
* _KEY_VALUE = 3_: Define a value for a named key in the current section
|
|
|
|
* _LIST_START = 4_: Begin a named list for list items
|
|
|
|
* _LIST_ITEM = 5_: Define an unnamed item value in the current list
|
|
|
|
* _LIST_END = 6_: End a previously started list
|
2014-03-11 17:36:22 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
uses an 8-bit length header. The string must not be null-terminated, the string
|
|
|
|
length does not include the length field itself.
|
|
|
|
|
|
|
|
Types having a value (KEY_VALUE and LIST_ITEM) have a raw blob sequence,
|
|
|
|
prefixed with a 16-bit network order length. The blob follows the type or the
|
|
|
|
name tag if available, the length defined by the length field does not include
|
|
|
|
the length field itself.
|
|
|
|
|
|
|
|
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
|
2014-10-08 16:13:31 +00:00
|
|
|
as strings or integer representations. The vici plugin currently uses
|
|
|
|
non-null terminated strings as values only; numbers get encoded as strings.
|
2014-03-11 17:36:22 +00:00
|
|
|
|
|
|
|
### Sections ###
|
|
|
|
|
|
|
|
Sections may be opened in the implicit root section, or any previously section.
|
|
|
|
They can be nested to arbitrary levels. A SECTION_END marker always closes
|
|
|
|
the last opened section; SECTION_START and SECTION_END items must be balanced
|
|
|
|
in a valid message.
|
|
|
|
|
|
|
|
### Key/Values ###
|
|
|
|
|
|
|
|
Key/Value pair elements may appear in the implicit root section or any explicit
|
|
|
|
sub-section at any level. Key names must be unique in the current section, use
|
|
|
|
lists to define multiple values for a key. Key/values may not appear in lists,
|
|
|
|
use a sub-section instead.
|
|
|
|
|
|
|
|
### Lists ###
|
|
|
|
|
|
|
|
Lists may appear at the same locations as Key/Values, and may not be nested.
|
|
|
|
Only a single list may be opened at the same time, and all lists must be closed
|
|
|
|
in valid messages. After opening a list, only list items may appear before the
|
|
|
|
list closing element. Empty lists are allowed, list items may appear within
|
|
|
|
lists only.
|
|
|
|
|
|
|
|
### Encoding example ###
|
|
|
|
|
|
|
|
Consider the following structure using pseudo-markup for this example:
|
|
|
|
|
|
|
|
key1 = value1
|
|
|
|
section1 = {
|
|
|
|
sub-section = {
|
|
|
|
key2 = value2
|
|
|
|
}
|
|
|
|
list1 = [ item1, item2 ]
|
|
|
|
}
|
|
|
|
|
|
|
|
The example above reprensents a valid tree structure, that gets encoded as
|
|
|
|
the following C array:
|
|
|
|
|
|
|
|
char msg[] = {
|
|
|
|
/* key1 = value1 */
|
|
|
|
2, 4,'k','e','y','1', 0,6,'v','a','l','u','e','1',
|
|
|
|
/* section1 */
|
|
|
|
0, 8,'s','e','c','t','i','o','n','1',
|
|
|
|
/* sub-section */
|
|
|
|
0, 11,'s','u','b','-','s','e','c','t','i','o','n',
|
|
|
|
/* key2 = value2 */
|
|
|
|
2, 4,'k','e','y','2', 0,6,'v','a','l','u','e','2',
|
|
|
|
/* sub-section end */
|
|
|
|
1,
|
|
|
|
/* list1 */
|
|
|
|
3, 5, 'l','i','s','t','1',
|
|
|
|
/* item1 */
|
|
|
|
4, 0,5,'i','t','e','m','1',
|
|
|
|
/* item2 */
|
|
|
|
4, 0,5,'i','t','e','m','2',
|
|
|
|
/* list1 end */
|
|
|
|
5,
|
|
|
|
/* section1 end */
|
|
|
|
1,
|
|
|
|
};
|
|
|
|
|
2014-10-08 16:13:31 +00:00
|
|
|
## 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>
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-03-11 17:36:22 +00:00
|
|
|
# libvici C client library #
|
|
|
|
|
|
|
|
libvici is the reference implementation of a C client library implementing
|
|
|
|
the vici protocol. It builds upon libstrongswan, but provides a stable API
|
|
|
|
to implement client applications in the C programming language. libvici uses
|
|
|
|
the libstrongswan thread pool to deliver event messages asynchronously.
|
|
|
|
|
2014-10-09 14:42:01 +00:00
|
|
|
## Connecting to the daemon ##
|
|
|
|
|
|
|
|
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.
|
2014-10-09 15:22:08 +00:00
|
|
|
|
|
|
|
# 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.
|