Asterisk - The Open Source Telephony Project GIT-master-f36a736
Data Structures | Macros | Functions | Variables
res_pjsip_acl.c File Reference
#include "asterisk.h"
#include <pjsip.h>
#include "asterisk/res_pjsip.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/sorcery.h"
#include "asterisk/acl.h"
#include "asterisk/stasis.h"
#include "asterisk/security_events.h"
Include dependency graph for res_pjsip_acl.c:

Go to the source code of this file.

Data Structures

struct  ast_sip_acl
 SIP ACL details and configuration. More...
 

Macros

#define SIP_SORCERY_ACL_TYPE   "acl"
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static void * acl_alloc (const char *name)
 
static void acl_change_stasis_cb (void *data, struct stasis_subscription *sub, struct stasis_message *message)
 
static void acl_destroy (void *obj)
 
static int acl_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 
static pj_bool_t acl_on_rx_msg (pjsip_rx_data *rdata)
 
static int apply_acl (pjsip_rx_data *rdata, struct ast_acl_list *acl)
 
static int apply_contact_acl (pjsip_rx_data *rdata, struct ast_acl_list *contact_acl)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static int check_acls (void *obj, void *arg, int flags)
 
static int extract_contact_addr (pjsip_contact_hdr *contact, struct ast_sockaddr **addrs)
 
static int load_module (void)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP ACL Resource" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, .requires = "res_pjsip", }
 
static struct stasis_subscriptionacl_change_sub
 
static pjsip_module acl_module
 
static const struct ast_module_infoast_module_info = &__mod_info
 

Macro Definition Documentation

◆ SIP_SORCERY_ACL_TYPE

#define SIP_SORCERY_ACL_TYPE   "acl"

Definition at line 192 of file res_pjsip_acl.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 343 of file res_pjsip_acl.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 343 of file res_pjsip_acl.c.

◆ acl_alloc()

static void * acl_alloc ( const char *  name)
static

Definition at line 279 of file res_pjsip_acl.c.

280{
281 struct ast_sip_acl *sip_acl =
282 ast_sorcery_generic_alloc(sizeof(*sip_acl), acl_destroy);
283
284 return sip_acl;
285}
static void acl_destroy(void *obj)
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
Definition: sorcery.c:1728
SIP ACL details and configuration.

References acl_destroy(), and ast_sorcery_generic_alloc().

Referenced by load_module().

◆ acl_change_stasis_cb()

static void acl_change_stasis_cb ( void *  data,
struct stasis_subscription sub,
struct stasis_message message 
)
static

Definition at line 287 of file res_pjsip_acl.c.

289{
291 return;
292 }
293
295}
struct stasis_message_type * ast_named_acl_change_type(void)
a stasis_message_type for changes against a named ACL or the set of all named ACLs
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#define SIP_SORCERY_ACL_TYPE
void ast_sorcery_force_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects even if no changes determin...
Definition: sorcery.c:1457
struct stasis_message_type * stasis_message_type(const struct stasis_message *msg)
Get the message type for a stasis_message.

References ast_named_acl_change_type(), ast_sip_get_sorcery(), ast_sorcery_force_reload_object(), SIP_SORCERY_ACL_TYPE, and stasis_message_type().

Referenced by load_module().

◆ acl_destroy()

static void acl_destroy ( void *  obj)
static

Definition at line 272 of file res_pjsip_acl.c.

273{
274 struct ast_sip_acl *sip_acl = obj;
275 sip_acl->acl = ast_free_acl_list(sip_acl->acl);
276 sip_acl->contact_acl = ast_free_acl_list(sip_acl->contact_acl);
277}
struct ast_acl_list * ast_free_acl_list(struct ast_acl_list *acl)
Free a list of ACLs.
Definition: acl.c:233
struct ast_acl_list * contact_acl
struct ast_acl_list * acl

References ast_sip_acl::acl, ast_free_acl_list(), and ast_sip_acl::contact_acl.

Referenced by acl_alloc().

◆ acl_handler()

static int acl_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
)
static

Definition at line 237 of file res_pjsip_acl.c.

