diff options
author | Alexei Gradinari <alex2grad@gmail.com> | 2016-05-13 12:38:20 -0400 |
---|---|---|
committer | Alexei Gradinari <alex2grad@gmail.com> | 2016-05-13 12:38:20 -0400 |
commit | 524a30297468dc2bb7627f0dd589bd9e7368c744 (patch) | |
tree | 62390381b2b8ad3d7027bc6bb1c3d5668e12acbb /res/res_pjsip/pjsip_configuration.c | |
parent | 1705c5d2ba8bfbb96e260a26a4d412bb16c60d9d (diff) |
res_pjsip: Endpoint IP Access Controls
With the old SIP module we can use IP access controls per peer.
PJSIP module missing this feature.
This patch added next configuration Endpoint options:
"acl" - list of IP ACL section names in acl.conf
"deny" - List of IP addresses to deny access from
"permit" - List of IP addresses to permit access from
"contact_acl" - List of Contact ACL section names in acl.conf
"contact_deny" - List of Contact header addresses to deny
"contact_permit" - List of Contact header addresses to permit
This patch also better logging failed request:
add custom message instead of "No matching endpoint found"
add SIP method to logging
ASTERISK-25900
Change-Id: I456dea3909d929d413864fb347d28578415ebf02
Diffstat (limited to 'res/res_pjsip/pjsip_configuration.c')
-rw-r--r-- | res/res_pjsip/pjsip_configuration.c | 71 |
1 files changed, 68 insertions, 3 deletions
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c index 8e7e95a5d..2e0df75e3 100644 --- a/res/res_pjsip/pjsip_configuration.c +++ b/res/res_pjsip/pjsip_configuration.c @@ -265,6 +265,65 @@ static const struct ast_sorcery_observer endpoint_observers = { .deleted = endpoint_deleted_observer, }; +static int endpoint_acl_handler(const struct aco_option *opt, struct ast_variable *var, void *obj) +{ + struct ast_sip_endpoint *endpoint = obj; + int error = 0; + int ignore; + + if (ast_strlen_zero(var->value)) return 0; + + if (!strncmp(var->name, "contact_", 8)) { + ast_append_acl(var->name + 8, var->value, &endpoint->contact_acl, &error, &ignore); + } else { + ast_append_acl(var->name, var->value, &endpoint->acl, &error, &ignore); + } + + return error; +} + +static int acl_to_str(const void *obj, const intptr_t *args, char **buf) +{ + const struct ast_sip_endpoint *endpoint = obj; + struct ast_acl_list *acl_list; + struct ast_acl *first_acl; + + if (endpoint && !ast_acl_list_is_empty(acl_list=endpoint->acl)) { + AST_LIST_LOCK(acl_list); + first_acl = AST_LIST_FIRST(acl_list); + if (ast_strlen_zero(first_acl->name)) { + *buf = "deny/permit"; + } else { + *buf = first_acl->name; + } + AST_LIST_UNLOCK(acl_list); + } + + *buf = ast_strdup(*buf); + return 0; +} + +static int contact_acl_to_str(const void *obj, const intptr_t *args, char **buf) +{ + const struct ast_sip_endpoint *endpoint = obj; + struct ast_acl_list *acl_list; + struct ast_acl *first_acl; + + if (endpoint && !ast_acl_list_is_empty(acl_list=endpoint->contact_acl)) { + AST_LIST_LOCK(acl_list); + first_acl = AST_LIST_FIRST(acl_list); + if (ast_strlen_zero(first_acl->name)) { + *buf = "deny/permit"; + } else { + *buf = first_acl->name; + } + AST_LIST_UNLOCK(acl_list); + } + + *buf = ast_strdup(*buf); + return 0; +} + static int dtmf_handler(const struct aco_option *opt, struct ast_variable *var, void *obj) { struct ast_sip_endpoint *endpoint = obj; @@ -275,8 +334,8 @@ static int dtmf_handler(const struct aco_option *opt, struct ast_variable *var, endpoint->dtmf = AST_SIP_DTMF_INBAND; } else if (!strcasecmp(var->value, "info")) { endpoint->dtmf = AST_SIP_DTMF_INFO; - } else if (!strcasecmp(var->value, "auto")) { - endpoint->dtmf = AST_SIP_DTMF_AUTO; + } else if (!strcasecmp(var->value, "auto")) { + endpoint->dtmf = AST_SIP_DTMF_AUTO; } else if (!strcasecmp(var->value, "none")) { endpoint->dtmf = AST_SIP_DTMF_NONE; } else { @@ -298,7 +357,7 @@ static int dtmf_to_str(const void *obj, const intptr_t *args, char **buf) case AST_SIP_DTMF_INFO : *buf = "info"; break; case AST_SIP_DTMF_AUTO : - *buf = "auto"; break; + *buf = "auto"; break; default: *buf = "none"; } @@ -1762,6 +1821,12 @@ int ast_res_pjsip_initialize_configuration(const struct ast_module_info *ast_mod ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "set_var", "", set_var_handler, set_var_to_str, set_var_to_vl, 0, 0); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "message_context", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, message_context)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "accountcode", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, accountcode)); + ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "deny", "", endpoint_acl_handler, NULL, NULL, 0, 0); + ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "permit", "", endpoint_acl_handler, NULL, NULL, 0, 0); + ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "acl", "", endpoint_acl_handler, acl_to_str, NULL, 0, 0); + ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "contact_deny", "", endpoint_acl_handler, NULL, NULL, 0, 0); + ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "contact_permit", "", endpoint_acl_handler, NULL, NULL, 0, 0); + ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "contact_acl", "", endpoint_acl_handler, contact_acl_to_str, NULL, 0, 0); if (ast_sip_initialize_sorcery_transport()) { ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n"); |