477 lines
15 KiB
C
477 lines
15 KiB
C
/*
|
|
* Copyright (C) 2014 Martin Willi
|
|
* Copyright (C) 2014 revosec AG
|
|
*
|
|
* libvici.h is MIT-licensed to simplify reuse, but please note that libvici.c
|
|
* is not, as it depends on the GPLv2 licensed libstrongswan.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in
|
|
* all copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
* THE SOFTWARE.
|
|
*/
|
|
|
|
/**
|
|
* @defgroup libvici libvici
|
|
* @{ @ingroup vici
|
|
*
|
|
* libvici is a low-level client library for the "Versatile IKE Control
|
|
* Interface" protocol. While it uses libstrongswan and its thread-pool for
|
|
* asynchronous message delivery, this interface does not directly depend on
|
|
* libstrongswan interfaces and should be stable.
|
|
*
|
|
* This interface provides the following basic functions:
|
|
*
|
|
* - vici_init()/vici_deinit(): Library initialization functions
|
|
* - vici_connect(): Connect to a vici service
|
|
* - vici_disconnect(): Disconnect from a vici service
|
|
*
|
|
* Library initialization implicitly initializes libstrongswan and a small
|
|
* thread pool.
|
|
*
|
|
* Connecting requires an uri, which is currently either a UNIX socket path
|
|
* prefixed with unix://, or a hostname:port tuple prefixed with tcp://.
|
|
* Passing NULL takes the system default socket path.
|
|
*
|
|
* After the connection has been established, request messages can be sent.
|
|
* Only a single thread may operate on a single connection instance
|
|
* simultaneously. To construct request messages, use the following functions:
|
|
*
|
|
* - vici_add_key_value() / vici_add_key_valuef(): Add key/value pairs
|
|
* - vici_begin(): Start constructing a new request message
|
|
* - vici_begin_section(): Open a new section to add contents to
|
|
* - vici_end_section(): Close a previously opened session
|
|
* - vici_begin_list(): Open a new list to add list items to
|
|
* - vici_end_list(): Close a previously opened list
|
|
* - vici_add_list_item() / vici_add_list_itemf(): Add list item
|
|
*
|
|
* Once the request message is complete, it can be sent or cancelled with:
|
|
*
|
|
* - vici_submit()
|
|
* - vici_free_req()
|
|
*
|
|
* If submitting a message is successful, a response message is returned. It
|
|
* can be processed using the following functions:
|
|
*
|
|
* - vici_parse(): Parse content type
|
|
* - vici_parse_name(): Parse name if content type provides one
|
|
* - vici_parse_name_eq(): Parse name and check if matches string
|
|
* - vici_parse_value() / vici_parse_value_str(): Parse value for content type
|
|
* - vici_dump(): Dump a full response to a FILE stream
|
|
* - vici_free_res(): Free response after use
|
|
*
|
|
* Usually vici_parse() is called in a loop, and depending on the returned
|
|
* type the name and value can be inspected.
|
|
*
|
|
* To register or unregister for asynchronous event messages vici_register() is
|
|
* used. The registered callback gets invoked by an asynchronous thread. To
|
|
* parse the event message, the vici_parse*() functions can be used.
|
|
*/
|
|
|
|
#ifndef LIBVICI_H_
|
|
#define LIBVICI_H_
|
|
|
|
#include <stdio.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* Opaque vici connection context.
|
|
*/
|
|
typedef struct vici_conn_t vici_conn_t;
|
|
|
|
/**
|
|
* Opaque vici request message.
|
|
*/
|
|
typedef struct vici_req_t vici_req_t;
|
|
|
|
/**
|
|
* Opaque vici response/event message.
|
|
*/
|
|
typedef struct vici_res_t vici_res_t;
|
|
|
|
/**
|
|
* Vici parse result, as returned by vici_parse().
|
|
*/
|
|
typedef enum {
|
|
/** encountered a section start, has a name */
|
|
VICI_PARSE_BEGIN_SECTION,
|
|
/** encountered a section end */
|
|
VICI_PARSE_END_SECTION,
|
|
/** encountered a list start, has a name */
|
|
VICI_PARSE_BEGIN_LIST,
|
|
/** encountered a list element, has a value */
|
|
VICI_PARSE_LIST_ITEM,
|
|
/** encountered a list end */
|
|
VICI_PARSE_END_LIST,
|
|
/** encountered a key/value pair, has a name and a value */
|
|
VICI_PARSE_KEY_VALUE,
|
|
/** encountered valid end of message */
|
|
VICI_PARSE_END,
|
|
/** parse error */
|
|
VICI_PARSE_ERROR,
|
|
} vici_parse_t;
|
|
|
|
/**
|
|
* Callback function invoked for received event messages.
|
|
*
|
|
* It is not allowed to call vici_submit() from this callback.
|
|
*
|
|
* @param user user data, as passed to vici_connect
|
|
* @param name name of received event
|
|
* @param msg associated event message, destroyed by libvici
|
|
*/
|
|
typedef void (*vici_event_cb_t)(void *user, char *name, vici_res_t *msg);
|
|
|
|
/**
|
|
* Callback function for key/value and list items, invoked by vici_parse_cb().
|
|
*
|
|
* @param user user data, as passed to vici_parse_cb()
|
|
* @param res message currently parsing
|
|
* @param name name of key or list
|
|
* @param value value buffer
|
|
* @param len length of value buffer
|
|
* @return 0 if parsed successfully
|
|
*/
|
|
typedef int (*vici_parse_value_cb_t)(void *user, vici_res_t *res, char *name,
|
|
void *value, int len);
|
|
|
|
/**
|
|
* Callback function for sections, invoked by vici_parse_cb().
|
|
*
|
|
* @param user user data, as passed to vici_parse_cb()
|
|
* @param res message currently parsing
|
|
* @param name name of the section
|
|
* @return 0 if parsed successfully
|
|
*/
|
|
typedef int (*vici_parse_section_cb_t)(void *user, vici_res_t *res, char *name);
|
|
|
|
/**
|
|
* Open a new vici connection.
|
|
*
|
|
* On error, NULL is returned and errno is set appropriately.
|
|
*
|
|
* @param uri URI to connect to, NULL to use system default
|
|
* @return opaque vici connection context, NULL on error
|
|
*/
|
|
vici_conn_t* vici_connect(char *uri);
|
|
|
|
/**
|
|
* Close a vici connection.
|
|
*
|
|
* @param conn connection context
|
|
*/
|
|
void vici_disconnect(vici_conn_t *conn);
|
|
|
|
/**
|
|
* Begin a new vici message request.
|
|
*
|
|
* This function always succeeds.
|
|
*
|
|
* @param name name of request command
|
|
* @return request message, to add contents
|
|
*/
|
|
vici_req_t* vici_begin(char *name);
|
|
|
|
/**
|
|
* Begin a new section in a vici request message.
|
|
*
|
|
* @param req request message to create a new section in
|
|
* @param name name of section to create
|
|
*/
|
|
void vici_begin_section(vici_req_t *req, char *name);
|
|
|
|
/**
|
|
* End a previously opened section.
|
|
*
|
|
* @param req request message to close an open section in
|
|
*/
|
|
void vici_end_section(vici_req_t *req);
|
|
|
|
/**
|
|
* Add a key/value pair, using an as-is blob as value.
|
|
*
|
|
* @param req request message to add key/value pair to
|
|
* @param key key name of key/value pair
|
|
* @param buf pointer to blob to add as value
|
|
* @param len length of value blob to add
|
|
*/
|
|
void vici_add_key_value(vici_req_t *req, char *key, void *buf, int len);
|
|
|
|
/**
|
|
* Add a key/value pair, setting value from a printf() format string.
|
|
*
|
|
* @param req request message to add key/value pair to
|
|
* @param key key name of key/value pair
|
|
* @param fmt format string for value
|
|
* @param ... arguments to format string
|
|
*/
|
|
void vici_add_key_valuef(vici_req_t *req, char *key, char *fmt, ...);
|
|
|
|
/**
|
|
* Begin a list in a request message.
|
|
*
|
|
* After starting a list, only list items can be added until the list gets
|
|
* closed by vici_end_list().
|
|
*
|
|
* @param req request message to begin list in
|
|
* @param name name of list to begin
|
|
*/
|
|
void vici_begin_list(vici_req_t *req, char *name);
|
|
|
|
/**
|
|
* Add a list item to a currently open list, using an as-is blob.
|
|
*
|
|
* @param req request message to add list item to
|
|
* @param buf pointer to blob to add as value
|
|
* @param len length of value blob to add
|
|
*/
|
|
void vici_add_list_item(vici_req_t *req, void *buf, int len);
|
|
|
|
/**
|
|
* Add a list item to a currently open list, using a printf() format string.
|
|
*
|
|
* @param req request message to add list item to
|
|
* @param fmt format string to create value from
|
|
* @param ... arguments to format string
|
|
*/
|
|
void vici_add_list_itemf(vici_req_t *req, char *fmt, ...);
|
|
|
|
/**
|
|
* End a previously opened list in a request message.
|
|
*
|
|
* @param req request message to end list in
|
|
*/
|
|
void vici_end_list(vici_req_t *req);
|
|
|
|
/**
|
|
* Submit a request message, and wait for response.
|
|
*
|
|
* The request messages gets cleaned up by this call and gets invalid.
|
|
* On error, NULL is returned an errno is set to:
|
|
* - EINVAL if the request is invalid/incomplete
|
|
* - ENOENT if the command is unknown
|
|
* - EBADMSG if the response is invalid
|
|
* - Any other IO related errno
|
|
*
|
|
* @param req request message to send
|
|
* @param conn connection context to send message over
|
|
* @return response message, NULL on error
|
|
*/
|
|
vici_res_t* vici_submit(vici_req_t *req, vici_conn_t *conn);
|
|
|
|
/**
|
|
* Cancel a request message started.
|
|
*
|
|
* If a request created by vici_begin() does not get submitted using
|
|
* vici_submit(), it has to get freed using this call.
|
|
*
|
|
* @param req request message to clean up
|
|
*/
|
|
void vici_free_req(vici_req_t *req);
|
|
|
|
/**
|
|
* Dump a message text representation to a FILE stream.
|
|
*
|
|
* On error, errno is set to:
|
|
* - EBADMSG if the message is invalid
|
|
*
|
|
* @param res response message to dump
|
|
* @param label a label to print for this message
|
|
* @param pretty use pretty print with indentation
|
|
* @param out FILE to dump to
|
|
* @return 0 if dumped complete message, 1 on error
|
|
*/
|
|
int vici_dump(vici_res_t *res, char *label, int pretty, FILE *out);
|
|
|
|
/**
|
|
* Parse next element from a vici response message.
|
|
*
|
|
* @param res response message to parse
|
|
* @return parse result
|
|
*/
|
|
vici_parse_t vici_parse(vici_res_t *res);
|
|
|
|
/**
|
|
* Parse name tag / key of a previously parsed element.
|
|
*
|
|
* This call is valid only after vici_parse() returned VICI_PARSE_KEY_VALUE,
|
|
* VICI_PARSE_BEGIN_SECTION or VICI_PARSE_BEGIN_LIST.
|
|
*
|
|
* The string is valid until vici_free_res() is called.
|
|
*
|
|
* On error, errno is set to:
|
|
*- EINVAL if not in valid parser state
|
|
*
|
|
* @param res response message to parse
|
|
* @return name tag / key, NULL on error
|
|
*/
|
|
char* vici_parse_name(vici_res_t *res);
|
|
|
|
/**
|
|
* Compare name tag / key of a previously parsed element.
|
|
*
|
|
* This call is valid only after vici_parse() returned VICI_PARSE_KEY_VALUE,
|
|
* VICI_PARSE_BEGIN_SECTION or VICI_PARSE_BEGIN_LIST.
|
|
*
|
|
* @param res response message to parse
|
|
* @param name string to compare
|
|
* @return 1 if name equals, 0 if not
|
|
*/
|
|
int vici_parse_name_eq(vici_res_t *res, char *name);
|
|
|
|
/**
|
|
* Parse value of a previously parsed element, as a blob.
|
|
*
|
|
* This call is valid only after vici_parse() returned VICI_PARSE_KEY_VALUE or
|
|
* VICI_PARSE_LIST_ITEM.
|
|
*
|
|
* The string is valid until vici_free_res() is called.
|
|
*
|
|
* On error, errno is set to:
|
|
* - EINVAL if not in valid parser state
|
|
*
|
|
* @param res response message to parse
|
|
* @param len pointer receiving value length
|
|
* @return pointer to value, NULL on error
|
|
*/
|
|
void* vici_parse_value(vici_res_t *res, int *len);
|
|
|
|
/**
|
|
* Parse value of a previously parsed element, as a string.
|
|
*
|
|
* This call is valid only after vici_parse() returned VICI_PARSE_KEY_VALUE or
|
|
* VICI_PARSE_LIST_ITEM.
|
|
*
|
|
* This call is successful only if the value contains no non-printable
|
|
* characters. The string is valid until vici_free_res() is called.
|
|
*
|
|
* On error, errno is set to:
|
|
* - EBADMSG if value is not a printable string
|
|
* - EINVAL if not in valid parser state
|
|
*
|
|
* @param res response message to parse
|
|
* @return value as string, NULL on error
|
|
*/
|
|
char* vici_parse_value_str(vici_res_t *res);
|
|
|
|
/**
|
|
* Parse a complete message with callbacks.
|
|
*
|
|
* Any of the callbacks may be NULL to skip this kind of item. Callbacks are
|
|
* invoked for the current section level only. To descent into sections, call
|
|
* vici_parse_cb() from within a section callback.
|
|
*
|
|
* On error, errno is set to:
|
|
* - EBADMSG if message encoding invalid
|
|
* - Any other errno set by the invoked callbacks
|
|
*
|
|
* @param res message to parse
|
|
* @param section callback invoked for each section
|
|
* @param kv callback invoked for key/value pairs
|
|
* @param li callback invoked for list items
|
|
* @param user user data to pass to callbacks
|
|
* @return 0 if parsing successful
|
|
*/
|
|
int vici_parse_cb(vici_res_t *res, vici_parse_section_cb_t section,
|
|
vici_parse_value_cb_t kv, vici_parse_value_cb_t li,
|
|
void *user);
|
|
|
|
/*
|
|
* Find a blob value in a message for a given key.
|
|
*
|
|
* Sections can be selected by prefixing them separated by dots.
|
|
*
|
|
* @param res response message to parse
|
|
* @param len length of returned object
|
|
* @param fmt printf format string of key and sections
|
|
* @param ... arguments to format string
|
|
* @return blob value, having *len bytes, NULL if not found
|
|
*/
|
|
void *vici_find(vici_res_t *res, int *len, char *fmt, ...);
|
|
|
|
/**
|
|
* Find a string value in a message for a given key.
|
|
*
|
|
* Sections can be selected by prefixing them separated by dots.
|
|
*
|
|
* @param res response message to parse
|
|
* @param def default value, if key not found
|
|
* @param fmt printf format string of key and sections
|
|
* @param ... arguments to format string
|
|
* @return string, def if not found
|
|
*/
|
|
char* vici_find_str(vici_res_t *res, char *def, char *fmt, ...);
|
|
|
|
/**
|
|
* Find an integer value in a message for a given key.
|
|
*
|
|
* Sections can be selected by prefixing them separated by dots.
|
|
*
|
|
* @param res response message to parse
|
|
* @param def default value, if key not found
|
|
* @param fmt printf format string of key and sections
|
|
* @param ... arguments to format string
|
|
* @return integer value, def if not found
|
|
*/
|
|
int vici_find_int(vici_res_t *res, int def, char *fmt, ...);
|
|
|
|
/**
|
|
* Clean up a received response message.
|
|
*
|
|
* Event messages get cleaned up by the library, it is not allowed to call
|
|
* vici_free_res() from within a vici_event_cb_t.
|
|
*
|
|
* @param res response message to free
|
|
*/
|
|
void vici_free_res(vici_res_t *res);
|
|
|
|
/**
|
|
* (Un-)Register for events of a given kind.
|
|
*
|
|
* Events callbacks get invoked by a different thread from the libstrongswan
|
|
* thread pool.
|
|
* On failure, errno is set to:
|
|
* - ENOENT if the event name is unknown
|
|
* - EBADMSG if the response is invalid
|
|
* - Any other IO related errno
|
|
*
|
|
* @param conn connection context
|
|
* @param name name of event messages to register to
|
|
* @param cb callback function to register, NULL to unregister
|
|
* @param user user data passed to callback invocations
|
|
* @return 0 if registered successfully
|
|
*/
|
|
int vici_register(vici_conn_t *conn, char *name, vici_event_cb_t cb, void *user);
|
|
|
|
/**
|
|
* Initialize libvici before first time use.
|
|
*/
|
|
void vici_init();
|
|
|
|
/**
|
|
* Deinitialize libvici after use.
|
|
*/
|
|
void vici_deinit();
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /** LIBVICI_H_ @}*/
|