# The Versatile IKE Control Interface (VICI) protocol # The vici _[ˈvitʃi]_ 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. 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. 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 request command. This mechanism is used to feed continuous data during a request, 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 hierarchical 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: * _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 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 as strings or integer representations. The vici plugin currently uses non-null terminated strings as values only; numbers get encoded as strings. ### 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 represents a valid tree structure, that gets encoded as the following C array: char msg[] = { /* key1 = value1 */ 3, 4,'k','e','y','1', 0,6,'v','a','l','u','e','1', /* section1 */ 1, 8,'s','e','c','t','i','o','n','1', /* sub-section */ 1, 11,'s','u','b','-','s','e','c','t','i','o','n', /* key2 = value2 */ 3, 4,'k','e','y','2', 0,6,'v','a','l','u','e','2', /* sub-section end */ 2, /* list1 */ 4, 5, 'l','i','s','t','1', /* item1 */ 5, 0,5,'i','t','e','m','1', /* item2 */ 5, 0,5,'i','t','e','m','2', /* list1 end */ 6, /* section1 end */ 2, }; ## 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 = version = sysname = release = machine = } ### stats() ### Returns IKE daemon statistics and load information. {} => { uptime = { running = since = } workers = { total = idle = active = { critical = high = medium = low = } } queues = { critical = high = medium = low = } scheduled = ikesas = { total = half-open = } plugins = [ ] mem = { # available if built with leak-detective or on Windows total = allocs = * = { # on Windows only total = allocs = } } mallinfo = { # available with mallinfo() support sbrk = mmap = used = free = } } ### reload-settings() ### Reloads _strongswan.conf_ settings and all plugins supporting configuration reload. {} => { success = errmsg = } ### initiate() ### Initiates an SA while streaming _control-log_ events. { child = ike = timeout = init-limits = loglevel = } => { success = errmsg = } The default timeout of 0 waits indefinitely for a result, and a timeout value of -1 returns a result immediately. ### terminate() ### Terminates an SA while streaming _control-log_ events. { child = ike = child-id = ike-id = force = timeout = loglevel = } => { success = matches = terminated = errmsg = } The default timeout of 0 waits indefinitely for a result, and a timeout value of -1 returns a result immediately. ### rekey() ### Initiate the rekeying of an SA. { child = ike = child-id = ike-id = reauth = } => { success = matches = errmsg = } ### redirect() ### Redirect a client-initiated IKE_SA to another gateway. Only for IKEv2 and if supported by the peer. { ike = ike-id = peer-ip = peer-id = } => { success = matches = errmsg = } ### install() ### Install a trap, drop or bypass policy defined by a CHILD_SA config. { child = ike = } => { success = errmsg = } ### uninstall() ### Uninstall a trap, drop or bypass policy defined by a CHILD_SA config. { child = ike = } => { success = errmsg = } ### list-sas() ### Lists currently active IKE_SAs and associated CHILD_SAs by streaming _list-sa_ events. { noblock = ike = ike-id = } => { # completes after streaming list-sa events } ### list-policies() ### List currently installed trap, drop and bypass policies by streaming _list-policy_ events. { drop = pass = trap = child = ike = } => { # 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 = } => { # 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-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 = flag = subject = } => { # completes after streaming list-cert events } ### list-authorities() ### List currently loaded certification authority information by streaming _list-authority_ events. { name = } => { # completes after streaming list-authority events } ### get-authorities() ### Return a list of currently loaded certification authority names. {} => { authorities = [ ] } ### load-conn() ### Load a single connection definition into the daemon. An existing connection with the same name gets updated or replaced. { = { # IKE configuration parameters with authentication and CHILD_SA # subsections. Refer to swanctl.conf(5) for details. } } => { success = errmsg = } ### unload-conn() ### Unload a previously loaded connection definition by name. { name = } => { success = errmsg = } ### load-cert() ### Load a certificate into the daemon. { type = flag = data = } => { success = errmsg = } ### load-key() ### Load a private key into the daemon. { type = data = } => { success = errmsg = id = } ### unload-key() ### Unload the private key with the given key identifier. { id = } => { success = errmsg = } ### get-keys() ### Return a list of identifiers of private keys loaded exclusively over vici, not including keys found in other backends. {} => { keys = [ ] } ### load-token() ### Load a private key located on a token into the daemon. Such keys may be listed and unloaded using the _get-keys_ and _unload-key_ commands, respectively (based on the key identifier derived from the public key). { handle = slot = module = pin = } => { success = errmsg = id = } ### load-shared() ### Load a shared IKE PSK, EAP, XAuth or NTLM secret into the daemon. { id = type = data = owners = [ ] } => { success = errmsg = } ### unload-shared() ### Unload a previously loaded shared IKE PSK, EAP, XAuth or NTLM secret by its unique identifier. { id = } => { success = errmsg = } ### get-shared() ### Return a list of unique identifiers of shared keys loaded exclusively over vici, not including keys found in other backends. {} => { keys = [ ] } ### flush-certs() ### Flushes the certificate cache. The optional type argument allows to flush only certificates of a given type, e.g. all cached CRLs. { type = } => { success = errmsg = } ### 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 = errmsg = } ### load-authority() ### Load a single certification authority definition into the daemon. An existing authority with the same name gets replaced. { = { # certification authority parameters # refer to swanctl.conf(5) for details. } } => { success = errmsg = } ### unload-authority() ### Unload a previously loaded certification authority definition by name. { name = } => { success = errmsg = } ### load-pool() ### Load an in-memory virtual IP and configuration attribute pool. Existing pools with the same name get updated, if possible. { = { addrs = * = [ # attribute type is one of address, dns, nbns, dhcp, netmask, # server, subnet, split_include, split_exclude or a numerical # attribute type identifier. ] } } => { success = errmsg = } ### unload-pool() ### Unload a previously loaded virtual IP and configuration attribute pool. Unloading fails for pools with leases currently online. { name = } => { success = errmsg = } ### get-pools() ### List the currently loaded pools. { leases = name = } => { * = { base = size = online = offline = leases = { * = { address = identity = status = } } } } ### get-algorithms() ### List currently loaded algorithms and their implementation. {} => { = { = } } ### get-counters() ### List global or connection-specific counters for several IKE events. { name = all = } => { counters = { = { } } success = errmsg = } ### reset-counters() ### Reset global or connection-specific IKE event counters. { name = all = } => { success = errmsg = } ## 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 = level = thread = ikesa-name = ikesa-uniqued = msg = } ### 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 = level = ikesa-name = ikesa-uniqued = msg = } ### list-sa ### The _list-sa_ event is issued to stream IKE_SAs during an active _list-sas_ command. { = { uniqueid = version = state = local-host = local-port = local-id = remote-host = remote-port = remote-id = remote-xauth-id = remote-eap-id = initiator = initiator-spi = responder-spi = nat-local = nat-remote = nat-fake = nat-any = if-id-in = if-id-out = encr-alg = encr-keysize = integ-alg = integ-keysize = prf-alg = dh-group = established = rekey-time = reauth-time = local-vips = [ ] remote-vips = [ ] tasks-queued = [ ] tasks-active = [ ] tasks-passive = [ ] child-sas = { * = { name = uniqueid = reqid = state = mode = protocol = encap = spi-in = spi-out = cpi-in = cpi-out = mark-in = mark-mask-in = mark-out = mark-mask-out = if-id-in = if-id-out = encr-alg = encr-keysize = integ-alg = integ-keysize = prf-alg = dh-group = esn = <1 if using extended sequence numbers> bytes-in = packets-in = use-in = bytes-out = packets-out = use-out = rekey-time = life-time = install-time = local-ts = [ ] remote-ts = [ ] } } } } ### list-policy ### The _list-policy_ event is issued to stream installed policies during an active _list-policies_ command. { = { child = ike = mode = local-ts = [ ] remote-ts = [ ] } } ### list-conn ### The _list-conn_ event is issued to stream loaded connection during an active _list-conns_ command. { = { local_addrs = [ ] remote_addrs = [ ] version = reauth_time = rekey_time = local*, remote* = { # multiple local and remote auth sections class = eap-type = eap-vendor = xauth = revocation = id = aaa_id = eap_id = xauth_id = groups = [ ] certs = [ ] cacerts = [ ] } children = { * = { mode = rekey_time = rekey_bytes = rekey_packets = local-ts = [ ] remote-ts = [ ] } } } } ### list-cert ### The _list-cert_ event is issued to stream loaded certificates during an active _list-certs_ command. { type = flag = has_privkey = data = subject = not-before =