Asterisk - The Open Source Telephony Project GIT-master-a358458
Macros | Functions | Variables
res_pjsip_endpoint_identifier_user.c File Reference
#include "asterisk.h"
#include <pjsip.h>
#include "asterisk/res_pjsip.h"
#include "asterisk/module.h"
Include dependency graph for res_pjsip_endpoint_identifier_user.c:

Go to the source code of this file.

Macros

#define DOMAIN_NAME_LEN   255
 
#define USERNAME_LEN   255
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static struct ast_sip_endpointauth_username_identify (pjsip_rx_data *rdata)
 
static struct ast_sip_endpointfind_endpoint (pjsip_rx_data *rdata, char *endpoint_name, char *domain_name)
 
static int find_transport_state_in_use (void *obj, void *arg, int flags)
 
static pjsip_authorization_hdr * get_auth_header (pjsip_rx_data *rdata, char *username, size_t username_size, char *realm, size_t realm_size, pjsip_authorization_hdr *start)
 
static int get_from_header (pjsip_rx_data *rdata, char *username, size_t username_size, char *domain, size_t domain_size)
 
static int load_module (void)
 
static int unload_module (void)
 
static struct ast_sip_endpointusername_identify (pjsip_rx_data *rdata)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP username endpoint identifier" , .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_CHANNEL_DEPEND - 4, .requires = "res_pjsip", }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_sip_endpoint_identifier auth_username_identifier
 
static struct ast_sip_endpoint_identifier username_identifier
 

Macro Definition Documentation

◆ DOMAIN_NAME_LEN

#define DOMAIN_NAME_LEN   255

Definition at line 78 of file res_pjsip_endpoint_identifier_user.c.

◆ USERNAME_LEN

#define USERNAME_LEN   255

Definition at line 79 of file res_pjsip_endpoint_identifier_user.c.

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 227 of file res_pjsip_endpoint_identifier_user.c.

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 227 of file res_pjsip_endpoint_identifier_user.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 227 of file res_pjsip_endpoint_identifier_user.c.

◆ auth_username_identify()

static struct ast_sip_endpoint * auth_username_identify ( pjsip_rx_data *  rdata)
static

Definition at line 165 of file res_pjsip_endpoint_identifier_user.c.

166{
167 char username[USERNAME_LEN + 1], realm[AST_SIP_AUTH_MAX_REALM_LENGTH + 1];
168 struct ast_sip_endpoint *endpoint;
169 pjsip_authorization_hdr *auth_header = NULL;
170
171 while ((auth_header = get_auth_header(rdata, username, sizeof(username), realm, sizeof(realm),
172 auth_header ? auth_header->next : NULL))) {
173 ast_debug(3, "Attempting identify by Authorization username '%s' realm '%s'\n", username,
174 realm);
175
176 endpoint = find_endpoint(rdata, username, realm);
177 if (!endpoint) {
178 ast_debug(3, "Endpoint not found for Authentication username '%s' realm '%s'\n",
179 username, realm);
180 ao2_cleanup(endpoint);
181 continue;
182 }
184 ast_debug(3, "Endpoint found for '%s' but 'auth_username' method not supported'\n",
185 username);
186 ao2_cleanup(endpoint);
187 continue;
188 }
189 ast_debug(3, "Identified by Authorization username '%s' realm '%s'\n", username, realm);
190
191 return endpoint;
192 }
193
194 return NULL;
195}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ast_debug(level,...)
Log a DEBUG message.
@ AST_SIP_ENDPOINT_IDENTIFY_BY_AUTH_USERNAME
Definition: res_pjsip.h:613
#define AST_SIP_AUTH_MAX_REALM_LENGTH
Definition: res_pjsip.h:74
static struct ast_sip_endpoint * find_endpoint(pjsip_rx_data *rdata, char *endpoint_name, char *domain_name)
static pjsip_authorization_hdr * get_auth_header(pjsip_rx_data *rdata, char *username, size_t username_size, char *realm, size_t realm_size, pjsip_authorization_hdr *start)
#define NULL
Definition: resample.c:96
An entity with which Asterisk communicates.
Definition: res_pjsip.h:963
enum ast_sip_endpoint_identifier_type ident_method
Definition: res_pjsip.h:1014

References ao2_cleanup, ast_debug, AST_SIP_AUTH_MAX_REALM_LENGTH, AST_SIP_ENDPOINT_IDENTIFY_BY_AUTH_USERNAME, find_endpoint(), get_auth_header(), ast_sip_endpoint::ident_method, NULL, and USERNAME_LEN.

◆ find_endpoint()

static struct ast_sip_endpoint * find_endpoint ( pjsip_rx_data *  rdata,
char *  endpoint_name,
char *  domain_name 
)
static

Definition at line 81 of file res_pjsip_endpoint_identifier_user.c.

