C APIs for the CaNI library

#ifndef CANI_API_H
#define CANI_API_H

#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/evp.h>
#include <openssl/safestack.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#include <sys/time.h>

/*!
 * Common API statements:
 *
 * Unless otherwise stated in the function description, all functions that 
 * return a value return a COPY of the real value used internally by the
 * API.  Modifying those values has no influence on the API workings.
 * Furthermore, the caller takes complete ownership of the return value.
 * It is his duty to deallocate the memory corresponding to it.
 *
 * All parameters passed to the functions will be copied internally, and the
 * copy  used in the original unless otherwise noted.  Changes to the 
 * passed parameters will have no effect.
 *
 * All functions that return an 'int' as a status report follow the convention
 * below unless otherwise noted in their individual description:
 * 0    Means success
 * !0   Is an error.
 */

/*!
 * The io_handler opaque type is used to hold all informations necessary
 * to do I/O over an SSL connection.
 */
typedef void *io_handler;

/*!
 * The cred_handler opaque type is used to hold all informations related to
 * the credentials used during the authentication process.  Different
 * cred_handler objects will be used for the client and server sides of a
 * connection.
 */
typedef void *cred_handler;

/**
 * The valid_handler opaque type is used to hold all informations related to
 * the validation process of a set of credentials.
 */
typedef void *valid_handler;

/**
 * The auth_ctx opaque type is used to hold information that will be used
 * throughout the library.
 */
typedef void *auth_ctx;

/**
 * This function returns an empty authentication context object.
 * @return  NULL in case of errors.
 */
auth_ctx authn_create_empty_ctx();

/**
 * This defines a new type, 'authn_password_callback' that represents a
 * function that will be called to retrieve the password to a set of credentials.
 *
 * @param ac The authentication context for the call
 * @param userdata A pointer to user specified data taht will be set by the user himself.
 *                  This parameter will be used 'as is.' No internal copy will be done.
 *
 * @return a C string with the password, or NULL in case of failure
 */
typedef char (*authn_password_callback)(auth_ctx ac, void *userdata);

/**
 * This function will specify were to find the CRLs that will be used in this context, 
 * and set this information in the passed authentication context. Its parameters are:
 * @param ac The authentication context for the call
 * @param path The path that will be set.  It will not be checked whether this path actually
 *             contains the CRLs or not.
 * @return a success/failure int.
 */
int authn_set_ctx_crl_path(auth_ctx ac, char *path);

/**
 * This function will return the path where CA certificates will be looked for:
 * @param ac The authentication context for the call
 * @return the path in which the CAs will be searched, or NULL if none was
 * specified. 
 */
char *authn_get_ctx_ca_path(authn_ctx ac);

/**
 * This function will return the path where CRL certificates will be looked for:
 * @param ac The authentication context for the call
 * @return the path in which the CRLs will be searched, or NULL if none was
 *         specified.
 */
char *authn_get_ctx_crl_path(authn_ctx ac);

/**
 * This function will set the credential to be associated to the context.  These
 * credentials will become the default ones for all API calls depending on this context.
 * @param ac The authentication context for the call
 * @param cert The certificate to load
 * @param chain It corresponding certificate chain
 * @param key Its private key
 * @return a success/failure int.
 */
int authn_set_ctx_own_cert(auth_ctx ac, X509 *cert, STACK_OF(X509*) chain, EVP_PKEY *key);

/**
 * This function will set the credential to be associated to the context.  These
 * credentials will become the default ones for all API calls depending on this context.
 * @param ac The authentication context for the call
 * @param cert The file containing the certificate to load
 * @param key The file containing the private key.  If NULL, then 'cert' should also contain the key
 * @param cb A callback function which should return the password to the private key, if needed.
 * @param userdata User specified data that will be passed as is to the callvack function.  Note that
 *                  the content of this pointer will not be copied internally, and will be passed
 *                  directly to the callback.  This means that altering the data pointed by it will have
 *                 a direct effect on the behaviour of the function.
 *
 * @return a success/failure int.
 */
int authn_set_ctx_own_cert_file(auth_ctx ac, char *cert, char *key, authn_password_callback cb, void *userdata);

/**
 * This function will return the certificate associated to the context,
 * @param ac The authentication context for the call
 * @return the certificate, or NULL if none was specified.
 */
