150 const pj_str_t *acc_name, pjsip_cred_info *
info)
156 return PJSIP_SC_FORBIDDEN;
160 return PJSIP_SC_FORBIDDEN;
164 return PJSIP_SC_FORBIDDEN;
166 if (pj_strcmp2(acc_name, auth->
auth_user)) {
167 return PJSIP_SC_FORBIDDEN;
170 pj_strdup2(pool, &
info->realm, auth->
realm);
173 switch (auth->
type) {
176 info->data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
180 info->data_type = PJSIP_CRED_DATA_DIGEST;
183 return PJSIP_SC_FORBIDDEN;
242 time_t now = time(
NULL);
250 if (sscanf(timestamp,
"%30d", ×tamp_int) != 1) {
268 struct pjsip_authorization_hdr *auth_hdr = (pjsip_authorization_hdr *) &rdata->msg_info.msg->hdr;
269 int challenge_found = 0;
272 while ((auth_hdr = (pjsip_authorization_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_AUTHORIZATION, auth_hdr->next))) {
273 ast_copy_pj_str(nonce, &auth_hdr->credential.digest.nonce,
sizeof(nonce));
274 if (
check_nonce(nonce, rdata, auth) && !pj_strcmp2(&auth_hdr->credential.digest.realm, auth->
realm)) {
280 return challenge_found;
286static void setup_auth_srv(pj_pool_t *pool, pjsip_auth_srv *auth_server,
const char *realm)
289 pj_cstr(&realm_str, realm);
291 pjsip_auth_srv_init(pool, auth_server, &realm_str,
digest_lookup, 0);
327 pjsip_auth_srv auth_server;
341 authed = pjsip_auth_srv_verify(&auth_server, rdata, &response_code);
344 if (authed == PJ_SUCCESS) {
352 if (authed == PJSIP_EAUTHNOAUTH) {
356 ast_debug(3,
"Realm: %s Username: %s Result: %s\n",
376static void challenge(
const char *realm, pjsip_tx_data *tdata,
const pjsip_rx_data *rdata,
int is_stale)
380 pjsip_auth_srv auth_server;
383 time_t timestamp = time(
NULL);
384 snprintf(time_buf,
sizeof(time_buf),
"%d", (
int) timestamp);
391 pj_cstr(&qop,
"auth");
392 pjsip_auth_srv_challenge(&auth_server, &qop, &pj_nonce,
NULL, is_stale ? PJ_TRUE : PJ_FALSE, tdata);
405 pjsip_rx_data *rdata, pjsip_tx_data *tdata)
420 auths =
ast_alloca(auth_size *
sizeof(*auths));
421 verify_res =
ast_alloca(auth_size *
sizeof(*verify_res));
439 memset(auths, 0, auth_size *
sizeof(*auths));
448 auths_shallow = auths;
454 auths_shallow =
ast_alloca(auth_size *
sizeof(*auths_shallow));
455 for (idx = 0; idx < auth_size; ++idx) {
466 auths_shallow[idx] =
ast_alloca(
sizeof(**auths_shallow));
467 memcpy(auths_shallow[idx], auths[idx],
sizeof(**auths_shallow));
469 ast_debug(3,
"Using default realm '%s' on incoming auth '%s'.\n",
472 auths_shallow[idx] = auths[idx];
477 for (idx = 0; idx < auth_size; ++idx) {
478 verify_res[idx] =
verify(auths_shallow[idx], rdata, tdata->pool);
488 for (idx = 0; idx < auth_size; ++idx) {
492 if (failures == auth_size) {
571 .
requires =
"res_pjsip",
static int copy(char *infile, char *outfile)
Utility function to copy a file.
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ao2_global_obj_replace_unref(holder, obj)
Replace an ao2 object in the global holder, throwing away any old object.
#define ao2_global_obj_ref(holder)
Get a reference to the object stored in the global holder.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_global_obj_release(holder)
Release the ao2 object held in the global holder.
#define ao2_alloc(data_size, destructor_fn)
char * strsep(char **str, const char *delims)
Support for logging to various files, console and syslog Configuration in file logger....
#define ast_debug(level,...)
Log a DEBUG message.
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODPRI_CHANNEL_DEPEND
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
static void * cleanup(void *unused)
static struct ast_sip_endpoint * artificial_endpoint
struct ast_sip_auth * ast_sip_get_artificial_auth(void)
Retrieves a reference to the artificial auth.
struct ast_sip_endpoint * ast_sip_get_artificial_endpoint(void)
Retrieves a reference to the artificial endpoint.
void ast_sip_cleanup_auths(struct ast_sip_auth *auths[], size_t num_auths)
Clean up retrieved auth structures from memory.
int ast_sip_retrieve_auths(const struct ast_sip_auth_vector *auths, struct ast_sip_auth **out)
Retrieve relevant SIP auth structures from sorcery.
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.
void ast_sip_unregister_authenticator(struct ast_sip_authenticator *auth)
Unregister a SIP authenticator.
void ast_sip_get_default_realm(char *realm, size_t size)
Retrieve the global default realm.
#define AST_SIP_AUTH_MAX_REALM_LENGTH
int ast_sip_register_authenticator(struct ast_sip_authenticator *auth)
Register a SIP authenticator.
@ AST_SIP_AUTH_TYPE_ARTIFICIAL
@ AST_SIP_AUTH_TYPE_USER_PASS
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
ast_sip_check_auth_result
Possible returns from ast_sip_check_authentication.
@ AST_SIP_AUTHENTICATION_CHALLENGE
@ AST_SIP_AUTHENTICATION_ERROR
@ AST_SIP_AUTHENTICATION_SUCCESS
@ AST_SIP_AUTHENTICATION_FAILED
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.
static struct ast_sorcery_observer global_observer
Observer which is used to update our default_realm when the global setting changes.
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.
digest_verify_result
Result of digest verification.
static int find_challenge(const pjsip_rx_data *rdata, const struct ast_sip_auth *auth)
static void global_loaded(const char *object_type)
AO2_GLOBAL_OBJ_STATIC(entity_id)
static struct ast_threadstorage auth_store
static int build_entity_id(void)
static const struct ast_sip_auth * get_auth(void)
Retrieve shallow copy authentication information from thread-local storage.
static int reload_module(void)
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 int store_auth(const struct ast_sip_auth *auth)
Store shallow copy authentication information in thread-local storage.
static char default_realm[AST_SIP_AUTH_MAX_REALM_LENGTH+1]
static int remove_auth(void)
Remove shallow copy authentication information from thread-local storage.
static int verify(const struct ast_sip_auth *auth, pjsip_rx_data *rdata, pj_pool_t *pool)
astobj2 callback for verifying incoming credentials
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.
static int load_module(void)
static char * verify_result_str[]
static int unload_module(void)
static void auth_store_cleanup(void *data)
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 digest_requires_authentication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
Determine if authentication is required.
static struct ast_sip_authenticator digest_authenticator
static int build_nonce(struct ast_str **nonce, const char *timestamp, const pjsip_rx_data *rdata, const char *realm)
Calculate a nonce.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
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.
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.
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.
String manipulation functions.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_alloca(init_len)
const ast_string_field md5_creds
const ast_string_field realm
unsigned int nonce_lifetime
const ast_string_field auth_user
const ast_string_field auth_pass
enum ast_sip_auth_type type
An interchangeable way of handling digest authentication for SIP.
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.
An entity with which Asterisk communicates.
struct ast_sip_auth_vector inbound_auths
Interface for a sorcery object type observer.
void(* loaded)(const char *object_type)
Callback for when an object type is loaded/reloaded.
Support for dynamic strings.
#define ast_test_suite_event_notify(s, f,...)
#define AST_THREADSTORAGE_CUSTOM(a, b, c)
Define a thread storage variable, with custom initialization and cleanup.
void * ast_threadstorage_get(struct ast_threadstorage *ts, size_t init_size)
Retrieve thread storage.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
void ast_md5_hash(char *output, const char *input)
Produces MD5 hash based on input string.
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.