83{
84 struct ast_sip_endpoint *endpoint;
85
87 struct ast_sip_domain_alias *alias;
89 struct ast_sip_transport_state *transport_state = NULL;
90 struct ast_sip_transport *transport = NULL;
91 char id[DOMAIN_NAME_LEN + USERNAME_LEN + sizeof("@")];
92
93 /* Attempt to find the endpoint given the name and domain provided */
94 snprintf(id, sizeof(id), "%s@%s", endpoint_name, domain_name);
95 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", id);
96 if (endpoint) {
97 return endpoint;
98 }
99
100 /* See if an alias exists for the domain provided */
101 alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias",
102 domain_name);
103 if (alias) {
104 snprintf(id, sizeof(id), "%s@%s", endpoint_name, alias->domain);
105 ao2_ref(alias, -1);
106 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", id);
107 if (endpoint) {
108 return endpoint;
109 }
110 }
111
112 /* See if the transport this came in on has a provided domain */
114 && (transport_state = ao2_callback(transport_states, 0, find_transport_state_in_use, rdata))
115 && (transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_state->id))
116 && !ast_strlen_zero(transport->domain)) {
117 snprintf(id, sizeof(id), "%s@%s", endpoint_name, transport->domain);
118 endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", id);
119 }
120 ao2_cleanup(transport);
121 ao2_cleanup(transport_state);
123 if (endpoint) {
124 return endpoint;
125 }
126 }
127
128 /* Fall back to no domain */
129 return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", endpoint_name);
130}
#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_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
static struct ao2_container * transport_states
struct ao2_container * ast_sip_get_transport_states(void)
Retrieves all transport states.
unsigned int ast_sip_get_disable_multi_domain(void)
Retrieve the system setting 'disable multi domain'.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
static int find_transport_state_in_use(void *obj, void *arg, int flags)
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition: sorcery.c:1853
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
Generic container type.
const ast_string_field domain
Definition: res_pjsip.h:323
Structure for SIP transport information.
Definition: res_pjsip.h:119
Transport to bind to.
Definition: res_pjsip.h:221
const ast_string_field domain
Definition: res_pjsip.h:241

References ao2_callback, ao2_cleanup, ao2_ref, ast_sip_get_disable_multi_domain(), ast_sip_get_sorcery(), ast_sip_get_transport_states(), ast_sorcery_retrieve_by_id(), ast_strlen_zero(), ast_sip_transport::domain, ast_sip_domain_alias::domain, DOMAIN_NAME_LEN, find_transport_state_in_use(), ast_sip_transport_state::id, NULL, transport_states, and USERNAME_LEN.

Referenced by auth_username_identify(), and username_identify().

◆ find_transport_state_in_use()

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

Definition at line 63 of file res_pjsip_endpoint_identifier_user.c.

64{
65 struct ast_sip_transport_state *transport_state = obj;
66 pjsip_rx_data *rdata = arg;
67
68 if (transport_state->transport == rdata->tp_info.transport
69 || (transport_state->factory
70 && !pj_strcmp(&transport_state->factory->addr_name.host, &rdata->tp_info.transport->local_name.host)
71 && transport_state->factory->addr_name.port == rdata->tp_info.transport->local_name.port)) {
72 return CMP_MATCH;
73 }
74
75 return 0;
76}
@ CMP_MATCH
Definition: astobj2.h:1027
struct pjsip_tpfactory * factory
Transport factory.
Definition: res_pjsip.h:123
struct pjsip_transport * transport
Transport itself.
Definition: res_pjsip.h:121

References CMP_MATCH, ast_sip_transport_state::factory, and ast_sip_transport_state::transport.

Referenced by find_endpoint().

◆ get_auth_header()

static pjsip_authorization_hdr * get_auth_header ( pjsip_rx_data *  rdata,
char *  username,
size_t  username_size,
char *  realm,
size_t  realm_size,
pjsip_authorization_hdr *  start 
)
static

Definition at line 46 of file res_pjsip_endpoint_identifier_user.c.

48{
49 pjsip_authorization_hdr *header;
50
51 header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_AUTHORIZATION, start);
52
53 if (!header || pj_stricmp2(&header->scheme, "digest")) {
54 return NULL;
55 }
56
57 ast_copy_pj_str(username, &header->credential.digest.username, username_size);
58 ast_copy_pj_str(realm, &header->credential.digest.realm, realm_size);
59
60 return header;
61}
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_copy_pj_str(), and NULL.

Referenced by auth_username_identify().

◆ get_from_header()

static int get_from_header ( pjsip_rx_data *  rdata,
char *  username,
size_t  username_size,
char *  domain,
size_t  domain_size 
)
static

Definition at line 32 of file res_pjsip_endpoint_identifier_user.c.

