36 #define MAX_REALM_LENGTH 40 152 const pj_str_t *acc_name, pjsip_cred_info *
info)
158 return PJSIP_SC_FORBIDDEN;
162 return PJSIP_SC_FORBIDDEN;
165 if (pj_strcmp2(realm, auth->
realm)) {
166 return PJSIP_SC_FORBIDDEN;
168 if (pj_strcmp2(acc_name, auth->
auth_user)) {
169 return PJSIP_SC_FORBIDDEN;
172 pj_strdup2(pool, &info->realm, auth->
realm);
173 pj_strdup2(pool, &info->username, auth->
auth_user);
175 switch (auth->
type) {
177 pj_strdup2(pool, &info->data, auth->
auth_pass);
178 info->data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
181 pj_strdup2(pool, &info->data, auth->
md5_creds);
182 info->data_type = PJSIP_CRED_DATA_DIGEST;
185 return PJSIP_SC_FORBIDDEN;
241 char *timestamp =
strsep(©,
"/");
243 time_t now = time(
NULL);
251 if (sscanf(timestamp,
"%30d", ×tamp_int) != 1) {
269 struct pjsip_authorization_hdr *auth_hdr = (pjsip_authorization_hdr *) &rdata->msg_info.msg->hdr;
270 int challenge_found = 0;
273 while ((auth_hdr = (pjsip_authorization_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_AUTHORIZATION, auth_hdr->next))) {
274 ast_copy_pj_str(nonce, &auth_hdr->credential.digest.nonce,
sizeof(nonce));
275 if (
check_nonce(nonce, rdata, auth) && !pj_strcmp2(&auth_hdr->credential.digest.realm, auth->
realm)) {
281 return challenge_found;
290 pj_cstr(&realm_str, realm);
292 pjsip_auth_srv_init(pool, auth_server, &realm_str,
digest_lookup, 0);
328 pjsip_auth_srv auth_server;
342 authed = pjsip_auth_srv_verify(&auth_server, rdata, &response_code);
345 if (authed == PJ_SUCCESS) {
353 if (authed == PJSIP_EAUTHNOAUTH) {
357 ast_debug(3,
"Realm: %s Username: %s Result: %s\n",
377 static void challenge(
const char *realm, pjsip_tx_data *tdata,
const pjsip_rx_data *rdata,
int is_stale)
381 pjsip_auth_srv auth_server;
384 time_t timestamp = time(
NULL);
385 snprintf(time_buf,
sizeof(time_buf),
"%d", (
int) timestamp);
392 pj_cstr(&qop,
"auth");
393 pjsip_auth_srv_challenge(&auth_server, &qop, &pj_nonce,
NULL, is_stale ? PJ_TRUE : PJ_FALSE, tdata);
406 pjsip_rx_data *rdata, pjsip_tx_data *tdata)
421 auths =
ast_alloca(auth_size *
sizeof(*auths));
422 verify_res =
ast_alloca(auth_size *
sizeof(*verify_res));
425 if (!artificial_endpoint) {
431 ao2_ref(artificial_endpoint, -1);
440 memset(auths, 0, auth_size *
sizeof(*auths));
449 auths_shallow = auths;
455 auths_shallow =
ast_alloca(auth_size *
sizeof(*auths_shallow));
456 for (idx = 0; idx < auth_size; ++idx) {
467 auths_shallow[idx] =
ast_alloca(
sizeof(**auths_shallow));
468 memcpy(auths_shallow[idx], auths[idx],
sizeof(**auths_shallow));
470 ast_debug(3,
"Using default realm '%s' on incoming auth '%s'.\n",
473 auths_shallow[idx] = auths[idx];
478 for (idx = 0; idx < auth_size; ++idx) {
479 verify_res[idx] =
verify(auths_shallow[idx], rdata, tdata->pool);
489 for (idx = 0; idx < auth_size; ++idx) {
493 if (failures == auth_size) {
572 .requires =
"res_pjsip",
Asterisk main include file. File version handling, generic pbx functions.
static const struct ast_sip_auth * get_auth(void)
Retrieve shallow copy authentication information from thread-local storage.
static int unload_module(void)
int ast_sip_register_authenticator(struct ast_sip_authenticator *auth)
Register a SIP authenticator.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
String manipulation functions.
static int verify(const struct ast_sip_auth *auth, pjsip_rx_data *rdata, pj_pool_t *pool)
astobj2 callback for verifying incoming credentials
static char default_realm[MAX_REALM_LENGTH+1]
AO2_GLOBAL_OBJ_STATIC(entity_id)
const ast_string_field md5_creds
ast_sip_check_auth_result
Possible returns from ast_sip_check_authentication.
static int build_entity_id(void)
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
static pj_pool_t * pool
Global memory pool for configuration and timers.
static int check_nonce(const char *candidate, const pjsip_rx_data *rdata, const struct ast_sip_auth *auth)
Ensure that a nonce on an incoming request is sane.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define ao2_global_obj_ref(holder)
static int copy(char *infile, char *outfile)
Utility function to copy a file.
#define ast_str_alloca(init_len)
void ast_sip_get_default_realm(char *realm, size_t size)
Retrieve the global default realm.
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.
static int digest_requires_authentication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
Determine if authentication is required.
#define ast_strlen_zero(foo)
digest_verify_result
Result of digest verification.
static int reload_module(void)
void ast_sip_unregister_authenticator(struct ast_sip_authenticator *auth)
Unregister a SIP authenticator.
int ast_sip_retrieve_auths(const struct ast_sip_auth_vector *auths, struct ast_sip_auth **out)
Retrieve relevant SIP auth structures from sorcery.
#define ast_debug(level,...)
Log a DEBUG message.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
static struct ast_sip_endpoint * artificial_endpoint
#define ao2_ref(o, delta)
unsigned int nonce_lifetime
#define ast_strdupa(s)
duplicate a string in memory from the stack
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
int(* requires_authentication)(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
Check if a request requires authentication See ast_sip_requires_authentication for more details...
static void challenge(const char *realm, pjsip_tx_data *tdata, const pjsip_rx_data *rdata, int is_stale)
astobj2 callback for adding digest challenges to responses
static int store_auth(const struct ast_sip_auth *auth)
Store shallow copy authentication information in thread-local storage.
An entity with which Asterisk communicates.
static int load_module(void)
static void global_loaded(const char *object_type)
int ast_sorcery_observer_add(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Add an observer to a specific object type.
#define ast_test_suite_event_notify(s, f,...)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
struct ast_sip_auth * ast_sip_get_artificial_auth(void)
Retrieves a reference to the artificial auth.
static void auth_store_cleanup(void *data)
struct ast_sip_auth_vector inbound_auths
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
static char * verify_result_str[]
const ast_string_field realm
static struct ast_threadstorage auth_store
Interface for a sorcery object type observer.
#define ao2_global_obj_release(holder)
struct ast_sip_endpoint * ast_sip_get_artificial_endpoint(void)
Retrieves a reference to the artificial endpoint.
#define ao2_alloc(data_size, destructor_fn)
static void setup_auth_srv(pj_pool_t *pool, pjsip_auth_srv *auth_server, const char *realm)
Common code for initializing a pjsip_auth_srv.
void ast_sip_cleanup_auths(struct ast_sip_auth *auths[], size_t num_auths)
Clean up retrieved auth structures from memory.
static struct ast_sorcery_observer global_observer
Observer which is used to update our default_realm when the global setting changes.
static int remove_auth(void)
Remove shallow copy authentication information from thread-local storage.
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
const ast_string_field auth_pass
enum ast_sip_auth_type type
Module has failed to load, may be in an inconsistent state.
static void * cleanup(void *unused)
void(* loaded)(const char *object_type)
Callback for when an object type is loaded/reloaded.
Support for logging to various files, console and syslog Configuration in file logger.conf.
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
#define AST_THREADSTORAGE_CUSTOM(a, b, c)
Define a thread storage variable, with custom initialization and cleanup.
static int build_nonce(struct ast_str **nonce, const char *timestamp, const pjsip_rx_data *rdata, const char *realm)
Calculate a nonce.
#define ao2_global_obj_replace_unref(holder, obj)
void ast_sorcery_observer_remove(const struct ast_sorcery *sorcery, const char *type, const struct ast_sorcery_observer *callbacks)
Remove an observer from a specific object type.
char * strsep(char **str, const char *delims)
An interchangeable way of handling digest authentication for SIP.
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
static int find_challenge(const pjsip_rx_data *rdata, const struct ast_sip_auth *auth)
void ast_md5_hash(char *output, const char *input)
Produces MD5 hash based on input string.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Asterisk module definitions.
static struct ast_sip_authenticator digest_authenticator
const ast_string_field auth_user
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
void ast_sorcery_reload_object(const struct ast_sorcery *sorcery, const char *type)
Inform any wizards of a specific object type to reload persistent objects.
static pj_status_t digest_lookup(pj_pool_t *pool, const pj_str_t *realm, const pj_str_t *acc_name, pjsip_cred_info *info)
Lookup callback for authentication verification.
static enum ast_sip_check_auth_result digest_check_auth(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pjsip_tx_data *tdata)
Check authentication using Digest scheme.