X509 *authn_get_ctx_certificate(authn_ctx ac);

/**
 * This function will return the certificate stack associated to the context
 * @param ac The authentication context for the call
 * @return the certificate stack, or NULL if none was specified.
 */
STACK_OF(X509) *authn_get_ctx_certificate_chain(authn_ctx ac);

/**
 * This function will return the private key associated to the context
 * @param ac The authentication context for the call
 * @return the private key, or NULL if none was specified.
 */
EVP_PKEY *authn_get_ctx_key(authn_ctx ac);

/**
 * This function will free the authentication context,
 * releasing all associated information.  The context must
 * not be used after this call.
 * @param ac the authentication context to free.
 */
void authn_free_authn_ctx(authn_ctx ac);

/**
 * This creates a new auth_ctx from an existing one.
 * @param ac The original context
 * @return a new context, or NULL in case of failures.
 */
auth_ctx emi_authn_create_env_ctx(auth_ctx ac);


#define ERROR_VALIDATION_FAILED   1 /**< Error during validation */
#define ERROR_MEMORY_INSUFFICIENT 2 /**< Out of memory */
#define ERROR_NET_ERROR           3 /**< Problem during communication (either than verification) */
#define ERROR_BAD_CALL            4 /**< Problem with the passed parameters */
#define ERROR_SSL_ERROR           5 /**< Problem during SSL handshake */
#define ERROR_FILE_ERROR          6 /**< Error while trying to access files (see errno for details) */

/**
 * This function will create an i/o handler from the authentication context.
 * This handler shall be passed to all I/O-related functions. 
 * @param ac the authentication context
 * @return an I/O context, or NULL if it did not succeed.
 */
io_handler authn_create_io_handler(auth_ctx ac);

/**
 * This function will set the passed credentials as the credentials that will be
 * used during the authentication process.
 * @param ac The authentication context
 * @param io The i/o context
 * @param cred The credentials to use.
 * @return a success/failure int.
 */
int authn_io_set_own_credentials(auth_ctx ac, io_handler io, cred_handler cred);

/**
 * This function will be return a copy of the caller's credentials that have been
 * used, or will be used, to authenticate.
 * @param ac The authentication context
 * @param io The i/o context
 * @return a credential handler, or NULL if none is set.
 */
cred_handler authn_io_get_own_credentials(auth_ctx ac, io_handler io);

/**
 * This function will be return a copy of the peer credentials that have been
 * used to authenticate him. 
 * @param ac The authentication context
 * @param io The i/o context
 * @return a credential handler, or NULL if the authentication process
 *         did not take place.
 */
cred_handler authn_io_get_peer_credentials(auth_ctx ac, io_handler io);


#define CONN_FLAG_CLEAR               0x00000001 /**< Connect on clear text */
#define CONN_FLAG_SSL                 0x00000002 /**< Connect using SSL */
#define CONN_FLAG_BLOCKING            0x00000004 /**< Read and write requests should be blocking */
#define CONN_FLAG_DO_NOT_AUTHENTICATE 0x00000008 /**< Do not authenticate */

/**
 * This function will try to connect to a server object, doing authentication
 * if requested.  If authentication is necessary, this function will return *after*
 * authentication is completed. 
 * @param ac The authentication context
 * @param io The i/o context
 * @param host The server to which to connect.
 * @param port The port on which the server is listening
 * @param flags The type of connection.  This should be an OR of the CONN_FLAG_* values
 * @param ch The credentials to use.  If not present, the ones in 'io' are used
 * @param timeout The timeout after which to drop the connect attempt.
 * @return a success/failure int.
 */
int authn_io_connect(auth_ctx ac, io_handler io, char *host, int port, int flags, cred_handler ch, struct timeval *timeout);

/**
 * This function will setup a server to accept connections from clients,
 * doing authentication if requested.  If authentication is necessary, this
 * function will return *after* authentication is completed.
 *
 * @param ac The authentication context
 * @param io The i/o context
 * @param port The port on which the server is listening
 * @param flags The type of connection.  This should be an OR of the CONN_FLAG_* values
 * @param ch The credentials to use.  If not present, the ones in 'io' are used
 * @param new After a connection is completed, this handler should be used to talk on it.
 * @param timeout The timeout after which to drop the connect attempt.
 *
 * @return a success/failure int.
 */