238{
239 struct ast_sip_acl *sip_acl = obj;
240 int error = 0;
241 int ignore;
242
243 if (!strncmp(var->name, "contact_", 8)) {
244 ast_append_acl(var->name + 8, var->value, &sip_acl->contact_acl, &error, &ignore);
245 if (error) {
246 ast_log(LOG_ERROR, "Bad contact ACL '%s' at line '%d' of pjsip.conf\n",
247 var->value, var->lineno);
248 }
249 } else {
250 ast_append_acl(var->name, var->value, &sip_acl->acl, &error, &ignore);
251 if (error) {
252 ast_log(LOG_ERROR, "Bad ACL '%s' at line '%d' of pjsip.conf\n",
253 var->value, var->lineno);
254 }
255 }
256
257 if (error) {
258 ast_log(LOG_ERROR, "There is an error in ACL configuration. Blocking ALL SIP traffic.\n");
259 ast_append_acl("deny", "0.0.0.0/0.0.0.0", &sip_acl->acl, NULL, &ignore);
260 }
261
262 return error;
263}
void ast_append_acl(const char *sense, const char *stuff, struct ast_acl_list **path, int *error, int *named_acl_flag)
Add a rule to an ACL struct.
Definition: acl.c:429
#define var
Definition: ast_expr2f.c:605
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
def ignore(key=None, val=None, section=None, pjsip=None, nmapped=None, type='endpoint')
Definition: sip_to_pjsip.py:48
#define NULL
Definition: resample.c:96
int error(const char *format,...)
Definition: utils/frame.c:999

References ast_sip_acl::acl, ast_append_acl(), ast_log, ast_sip_acl::contact_acl, error(), sip_to_pjsip::ignore(), LOG_ERROR, NULL, and var.

Referenced by load_module().

◆ acl_on_rx_msg()

static pj_bool_t acl_on_rx_msg ( pjsip_rx_data *  rdata)
static

Definition at line 215 of file res_pjsip_acl.c.

216{
220 RAII_VAR(struct ast_sip_acl *, matched_acl, NULL, ao2_cleanup);
221
222 if (!acls) {
223 ast_log(LOG_ERROR, "Unable to retrieve ACL sorcery data\n");
224 return PJ_FALSE;
225 }
226
227 if ((matched_acl = ao2_callback(acls, 0, check_acls, rdata))) {
228 if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
229 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
230 }
231 return PJ_TRUE;
232 }
233
234 return PJ_FALSE;
235}
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
Definition: astobj2.h:1693
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition: res_pjsip.c:520
static int check_acls(void *obj, void *arg, int flags)
@ AST_RETRIEVE_FLAG_MULTIPLE
Return all matching objects.
Definition: sorcery.h:120
@ AST_RETRIEVE_FLAG_ALL
Perform no matching, return all objects.
Definition: sorcery.h:123
void * ast_sorcery_retrieve_by_fields(const struct ast_sorcery *sorcery, const char *type, unsigned int flags, struct ast_variable *fields)
Retrieve an object or multiple objects using specific fields.
Definition: sorcery.c:1897
Generic container type.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References ao2_callback, ao2_cleanup, ast_log, AST_RETRIEVE_FLAG_ALL, AST_RETRIEVE_FLAG_MULTIPLE, ast_sip_get_pjsip_endpoint(), ast_sip_get_sorcery(), ast_sorcery_retrieve_by_fields(), check_acls(), LOG_ERROR, NULL, RAII_VAR, and SIP_SORCERY_ACL_TYPE.

◆ apply_acl()

static int apply_acl ( pjsip_rx_data *  rdata,
struct ast_acl_list acl 
)
static

Definition at line 121 of file res_pjsip_acl.c.

122{
123 struct ast_sockaddr addr;
124
126 return 0;
127 }
128
129 memset(&addr, 0, sizeof(addr));
130 ast_sockaddr_parse(&addr, rdata->pkt_info.src_name, PARSE_PORT_FORBID);
131 ast_sockaddr_set_port(&addr, rdata->pkt_info.src_port);
132
133 if (ast_apply_acl(acl, &addr, "SIP ACL: ") != AST_SENSE_ALLOW) {
134 ast_log(LOG_WARNING, "Incoming SIP message from %s did not pass ACL test\n", ast_sockaddr_stringify(&addr));
135 return 1;
136 }
137 return 0;
138}
enum ast_acl_sense ast_apply_acl(struct ast_acl_list *acl_list, const struct ast_sockaddr *addr, const char *purpose)
Apply a set of rules to a given IP address.
Definition: acl.c:799
@ AST_SENSE_ALLOW
Definition: acl.h:38
int ast_acl_list_is_empty(struct ast_acl_list *acl_list)
Determines if an ACL is empty or if it contains entries.
Definition: acl.c:540
#define LOG_WARNING
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
Definition: test_acl.c:111
Socket address structure.
Definition: netsock2.h:97

