mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-07 00:01:49 -04:00
Merge branch 'update-vici-bindings'
Updates the command wrappers in all the bindings and simplifies calling new commands (i.e. not yet wrapped) with the Python and Ruby bindings. Fixes #3028.
This commit is contained in:
commit
6b952f6921
@ -448,11 +448,11 @@ with the same name gets updated or replaced.
|
|||||||
<IKE_SA config name> = {
|
<IKE_SA config name> = {
|
||||||
# IKE configuration parameters with authentication and CHILD_SA
|
# IKE configuration parameters with authentication and CHILD_SA
|
||||||
# subsections. Refer to swanctl.conf(5) for details.
|
# subsections. Refer to swanctl.conf(5) for details.
|
||||||
|
}
|
||||||
} => {
|
} => {
|
||||||
success = <yes or no>
|
success = <yes or no>
|
||||||
errmsg = <error string on failure>
|
errmsg = <error string on failure>
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
### unload-conn() ###
|
### unload-conn() ###
|
||||||
|
|
||||||
@ -603,11 +603,11 @@ authority with the same name gets replaced.
|
|||||||
<certification authority name> = {
|
<certification authority name> = {
|
||||||
# certification authority parameters
|
# certification authority parameters
|
||||||
# refer to swanctl.conf(5) for details.
|
# refer to swanctl.conf(5) for details.
|
||||||
|
}
|
||||||
} => {
|
} => {
|
||||||
success = <yes or no>
|
success = <yes or no>
|
||||||
errmsg = <error string on failure>
|
errmsg = <error string on failure>
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
### unload-authority() ###
|
### unload-authority() ###
|
||||||
|
|
||||||
|
@ -36,6 +36,10 @@ sub terminate {
|
|||||||
return request_vars_res('terminate', @_);
|
return request_vars_res('terminate', @_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub rekey {
|
||||||
|
return request_vars_res('rekey', @_);
|
||||||
|
}
|
||||||
|
|
||||||
sub redirect {
|
sub redirect {
|
||||||
return request_vars_res('redirect', @_);
|
return request_vars_res('redirect', @_);
|
||||||
}
|
}
|
||||||
@ -89,13 +93,33 @@ sub load_cert {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sub load_key {
|
sub load_key {
|
||||||
return request_vars_res('load-key', @_);
|
return request_vars('load-key', @_);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub unload_key {
|
||||||
|
return request_vars_res('unload-key', @_);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_keys {
|
||||||
|
return request('get-keys', @_);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub load_token {
|
||||||
|
return request_vars('load-token', @_);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub load_shared {
|
sub load_shared {
|
||||||
return request_vars_res('load-shared', @_);
|
return request_vars_res('load-shared', @_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub unload_shared {
|
||||||
|
return request_vars_res('unload-shared', @_);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_shared {
|
||||||
|
return request('get-shared', @_);
|
||||||
|
}
|
||||||
|
|
||||||
sub flush_certs {
|
sub flush_certs {
|
||||||
return request_vars_res('flush-certs', @_);
|
return request_vars_res('flush-certs', @_);
|
||||||
}
|
}
|
||||||
@ -128,6 +152,14 @@ sub get_algorithms {
|
|||||||
return request('get-algorithms', @_);
|
return request('get-algorithms', @_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub get_counters {
|
||||||
|
return request_vars('get-counters', @_);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub reset_counters {
|
||||||
|
return request_vars_res('reset-counters', @_);
|
||||||
|
}
|
||||||
|
|
||||||
# Private functions
|
# Private functions
|
||||||
|
|
||||||
sub request {
|
sub request {
|
||||||
@ -135,6 +167,11 @@ sub request {
|
|||||||
return $self->{'Packet'}->request($command);
|
return $self->{'Packet'}->request($command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub request_vars {
|
||||||
|
my ($command, $self, $vars) = @_;
|
||||||
|
return $self->{'Packet'}->request($command, $vars);
|
||||||
|
}
|
||||||
|
|
||||||
sub request_res {
|
sub request_res {
|
||||||
my ($command, $self) = @_;
|
my ($command, $self) = @_;
|
||||||
my $msg = $self->{'Packet'}->request($command);
|
my $msg = $self->{'Packet'}->request($command);
|
||||||
|
354
src/libcharon/plugins/vici/python/vici/command_wrappers.py
Normal file
354
src/libcharon/plugins/vici/python/vici/command_wrappers.py
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
class CommandWrappers(object):
|
||||||
|
def version(self):
|
||||||
|
"""Retrieve daemon and system specific version information.
|
||||||
|
|
||||||
|
:return: daemon and system specific version information
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
return self.request("version")
|
||||||
|
|
||||||
|
def stats(self):
|
||||||
|
"""Retrieve IKE daemon statistics and load information.
|
||||||
|
|
||||||
|
:return: IKE daemon statistics and load information
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
return self.request("stats")
|
||||||
|
|
||||||
|
def reload_settings(self):
|
||||||
|
"""Reload strongswan.conf settings and any plugins supporting reload.
|
||||||
|
"""
|
||||||
|
self.request("reload-settings")
|
||||||
|
|
||||||
|
def initiate(self, sa):
|
||||||
|
"""Initiate an SA.
|
||||||
|
|
||||||
|
:param sa: the SA to initiate
|
||||||
|
:type sa: dict
|
||||||
|
:return: generator for logs emitted as dict
|
||||||
|
:rtype: generator
|
||||||
|
"""
|
||||||
|
return self.streamed_request("initiate", "control-log", sa)
|
||||||
|
|
||||||
|
def terminate(self, sa):
|
||||||
|
"""Terminate an SA.
|
||||||
|
|
||||||
|
:param sa: the SA to terminate
|
||||||
|
:type sa: dict
|
||||||
|
:return: generator for logs emitted as dict
|
||||||
|
:rtype: generator
|
||||||
|
"""
|
||||||
|
return self.streamed_request("terminate", "control-log", sa)
|
||||||
|
|
||||||
|
def rekey(self, sa):
|
||||||
|
"""Initiate the rekeying of an SA.
|
||||||
|
|
||||||
|
.. versionadded:: 5.5.2
|
||||||
|
|
||||||
|
:param sa: the SA to rekey
|
||||||
|
:type sa: dict
|
||||||
|
:return: number of matched SAs
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
return self.request("rekey", sa)
|
||||||
|
|
||||||
|
def redirect(self, sa):
|
||||||
|
"""Redirect an IKE_SA.
|
||||||
|
|
||||||
|
.. versionchanged:: 5.5.2
|
||||||
|
The number of matched SAs is returned.
|
||||||
|
|
||||||
|
:param sa: the SA to redirect
|
||||||
|
:type sa: dict
|
||||||
|
:return: number of matched SAs
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
return self.request("redirect", sa)
|
||||||
|
|
||||||
|
def install(self, policy):
|
||||||
|
"""Install a trap, drop or bypass policy defined by a CHILD_SA config.
|
||||||
|
|
||||||
|
:param policy: policy to install
|
||||||
|
:type policy: dict
|
||||||
|
"""
|
||||||
|
self.request("install", policy)
|
||||||
|
|
||||||
|
def uninstall(self, policy):
|
||||||
|
"""Uninstall a trap, drop or bypass policy defined by a CHILD_SA config.
|
||||||
|
|
||||||
|
:param policy: policy to uninstall
|
||||||
|
:type policy: dict
|
||||||
|
"""
|
||||||
|
self.request("uninstall", policy)
|
||||||
|
|
||||||
|
def list_sas(self, filters=None):
|
||||||
|
"""Retrieve active IKE_SAs and associated CHILD_SAs.
|
||||||
|
|
||||||
|
:param filters: retrieve only matching IKE_SAs (optional)
|
||||||
|
:type filters: dict
|
||||||
|
:return: generator for active IKE_SAs and associated CHILD_SAs as dict
|
||||||
|
:rtype: generator
|
||||||
|
"""
|
||||||
|
return self.streamed_request("list-sas", "list-sa", filters)
|
||||||
|
|
||||||
|
def list_policies(self, filters=None):
|
||||||
|
"""Retrieve installed trap, drop and bypass policies.
|
||||||
|
|
||||||
|
:param filters: retrieve only matching policies (optional)
|
||||||
|
:type filters: dict
|
||||||
|
:return: generator for installed trap, drop and bypass policies as dict
|
||||||
|
:rtype: generator
|
||||||
|
"""
|
||||||
|
return self.streamed_request("list-policies", "list-policy",
|
||||||
|
filters)
|
||||||
|
|
||||||
|
def list_conns(self, filters=None):
|
||||||
|
"""Retrieve loaded connections.
|
||||||
|
|
||||||
|
:param filters: retrieve only matching configuration names (optional)
|
||||||
|
:type filters: dict
|
||||||
|
:return: generator for loaded connections as dict
|
||||||
|
:rtype: generator
|
||||||
|
"""
|
||||||
|
return self.streamed_request("list-conns", "list-conn",
|
||||||
|
filters)
|
||||||
|
|
||||||
|
def get_conns(self):
|
||||||
|
"""Retrieve connection names loaded exclusively over vici.
|
||||||
|
|
||||||
|
:return: connection names
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
return self.request("get-conns")
|
||||||
|
|
||||||
|
def list_certs(self, filters=None):
|
||||||
|
"""Retrieve loaded certificates.
|
||||||
|
|
||||||
|
:param filters: retrieve only matching certificates (optional)
|
||||||
|
:type filters: dict
|
||||||
|
:return: generator for loaded certificates as dict
|
||||||
|
:rtype: generator
|
||||||
|
"""
|
||||||
|
return self.streamed_request("list-certs", "list-cert", filters)
|
||||||
|
|
||||||
|
def list_authorities(self, filters=None):
|
||||||
|
"""Retrieve loaded certification authority information.
|
||||||
|
|
||||||
|
.. versionadded:: 5.3.3
|
||||||
|
|
||||||
|
:param filters: retrieve only matching CAs (optional)
|
||||||
|
:type filters: dict
|
||||||
|
:return: generator for loaded CAs as dict
|
||||||
|
:rtype: generator
|
||||||
|
"""
|
||||||
|
return self.streamed_request("list-authorities", "list-authority",
|
||||||
|
filters)
|
||||||
|
|
||||||
|
def get_authorities(self):
|
||||||
|
"""Retrieve certification authority names loaded exclusively over vici.
|
||||||
|
|
||||||
|
:return: CA names
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
return self.request("get-authorities")
|
||||||
|
|
||||||
|
def load_conn(self, connection):
|
||||||
|
"""Load a connection definition into the daemon.
|
||||||
|
|
||||||
|
:param connection: connection definition
|
||||||
|
:type connection: dict
|
||||||
|
"""
|
||||||
|
self.request("load-conn", connection)
|
||||||
|
|
||||||
|
def unload_conn(self, name):
|
||||||
|
"""Unload a connection definition.
|
||||||
|
|
||||||
|
:param name: connection definition name
|
||||||
|
:type name: dict
|
||||||
|
"""
|
||||||
|
self.request("unload-conn", name)
|
||||||
|
|
||||||
|
def load_cert(self, certificate):
|
||||||
|
"""Load a certificate into the daemon.
|
||||||
|
|
||||||
|
:param certificate: PEM or DER encoded certificate
|
||||||
|
:type certificate: dict
|
||||||
|
"""
|
||||||
|
self.request("load-cert", certificate)
|
||||||
|
|
||||||
|
def load_key(self, private_key):
|
||||||
|
"""Load a private key into the daemon.
|
||||||
|
|
||||||
|
.. versionchanged:: 5.5.3
|
||||||
|
The key identifier of the loaded key is returned.
|
||||||
|
|
||||||
|
:param private_key: PEM or DER encoded key
|
||||||
|
:type private_key: dict
|
||||||
|
:return: key identifier
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
return self.request("load-key", private_key)
|
||||||
|
|
||||||
|
def unload_key(self, key_id):
|
||||||
|
"""Unload the private key with the given key identifier.
|
||||||
|
|
||||||
|
.. versionadded:: 5.5.2
|
||||||
|
|
||||||
|
:param key_id: key identifier
|
||||||
|
:type key_id: dict
|
||||||
|
"""
|
||||||
|
self.request("unload-key", key_id)
|
||||||
|
|
||||||
|
def get_keys(self):
|
||||||
|
"""Retrieve identifiers of private keys loaded exclusively over vici.
|
||||||
|
|
||||||
|
.. versionadded:: 5.5.2
|
||||||
|
|
||||||
|
:return: key identifiers
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
return self.request("get-keys")
|
||||||
|
|
||||||
|
def load_token(self, token):
|
||||||
|
"""Load a private key located on a token into the daemon.
|
||||||
|
|
||||||
|
.. versionadded:: 5.5.2
|
||||||
|
|
||||||
|
:param token: token details
|
||||||
|
:type token: dict
|
||||||
|
:return: key identifier
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
return self.request("load-token", token)
|
||||||
|
|
||||||
|
def load_shared(self, secret):
|
||||||
|
"""Load a shared IKE PSK, EAP or XAuth secret into the daemon.
|
||||||
|
|
||||||
|
.. versionchanged:: 5.5.2
|
||||||
|
A unique identifier may be associated with the secret.
|
||||||
|
|
||||||
|
:param secret: shared IKE PSK, EAP or XAuth secret
|
||||||
|
:type secret: dict
|
||||||
|
"""
|
||||||
|
self.request("load-shared", secret)
|
||||||
|
|
||||||
|
|
||||||
|
def unload_shared(self, identifier):
|
||||||
|
"""Unload a previously loaded shared secret by its unique identifier.
|
||||||
|
|
||||||
|
.. versionadded:: 5.5.2
|
||||||
|
|
||||||
|
:param identifier: unique identifier
|
||||||
|
:type secret: dict
|
||||||
|
"""
|
||||||
|
self.request("unload-shared", identifier)
|
||||||
|
|
||||||
|
def get_shared(self):
|
||||||
|
"""Retrieve identifiers of shared keys loaded exclusively over vici.
|
||||||
|
|
||||||
|
.. versionadded:: 5.5.2
|
||||||
|
|
||||||
|
:return: identifiers
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
return self.request("get-shared")
|
||||||
|
|
||||||
|
def flush_certs(self, filter=None):
|
||||||
|
"""Flush the volatile certificate cache.
|
||||||
|
|
||||||
|
Flush the certificate stored temporarily in the cache. The filter
|
||||||
|
allows to flush only a certain type of certificates, e.g. CRLs.
|
||||||
|
|
||||||
|
:param filter: flush only certificates of a given type (optional)
|
||||||
|
:type filter: dict
|
||||||
|
"""
|
||||||
|
self.request("flush-certs", filter)
|
||||||
|
|
||||||
|
def clear_creds(self):
|
||||||
|
"""Clear credentials loaded over vici.
|
||||||
|
|
||||||
|
Clear all loaded certificate, private key and shared key credentials.
|
||||||
|
This affects only credentials loaded over vici, but additionally
|
||||||
|
flushes the credential cache.
|
||||||
|
"""
|
||||||
|
self.request("clear-creds")
|
||||||
|
|
||||||
|
def load_authority(self, ca):
|
||||||
|
"""Load a certification authority definition into the daemon.
|
||||||
|
|
||||||
|
:param ca: certification authority definition
|
||||||
|
:type ca: dict
|
||||||
|
"""
|
||||||
|
self.request("load-authority", ca)
|
||||||
|
|
||||||
|
def unload_authority(self, ca):
|
||||||
|
"""Unload a previously loaded certification authority by name.
|
||||||
|
|
||||||
|
:param ca: certification authority name
|
||||||
|
:type ca: dict
|
||||||
|
"""
|
||||||
|
self.request("unload-authority", ca)
|
||||||
|
|
||||||
|
def load_pool(self, pool):
|
||||||
|
"""Load a virtual IP pool.
|
||||||
|
|
||||||
|
Load an in-memory virtual IP and configuration attribute pool.
|
||||||
|
Existing pools with the same name get updated, if possible.
|
||||||
|
|
||||||
|
:param pool: virtual IP and configuration attribute pool
|
||||||
|
:type pool: dict
|
||||||
|
"""
|
||||||
|
return self.request("load-pool", pool)
|
||||||
|
|
||||||
|
def unload_pool(self, pool_name):
|
||||||
|
"""Unload a virtual IP pool.
|
||||||
|
|
||||||
|
Unload a previously loaded virtual IP and configuration attribute pool.
|
||||||
|
Unloading fails for pools with leases currently online.
|
||||||
|
|
||||||
|
:param pool_name: pool by name
|
||||||
|
:type pool_name: dict
|
||||||
|
"""
|
||||||
|
self.request("unload-pool", pool_name)
|
||||||
|
|
||||||
|
def get_pools(self, options):
|
||||||
|
"""Retrieve loaded pools.
|
||||||
|
|
||||||
|
:param options: filter by name and/or retrieve leases (optional)
|
||||||
|
:type options: dict
|
||||||
|
:return: loaded pools
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
return self.request("get-pools", options)
|
||||||
|
|
||||||
|
def get_algorithms(self):
|
||||||
|
"""List of currently loaded algorithms and their implementation.
|
||||||
|
|
||||||
|
.. versionadded:: 5.4.0
|
||||||
|
|
||||||
|
:return: algorithms
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
return self.request("get-algorithms")
|
||||||
|
|
||||||
|
def get_counters(self, options=None):
|
||||||
|
"""List global or connection-specific counters for several IKE events.
|
||||||
|
|
||||||
|
.. versionadded:: 5.6.1
|
||||||
|
|
||||||
|
:param options: get global counters or those of all or one connection
|
||||||
|
:type options: dict
|
||||||
|
:return: counters
|
||||||
|
:rtype: dict
|
||||||
|
"""
|
||||||
|
return self.request("get-counters", options)
|
||||||
|
|
||||||
|
def reset_counters(self, options=None):
|
||||||
|
"""Reset global or connection-specific IKE event counters.
|
||||||
|
|
||||||
|
.. versionadded:: 5.6.1
|
||||||
|
|
||||||
|
:param options: reset global counters or those of all or one connection
|
||||||
|
:type options: dict
|
||||||
|
"""
|
||||||
|
self.request("reset-counters", options)
|
@ -1,13 +1,17 @@
|
|||||||
"""Exception types that may be thrown by this library."""
|
"""Exception types that may be thrown by this library."""
|
||||||
|
|
||||||
|
|
||||||
class DeserializationException(Exception):
|
class DeserializationException(Exception):
|
||||||
"""Encountered an unexpected byte sequence or missing element type."""
|
"""Encountered an unexpected byte sequence or missing element type."""
|
||||||
|
|
||||||
|
|
||||||
class SessionException(Exception):
|
class SessionException(Exception):
|
||||||
"""Session request exception."""
|
"""Session request exception."""
|
||||||
|
|
||||||
|
|
||||||
class CommandException(Exception):
|
class CommandException(Exception):
|
||||||
"""Command result exception."""
|
"""Command result exception."""
|
||||||
|
|
||||||
|
|
||||||
class EventUnknownException(Exception):
|
class EventUnknownException(Exception):
|
||||||
"""Event unknown exception."""
|
"""Event unknown exception."""
|
||||||
|
@ -3,237 +3,15 @@ import socket
|
|||||||
|
|
||||||
from .exception import SessionException, CommandException, EventUnknownException
|
from .exception import SessionException, CommandException, EventUnknownException
|
||||||
from .protocol import Transport, Packet, Message
|
from .protocol import Transport, Packet, Message
|
||||||
|
from .command_wrappers import CommandWrappers
|
||||||
|
|
||||||
|
|
||||||
class Session(object):
|
class Session(CommandWrappers, object):
|
||||||
def __init__(self, sock=None):
|
def __init__(self, sock=None):
|
||||||
if sock is None:
|
if sock is None:
|
||||||
sock = socket.socket(socket.AF_UNIX)
|
sock = socket.socket(socket.AF_UNIX)
|
||||||
sock.connect("/var/run/charon.vici")
|
sock.connect("/var/run/charon.vici")
|
||||||
self.handler = SessionHandler(Transport(sock))
|
self.transport = Transport(sock)
|
||||||
|
|
||||||
def version(self):
|
|
||||||
"""Retrieve daemon and system specific version information.
|
|
||||||
|
|
||||||
:return: daemon and system specific version information
|
|
||||||
:rtype: dict
|
|
||||||
"""
|
|
||||||
return self.handler.request("version")
|
|
||||||
|
|
||||||
def stats(self):
|
|
||||||
"""Retrieve IKE daemon statistics and load information.
|
|
||||||
|
|
||||||
:return: IKE daemon statistics and load information
|
|
||||||
:rtype: dict
|
|
||||||
"""
|
|
||||||
return self.handler.request("stats")
|
|
||||||
|
|
||||||
def reload_settings(self):
|
|
||||||
"""Reload strongswan.conf settings and any plugins supporting reload.
|
|
||||||
"""
|
|
||||||
self.handler.request("reload-settings")
|
|
||||||
|
|
||||||
def initiate(self, sa):
|
|
||||||
"""Initiate an SA.
|
|
||||||
|
|
||||||
:param sa: the SA to initiate
|
|
||||||
:type sa: dict
|
|
||||||
:return: generator for logs emitted as dict
|
|
||||||
:rtype: generator
|
|
||||||
"""
|
|
||||||
return self.handler.streamed_request("initiate", "control-log", sa)
|
|
||||||
|
|
||||||
def terminate(self, sa):
|
|
||||||
"""Terminate an SA.
|
|
||||||
|
|
||||||
:param sa: the SA to terminate
|
|
||||||
:type sa: dict
|
|
||||||
:return: generator for logs emitted as dict
|
|
||||||
:rtype: generator
|
|
||||||
"""
|
|
||||||
return self.handler.streamed_request("terminate", "control-log", sa)
|
|
||||||
|
|
||||||
def redirect(self, sa):
|
|
||||||
"""Redirect an IKE_SA.
|
|
||||||
|
|
||||||
:param sa: the SA to redirect
|
|
||||||
:type sa: dict
|
|
||||||
"""
|
|
||||||
self.handler.request("redirect", sa)
|
|
||||||
|
|
||||||
def install(self, policy):
|
|
||||||
"""Install a trap, drop or bypass policy defined by a CHILD_SA config.
|
|
||||||
|
|
||||||
:param policy: policy to install
|
|
||||||
:type policy: dict
|
|
||||||
"""
|
|
||||||
self.handler.request("install", policy)
|
|
||||||
|
|
||||||
def uninstall(self, policy):
|
|
||||||
"""Uninstall a trap, drop or bypass policy defined by a CHILD_SA config.
|
|
||||||
|
|
||||||
:param policy: policy to uninstall
|
|
||||||
:type policy: dict
|
|
||||||
"""
|
|
||||||
self.handler.request("uninstall", policy)
|
|
||||||
|
|
||||||
def list_sas(self, filters=None):
|
|
||||||
"""Retrieve active IKE_SAs and associated CHILD_SAs.
|
|
||||||
|
|
||||||
:param filters: retrieve only matching IKE_SAs (optional)
|
|
||||||
:type filters: dict
|
|
||||||
:return: generator for active IKE_SAs and associated CHILD_SAs as dict
|
|
||||||
:rtype: generator
|
|
||||||
"""
|
|
||||||
return self.handler.streamed_request("list-sas", "list-sa", filters)
|
|
||||||
|
|
||||||
def list_policies(self, filters=None):
|
|
||||||
"""Retrieve installed trap, drop and bypass policies.
|
|
||||||
|
|
||||||
:param filters: retrieve only matching policies (optional)
|
|
||||||
:type filters: dict
|
|
||||||
:return: generator for installed trap, drop and bypass policies as dict
|
|
||||||
:rtype: generator
|
|
||||||
"""
|
|
||||||
return self.handler.streamed_request("list-policies", "list-policy",
|
|
||||||
filters)
|
|
||||||
|
|
||||||
def list_conns(self, filters=None):
|
|
||||||
"""Retrieve loaded connections.
|
|
||||||
|
|
||||||
:param filters: retrieve only matching configuration names (optional)
|
|
||||||
:type filters: dict
|
|
||||||
:return: generator for loaded connections as dict
|
|
||||||
:rtype: generator
|
|
||||||
"""
|
|
||||||
return self.handler.streamed_request("list-conns", "list-conn",
|
|
||||||
filters)
|
|
||||||
|
|
||||||
def get_conns(self):
|
|
||||||
"""Retrieve connection names loaded exclusively over vici.
|
|
||||||
|
|
||||||
:return: connection names
|
|
||||||
:rtype: dict
|
|
||||||
"""
|
|
||||||
return self.handler.request("get-conns")
|
|
||||||
|
|
||||||
def list_certs(self, filters=None):
|
|
||||||
"""Retrieve loaded certificates.
|
|
||||||
|
|
||||||
:param filters: retrieve only matching certificates (optional)
|
|
||||||
:type filters: dict
|
|
||||||
:return: generator for loaded certificates as dict
|
|
||||||
:rtype: generator
|
|
||||||
"""
|
|
||||||
return self.handler.streamed_request("list-certs", "list-cert", filters)
|
|
||||||
|
|
||||||
def load_conn(self, connection):
|
|
||||||
"""Load a connection definition into the daemon.
|
|
||||||
|
|
||||||
:param connection: connection definition
|
|
||||||
:type connection: dict
|
|
||||||
"""
|
|
||||||
self.handler.request("load-conn", connection)
|
|
||||||
|
|
||||||
def unload_conn(self, name):
|
|
||||||
"""Unload a connection definition.
|
|
||||||
|
|
||||||
:param name: connection definition name
|
|
||||||
:type name: dict
|
|
||||||
"""
|
|
||||||
self.handler.request("unload-conn", name)
|
|
||||||
|
|
||||||
def load_cert(self, certificate):
|
|
||||||
"""Load a certificate into the daemon.
|
|
||||||
|
|
||||||
:param certificate: PEM or DER encoded certificate
|
|
||||||
:type certificate: dict
|
|
||||||
"""
|
|
||||||
self.handler.request("load-cert", certificate)
|
|
||||||
|
|
||||||
def load_key(self, private_key):
|
|
||||||
"""Load a private key into the daemon.
|
|
||||||
|
|
||||||
:param private_key: PEM or DER encoded key
|
|
||||||
"""
|
|
||||||
self.handler.request("load-key", private_key)
|
|
||||||
|
|
||||||
def load_shared(self, secret):
|
|
||||||
"""Load a shared IKE PSK, EAP or XAuth secret into the daemon.
|
|
||||||
|
|
||||||
:param secret: shared IKE PSK, EAP or XAuth secret
|
|
||||||
:type secret: dict
|
|
||||||
"""
|
|
||||||
self.handler.request("load-shared", secret)
|
|
||||||
|
|
||||||
def flush_certs(self, filter=None):
|
|
||||||
"""Flush the volatile certificate cache.
|
|
||||||
|
|
||||||
Flush the certificate stored temporarily in the cache. The filter
|
|
||||||
allows to flush only a certain type of certificates, e.g. CRLs.
|
|
||||||
|
|
||||||
:param filter: flush only certificates of a given type (optional)
|
|
||||||
:type filter: dict
|
|
||||||
"""
|
|
||||||
self.handler.request("flush-certs", filter)
|
|
||||||
|
|
||||||
def clear_creds(self):
|
|
||||||
"""Clear credentials loaded over vici.
|
|
||||||
|
|
||||||
Clear all loaded certificate, private key and shared key credentials.
|
|
||||||
This affects only credentials loaded over vici, but additionally
|
|
||||||
flushes the credential cache.
|
|
||||||
"""
|
|
||||||
self.handler.request("clear-creds")
|
|
||||||
|
|
||||||
def load_pool(self, pool):
|
|
||||||
"""Load a virtual IP pool.
|
|
||||||
|
|
||||||
Load an in-memory virtual IP and configuration attribute pool.
|
|
||||||
Existing pools with the same name get updated, if possible.
|
|
||||||
|
|
||||||
:param pool: virtual IP and configuration attribute pool
|
|
||||||
:type pool: dict
|
|
||||||
"""
|
|
||||||
return self.handler.request("load-pool", pool)
|
|
||||||
|
|
||||||
def unload_pool(self, pool_name):
|
|
||||||
"""Unload a virtual IP pool.
|
|
||||||
|
|
||||||
Unload a previously loaded virtual IP and configuration attribute pool.
|
|
||||||
Unloading fails for pools with leases currently online.
|
|
||||||
|
|
||||||
:param pool_name: pool by name
|
|
||||||
:type pool_name: dict
|
|
||||||
"""
|
|
||||||
self.handler.request("unload-pool", pool_name)
|
|
||||||
|
|
||||||
def get_pools(self, options):
|
|
||||||
"""Retrieve loaded pools.
|
|
||||||
|
|
||||||
:param options: filter by name and/or retrieve leases (optional)
|
|
||||||
:type options: dict
|
|
||||||
:return: loaded pools
|
|
||||||
:rtype: dict
|
|
||||||
"""
|
|
||||||
return self.handler.request("get-pools", options)
|
|
||||||
|
|
||||||
def listen(self, event_types):
|
|
||||||
"""Register and listen for the given events.
|
|
||||||
|
|
||||||
:param event_types: event types to register
|
|
||||||
:type event_types: list
|
|
||||||
:return: generator for streamed event responses as (event_type, dict)
|
|
||||||
:rtype: generator
|
|
||||||
"""
|
|
||||||
return self.handler.listen(event_types)
|
|
||||||
|
|
||||||
|
|
||||||
class SessionHandler(object):
|
|
||||||
"""Handles client command execution requests over vici."""
|
|
||||||
|
|
||||||
def __init__(self, transport):
|
|
||||||
self.transport = transport
|
|
||||||
|
|
||||||
def _communicate(self, packet):
|
def _communicate(self, packet):
|
||||||
"""Send packet over transport and parse response.
|
"""Send packet over transport and parse response.
|
||||||
@ -322,7 +100,7 @@ class SessionHandler(object):
|
|||||||
if message is not None:
|
if message is not None:
|
||||||
message = Message.serialize(message)
|
message = Message.serialize(message)
|
||||||
|
|
||||||
self._register_unregister(event_stream_type, True);
|
self._register_unregister(event_stream_type, True)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
packet = Packet.request(command, message)
|
packet = Packet.request(command, message)
|
||||||
@ -352,7 +130,7 @@ class SessionHandler(object):
|
|||||||
)
|
)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
self._register_unregister(event_stream_type, False);
|
self._register_unregister(event_stream_type, False)
|
||||||
|
|
||||||
# evaluate command result, if any
|
# evaluate command result, if any
|
||||||
if "success" in command_response:
|
if "success" in command_response:
|
||||||
@ -379,7 +157,8 @@ class SessionHandler(object):
|
|||||||
response = Packet.parse(self.transport.receive())
|
response = Packet.parse(self.transport.receive())
|
||||||
if response.response_type == Packet.EVENT:
|
if response.response_type == Packet.EVENT:
|
||||||
try:
|
try:
|
||||||
yield response.event_type, Message.deserialize(response.payload)
|
msg = Message.deserialize(response.payload)
|
||||||
|
yield response.event_type, msg
|
||||||
except GeneratorExit:
|
except GeneratorExit:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
5
src/libcharon/plugins/vici/ruby/.rubocop.yml
Normal file
5
src/libcharon/plugins/vici/ruby/.rubocop.yml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Naming/AccessorMethodName:
|
||||||
|
Enabled: false
|
||||||
|
|
||||||
|
Style/StringLiterals:
|
||||||
|
EnforcedStyle: double_quotes
|
@ -3,6 +3,9 @@
|
|||||||
# strongSwan VICI protocol. The Connection class provides a high-level
|
# strongSwan VICI protocol. The Connection class provides a high-level
|
||||||
# interface to issue requests or listen for events.
|
# interface to issue requests or listen for events.
|
||||||
#
|
#
|
||||||
|
# Copyright (C) 2019 Tobias Brunner
|
||||||
|
# HSR Hochschule fuer Technik Rapperswil
|
||||||
|
#
|
||||||
# Copyright (C) 2014 Martin Willi
|
# Copyright (C) 2014 Martin Willi
|
||||||
# Copyright (C) 2014 revosec AG
|
# Copyright (C) 2014 revosec AG
|
||||||
#
|
#
|
||||||
@ -25,7 +28,6 @@
|
|||||||
# THE SOFTWARE.
|
# THE SOFTWARE.
|
||||||
|
|
||||||
module Vici
|
module Vici
|
||||||
|
|
||||||
##
|
##
|
||||||
# Vici specific exception all others inherit from
|
# Vici specific exception all others inherit from
|
||||||
class Error < StandardError
|
class Error < StandardError
|
||||||
@ -76,12 +78,10 @@ module Vici
|
|||||||
class StopEventListening < Exception
|
class StopEventListening < Exception
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# The Message class provides the low level encoding and decoding of vici
|
# The Message class provides the low level encoding and decoding of vici
|
||||||
# protocol messages. Directly using this class is usually not required.
|
# protocol messages. Directly using this class is usually not required.
|
||||||
class Message
|
class Message
|
||||||
|
|
||||||
SECTION_START = 1
|
SECTION_START = 1
|
||||||
SECTION_END = 2
|
SECTION_END = 2
|
||||||
KEY_VALUE = 3
|
KEY_VALUE = 3
|
||||||
@ -90,8 +90,8 @@ module Vici
|
|||||||
LIST_END = 6
|
LIST_END = 6
|
||||||
|
|
||||||
def initialize(data = "")
|
def initialize(data = "")
|
||||||
if data == nil
|
if data.nil?
|
||||||
@root = Hash.new()
|
@root = {}
|
||||||
elsif data.is_a?(Hash)
|
elsif data.is_a?(Hash)
|
||||||
@root = data
|
@root = data
|
||||||
else
|
else
|
||||||
@ -102,18 +102,14 @@ module Vici
|
|||||||
##
|
##
|
||||||
# Get the raw byte encoding of an on-the-wire message
|
# Get the raw byte encoding of an on-the-wire message
|
||||||
def encoding
|
def encoding
|
||||||
if @encoded == nil
|
@encoded = encode(@root) if @encoded.nil?
|
||||||
@encoded = encode(@root)
|
|
||||||
end
|
|
||||||
@encoded
|
@encoded
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Get the root element of the parsed ruby data structures
|
# Get the root element of the parsed ruby data structures
|
||||||
def root
|
def root
|
||||||
if @root == nil
|
@root = parse(@encoded) if @root.nil?
|
||||||
@root = parse(@encoded)
|
|
||||||
end
|
|
||||||
@root
|
@root
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -124,9 +120,7 @@ module Vici
|
|||||||
end
|
end
|
||||||
|
|
||||||
def encode_value(value)
|
def encode_value(value)
|
||||||
if value.class != String
|
value = value.to_s if value.class != String
|
||||||
value = value.to_s
|
|
||||||
end
|
|
||||||
[value.length].pack("n") << value
|
[value.length].pack("n") << value
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -150,17 +144,12 @@ module Vici
|
|||||||
def encode(node)
|
def encode(node)
|
||||||
encoding = ""
|
encoding = ""
|
||||||
node.each do |key, value|
|
node.each do |key, value|
|
||||||
case value.class
|
encoding = if value.is_a?(Hash)
|
||||||
when String, Fixnum, true, false
|
encode_section(encoding, key, value)
|
||||||
encoding = encode_kv(encoding, key, value)
|
|
||||||
else
|
|
||||||
if value.is_a?(Hash)
|
|
||||||
encoding = encode_section(encoding, key, value)
|
|
||||||
elsif value.is_a?(Array)
|
elsif value.is_a?(Array)
|
||||||
encoding = encode_list(encoding, key, value)
|
encode_list(encoding, key, value)
|
||||||
else
|
else
|
||||||
encoding = encode_kv(encoding, key, value)
|
encode_kv(encoding, key, value)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
encoding
|
encoding
|
||||||
@ -169,30 +158,28 @@ module Vici
|
|||||||
def parse_name(encoding)
|
def parse_name(encoding)
|
||||||
len = encoding.unpack("c")[0]
|
len = encoding.unpack("c")[0]
|
||||||
name = encoding[1, len]
|
name = encoding[1, len]
|
||||||
return encoding[(1 + len)..-1], name
|
[encoding[(1 + len)..-1], name]
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_value(encoding)
|
def parse_value(encoding)
|
||||||
len = encoding.unpack("n")[0]
|
len = encoding.unpack("n")[0]
|
||||||
value = encoding[2, len]
|
value = encoding[2, len]
|
||||||
return encoding[(2 + len)..-1], value
|
[encoding[(2 + len)..-1], value]
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse(encoding)
|
def parse(encoding)
|
||||||
stack = [Hash.new]
|
stack = [{}]
|
||||||
list = nil
|
list = nil
|
||||||
while encoding.length != 0 do
|
until encoding.empty?
|
||||||
type = encoding.unpack("c")[0]
|
type = encoding.unpack("c")[0]
|
||||||
encoding = encoding[1..-1]
|
encoding = encoding[1..-1]
|
||||||
case type
|
case type
|
||||||
when SECTION_START
|
when SECTION_START
|
||||||
encoding, name = parse_name(encoding)
|
encoding, name = parse_name(encoding)
|
||||||
stack.push(stack[-1][name] = Hash.new)
|
stack.push(stack[-1][name] = {})
|
||||||
when SECTION_END
|
when SECTION_END
|
||||||
if stack.length() == 1
|
raise ParseError, "unexpected section end" if stack.length == 1
|
||||||
raise ParseError, "unexpected section end"
|
stack.pop
|
||||||
end
|
|
||||||
stack.pop()
|
|
||||||
when KEY_VALUE
|
when KEY_VALUE
|
||||||
encoding, name = parse_name(encoding)
|
encoding, name = parse_name(encoding)
|
||||||
encoding, value = parse_value(encoding)
|
encoding, value = parse_value(encoding)
|
||||||
@ -202,30 +189,26 @@ module Vici
|
|||||||
stack[-1][name] = []
|
stack[-1][name] = []
|
||||||
list = name
|
list = name
|
||||||
when LIST_ITEM
|
when LIST_ITEM
|
||||||
raise ParseError, "unexpected list item" if list == nil
|
raise ParseError, "unexpected list item" if list.nil?
|
||||||
encoding, value = parse_value(encoding)
|
encoding, value = parse_value(encoding)
|
||||||
stack[-1][list].push(value)
|
stack[-1][list].push(value)
|
||||||
when LIST_END
|
when LIST_END
|
||||||
raise ParseError, "unexpected list end" if list == nil
|
raise ParseError, "unexpected list end" if list.nil?
|
||||||
list = nil
|
list = nil
|
||||||
else
|
else
|
||||||
raise ParseError, "invalid type: #{type}"
|
raise ParseError, "invalid type: #{type}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if stack.length() > 1
|
raise ParseError, "unexpected message end" if stack.length > 1
|
||||||
raise ParseError, "unexpected message end"
|
|
||||||
end
|
|
||||||
stack[0]
|
stack[0]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# The Transport class implements to low level segmentation of packets
|
# The Transport class implements to low level segmentation of packets
|
||||||
# to the underlying transport stream. Directly using this class is usually
|
# to the underlying transport stream. Directly using this class is usually
|
||||||
# not required.
|
# not required.
|
||||||
class Transport
|
class Transport
|
||||||
|
|
||||||
CMD_REQUEST = 0
|
CMD_REQUEST = 0
|
||||||
CMD_RESPONSE = 1
|
CMD_RESPONSE = 1
|
||||||
CMD_UNKNOWN = 2
|
CMD_UNKNOWN = 2
|
||||||
@ -239,18 +222,16 @@ module Vici
|
|||||||
# Create a transport layer using a provided socket for communication.
|
# Create a transport layer using a provided socket for communication.
|
||||||
def initialize(socket)
|
def initialize(socket)
|
||||||
@socket = socket
|
@socket = socket
|
||||||
@events = Hash.new
|
@events = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Receive data from socket, until len bytes read
|
# Receive data from socket, until len bytes read
|
||||||
def recv_all(len)
|
def recv_all(len)
|
||||||
encoding = ""
|
encoding = ""
|
||||||
while encoding.length < len do
|
while encoding.length < len
|
||||||
data = @socket.recv(len - encoding.length)
|
data = @socket.recv(len - encoding.length)
|
||||||
if data.empty?
|
raise TransportError, "connection closed" if data.empty?
|
||||||
raise TransportError, "connection closed"
|
|
||||||
end
|
|
||||||
encoding << data
|
encoding << data
|
||||||
end
|
end
|
||||||
encoding
|
encoding
|
||||||
@ -260,9 +241,7 @@ module Vici
|
|||||||
# Send data to socket, until all bytes sent
|
# Send data to socket, until all bytes sent
|
||||||
def send_all(encoding)
|
def send_all(encoding)
|
||||||
len = 0
|
len = 0
|
||||||
while len < encoding.length do
|
len += @socket.send(encoding[len..-1], 0) while len < encoding.length
|
||||||
len += @socket.send(encoding[len..-1], 0)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
@ -270,12 +249,8 @@ module Vici
|
|||||||
# specifies the message, the optional label and message get appended.
|
# specifies the message, the optional label and message get appended.
|
||||||
def write(type, label, message)
|
def write(type, label, message)
|
||||||
encoding = ""
|
encoding = ""
|
||||||
if label
|
encoding << label.length << label if label
|
||||||
encoding << label.length << label
|
encoding << message.encoding if message
|
||||||
end
|
|
||||||
if message
|
|
||||||
encoding << message.encoding
|
|
||||||
end
|
|
||||||
send_all([encoding.length + 1, type].pack("Nc") + encoding)
|
send_all([encoding.length + 1, type].pack("Nc") + encoding)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -296,10 +271,12 @@ module Vici
|
|||||||
else
|
else
|
||||||
raise TransportError, "invalid message: #{type}"
|
raise TransportError, "invalid message: #{type}"
|
||||||
end
|
end
|
||||||
if encoding.length == len
|
message = if encoding.length == len
|
||||||
return type, label, Message.new
|
Message.new
|
||||||
|
else
|
||||||
|
Message.new(encoding[len..-1])
|
||||||
end
|
end
|
||||||
return type, label, Message.new(encoding[len..-1])
|
[type, label, message]
|
||||||
end
|
end
|
||||||
|
|
||||||
def dispatch_event(name, message)
|
def dispatch_event(name, message)
|
||||||
@ -310,22 +287,17 @@ module Vici
|
|||||||
|
|
||||||
def read_and_dispatch_event
|
def read_and_dispatch_event
|
||||||
type, label, message = read
|
type, label, message = read
|
||||||
p
|
raise TransportError, "unexpected message: #{type}" if type != EVENT
|
||||||
if type == EVENT
|
|
||||||
dispatch_event(label, message)
|
dispatch_event(label, message)
|
||||||
else
|
|
||||||
raise TransportError, "unexpected message: #{type}"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def read_and_dispatch_events
|
def read_and_dispatch_events
|
||||||
loop do
|
loop do
|
||||||
type, label, message = read
|
type, label, message = read
|
||||||
if type == EVENT
|
return type, label, message if type != EVENT
|
||||||
|
|
||||||
dispatch_event(label, message)
|
dispatch_event(label, message)
|
||||||
else
|
|
||||||
return type, label, message
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -334,7 +306,7 @@ module Vici
|
|||||||
# the reply message on success.
|
# the reply message on success.
|
||||||
def request(name, message = nil)
|
def request(name, message = nil)
|
||||||
write(CMD_REQUEST, name, message)
|
write(CMD_REQUEST, name, message)
|
||||||
type, label, message = read_and_dispatch_events
|
type, _label, message = read_and_dispatch_events
|
||||||
case type
|
case type
|
||||||
when CMD_RESPONSE
|
when CMD_RESPONSE
|
||||||
return message
|
return message
|
||||||
@ -349,13 +321,13 @@ module Vici
|
|||||||
# Register a handler method for the given event name
|
# Register a handler method for the given event name
|
||||||
def register(name, handler)
|
def register(name, handler)
|
||||||
write(EVENT_REGISTER, name, nil)
|
write(EVENT_REGISTER, name, nil)
|
||||||
type, label, message = read_and_dispatch_events
|
type, _label, _message = read_and_dispatch_events
|
||||||
case type
|
case type
|
||||||
when EVENT_CONFIRM
|
when EVENT_CONFIRM
|
||||||
if @events.has_key?(name)
|
if @events.key?(name)
|
||||||
@events[name] += [handler]
|
@events[name] += [handler]
|
||||||
else
|
else
|
||||||
@events[name] = [handler];
|
@events[name] = [handler]
|
||||||
end
|
end
|
||||||
when EVENT_UNKNOWN
|
when EVENT_UNKNOWN
|
||||||
raise EventUnknownError, name
|
raise EventUnknownError, name
|
||||||
@ -368,7 +340,7 @@ module Vici
|
|||||||
# Unregister a handler method for the given event name
|
# Unregister a handler method for the given event name
|
||||||
def unregister(name, handler)
|
def unregister(name, handler)
|
||||||
write(EVENT_UNREGISTER, name, nil)
|
write(EVENT_UNREGISTER, name, nil)
|
||||||
type, label, message = read_and_dispatch_events
|
type, _label, _message = read_and_dispatch_events
|
||||||
case type
|
case type
|
||||||
when EVENT_CONFIRM
|
when EVENT_CONFIRM
|
||||||
@events[name] -= [handler]
|
@events[name] -= [handler]
|
||||||
@ -380,7 +352,6 @@ module Vici
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# The Connection class provides the high-level interface to monitor, configure
|
# The Connection class provides the high-level interface to monitor, configure
|
||||||
# and control the IKE daemon. It takes a connected stream-oriented Socket for
|
# and control the IKE daemon. It takes a connected stream-oriented Socket for
|
||||||
@ -393,19 +364,65 @@ module Vici
|
|||||||
# Non-String values that are not a Hash nor an Array get converted with .to_s
|
# Non-String values that are not a Hash nor an Array get converted with .to_s
|
||||||
# during encoding.
|
# during encoding.
|
||||||
class Connection
|
class Connection
|
||||||
|
##
|
||||||
|
# Create a connection, optionally using the given socket
|
||||||
def initialize(socket = nil)
|
def initialize(socket = nil)
|
||||||
if socket == nil
|
socket = UNIXSocket.new("/var/run/charon.vici") if socket.nil?
|
||||||
socket = UNIXSocket.new("/var/run/charon.vici")
|
|
||||||
end
|
|
||||||
@transp = Transport.new(socket)
|
@transp = Transport.new(socket)
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# List matching loaded connections. The provided closure is invoked
|
# Get daemon version information
|
||||||
# for each matching connection.
|
def version
|
||||||
def list_conns(match = nil, &block)
|
call("version")
|
||||||
call_with_event("list-conns", Message.new(match), "list-conn", &block)
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Get daemon statistics and information.
|
||||||
|
def stats
|
||||||
|
call("stats")
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Reload strongswan.conf settings.
|
||||||
|
def reload_settings
|
||||||
|
call("reload-settings")
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Initiate a connection. The provided closure is invoked for each log line.
|
||||||
|
def initiate(options, &block)
|
||||||
|
call_with_event("initiate", Message.new(options), "control-log", &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Terminate a connection. The provided closure is invoked for each log line.
|
||||||
|
def terminate(options, &block)
|
||||||
|
call_with_event("terminate", Message.new(options), "control-log", &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Initiate the rekeying of an SA.
|
||||||
|
def rekey(options)
|
||||||
|
call("rekey", Message.new(options))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Redirect an IKE_SA.
|
||||||
|
def redirect(options)
|
||||||
|
call("redirect", Message.new(options))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Install a shunt/route policy.
|
||||||
|
def install(policy)
|
||||||
|
call("install", Message.new(policy))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Uninstall a shunt/route policy.
|
||||||
|
def uninstall(policy)
|
||||||
|
call("uninstall", Message.new(policy))
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
@ -423,6 +440,19 @@ module Vici
|
|||||||
&block)
|
&block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# List matching loaded connections. The provided closure is invoked
|
||||||
|
# for each matching connection.
|
||||||
|
def list_conns(match = nil, &block)
|
||||||
|
call_with_event("list-conns", Message.new(match), "list-conn", &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Get the names of connections managed by vici.
|
||||||
|
def get_conns
|
||||||
|
call("get-conns")
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# List matching loaded certificates. The provided closure is invoked
|
# List matching loaded certificates. The provided closure is invoked
|
||||||
# for each matching certificate definition.
|
# for each matching certificate definition.
|
||||||
@ -430,120 +460,138 @@ module Vici
|
|||||||
call_with_event("list-certs", Message.new(match), "list-cert", &block)
|
call_with_event("list-certs", Message.new(match), "list-cert", &block)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# List matching loaded certification authorities. The provided closure is
|
||||||
|
# invoked for each matching certification authority definition.
|
||||||
|
def list_authorities(match = nil, &block)
|
||||||
|
call_with_event("list-authorities", Message.new(match), "list-authority",
|
||||||
|
&block)
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Get the names of certification authorities managed by vici.
|
||||||
|
def get_authorities
|
||||||
|
call("get-authorities")
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Load a connection into the daemon.
|
# Load a connection into the daemon.
|
||||||
def load_conn(conn)
|
def load_conn(conn)
|
||||||
check_success(@transp.request("load-conn", Message.new(conn)))
|
call("load-conn", Message.new(conn))
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Unload a connection from the daemon.
|
# Unload a connection from the daemon.
|
||||||
def unload_conn(conn)
|
def unload_conn(conn)
|
||||||
check_success(@transp.request("unload-conn", Message.new(conn)))
|
call("unload-conn", Message.new(conn))
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Get the names of connections managed by vici.
|
|
||||||
def get_conns()
|
|
||||||
@transp.request("get-conns").root
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Flush credential cache.
|
|
||||||
def flush_certs(match = nil)
|
|
||||||
check_success(@transp.request("flush-certs", Message.new(match)))
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Clear all loaded credentials.
|
|
||||||
def clear_creds()
|
|
||||||
check_success(@transp.request("clear-creds"))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Load a certificate into the daemon.
|
# Load a certificate into the daemon.
|
||||||
def load_cert(cert)
|
def load_cert(cert)
|
||||||
check_success(@transp.request("load-cert", Message.new(cert)))
|
call("load-cert", Message.new(cert))
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Load a private key into the daemon.
|
# Load a private key into the daemon.
|
||||||
def load_key(key)
|
def load_key(key)
|
||||||
check_success(@transp.request("load-key", Message.new(key)))
|
call("load-key", Message.new(key))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Unload a private key from the daemon.
|
||||||
|
def unload_key(key)
|
||||||
|
call("unload-key", Message.new(key))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Get the identifiers of private keys loaded via vici.
|
||||||
|
def get_keys
|
||||||
|
call("get-keys")
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Load a private key located on a token into the daemon.
|
||||||
|
def load_token(token)
|
||||||
|
call("load-token", Message.new(token))
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Load a shared key into the daemon.
|
# Load a shared key into the daemon.
|
||||||
def load_shared(shared)
|
def load_shared(shared)
|
||||||
check_success(@transp.request("load-shared", Message.new(shared)))
|
call("load-shared", Message.new(shared))
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Load a virtual IP / attribute pool
|
# Unload a shared key from the daemon.
|
||||||
|
def unload_shared(shared)
|
||||||
|
call("unload-shared", Message.new(shared))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Get the unique identifiers of shared keys loaded via vici.
|
||||||
|
def get_shared
|
||||||
|
call("get-shared")
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Flush credential cache.
|
||||||
|
def flush_certs(match = nil)
|
||||||
|
call("flush-certs", Message.new(match))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Clear all loaded credentials.
|
||||||
|
def clear_creds
|
||||||
|
call("clear-creds")
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Load a certification authority into the daemon.
|
||||||
|
def load_authority(authority)
|
||||||
|
call("load-authority", Message.new(authority))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Unload a certification authority from the daemon.
|
||||||
|
def unload_authority(authority)
|
||||||
|
call("unload-authority", Message.new(authority))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Load a virtual IP / attribute pool into the daemon.
|
||||||
def load_pool(pool)
|
def load_pool(pool)
|
||||||
check_success(@transp.request("load-pool", Message.new(pool)))
|
call("load-pool", Message.new(pool))
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Unload a virtual IP / attribute pool
|
# Unload a virtual IP / attribute pool from the daemon.
|
||||||
def unload_pool(pool)
|
def unload_pool(pool)
|
||||||
check_success(@transp.request("unload-pool", Message.new(pool)))
|
call("unload-pool", Message.new(pool))
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Get the currently loaded pools.
|
# Get the currently loaded pools.
|
||||||
def get_pools(options)
|
def get_pools(options)
|
||||||
@transp.request("get-pools", Message.new(options)).root
|
call("get-pools", Message.new(options))
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Initiate a connection. The provided closure is invoked for each log line.
|
# Get currently loaded algorithms and their implementation.
|
||||||
def initiate(options, &block)
|
def get_algorithms
|
||||||
check_success(call_with_event("initiate", Message.new(options),
|
call("get-algorithms")
|
||||||
"control-log", &block))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Terminate a connection. The provided closure is invoked for each log line.
|
# Get global or connection-specific counters for IKE events.
|
||||||
def terminate(options, &block)
|
def get_counters(options = nil)
|
||||||
check_success(call_with_event("terminate", Message.new(options),
|
call("get-counters", Message.new(options))
|
||||||
"control-log", &block))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Redirect an IKE_SA.
|
# Reset global or connection-specific IKE event counters.
|
||||||
def redirect(options)
|
def reset_counters(options = nil)
|
||||||
check_success(@transp.request("redirect", Message.new(options)))
|
call("reset-counters", Message.new(options))
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Install a shunt/route policy.
|
|
||||||
def install(policy)
|
|
||||||
check_success(@transp.request("install", Message.new(policy)))
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Uninstall a shunt/route policy.
|
|
||||||
def uninstall(policy)
|
|
||||||
check_success(@transp.request("uninstall", Message.new(policy)))
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Reload strongswan.conf settings.
|
|
||||||
def reload_settings
|
|
||||||
check_success(@transp.request("reload-settings", nil))
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Get daemon statistics and information.
|
|
||||||
def stats
|
|
||||||
@transp.request("stats", nil).root
|
|
||||||
end
|
|
||||||
|
|
||||||
##
|
|
||||||
# Get daemon version information
|
|
||||||
def version
|
|
||||||
@transp.request("version", nil).root
|
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
@ -573,6 +621,13 @@ module Vici
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
# Issue a command request. Checks if the reply of a command indicates
|
||||||
|
# "success", otherwise raises a CommandExecError exception.
|
||||||
|
def call(command, request = nil)
|
||||||
|
check_success(@transp.request(command, request))
|
||||||
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
# Issue a command request, but register for a specific event while the
|
# Issue a command request, but register for a specific event while the
|
||||||
# command is active. VICI uses this mechanism to stream potentially large
|
# command is active. VICI uses this mechanism to stream potentially large
|
||||||
@ -580,7 +635,7 @@ module Vici
|
|||||||
# event messages.
|
# event messages.
|
||||||
def call_with_event(command, request, event, &block)
|
def call_with_event(command, request, event, &block)
|
||||||
self.class.instance_eval do
|
self.class.instance_eval do
|
||||||
define_method(:call_event) do |label, message|
|
define_method(:call_event) do |_label, message|
|
||||||
block.call(message.root)
|
block.call(message.root)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -590,7 +645,7 @@ module Vici
|
|||||||
ensure
|
ensure
|
||||||
@transp.unregister(event, method(:call_event))
|
@transp.unregister(event, method(:call_event))
|
||||||
end
|
end
|
||||||
reply
|
check_success(reply)
|
||||||
end
|
end
|
||||||
|
|
||||||
##
|
##
|
||||||
@ -598,9 +653,10 @@ module Vici
|
|||||||
# CommandExecError exception
|
# CommandExecError exception
|
||||||
def check_success(reply)
|
def check_success(reply)
|
||||||
root = reply.root
|
root = reply.root
|
||||||
if root["success"] != "yes"
|
if root.key?("success") && root["success"] != "yes"
|
||||||
raise CommandExecError, root["errmsg"]
|
raise CommandExecError, root["errmsg"]
|
||||||
end
|
end
|
||||||
|
|
||||||
root
|
root
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
Gem::Specification.new do |s|
|
Gem::Specification.new do |s|
|
||||||
s.name = "vici"
|
s.name = "vici"
|
||||||
s.version = "@GEM_VERSION@"
|
s.version = "@GEM_VERSION@"
|
||||||
s.authors = ["Martin Willi"]
|
s.authors = ["strongSwan Project"]
|
||||||
s.email = ["martin@strongswan.org"]
|
s.email = ["info@strongswan.org"]
|
||||||
s.description = %q{
|
s.description = %q{
|
||||||
The strongSwan VICI protocol allows external application to monitor,
|
The strongSwan VICI protocol allows external application to monitor,
|
||||||
configure and control the IKE daemon charon. This ruby gem provides a
|
configure and control the IKE daemon charon. This Ruby Gem provides a
|
||||||
native client side implementation of the VICI protocol, well suited to
|
native client side implementation of the VICI protocol, well suited to
|
||||||
script automated tasks in a relaible way.
|
script automated tasks in a relaible way.
|
||||||
}
|
}
|
||||||
s.summary = "Native ruby interface for strongSwan VICI"
|
s.summary = "Native Ruby interface for strongSwan VICI"
|
||||||
s.homepage = "https://wiki.strongswan.org/projects/strongswan/wiki/Vici"
|
s.homepage = "https://wiki.strongswan.org/projects/strongswan/wiki/Vici"
|
||||||
s.license = "MIT"
|
s.license = "MIT"
|
||||||
s.files = "lib/vici.rb"
|
s.files = "lib/vici.rb"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user