int authn_io_accept(auth_ctx ac, io_handler io, int port, int flags, cred_handler ch, io_handler *new, struct timeval *timeout);

/**
 * This function will setup the validation handler to be used for credential
 * validation during the io.
 *
 * @param ac The authentication context
 * @param io The i/o context
 * @param vh The validation handle.
 *
 * @return a success/failure int.
 */
int authn_io_set_validator_handler(auth_ctx ac, io_handler io, valid_handler vh);

#define SOCKET_OPEN          0x00000001 /**< The socket is open */
#define SOCKET_SSL_CONNECTED 0x00000002 /**< The socket is connected */
#define SOCKET_SSL_ACCEPTED  0x00000004 /**< The socket is the result of an 'accept() operation */
#define SOCKET_CLEAR         0x00000008 /**< Communication is on the clear */
#define SOCKET_SSL           0x00000010 /**< Communication is via SSL */
#define SOCKET_SSL_ONLY      0x00000020 /**< Communication can ONLY be done via SSL */
#define SOCKET_BLOCKING      0x00000040 /**< Communication is blocking */

/**
 * This function will be used to access the underlying structures of the connection.
 *
 * @param ac The authentication context
 * @param io The i/o context
 * @param socket OUTPUT the socket that will be used by the connection
 * @param ssl OUTPUT The SSL structure that will be used by the connection.
 *
 * @return a success/failure int.
 *
 * @note The SSL and socket returned are the actual ones used by the library.
 * Modifying them *will* affect the behaviour of the library.
 */
int authn_io_get_socket(auth_ctx ac, io_handler io, int *socket, SSL **ssl);

/**
 * This function will be used to set the underlying structures of the connection.
 * Note that calling this function on an i/o handler object belonging to an
 * established connection, or to a listening one, will immediately destroy it.
 *
 * @param ac The authentication context
 * @param io The i/o context
 * @param socket The socket that will be used by the connection
 * @param ssl The SSL structure that will be used by the connection.
 * @param flags a combination of the OR flags above.  This will only be significant if
 *              the socket and ssl objects passed do not belong to an active connection.
 *
 * @return a success/failure int.
 */
int authn_io_put_socket(auth_ctx ac, io_handler io, int socket, SSL *ssl, int flags);

/**
 * This function will return the underlying BIO used during connections.
 *
 * @param ac The authentication context
 * @param io The i/o context
 *
 * @return the underlying BIO, or NULL id one was not created yet.
 * @note Note that this is the actual BIO used by the function, and modifying this
 * *will* affect the library.
 */
BIO *authn_io_get_bio(auth_ctx ac, io_handler io);

/**
 * This function will set a new BIO for the library's I/O.  Note that calling this function 
 * will cause the library to call BIO_free_all() on the previously used BIO.  Any pointer
 * obtained by authn_io_get_bio() will consequently become useless.
 *
 * @param ac The authentication context
 * @param io The i/o context
 * @param bio The new BIO to use.
 *
 * @return a success/failure int.
 */
int authn_io_set_bio(auth_ctx ac, io_handler io, BIO *bio);

/**
 * This function will read data from the connection.  It has the same semantics as
 * read() for what regards its treatment of the 'buffer' and 'size' parameters, along with
 * its return value.
 *
 * @param ac The authentication context
 * @param io The i/o context
 * @param buffer the buffer into which to copy the data read.
 * @param size The size of the buffer
 * @param timeout The maximum time that the connection will hang if blocking.
 * 
 * @return the number of bytes actually read, or -1 if an error happened.
 */
size_t authn_io_read(auth_ctx ac, io_handler io, void *buffer, size_t size, struct timeval *timeout);

/**
 * This function will write data to the conection.  It has the same semantics as
 * read() for what regards its treatment of the 'buffer' and 'size' parameters, along with
 * its return value.
 *
 * @param ac The authentication context
 * @param io The i/o context
 * @param buffer the buffer containing the data to write.
 * @param size The size of the buffer
 * @param timeout The maximum time that the connection will hang if blocking.
 * 
 * @return the number of bytes actually written, or -1 if an error happened.
 */
size_t authn_io_write(auth_ctx ac, io_handler io, void *buffer, size_t size, struct timeval *timeout);