33{
34 pjsip_uri *from = rdata->msg_info.from->uri;
35
36 if (!ast_sip_is_uri_sip_sips(from)) {
37 return -1;
38 }
39
40 ast_copy_pj_str(username, ast_sip_pjsip_uri_get_username(from), username_size);
41 ast_copy_pj_str(domain, ast_sip_pjsip_uri_get_hostname(from), domain_size);
42
43 return 0;
44}
const pj_str_t * ast_sip_pjsip_uri_get_username(pjsip_uri *uri)
Get the user portion of the pjsip_uri.
Definition: res_pjsip.c:3477
int ast_sip_is_uri_sip_sips(pjsip_uri *uri)
Check whether a pjsip_uri is SIP/SIPS or not.
Definition: res_pjsip.c:3467
const pj_str_t * ast_sip_pjsip_uri_get_hostname(pjsip_uri *uri)
Get the host portion of the pjsip_uri.
Definition: res_pjsip.c:3496

References ast_copy_pj_str(), ast_sip_is_uri_sip_sips(), ast_sip_pjsip_uri_get_hostname(), and ast_sip_pjsip_uri_get_username().

Referenced by username_identify().

◆ load_module()

static int load_module ( void  )
static

Definition at line 207 of file res_pjsip_endpoint_identifier_user.c.

208{
212}
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
int ast_sip_register_endpoint_identifier_with_name(struct ast_sip_endpoint_identifier *identifier, const char *name)
Register a SIP endpoint identifier with a name.
Definition: res_pjsip.c:233
static struct ast_sip_endpoint_identifier username_identifier
static struct ast_sip_endpoint_identifier auth_username_identifier

References AST_MODULE_LOAD_SUCCESS, ast_sip_register_endpoint_identifier_with_name(), auth_username_identifier, and username_identifier.

◆ unload_module()

static int unload_module ( void  )
static

Definition at line 214 of file res_pjsip_endpoint_identifier_user.c.

215{
218 return 0;
219}
void ast_sip_unregister_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
Unregister a SIP endpoint identifier.
Definition: res_pjsip.c:315

References ast_sip_unregister_endpoint_identifier(), auth_username_identifier, and username_identifier.

◆ username_identify()

static struct ast_sip_endpoint * username_identify ( pjsip_rx_data *  rdata)
static

Definition at line 132 of file res_pjsip_endpoint_identifier_user.c.

133{
134 char username[USERNAME_LEN + 1];
135 char domain[DOMAIN_NAME_LEN + 1];
136 struct ast_sip_endpoint *endpoint;
137
138 if (get_from_header(rdata, username, sizeof(username), domain, sizeof(domain))) {
139 return NULL;
140 }
141
142 /*
143 * We may want to be matched without any user options getting
144 * in the way.
145 */
147
148 ast_debug(3, "Attempting identify by From username '%s' domain '%s'\n", username, domain);
149
150 endpoint = find_endpoint(rdata, username, domain);
151 if (!endpoint) {
152 ast_debug(3, "Endpoint not found for From username '%s' domain '%s'\n", username, domain);
153 return NULL;
154 }
156 ast_debug(3, "Endpoint found for '%s' but 'username' method not supported'\n", username);
157 ao2_cleanup(endpoint);
158 return NULL;
159 }
160 ast_debug(3, "Identified by From username '%s' domain '%s'\n", username, domain);
161
162 return endpoint;
163}
@ AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME
Definition: res_pjsip.h:611
#define AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(str)
Truncate the URI user field options string if enabled.
Definition: res_pjsip.h:3351
static int get_from_header(pjsip_rx_data *rdata, char *username, size_t username_size, char *domain, size_t domain_size)

References ao2_cleanup, ast_debug, AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME, AST_SIP_USER_OPTIONS_TRUNCATE_CHECK, DOMAIN_NAME_LEN, find_endpoint(), get_from_header(), ast_sip_endpoint::ident_method, NULL, and USERNAME_LEN.

Variable Documentation

◆ __mod_info

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "PJSIP username endpoint identifier" , .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_CHANNEL_DEPEND - 4, .requires = "res_pjsip", }
static

Definition at line 227 of file res_pjsip_endpoint_identifier_user.c.

◆ ast_module_info

const struct ast_module_info* ast_module_info = &__mod_info
static

Definition at line 227 of file res_pjsip_endpoint_identifier_user.c.

◆ auth_username_identifier

struct ast_sip_endpoint_identifier auth_username_identifier
static
Initial value:
= {
.identify_endpoint = auth_username_identify,
}
static struct ast_sip_endpoint * auth_username_identify(pjsip_rx_data *rdata)

Definition at line 202 of file res_pjsip_endpoint_identifier_user.c.

Referenced by load_module(), and unload_module().

◆ username_identifier

struct ast_sip_endpoint_identifier username_identifier
static
Initial value:
= {
.identify_endpoint = username_identify,
}
static struct ast_sip_endpoint * username_identify(pjsip_rx_data *rdata)

Definition at line 198 of file res_pjsip_endpoint_identifier_user.c.

Referenced by load_module(), and unload_module().