References ast_acl_list_is_empty(), ast_apply_acl(), ast_log, AST_SENSE_ALLOW, ast_sockaddr_parse(), ast_sockaddr_set_port, ast_sockaddr_stringify(), LOG_WARNING, and PARSE_PORT_FORBID.

Referenced by check_acls().

◆ apply_contact_acl()

static int apply_contact_acl ( pjsip_rx_data *  rdata,
struct ast_acl_list contact_acl 
)
static

Definition at line 158 of file res_pjsip_acl.c.

159{
160 int num_contact_addrs;
161 int forbidden = 0;
162 struct ast_sockaddr *contact_addrs;
163 int i;
164 pjsip_contact_hdr *contact = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
165
166 if (ast_acl_list_is_empty(contact_acl)) {
167 return 0;
168 }
169
170 while ((contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next))) {
171 num_contact_addrs = extract_contact_addr(contact, &contact_addrs);
172 if (num_contact_addrs <= 0) {
173 continue;
174 }
175 for (i = 0; i < num_contact_addrs; ++i) {
176 if (ast_apply_acl(contact_acl, &contact_addrs[i], "SIP Contact ACL: ") != AST_SENSE_ALLOW) {
177 ast_log(LOG_WARNING, "Incoming SIP message from %s did not pass ACL test\n", ast_sockaddr_stringify(&contact_addrs[i]));
178 forbidden = 1;
179 break;
180 }
181 }
182 ast_free(contact_addrs);
183 if (forbidden) {
184 /* No use checking other contacts if we already have failed ACL check */
185 break;
186 }
187 }
188
189 return forbidden;
190}
if(!yyg->yy_init)
Definition: ast_expr2f.c:854
#define ast_free(a)
Definition: astmm.h:180
static int extract_contact_addr(pjsip_contact_hdr *contact, struct ast_sockaddr **addrs)

References ast_acl_list_is_empty(), ast_apply_acl(), ast_free, ast_log, AST_SENSE_ALLOW, ast_sockaddr_stringify(), extract_contact_addr(), if(), and LOG_WARNING.

Referenced by check_acls().

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 343 of file res_pjsip_acl.c.

◆ check_acls()

static int check_acls ( void *  obj,
void *  arg,
int  flags 
)
static

Definition at line 203 of file res_pjsip_acl.c.

204{
205 struct ast_sip_acl *sip_acl = obj;
206 pjsip_rx_data *rdata = arg;
207
208 if (apply_acl(rdata, sip_acl->acl) ||
209 apply_contact_acl(rdata, sip_acl->contact_acl)) {
210 return CMP_MATCH | CMP_STOP;
211 }
212 return 0;
213}
@ CMP_MATCH
Definition: astobj2.h:1027
@ CMP_STOP
Definition: astobj2.h:1028
static int apply_acl(pjsip_rx_data *rdata, struct ast_acl_list *acl)
static int apply_contact_acl(pjsip_rx_data *rdata, struct ast_acl_list *contact_acl)

References ast_sip_acl::acl, apply_acl(), apply_contact_acl(), CMP_MATCH, CMP_STOP, and ast_sip_acl::contact_acl.

Referenced by acl_on_rx_msg().

◆ extract_contact_addr()

static int extract_contact_addr ( pjsip_contact_hdr *  contact,
struct ast_sockaddr **  addrs 
)
static

Definition at line 140 of file res_pjsip_acl.c.