/**
 * This function will create a string detailing the error which happened during i/o.
 *
 * @param ac The authentication context
 * @param io The i/o context
 * @param reason OUTPUT The detailed error string
 *
 * @return a success/failure int.
 */
int authn_io_get_error(auth_ctx ac, io_handler io, char **reason); /**< This gives additional info -- for example, exact reason why verification failed. */

/**
 * This function will close an existing connection.  The 'io' object may be
 * reused by another connection.  It is safe to call this function on an io
 * object which was connected.
 *
 * @param ac The authentication context
 * @param io The i/o context
 *
 * @return a success/failure int.
 */
int authn_io_close(auth_ctx ac, io_handler io);

/**
 * This function will destroy an existing i/o handler, closing the
 * underlying connection if necessary.  It is safe to call this function on an io
 * object which is not connected, or which is NULL.
 *
 * @param ac The authentication context
 * @param io The i/o context
 *
 */
void authn_io_destroy(auth_ctx ac, io_handler io);

/**
 * This function will create an empty credential handler to
 * contain a set of credentials, either local or remote.
 *
 * @param ac The authentication context
 *
 * @return a credential handler, or NULL if there were problems.  
 * The returned credential will refer to the default credentials present
 * in the context, if they have been set.
 */
cred_handler authn_create_cred_handler(auth_ctx ac);


/**
 * This function will specify which validator to use for the credentials.
 * This operation cannot fail, but note that this function should be
 * called *before* the credentials are validated to have any effect.
 *
 * @param ac The authentication context
 * @param ch The credentials handler for which to set the validator
 * @param vh The validator to be used.
 *
 */
void authn_cred_set_validator_handle(auth_ctx ac, cred_handler ch, valid_handler vh);

/**
 * This function will load the specified credentials in the credential handler
 *
 * @param ac The authentication context
 * @param ch The credential handler
 * @param cert The certificate to load
 * @param chain It corresponding certificate chain
 * @param key Its private key
 */
int authn_cred_put_credential(auth_ctx ac, cred_handler ch, X509 *cert, STACK_OF(X509)*chain, EVP_PKEY *key);

/**
 * This function will return the credentials loaded in the credential handler.
 *
 * @param ac The authentication context
 * @param ch The credentials handler.
 * @param cert OUTPUT The certificate
 * @param key OUTPUT Its private key
 *
 * @return the certificate chain, or NULL if there are problems.
 */
STACK_OF(X509*) authn_cred_get_credential(auth_ctx ac, cred_handler ch, X509 **cert, EVP_PKEY **key);

/**
 * This function will set the passed credentials as the default credentials
 * in the context.
 *
 * @param ac The authentication context
 * @param ch The credentials to set.
 *
 * @return a success/failure int
 */
int authn_cred_put_credential_ctx(auth_ctx ac, cred_handler ch);

/**
 * This function will return the authentication context associated
 * to a credential handler.
 *
 * @param ch the credential handler
 *
 * @return a context object.  NOTE that this will be
 * the actual context, not a copy of it.
 */
auth_ctx authn_cred_get_credential_ctx(cred_handler ch);

/**
 * This function will delete the credential handler object passed.  
 * After this call, the credential handler can no longer be used.
 *
 * @param ac The authentication context
 * @param ch The credentials to delete.
 */
void authn_cred_delete_credentials(auth_ctx ac, cred_handler ch);

/**
 * This function will validate the passed credential according to the set context.
 *
 * @param ac the context
 * @param ch the credentials to validate.
 *
 * @return a success/faliure int.
 */
int authn_cred_validate(auth_ctx ac, cred_handler ch);

/**
 * This function will return a string detailing why the validation failed.
 *
 * @param ac the context
 * @param ch the credentials validated.
 * @param reason The reason why the validation failed.
 *
 * @return an error code, or 0 if there was no failure.  Note that 'reason' 
 * is only significant if the return code is not 0.  'reason' may be changed
 * even if the return code is 0.
 *
 */
int authn_cred_get_error(auth_ctx ac, cred_handler ch, char **reason);

/**
 * This function will create a validator handle.  The default validator will do
 * full validation.
 *
 * @param ac The authentication context
 *
 * @return a validator, or NULL if there are problems.
 */
