| # 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 = <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> |
| ike = <IKE_SA configuration name to initiate or to find child under> |
| timeout = <timeout in ms before returning> |
| init-limits = <whether limits may prevent initiating the CHILD_SA> |
| loglevel = <loglevel to issue "control-log" events for> |
| } => { |
| success = <yes or no> |
| errmsg = <error string on failure or timeout> |
| } |
| |
| 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 = <terminate a CHILD_SA by configuration name> |
| ike = <terminate an IKE_SA by configuration name> |
| child-id = <terminate a CHILD_SA by its unique id> |
| ike-id = <terminate an IKE_SA by its unique id> |
| force = <terminate IKE_SA without waiting for proper DELETE, if timeout |
| is given, waits for a response until it is reached> |
| timeout = <timeout in ms before returning, see below> |
| loglevel = <loglevel to issue "control-log" events for> |
| } => { |
| success = <yes or no> |
| matches = <number of matched SAs> |
| terminated = <number of terminated SAs> |
| errmsg = <error string on failure or timeout> |
| } |
| |
| 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 = <rekey a CHILD_SA by configuration name> |
| ike = <rekey an IKE_SA by configuration name> |
| child-id = <rekey a CHILD_SA by its unique id> |
| ike-id = <rekey an IKE_SA by its unique id> |
| reauth = <reauthenticate instead of rekey an IKEv2 SA> |
| } => { |
| success = <yes or no> |
| matches = <number of matched SAs> |
| errmsg = <error string on failure> |
| } |
| |
| ### redirect() ### |
| |
| Redirect a client-initiated IKE_SA to another gateway. Only for IKEv2 and if |
| supported by the peer. |
| |
| { |
| ike = <redirect an IKE_SA by configuration name> |
| ike-id = <redirect an IKE_SA by its unique id> |
| peer-ip = <redirect an IKE_SA with matching peer IP, may also be a |
| subnet in CIDR notation or an IP range> |
| peer-id = <redirect an IKE_SA with matching peer identity, may contain |
| wildcards> |
| } => { |
| success = <yes or no> |
| matches = <number of matched SAs> |
| errmsg = <error string on failure> |
| } |
| |
| ### install() ### |
| |
| Install a trap, drop or bypass policy defined by a CHILD_SA config. |
| |
| { |
| child = <CHILD_SA configuration name to install> |
| ike = <optional IKE_SA configuration name to find child under> |
| } => { |
| 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> |
| ike = <optional IKE_SA configuration name to find child under, |
| if not given the first policy matching child is removed> |
| } => { |
| 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> |
| child = <filter listed CHILD_SAs by name> |
| child-id = <filter listed CHILD_SAs by 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> |
| ike = <filter by IKE_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, X509|X509_AC|X509_CRL| |
| OCSP_RESPONSE|PUBKEY or ANY> |
| flag = <X.509 certificate flag to filter for, NONE|CA|AA|OCSP or ANY> |
| subject = <set to list only certificates having subject> |
| } => { |
| # completes after streaming list-cert events |
| } |
| |
| ### list-authorities() ### |
| |
| List currently loaded certification authority information by streaming |
| _list-authority_ events. |
| |
| { |
| name = <list certification authority of a given name> |
| } => { |
| # completes after streaming list-authority events |
| } |
| |
| ### get-authorities() ### |
| |
| Return a list of currently loaded certification authority names. |
| |
| {} => { |
| authorities = [ |
| <list of certification authority names> |
| ] |
| } |
| |
| ### 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|X509_AC|X509_CRL> |
| flag = <X.509 certificate flag, NONE|CA|AA|OCSP> |
| 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|ed25519|ed448|any> |
| data = <PEM or DER encoded key data> |
| } => { |
| success = <yes or no> |
| errmsg = <error string on failure> |
| id = <hex-encoded SHA-1 key identifier of the public key on success> |
| } |
| |
| ### unload-key() ### |
| |
| Unload the private key with the given key identifier. |
| |
| { |
| id = <hex-encoded SHA-1 key identifier of the private key to unload> |
| } => { |
| success = <yes or no> |
| errmsg = <error string on failure> |
| } |
| |
| ### get-keys() ### |
| |
| Return a list of identifiers of private keys loaded exclusively over vici, not |
| including keys found in other backends. |
| |
| {} => { |
| keys = [ |
| <list of hex-encoded SHA-1 key identifiers> |
| ] |
| } |
| |
| ### 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 = <hex-encoded CKA_ID of the private key on token> |
| slot = <optional slot number> |
| module = <optional PKCS#11 module> |
| pin = <optional PIN to access the key, has to be provided via other |
| means if not given> |
| } => { |
| success = <yes or no> |
| errmsg = <error string on failure> |
| id = <hex-encoded SHA-1 key identifier of the public key on success> |
| } |
| |
| ### load-shared() ### |
| |
| Load a shared IKE PSK, EAP, XAuth or NTLM secret into the daemon. |
| |
| { |
| id = <optional unique identifier of this shared key> |
| type = <shared key type, IKE|EAP|XAUTH|NTLM> |
| data = <raw shared key data> |
| owners = [ |
| <list of shared key owner identities> |
| ] |
| } => { |
| success = <yes or no> |
| errmsg = <error string on failure> |
| } |
| |
| ### unload-shared() ### |
| |
| Unload a previously loaded shared IKE PSK, EAP, XAuth or NTLM secret by its |
| unique identifier. |
| |
| { |
| id = <unique identifier of the shared key to unload> |
| } => { |
| success = <yes or no> |
| errmsg = <error string on failure> |
| } |
| |
| ### get-shared() ### |
| |
| Return a list of unique identifiers of shared keys loaded exclusively over vici, |
| not including keys found in other backends. |
| |
| {} => { |
| keys = [ |
| <list of unique identifiers> |
| ] |
| } |
| |
| ### 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 = <certificate type to filter for, X509|X509_AC|X509_CRL| |
| OCSP_RESPONSE|PUBKEY or ANY> |
| } => { |
| 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-authority() ### |
| |
| Load a single certification authority definition into the daemon. An existing |
| authority with the same name gets replaced. |
| |
| { |
| <certification authority name> = { |
| # certification authority parameters |
| # refer to swanctl.conf(5) for details. |
| } |
| } => { |
| success = <yes or no> |
| errmsg = <error string on failure> |
| } |
| |
| ### unload-authority() ### |
| |
| Unload a previously loaded certification authority definition by name. |
| |
| { |
| name = <certification authority name> |
| } => { |
| 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. |
| |
| { |
| leases = <set to yes to include leases> |
| name = <optional name of the pool to query> |
| } => { |
| <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> |
| leases = { |
| <zero-based index>* = { |
| address = <IP address> |
| identity = <assigned identity> |
| status = <online|offline> |
| } |
| } |
| } |
| } |
| |
| ### get-algorithms() ### |
| |
| List currently loaded algorithms and their implementation. |
| |
| {} => { |
| <algorithm type> = { |
| <algorithm> = <plugin providing the implementation> |
| } |
| } |
| |
| ### get-counters() ### |
| |
| List global or connection-specific counters for several IKE events. |
| |
| { |
| name = <optional connection name, omit for global counters> |
| all = <yes to get counters for all connections, name is ignored> |
| } => { |
| counters = { |
| <name|empty for global counters> = { |
| <pairs of counter name and 64-bit counter value> |
| } |
| } |
| success = <yes or no> |
| errmsg = <error string on failure> |
| } |
| |
| ### reset-counters() ### |
| |
| Reset global or connection-specific IKE event counters. |
| |
| { |
| name = <optional connection name, omit for global counters> |
| all = <yes to reset counters for all connections, name is ignored> |
| } => { |
| success = <yes or no> |
| errmsg = <error string on failure> |
| } |
| |
| ## 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 on |
| level 0 or 1. This event is not associated with a command. |
| |
| { |
| group = <subsystem identifier for debug message> |
| level = <log level, 0-1> |
| 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-port = <local IKE endpoint port> |
| local-id = <local IKE identity> |
| remote-host = <remote IKE endpoint address> |
| remote-port = <remote IKE endpoint port> |
| 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> |
| nat-local = <yes, if local endpoint is behind a NAT> |
| nat-remote = <yes, if remote endpoint is behind a NAT> |
| nat-fake = <yes, if NAT situation has been faked as responder> |
| nat-any = <yes, if any endpoint is behind a NAT (also if faked)> |
| if-id-in = <hex encoded default inbound XFRM interface ID> |
| if-id-out = <hex encoded default outbound XFRM interface ID> |
| 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> |
| local-vips = [ |
| <list of virtual IPs assigned by the remote peer, installed locally> |
| ] |
| remote-vips = [ |
| <list of virtual IPs assigned to the remote peer> |
| ] |
| 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 = { |
| <unique child-sa-name>* = { |
| name = <name of the CHILD_SA> |
| uniqueid = <unique CHILD_SA identifier> |
| 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> |
| mark-in = <hex encoded inbound Netfilter mark value> |
| mark-mask-in = <hex encoded inbound Netfilter mark mask> |
| mark-out = <hex encoded outbound Netfilter mark value> |
| mark-mask-out = <hex encoded outbound Netfilter mark mask> |
| if-id-in = <hex encoded inbound XFRM interface ID> |
| if-id-out = <hex encoded outbound XFRM interface ID> |
| per-cpu-sas = <yes if per-CPU SAs enabled> |
| cpu = <CPU ID of per-CPU SA> |
| label = <hex encoded security label> |
| 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. |
| |
| { |
| <ike-sa-config-name/child-sa-config-name> = { |
| child = <CHILD_SA configuration name> |
| ike = <IKE_SA configuration name or namespace, if available> |
| mode = <policy mode, tunnel|transport|pass|drop> |
| label = <hex encoded security label> |
| 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> |
| ] |
| local_port = <local IKE endpoint port> |
| remote_port = <remote IKE endpoint port> |
| version = <IKE version as string, IKEv1|IKEv2 or 0 for any> |
| reauth_time = <IKE_SA reauthentication interval in seconds> |
| rekey_time = <IKE_SA rekeying interval in seconds> |
| |
| 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> |
| label = <hex encoded security label> |
| rekey_time = <CHILD_SA rekeying interval in seconds> |
| rekey_bytes = <CHILD_SA rekeying interval in bytes> |
| rekey_packets = <CHILD_SA rekeying interval in packets> |
| 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, X509|X509_AC|X509_CRL|OCSP_RESPONSE|PUBKEY> |
| flag = <X.509 certificate flag, NONE|CA|AA|OCSP> |
| has_privkey = <set if a private key for the certificate is available> |
| data = <ASN1 encoded certificate data> |
| subject = <subject string if defined and certificate type is PUBKEY> |
| not-before = <time string if defined and certificate type is PUBKEY> |
| not-after = <time string if defined and certificate type is PUBKEY> |
| } |
| |
| ### list-authority ### |
| |
| The _list-authority_ event is issued to stream loaded certification authority |
| information during an active_list-authorities_ command. |
| |
| { |
| <certification authority name> = { |
| cacert = <subject distinguished name of CA certificate> |
| crl_uris = [ |
| <CRL URI (http, ldap or file)> |
| ] |
| ocsp_uris = [ |
| <OCSP URI (http)> |
| ] |
| cert_uri_base = <base URI for download of hash-and-URL certificates> |
| } |
| } |
| |
| ### ike-updown ### |
| |
| The _ike-updown_ event is issued when an IKE_SA is established or terminated. |
| |
| { |
| up = <set if up event> |
| <IKE_SA config name> = { |
| <same data as in the list-sas event, but without child-sas section> |
| } |
| } |
| |
| ### ike-rekey ### |
| |
| The _ike-rekey_ event is issued when an IKE_SA is rekeyed. |
| |
| { |
| <IKE_SA config name> = { |
| old = { |
| <same data as in the list-sas event, but without child-sas section> |
| } |
| new = { |
| <same data as in the list-sas event, but without child-sas section> |
| } |
| } |
| } |
| |
| ### ike-update ### |
| |
| The _ike-update_ event is issued when the local or remote endpoint address of an |
| IKE_SA is about to change (at least one address/port is different). |
| |
| { |
| local-host = <new/current local IKE endpoint address> |
| local-port = <new/current local IKE endpoint port> |
| remote-host = <new/current remote IKE endpoint address> |
| remote-port = <new/current remote IKE endpoint port> |
| <IKE_SA config name> = { |
| <same data as in the list-sas event, but without child-sas section |
| and listing the old addresses/ports> |
| } |
| } |
| |
| ### child-updown ### |
| |
| The _child-updown_ event is issued when a CHILD_SA is established or terminated. |
| |
| { |
| up = <set if up event> |
| <IKE_SA config name> = { |
| <same data as in the list-sas event, but with only the affected |
| CHILD_SA in the child-sas section> |
| } |
| } |
| |
| ### child-rekey ### |
| |
| The _child-rekey_ event is issued when a CHILD_SA is rekeyed. |
| |
| { |
| <IKE_SA config name> = { |
| <same data as in the list-sas event, but with the child-sas section |
| as follows> |
| child-sas = { |
| <child-sa-name> = { |
| old = { |
| <same data as in the list-sas event> |
| } |
| new = { |
| <same data as in the list-sas event> |
| } |
| } |
| } |
| } |
| } |
| |
| ### alert ### |
| |
| The _alert_ event is issued for specific error conditions. Some alerts can |
| be associated with an IKE_SA; if so, the IKE_SA details are included under an |
| _ike-sa_ property. |
| |
| { |
| type = <alert type> |
| ike-sa = { |
| <IKE_SA config name> = { |
| <same data as in list-sas event, but without child-sas section> |
| } |
| } |
| } |
| |
| The _type_ property currently has one of the following fixed string values: |
| |
| * _authorization-failed_: an authorization hook failed |
| * _cert-exceeded-path-len_: Certificate trustchain length exceeds limit |
| * _cert-expired_: Certificate rejected; it has expired |
| * _cert-no-issuer_: Certificate rejected; no trusted issuer found |
| * _cert-policy-violation_: Certificate rejected; other policy violation |
| * _cert-revoked_: Certificate rejected; it has been revoked |
| * _cert-untrusted-root_: Certificate rejected; root not trusted |
| * _cert-validation-failed_: Certificate rejected: Validating status failed |
| * _half-open-timeout_: received half-open timeout before IKE_SA established |
| * _ike-sa-expired_: IKE_SA hit hard lifetime limit before it could be rekeyed |
| * _install-child-policy-failed_: Installation of IPsec Policy failed |
| * _install-child-sa-failed_: Installation of IPsec SAs failed |
| * _invalid-ike-spi_: received IKE message with invalid SPI |
| * _keep-on-child-sa-failure_: IKE_SA kept on failed child SA establishment |
| * _local-auth-failed_: local peer authentication failed (by us or by peer) |
| * _parse-error-body_: received IKE message with invalid body |
| * _parse-error-header_: received IKE message with invalid header |
| * _peer-addr-failed_: failed to resolve peer address |
| * _peer-auth-failed_: peer authentication failed |
| * _peer-init-unreachable_: peer did not respond to initial message |
| * _proposal-mismatch-child_: CHILD proposals do not match |
| * _proposal-mismatch-ike_: IKE proposals do not match |
| * _radius-not-responding_: a RADIUS server did not respond |
| * _retransmit-receive_: received a retransmit for a message |
| * _retransmit-send_: sending a retransmit for a message |
| * _retransmit-send-cleared_: received response for retransmitted request |
| * _retransmit-send-timeout_: sending retransmits timed out |
| * _shutdown-signal_: a shutdown signal has been received |
| * _ts-mismatch_: traffic selectors do not match |
| * _ts-narrowed_: traffic selectors have been narrowed (by us or by peer) |
| * _unique-keep_: IKE_SA deleted because of "keep" unique policy |
| * _unique-replace_: IKE_SA deleted because of "replace" unique policy |
| * _vip-failure_: allocating virtual IP failed |
| |
| # 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. |
| |
| ## 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. |
| |
| # 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 can be passed to the |
| _Connection_ constructor. If none is passed, a default Unix socket at |
| _/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. |
| |
| # vici Python wheel # |
| |
| The _vici Python wheel_ is a pure Python implementation of the VICI protocol to |
| implement client applications. It is provided in the _python_ subdirectory, and |
| gets built if strongSwan has been _./configure_'d with |
| _--enable-vici_ and _--enable-python-wheels_. It is not installed automatically. |
| |
| The _vici_ module provides a _Session()_ constructor for a high level interface, |
| the underlying classes are usually not required to build Python applications |
| using VICI. The _Session_ class provides methods for the supported VICI |
| commands. |
| |
| To represent the VICI message data tree, the library converts the binary |
| encoding to Python data types. The _Session_ class takes and returns Python |
| objects for the exchanged message data: |
| * Sections get encoded as OrderedDict, containing other sections, or |
| * Key/Values, where the values are strings as dictionary values |
| * Lists get encoded as Python Lists with string values |
| Values that do not conform to Python dict or list get converted to strings using |
| str(). |
| |
| ## Connecting to the daemon ## |
| |
| To create a connection to the daemon, a socket can be passed to the _Session_ |
| constructor. If none is passed, a default Unix socket at _/var/run/charon.vici_ |
| is used: |
| |
| import vici |
| import socket |
| |
| s = socket.socket(socket.AF_UNIX) |
| s.connect("/var/run/charon.vici") |
| v = vici.Session(s) |
| |
| ## A simple client request ## |
| |
| An example to print the daemon version information is as simple as: |
| |
| ver = v.version() |
| |
| print "{daemon} {version} ({sysname}, {release}, {machine})".format(**ver) |
| |
| ## A request with response iteration ## |
| |
| The _Session_ class returns an iterable Python generator for streamed events to |
| continuously stream objects to the caller. The following example lists all |
| loaded connections using the _list-conns_ command and implicitly the _list-conn_ |
| event: |
| |
| for conn in v.list_conns(): |
| for key in conn: |
| print key |
| |
| Please note that if the returned generator is not iterated completely, it must |
| be closed using _close()_. This is implicitly done when breaking from a loop, |
| but an explicit call may be required when directly iterating the generator with |
| _next()_. |
| |
| ## Sorting in dictionaries ## |
| |
| In VICI, in some message trees the order of objects in dictionary matters. In |
| contrast to ruby Hashes, Python dictionaries do not preserve order of added |
| objects. It is therefore recommended to use OrderedDicts instead of the default |
| dictionaries. Objects returned by the library use OrderedDicts. |
| |
| ## API documentation ## |
| |
| For more details about the Python egg refer to the comments in the Python source |
| code. |
| |
| # Vici::Session Perl CPAN module # |
| |
| The _Vici::Session Perl CPAN module_ is a pure Perl implementation of the VICI |
| protocol to implement client applications. It is provided in the _perl_ |
| subdirectory, and gets built and installed if strongSwan has been |
| _./configure_'d with_--enable-vici_ and _--enable-perl-cpan_. |
| |
| The _Vici::Session_ module provides a _new()_ constructor for a high level |
| interface, the underlying _Vici::Packet_ and _Vici::Transport_ classes are |
| usually not required to build Perl applications using VICI. The _Vici::Session_ |
| class provides methods for the supported VICI commands. The auxiliary |
| _Vici::Message_ class is used to encode configuration parameters sent to |
| the daemon and decode data returned by the daemon. |
| |
| ## Connecting to the daemon ## |
| |
| use IO::Socket::UNIX; |
| use Vici::Session; |
| use Vici::Message; |
| |
| my $socket = IO::Socket::UNIX->new( |
| Type => SOCK_STREAM, |
| Peer => '/var/run/charon.vici', |
| ) or die "Vici socket: $!"; |
| |
| my $session = Vici::Session->new($socket); |
| |
| ## A simple client request ## |
| |
| An example to print the daemon version information is as simple as: |
| |
| my $version = $session->version()->hash(); |
| |
| foreach my $key ('daemon', 'version', 'sysname', 'release', 'machine' ) { |
| print $version->{$key}, " "; |
| } |
| |
| The _Vici::Session_ methods are explained in the perl/Vici-Session/README.pod |
| document. |