141{
142 pjsip_sip_uri *sip_uri;
143 char host[256];
144
145 if (!contact || contact->star) {
146 *addrs = NULL;
147 return 0;
148 }
149 if (!PJSIP_URI_SCHEME_IS_SIP(contact->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
150 *addrs = NULL;
151 return 0;
152 }
153 sip_uri = pjsip_uri_get_uri(contact->uri);
154 ast_copy_pj_str(host, &sip_uri->host, sizeof(host));
156}
@ AST_AF_UNSPEC
Definition: netsock2.h:54
int ast_sockaddr_resolve(struct ast_sockaddr **addrs, const char *str, int flags, int family)
Parses a string with an IPv4 or IPv6 address and place results into an array.
Definition: netsock2.c:280
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:2201

References AST_AF_UNSPEC, ast_copy_pj_str(), ast_sockaddr_resolve(), NULL, and PARSE_PORT_FORBID.

Referenced by apply_contact_acl().

◆ load_module()

static int load_module ( void  )
static

Definition at line 297 of file res_pjsip_acl.c.

298{
301 "config", "pjsip.conf,criteria=type=acl");
302
304 acl_alloc, NULL, NULL)) {
305
306 ast_log(LOG_ERROR, "Failed to register SIP %s object with sorcery\n",
309 }
310
318
320
324
326
328}
@ OPT_NOOP_T
Type for a default handler that should do nothing.
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
int ast_sip_register_service(pjsip_module *module)
Register a SIP service in Asterisk.
Definition: res_pjsip.c:117
static int acl_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
static struct stasis_subscription * acl_change_sub
static pjsip_module acl_module
static void * acl_alloc(const char *name)
static void acl_change_stasis_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
struct stasis_topic * ast_security_topic(void)
A stasis_topic which publishes messages for security related issues.
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
Definition: sorcery.h:837
void ast_sorcery_load_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to load persistent objects.
Definition: sorcery.c:1393
#define ast_sorcery_object_field_register_custom(sorcery, type, name, default_val, config_handler, sorcery_handler, multiple_handler, flags,...)
Register a field within an object with custom handlers.
Definition: sorcery.h:1005
#define ast_sorcery_apply_config(sorcery, name)
Definition: sorcery.h:455
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
Definition: sorcery.h:955
#define ast_sorcery_apply_default(sorcery, type, name, data)
Definition: sorcery.h:476
@ STASIS_SUBSCRIPTION_FILTER_SELECTIVE
Definition: stasis.h:297
int stasis_subscription_accept_message_type(struct stasis_subscription *subscription, const struct stasis_message_type *type)
Indicate to a subscription that we are interested in a message type.
Definition: stasis.c:1024
int stasis_subscription_set_filter(struct stasis_subscription *subscription, enum stasis_subscription_message_filter filter)
Set the message type filtering level on a subscription.
Definition: stasis.c:1078
#define stasis_subscribe(topic, callback, data)
Definition: stasis.h:649

References acl_alloc(), acl_change_stasis_cb(), acl_change_sub, acl_handler(), acl_module, ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_named_acl_change_type(), ast_security_topic(), ast_sip_get_sorcery(), ast_sip_register_service(), ast_sorcery_apply_config, ast_sorcery_apply_default, ast_sorcery_load_object(), ast_sorcery_object_field_register, ast_sorcery_object_field_register_custom, ast_sorcery_object_register, LOG_ERROR, NULL, OPT_NOOP_T, SIP_SORCERY_ACL_TYPE, stasis_subscribe, stasis_subscription_accept_message_type(), STASIS_SUBSCRIPTION_FILTER_SELECTIVE, and stasis_subscription_set_filter().

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 330 of file res_pjsip_acl.c.

331{
334 return 0;
335}
void ast_sip_unregister_service(pjsip_module *module)
Definition: res_pjsip.c:133
struct stasis_subscription * stasis_unsubscribe_and_join(struct stasis_subscription *subscription)
Cancel a subscription, blocking until the last message is processed.
Definition: stasis.c:1135

References acl_change_sub, acl_module, ast_sip_unregister_service(), and stasis_unsubscribe_and_join().

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP ACL Resource" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_APP_DEPEND, .requires = "res_pjsip", }
static

Definition at line 343 of file res_pjsip_acl.c.

◆ acl_change_sub

struct stasis_subscription* acl_change_sub
static

Definition at line 119 of file res_pjsip_acl.c.

Referenced by load_module(), and unload_module().

◆ acl_module

pjsip_module acl_module
static

Definition at line 265 of file res_pjsip_acl.c.

Referenced by load_module(), and unload_module().

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 343 of file res_pjsip_acl.c.