valid_handler authn_create_validator_handle(auth_ctx ac);

/**
 * This function will destroy a validation handle.  It can no longer be used 
 * after calling this function.
 *
 * @param vh the validator handle to destroy.
 */
void authn_destroy_validator_handle(valid_handler vh);

#define VALIDATION_CRL_MANDATORY       0x00000001 /**< Require valid CRLs */
#define VALIDATION_CRL_IF_VALID        0x00000002 /**< CRLs must be enforced if present and valid */
#define VALIDATION_CRL_IF_PRESENT      0x00000004 /**< CRLs must be valid and enforced if present */

#define VALIDATION_NAMESPACE_MANDATORY 0x00000008 /**< Namespaces must be present and enforced */
#define VALIDATION_NAMESPACE_LAX       0x00000010 /**< Namespaces must be enforced if present */

#define VALIDATION_PROXY               0x00000020 /**< Only do basic certificate validation. Proxies would fail validation. */
#define VALIDATION_BASIC               0x00000040 /**< Add the checks for proxy validation */

#define VALIDATION_NO_VALIDATION       0 /**< Do not validate anything */

/**
 * This function will specify exactly how much to validate.
 *
 * @param ac The authentication context
 * @param vh the validator handle.
 * @param flags an OR of the VALIDATION_* flags.
 */
void authn_vh_set_validation_mode(auth_ctx ac, valid_handler vh, int flags);

/**
 * This function will return the current validation mode.
 *
 * @param ac The authentication context
 * @param vh the validator handle.
 *
 * @return the set of flags which was specified in the 
 * authn_vh_set_validation_mode() function, or VALIDATION_FULL if the
 * function was not called.
 */
int authn_vh_get_validation_mode(auth_ctx ac, valid_handler vh);


#define VALIDATION_ANCILLARY_CAPATH  1 /**< The path in which CAs will be searched */
#define VALIDATION_ANCILLARY_CRLPATH 2 /**< The path in which CRLs will be searched */

/**
 * This function will allow to set additional information of use to the validator.
 * Values set through this function will always take precedence on values
 * present in the context.
 *
 * @param ac The authentication context
 * @param vh the validator handle.
 * @param key The data to set, to be chosen from the VALIDATION_ANCILLARY_* types
 * @param value its value
 *
 * @return a success/failure int.
 */
int authn_vh_set_ancillary_data(auth_ctx ac, valid_handler vh, int key, char *value);

/**
 * This function will allow to set additional information of use to the validator.
 * It takes its values from those set in the context.
 *
 * @param ctx The authentication context
 * @param vh the validator handle.
 *
 * @return a success/failure int.
 */
int authn_vh_set_ancillary_data_ctx(valid_handler vh, auth_ctx ctx);

/**
 * This defines a new type, 'authn_validation_callback' that represents a
 * function that will be called when certificate validation failed, and which
 * can then be used to reverse this decision.
 *
 * @param ac The authentication context for the call
 * @param store The credential store that is being validated,
 * @param cert The certificate that caused the failure
 * @param position The certificate's position in the store 
 * @param userdata A pointer to user specified data that will be set by the user himself.
 *                  This parameter will be used 'as is.' No internal copy will be done.
 * @param reason Why validation failed. Values for reason here are SSL errors as 
 *                 defined in openssl/x509.h
 *
 * @return 0 (success) or a new 'reason' for the failure.
 *
 */
typedef int (*authn_validation_callback)(auth_ctx ac, X509_STORE *store, X509 *cert, int position, void *userdata, int* reason);

/**
 * This function allows to setup a callback function to the validation procedure, to
 * reverse a validation failure.  This function may be called multiple times on the
 * same validation handler, thus setting up multiple callbacks.  However, the order
 * in which the callbacks will be called is undefined, and as soon as one return
 * success no more callbacks will be called.
 *
 * @param ac The authentication context for the call
 * @param vh The validator handle
 * @param callback The callback function to call
 * @param userdata User specified data that will be passed as is to the callvack function.  Note that
 *                  the content of this pointer will not be copied internally, and will be passed
 *                  directly to the callback.  This means that altering the data pointed by it will have
 *                 a direct effect on the behaviour of the function.
 *
 * @return a success/failure int.
 */
