blob: 8b8cfe3cef50809ddc465829a3356ab2cf4d6109 [file] [log] [blame]
#ifndef __policy_h__
#define __policy_h__
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
#include "config.h"
#include "entity.h"
#include "entity_cache.h"
#include "parse_tree.h"
#include "qpid/dispatch.h"
#include "qpid/dispatch/alloc.h"
#include "qpid/dispatch/alloc_pool.h"
#include "qpid/dispatch/ctools.h"
#include "qpid/dispatch/policy_spec.h"
#include "qpid/dispatch/server.h"
#include "qpid/dispatch/static_assert.h"
#include <dlfcn.h>
typedef struct qd_policy_denial_counts_s qd_policy_denial_counts_t;
// TODO: Provide locking
struct qd_policy_denial_counts_s {
uint64_t sessionDenied;
uint64_t senderDenied;
uint64_t receiverDenied;
uint64_t maxSizeMessagesDenied;
};
typedef struct qd_policy_t qd_policy_t;
//
// Policy settings are defined in include/qpid/dispatch/policy_settings.h
//
struct qd_policy__settings_s {
qd_policy_spec_t spec;
char *sources;
char *targets;
char *sourcePattern;
char *targetPattern;
qd_parse_tree_t *sourceParseTree;
qd_parse_tree_t *targetParseTree;
qd_policy_denial_counts_t *denialCounts;
char *vhost_name;
};
typedef struct qd_policy__settings_s qd_policy_settings_t;
ALLOC_DECLARE(qd_policy_settings_t);
/** Configure the C policy entity from the settings in qdrouterd.conf["policy"]
* Called python-to-C during config processing.
* @param[in] policy pointer to the policy
* @param[in] entity pointer to the managed entity
* @return error or not. If error then the policy is freed.
**/
qd_error_t qd_entity_configure_policy(qd_policy_t *policy, qd_entity_t *entity);
/** Memorize the address of python policy_manager object.
* This python object gets called by C to execute user lookups
* @param[in] policy pointer to the policy
* @param[in] policy_manager the address of the policy_manager object
**/
qd_error_t qd_register_policy_manager(qd_policy_t *policy, void *policy_manager);
/** Allocate counts statistics block.
* Called from Python
*/
long qd_policy_c_counts_alloc();
/** Free counts statistics block.
* Called from Python
*/
void qd_policy_c_counts_free(long ccounts);
/** Refresh a counts statistics block
* Called from Python
*/
qd_error_t qd_policy_c_counts_refresh(long ccounts, qd_entity_t*entity);
/** Allow or deny an incoming connection based on connection count(s).
* A server listener has just accepted a socket.
* Allow or deny this connection based on the absolute number
* of allowed connections.
* The identity of the connecting user has not been negotiated yet.
* @param[in] context the current policy
* @param[in] name the connector name
* @return the connection is allowed or not
**/
bool qd_policy_socket_accept(qd_policy_t *context, const char *hostname);
/** Record a closing connection.
* A server listener is closing a socket.
* Release the counted connection against provisioned limits
*
* @param[in] context the current policy
* @param[in] conn qd_connection
**/
void qd_policy_socket_close(qd_policy_t *context, const qd_connection_t *conn);
/** Look up vhost in python vhost aliases database
* * Return false if the mechanics of calling python fails or if returned name buf is blank.
* * Return true if a name was returned.
* @param[in] policy pointer to policy
* @param[in] vhost vhost name received in remote AMQP Open.hostname
* @param[out] name_buf pointer to result name buffer
* @param[in] name_buf_size size of name_buf
**/
bool qd_policy_lookup_vhost_alias(
qd_policy_t *policy,
const char *vhost,
char *name_buf,
int name_buf_size);
/** Approve a new session based on connection's policy.
* Sessions denied are closed and counted.
*
* @param[in] ssn proton session being approved
* @param[in] qd_conn dispatch connection with policy settings and counts
**/
bool qd_policy_approve_amqp_session(pn_session_t *ssn, qd_connection_t *qd_conn);
/** Apply policy or default settings for a new session.
*
* @param[in] ssn proton session being set
* @param[in] qd_conn dispatch connection with policy settings and counts
**/
void qd_policy_apply_session_settings(pn_session_t *ssn, qd_connection_t *qd_conn);
/** Approve a new sender link based on connection's policy.
* Links denied are closed and counted.
*
* @param[in] pn_link proton link being approved
* @param[in] qd_conn dispatch connection with policy settings and counts
**/
bool qd_policy_approve_amqp_sender_link(pn_link_t *pn_link, qd_connection_t *qd_conn);
/** Approve a new receiver link based on connection's policy.
* Links denied are closed and counted.
*
* @param[in] pn_link proton link being approved
* @param[in] qd_conn dispatch connection with policy settings and counts
**/
bool qd_policy_approve_amqp_receiver_link(pn_link_t *pn_link, qd_connection_t *qd_conn);
/** Allow or deny an incoming connection.
* An Open performative was received over a new connection.
* Consult local policy to determine if this host/user is
* allowed to make this connection.
* Denied pn_connections are closed with a condition.
* Allowed connections are signaled through qd_connection_manager.
**/
void qd_policy_amqp_open(qd_connection_t *conn);
/** Allow or deny an outgoing connector connection.
* An Open performative was received over a new connection.
* Consult local policy to determine if this host/user is
* allowed to make this connection.
* Denied pn_connections are closed with a condition.
**/
void qd_policy_amqp_open_connector(qd_connection_t *conn);
/** Dispose of policy settings
*
* @param settings the settings to be destroyed
*/
void qd_policy_settings_free(qd_policy_settings_t *settings);
/** Approve link by source/target name.
* @param[in] username authenticated user name
* @param[in] settings policy settings
* @param[in] proposed the link target name to be approved
* @param[in] isReceiver indication to check using receiver settings
*/
bool qd_policy_approve_link_name(const char *username,
const qd_policy_settings_t *settings,
const char *proposed,
bool isReceiver
);
/** Add a hostname to the lookup parse_tree
* Note that the parse_tree may store an 'optimised' pattern for a given
* pattern. Thus the patterns a user puts in may collide with existing
* patterns even though the text of the host patterns is different.
* This function does not allow new patterns with thier optimizations
* to overwrite existing patterns that may have been optimised.
* @param[in] policy qd_policy_t
* @param[in] hostPattern the hostname pattern with possible parse_tree wildcards
* @return True if the possibly optimised pattern was added to the lookup parse tree
*/
bool qd_policy_host_pattern_add(qd_policy_t *policy, const char *hostPattern);
/** Remove a hostname from the lookup parse_tree
* @param[in] policy qd_policy_t
* @param[in] hostPattern the hostname pattern with possible parse_tree wildcards
*/
void qd_policy_host_pattern_remove(qd_policy_t *policy, const char *hostPattern);
/** Look up a hostname in the lookup parse_tree
* @param[in] policy qd_policy_t
* @param[in] hostname a concrete vhost name
* @return the name of the ruleset whose hostname pattern matched this actual hostname
*/
char * qd_policy_host_pattern_lookup(qd_policy_t *policy, const char *hostPattern);
/**
* Compile raw CSV spec of allowed sources/targets and return
* the string of tuples used by policy runtime.
* The returned string is allocated here and freed by the caller.
* This function does no error checking or logging.
*
* @param[in] csv the CSV allowed list
* @return the ruleset string to be used in policy settings.
*/
char * qd_policy_compile_allowed_csv(char * csv);
/**
* Approve sending of message on anonymous link based on connection's policy.
*
* @param[in] address the address from the message 'to' field
* @param[in] qd_conn dispatch connection with policy settings
*/
bool qd_policy_approve_message_target(qd_iterator_t *address, qd_connection_t *qd_conn);
/**
* Increment counters for a link when policy maxMessageSize limit is exceeded.
*
* @param[in] pn_link proton link being with delivery/transfer being rejected
* @param[in] qd_conn dispatch connection with policy settings and counts
**/
void qd_policy_count_max_size_event(pn_link_t *link, qd_connection_t *qd_conn);
/**
* Return POLICY log_source to log policy
*/
qd_log_source_t* qd_policy_log_source();
#endif