23 #include "asterisk/res_pjsip.h"
27 #include "include/res_pjsip_private.h"
28 #include "asterisk/res_pjsip_cli.h"
30 static void auth_destroy(
void *obj)
36 static void *auth_alloc(
const char *name)
55 if (!strcasecmp(var->
value,
"userpass")) {
56 auth->
type = AST_SIP_AUTH_TYPE_USER_PASS;
57 }
else if (!strcasecmp(var->
value,
"md5")) {
58 auth->
type = AST_SIP_AUTH_TYPE_MD5;
59 }
else if (!strcasecmp(var->
value,
"google_oauth")) {
60 #ifdef HAVE_PJSIP_OAUTH_AUTHENTICATION
61 auth->
type = AST_SIP_AUTH_TYPE_GOOGLE_OAUTH;
63 ast_log(LOG_WARNING,
"OAuth support is not available in the version of PJSIP in use\n");
67 ast_log(LOG_WARNING,
"Unknown authentication storage type '%s' specified for %s\n",
74 static const char *auth_types_map[] = {
75 [AST_SIP_AUTH_TYPE_USER_PASS] =
"userpass",
76 [AST_SIP_AUTH_TYPE_MD5] =
"md5",
77 [AST_SIP_AUTH_TYPE_GOOGLE_OAUTH] =
"google_oauth"
80 const char *ast_sip_auth_type_to_str(
enum ast_sip_auth_type
type)
83 auth_types_map[
type] :
"";
86 static int auth_type_to_str(
const void *obj,
const intptr_t *args,
char **buf)
93 static int auth_apply(
const struct ast_sorcery *sorcery,
void *obj)
99 ast_log(LOG_ERROR,
"No authentication username for auth '%s'\n",
104 switch (auth->
type) {
105 case AST_SIP_AUTH_TYPE_MD5:
107 ast_log(LOG_ERROR,
"'md5' authentication specified but no md5_cred "
110 }
else if (strlen(auth->
md5_creds) != PJSIP_MD5STRLEN) {
111 ast_log(LOG_ERROR,
"'md5' authentication requires digest of size '%d', but "
112 "digest is '%d' in size for auth '%s'\n", PJSIP_MD5STRLEN, (
int)strlen(auth->
md5_creds),
117 case AST_SIP_AUTH_TYPE_GOOGLE_OAUTH:
121 ast_log(LOG_ERROR,
"'google_oauth' authentication specified but refresh_token,"
122 " oauth_clientid, or oauth_secret not specified for auth '%s'\n",
127 case AST_SIP_AUTH_TYPE_USER_PASS:
128 case AST_SIP_AUTH_TYPE_ARTIFICIAL:
147 ast_sip_get_sorcery(), SIP_SORCERY_AUTH_TYPE,
154 if (on_auth(auth, arg, 0)) {
162 static int sip_auth_to_ami(
const struct ast_sip_auth *auth,
165 return ast_sip_sorcery_object_to_ami(auth, buf);
168 static int format_ami_auth_handler(
void *obj,
void *arg,
int flags)
174 ast_sip_create_ami_event(
"AuthDetail", ami), ast_free);
180 if (sip_auth_to_ami(auth, &buf)) {
198 return ast_sip_for_each_auth(auths, format_ami_auth_handler, ami);
201 static int format_ami_endpoint_auth(
const struct ast_sip_endpoint *endpoint,
204 ami->
arg = (
void *)endpoint;
205 if (ast_sip_format_auths_ami(&endpoint->
inbound_auths, ami)) {
226 static int format_ami_authlist_handler(
void *obj,
void *arg,
int flags)
232 buf = ast_sip_create_ami_event(
"AuthList", ami);
237 sip_auth_to_ami(auth, &buf);
252 auths = cli_get_auths();
277 static struct ao2_container *cli_get_container(
const char *regex)
303 return ast_sip_for_each_auth(container, callback, args);
306 static void *cli_retrieve_by_id(
const char *
id)
311 static int cli_print_header(
void *obj,
void *arg,
int flags)
314 int indent = CLI_INDENT_TO_SPACES(context->
indent_level);
315 int filler = CLI_MAX_WIDTH - indent - 20;
320 "%*s: <AuthId/UserName%*.*s>\n", indent,
"I/OAuth", filler, filler,
326 static int cli_print_body(
void *obj,
void *arg,
int flags)
334 snprintf(title,
sizeof(title),
"%sAuth",
344 ast_sip_cli_print_sorcery_objectset(auth, context, 0);
351 AST_CLI_DEFINE(ast_sip_cli_traverse_objects,
"List PJSIP Auths",
353 .
usage =
"Usage: pjsip list auths [ like <pattern> ]\n"
354 " List the configured PJSIP Auths\n"
355 " Optional regular expression pattern is used to filter the list.\n"),
356 AST_CLI_DEFINE(ast_sip_cli_traverse_objects,
"Show PJSIP Auths",
358 .
usage =
"Usage: pjsip show auths [ like <pattern> ]\n"
359 " Show the configured PJSIP Auths\n"
360 " Optional regular expression pattern is used to filter the list.\n"),
361 AST_CLI_DEFINE(ast_sip_cli_traverse_objects,
"Show PJSIP Auth",
363 .
usage =
"Usage: pjsip show auth <id>\n"
364 " Show the configured PJSIP Auth\n"),
370 int ast_sip_initialize_sorcery_auth(
void)
372 struct ast_sorcery *sorcery = ast_sip_get_sorcery();
374 ast_sorcery_apply_default(sorcery, SIP_SORCERY_AUTH_TYPE,
"config",
"pjsip.conf,criteria=type=auth");
399 "userpass", auth_type_handler, auth_type_to_str, NULL, 0, 0);
401 ast_sip_register_endpoint_formatter(&endpoint_auth_formatter);
404 if (!cli_formatter) {
405 ast_log(LOG_ERROR,
"Unable to allocate memory for cli formatter\n");
408 cli_formatter->
name = SIP_SORCERY_AUTH_TYPE;
412 cli_formatter->
iterate = cli_iterator;
416 ast_sip_register_cli_formatter(cli_formatter);
426 int ast_sip_destroy_sorcery_auth(
void)
429 ast_sip_unregister_cli_formatter(cli_formatter);
430 ast_sip_unregister_endpoint_formatter(&endpoint_auth_formatter);
struct ast_str * output_buffer
struct ao2_container *(* get_container)(const char *regex)
#define ARRAY_IN_BOUNDS(v, a)
Checks to see if value is within the bounds of the given array.
void astman_append(struct mansession *s, const char *fmt,...)
Asterisk main include file. File version handling, generic pbx functions.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
CLI Formatter Registry Entry.
int( ao2_callback_fn)(void *obj, void *arg, int flags)
Type of a generic callback function.
const ast_string_field oauth_secret
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
const ast_string_field md5_creds
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
descriptor for a cli entry.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container, as described below.
#define ao2_container_alloc_list(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a list container.
Structure for variables, used for configurations and for channel variables.
struct ast_sip_auth_vector outbound_auths
Perform no matching, return all objects.
int ast_sorcery_object_id_compare(void *obj, void *arg, int flags)
ao2 object comparator based on sorcery id.
Full structure for sorcery.
int(* iterate)(void *container, ao2_callback_fn callback, void *args)
Type for a default handler that should do nothing.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Return all matching objects.
#define ast_strdup(str)
A wrapper for strdup()
CLI Formatter Context passed to all formatters.
struct ao2_container * ast_sorcery_retrieve_by_regex(const struct ast_sorcery *sorcery, const char *type, const char *regex)
Retrieve multiple objects using a regular expression on their id.
const ast_string_field oauth_clientid
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
#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.
#define FLDSET(type,...)
Convert a struct and list of fields to an argument list of field offsets.
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Type for default option handler for unsigned integers.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
In case you didn't read that giant block of text above the mansession_session struct, the mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
int ast_sorcery_object_id_sort(const void *obj, const void *arg, int flags)
ao2 object sorter based on sorcery id.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
void *(* retrieve_by_id)(const char *id)
struct ao2_container * container
An entity with which Asterisk communicates.
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
struct ast_sip_auth_vector inbound_auths
Support for dynamic strings.
int ao2_container_dup(struct ao2_container *dest, struct ao2_container *src, enum search_flags flags)
Copy all object references in the src container into the dest container.
#define STRFLDSET(type,...)
Convert a struct and a list of stringfield fields to an argument list of field offsets.
enum ast_sip_auth_type type
Support for logging to various files, console and syslog Configuration in file logger.conf.
const char *(* get_id)(const void *obj)
const ast_string_field refresh_token
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.
#define ast_sorcery_object_field_register(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object.
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Standard Command Line Interface.
Type for default option handler for stringfields.
ao2_callback_fn * print_header
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
ao2_callback_fn * print_body
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
const ast_string_field auth_user
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Sorcery Data Access Layer API.
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
unsigned show_details_only_level_0