int authn_vh_set_validation_callback(auth_ctx ac, valid_handler vh, authn_validation_callback callback, void *userdata);


typedef void *certrequest;  /**< Keeps track of the data associated to a certificate request*/

/**
 * This function will create an empty certrequest object.
 * 
 * @return It will return an empty certrequest object.
 */
certrequest *req_init();

/**
 * This function will delete en existing certrequest object.
 * 
 * @param cr the certrequest object to destroy.
 */
void req_destroy(certrequest *cr);

/**
 * This function loads a fully formed certificate request to be used for the signing of the certificate.
 * 
 * @param cr the certrequest object
 * @param req the req
 *
 * @return a success/failure int.
 */
int req_load_req(certrequest cr, X509_REQ *req);

/**
 * This function loads a fully formed certificate request to be used for the signing of the certificate.
 * 
 * @param cr the certrequest object
 * @param req the req
 *
 * @return a success/failure int.
 */
int req_load_cert(certrequest cr, X509 *req);

/**
 * This function sets the dn of the certificate that will be signed.
 * 
 * @param cr the certrequest object
 * @param dn the DN to set
 *
 * @return a success/failure int.
 */
int req_set_dn(certrequest cr, X509_NAME *dn);

/**
 * This function sets the validity time of the certificate.
 * 
 * @param cr the certrequest object
 * @param until the validity.
 *
 * @return a success/failure int.
 */
int req_set_valid_till(certrequest cr, time_t until);

/**
 * This function sets the validity time of the certificate.
 * 
 * @param cr the certrequest object
 * @param from the validity
 *
 * @return a success/failure int.
 */
int req_set_valid_from(certrequest cr, time_t from);

/**
 * This function sets the public key of the certificate that will be signed.
 * 
 * @param cr the certrequest object
 * @param key the public key
 *
 * @return a success/failure int.
 */
int req_set_public_key(certrequest cr, EVP_PKEY *key);

/**
 * This function adds the specified extension to the certificate that will be signed.
 * 
 * @param cr the certrequest object
 * @param ext the extension to add
 *
 * @return a success/failure int.
 */
int req_set_extension(certrequest cr, X509_EXTENSION *ext);

/**
 * This function specifies the type of the certificate that will be signed.
 * 
 * @param cr the certrequest object
 * @param type the certificate type
 *
 * @return a success/failure int.
 */
int req_set_type(certrequest cr, int type);

#define CERT_TYPE_EE       0 /**< End entity Certificate */
#define CERT_TYPE_RFCPROXY 1 /**< RFC Proxy */
#define CERT_TYPE_OLDPROXY 2 /**< Legacy Proxy */

/**
 * This function returns a X509_REQ object corresponding to the current requested certificate.
 * 
 * @param cr the certrequest object
 *
 * @return a pointer to a X509_REQ structure
 */
X509_REQ *req_get_request(certrequest cr);

/**
 * This function signs the request and return a certificate.
 * 
 * @param req The X509_REQ request
 * @param signer The credential object containing the signer's info
 *
 * @return a pointer to a X509 certificate
 */
X509 *req_sign_request(X509_REQ *req, cred_handler signer);

/**
 * This function signs the request and return a certificate.
 * 
 * @param cr the certrequest object
 * @param signer The credential object containing the signer's info
 *
 * @return a pointer to a X509 certificate
 */
X509 *req_sign_certrequest(certrequest cr, cred_handler signer);

#endif


-- VincenzoCiaschini - 24-Nov-2010

Topic attachments
I Attachment History Action Size Date Who Comment
Unknown file formatext Doxyfile r1 manage 46.6 K 2011-05-06 - 15:49 VincenzoCiaschiniExCern  
PDFpdf refman.pdf r1 manage 221.9 K 2011-05-06 - 15:49 VincenzoCiaschiniExCern  
Edit | Attach | Watch | Print version | History: r7 < r6 < r5 < r4 < r3 | Backlinks | Raw View | WYSIWYG | More topic actions
Topic revision: r7 - 2011-05-06 - VincenzoCiaschiniExCern
 
    • Cern Search Icon Cern Search
    • TWiki Search Icon TWiki Search
    • Google Search Icon Google Search

    EMI All webs login

This site is powered by the TWiki collaboration platform Powered by PerlCopyright & 2008-2020 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback