45 #define AST_API_MODULE 49 #include <sys/ioctl.h> 50 #include <sys/socket.h> 53 #include <sys/sockio.h> 75 #define MAX_PROVIDER_BUCKETS 1 76 #define MAX_PROFILE_BUCKETS 1 77 #define MAX_ROUTE_BUCKETS 1 78 #define MAX_USER_BUCKETS 1 80 #define MAX_PROVIDER_BUCKETS 17 81 #define MAX_PROFILE_BUCKETS 17 82 #define MAX_ROUTE_BUCKETS 563 83 #define MAX_USER_BUCKETS 563 86 #define VAR_BUF_SIZE 4096 128 #define SIMPLE_HASH_FN(fname, stype, field) \ 129 static int fname(const void *obj, const int flags) \ 131 const struct stype *provider = obj; \ 133 switch (flags & OBJ_SEARCH_MASK) { \ 134 case OBJ_SEARCH_KEY: \ 137 case OBJ_SEARCH_OBJECT: \ 139 key = provider->field; \ 145 return ast_str_hash(key); \ 157 #define SIMPLE_CMP_FN(fname, stype, field) \ 158 static int fname(void *obj, void *arg, int flags) \ 160 const struct stype *object_left = obj, *object_right = arg; \ 161 const char *right_key = arg; \ 163 switch (flags & OBJ_SEARCH_MASK) { \ 164 case OBJ_SEARCH_OBJECT: \ 165 right_key = object_right->field; \ 166 case OBJ_SEARCH_KEY: \ 167 cmp = strcmp(object_left->field, right_key); \ 169 case OBJ_SEARCH_PARTIAL_KEY: \ 170 cmp = strncmp(object_left->field, right_key, strlen(right_key)); \ 263 static struct in_addr
__ourip = { .s_addr = 0x00000000, };
317 struct phone_profile *profile;
332 struct phone_profile *profile;
338 #define SIPUSERS_PROVIDER_NAME "sipusers" 345 struct sockaddr_in *sin;
347 memset(&ifr, 0,
sizeof(ifr));
350 mysock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
356 res = ioctl(mysock, SIOCGIFADDR, &ifr);
365 sin = (
struct sockaddr_in *)&ifr.ifr_addr;
366 memcpy(address, &sin->sin_addr,
sizeof(*address));
399 static int load_file(
const char *filename,
char **ret)
404 if (!(f = fopen(filename,
"r"))) {
409 fseek(f, 0, SEEK_END);
411 fseek(f, 0, SEEK_SET);
417 if (len != fread(*ret,
sizeof(
char), len, f)) {
447 ast_get_dst_info(&utc_time, &dstenable, &dststart, &dstend, &tzoffset, zone);
448 snprintf(buffer,
sizeof(buffer),
"%d", tzoffset);
457 when.tv_sec = dststart;
460 snprintf(buffer,
sizeof(buffer),
"%d", tm_info.
tm_mon+1);
463 snprintf(buffer,
sizeof(buffer),
"%d", tm_info.
tm_mday);
466 snprintf(buffer,
sizeof(buffer),
"%d", tm_info.
tm_hour);
469 when.tv_sec = dstend;
472 snprintf(buffer,
sizeof(buffer),
"%d", tm_info.
tm_mon + 1);
475 snprintf(buffer,
sizeof(buffer),
"%d", tm_info.
tm_mday);
478 snprintf(buffer,
sizeof(buffer),
"%d", tm_info.
tm_hour);
482 static struct http_route *
unref_route(
struct http_route *route)
491 struct http_route *route = obj;
513 struct http_route *route;
527 route->
file = pp_file;
535 static struct phone_profile *
unref_profile(
struct phone_profile *prof)
550 struct phone_profile *profile = obj;
586 struct phone_profile *profile;
606 for (; v; v = v->
next) {
607 if (!strcasecmp(v->
name,
"mime_type")) {
609 }
else if (!strcasecmp(v->
name,
"setvar")) {
610 char value_copy[strlen(v->
value) + 1];
617 strcpy(value_copy, v->
value);
628 }
else if (!strcasecmp(v->
name,
"staticdir")) {
632 char *file_extension;
633 char value_copy[strlen(v->
value) + 1];
645 if ((file_extension = strrchr(pp_file->
format,
'.')))
648 strcpy(value_copy, v->
value);
660 if (!strcasecmp(v->
name,
"static_file")) {
712 sscanf(tmp,
"%d", &exten->
index);
726 static struct user *
unref_user(
struct user *user)
741 struct http_route *route = obj;
742 struct user *user = route->
user;
754 struct user *user = obj;
836 }
else if (exten->
index == exten_iter->
index) {
871 struct http_route *route;
881 ast_http_error(ser, 501,
"Not Implemented",
"Attempt to use unimplemented / unsupported method");
893 fd = open(path, O_RDONLY);
898 len = lseek(fd, 0, SEEK_END);
899 lseek(fd, 0, SEEK_SET);
907 ast_str_set(&http_header, 0,
"Content-type: %s\r\n",
949 struct sockaddr_in sa_in;
951 socklen_t namelen =
sizeof(name.sa);
972 ast_str_set(&http_header, 0,
"Content-type: %s\r\n",
999 ast_http_error(ser, 500,
"Internal Error",
"An internal error has occured.");
1021 while ((tmp = strstr(
args.string,
"%{")))
1055 .
name =
"PP_EACH_USER",
1077 ast_log(
LOG_WARNING,
"PP_EACH_EXTENSION requries both a macaddress and template filename.\n");
1138 #define FORMATS "%-20.20s %-40.40s %-30.30s\n" 1139 #define FORMATD "%-20.20s %-20.20s %-40.40s %-30.30s\n" 1140 static int route_list_cb(
void *obj,
void *arg,
void *data,
int flags)
1142 int fd = *(
int *)arg;
1143 struct http_route *route = obj;
1145 if (data && route->
user) {
1148 if (!data && !route->
user) {
1161 e->
command =
"phoneprov show routes";
1163 "Usage: phoneprov show routes\n" 1164 " Lists all registered phoneprov http routes.\n";
1173 ast_cli(a->
fd, FORMATS,
"Profile",
"Relative URI",
"Physical location");
1178 ast_cli(a->
fd, FORMATD,
"Provider",
"Profile",
"Relative URI",
"Template");
1191 .description =
"Asterisk HTTP Phone Provisioning Tool",
1212 if (!(phoneprov_cfg =
ast_config_load(
"phoneprov.conf", config_flags))
1221 struct in_addr addr;
1307 if (strcasecmp(cat,
"general") && strcasecmp(cat,
"authentication")) {
1356 if (!(phoneprov_cfg =
ast_config_load(
"phoneprov.conf", config_flags))
1364 if (!strcasecmp(cat,
"general")) {
1453 ast_log(
LOG_WARNING,
"Unable register sip/users config provider. Others may succeed.\n");
1514 if (var >= AST_PHONEPROV_STD_VAR_LIST_LENGTH) {
1532 ast_log(
LOG_WARNING,
"Provider '%s' cannot be registered: res_phoneprov not loaded.\n", provider_name);
1538 ast_log(
LOG_ERROR,
"There is already a provider registered named '%s'.\n", provider_name);
1545 ast_log(
LOG_ERROR,
"Unable to allocate sufficient memory for provider '%s'.\n", provider_name);
1551 ast_log(
LOG_ERROR,
"Unable to allocate sufficient memory for provider '%s' stringfields.\n", provider_name);
1562 ast_log(
LOG_ERROR,
"Unable to load provider '%s' users. Register aborted.\n", provider_name);
1572 char *provider_name = arg;
1573 struct user *user = obj;
1582 struct user *user = obj;
1583 char *provider_name = data;
1584 char *macaddress = arg;
1654 ast_log(
LOG_ERROR,
"Provider '%s' wasn't found in the registry.\n", provider_name);
1660 if (!profile_name) {
1661 ast_log(
LOG_ERROR,
"No profile could be found for user '%s' - skipping.\n", username);
1665 ast_log(
LOG_ERROR,
"Could not look up profile '%s' - skipping.\n", profile_name);
1671 if (!(user =
build_user(mac, profile, provider_name))) {
const ast_string_field staticdir
struct ast_variable * next
static void route_destructor(void *obj)
static char exten[AST_MAX_EXTENSION]
static void build_route(struct phoneprov_file *pp_file, struct phone_profile *profile, struct user *user, char *uri)
Build a route structure and add it to the list of available http routes.
Main Channel structure associated with a channel.
#define AST_CLI_DEFINE(fn, txt,...)
Asterisk main include file. File version handling, generic pbx functions.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
static const char * pp_general_lookup[]
static void build_profile(const char *name, struct ast_variable *v)
Build a phone profile and add it to the list of phone profiles.
int ast_phoneprov_provider_register(char *provider_name, ast_phoneprov_load_users_cb load_users)
Registers a config provider to phoneprov.
void ast_http_error(struct ast_tcptls_session_instance *ser, int status, const char *title, const char *text)
Send HTTP error message and close socket.
ast_http_callback callback
static const char * pp_user_lookup[]
String manipulation functions.
Asterisk version information.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
The arg parameter is a search key, but is not an object.
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
ast_phoneprov_std_variables
static int extensions_delete_cb(void *obj, void *arg, int flags)
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
const ast_string_field format
#define SIMPLE_HASH_FN(fname, stype, field)
Creates a hash function for a structure string field.
descriptor for a cli entry.
void ast_phoneprov_delete_extensions(char *provider_name)
Deletes all extensions for this provider.
int ast_http_uri_link(struct ast_http_uri *urihandler)
Register a URI handler.
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)
static int user_hash_fn(const void *obj, const int flags)
#define CONFIG_STATUS_FILEINVALID
const char * ast_http_ftype2mtype(const char *ftype) attribute_pure
Return mime type based on extension.
static struct ast_custom_function pp_each_user_function
const ast_string_field template
static int pp_each_extension_helper(struct ast_channel *chan, const char *cmd, char *data, char *buf, struct ast_str **bufstr, int len)
A dialplan function that can be used to output a template for each extension attached to a user...
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
static int lookup_iface(const char *iface, struct in_addr *address)
Structure for variables, used for configurations and for channel variables.
static void delete_profiles(void)
Delete all phone profiles, freeing their memory.
static void delete_routes(void)
Delete all http routes, freeing their memory.
static int routes_delete_cb(void *obj, void *arg, int flags)
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
struct ao2_container * profiles
void ast_http_uri_unlink(struct ast_http_uri *urihandler)
Unregister a URI handler.
#define ast_calloc_with_stringfields(n, type, size)
Allocate a structure with embedded stringfields in a single allocation.
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.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream's file descriptor.
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
static int build_user_routes(struct user *user)
Add an http route for dynamic files attached to the profile of the user.
static void delete_providers(void)
Delete all providers.
const ast_string_field uri
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
struct phoneprov_file * file
structure to hold file data
void ast_cli(int fd, const char *fmt,...)
struct phone_profile::@474 static_files
void ast_http_send(struct ast_tcptls_session_instance *ser, enum ast_http_method method, int status_code, const char *status_title, struct ast_str *http_header, struct ast_str *out, int fd, unsigned int static_content)
Generic function for sending HTTP/1.1 response.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
static struct user * find_user(const char *macaddress)
Return a user looked up by name.
const ast_string_field default_mime_type
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
struct varshead * ast_var_list_clone(struct varshead *head)
int(* ast_phoneprov_load_users_cb)(void)
Causes the provider to load its users.
static void set_timezone_variables(struct varshead *headp, const char *zone)
Set all timezone-related variables based on a zone (i.e. America/New_York)
static struct phoneprov_provider * find_provider(char *name)
#define ast_strlen_zero(foo)
static int http_route_cmp_fn(void *obj, void *arg, int flags)
#define SIMPLE_CMP_FN(fname, stype, field)
Creates a compare function for a structure string field.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
static int load_common(void)
Configuration File Parser.
Support for Private Asterisk HTTP Servers.
structure to hold config providers
#define MAX_PROFILE_BUCKETS
#define ast_config_load(filename, flags)
Load a config file.
int ast_build_string(char **buffer, size_t *space, const char *fmt,...)
Build a string in a buffer, designed to be called repeatedly.
static int load_module(void)
Load the module.
static int user_cmp_fn(void *obj, void *arg, int flags)
static struct extension * build_extension(const char *name, struct varshead *vars)
General Asterisk PBX channel definitions.
Asterisk file paths, configured in asterisk.conf.
static int pp_each_extension_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
static int unload_module(void)
static struct user * build_user(const char *mac, struct phone_profile *profile, char *provider_name)
Build and return a user structure based on gathered config data.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Data structure associated with a custom dialplan function.
Access Control of various sorts.
static int phone_profile_cmp_fn(void *obj, void *arg, int flags)
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
#define AST_STRING_FIELD(name)
Declare a string field.
structure to hold extensions
#define ao2_ref(o, delta)
void ast_config_destroy(struct ast_config *config)
Destroys a config.
struct ao2_container * providers
static void profile_destructor(void *obj)
#define ast_malloc(len)
A wrapper for malloc()
struct phone_profile * profile
static struct varshead * get_defaults(void)
static struct phone_profile * unref_profile(struct phone_profile *prof)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
const ast_string_field name
AST_LIST_HEAD_NOLOCK(contactliststruct, contact)
static int load_file(const char *filename, char **ret)
Read a TEXT file into a string and return the length.
Core PBX routines and definitions.
describes a server instance
const char * ast_config_AST_DATA_DIR
static int http_route_hash_fn(const void *obj, const int flags)
static char * handle_show_routes(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
CLI command to list static and dynamic routes.
struct phone_profile * profile
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
void ast_str_substitute_variables_varshead(struct ast_str **buf, ssize_t maxlen, struct varshead *headp, const char *templ)
static int route_list_cb(void *obj, void *arg, void *data, int flags)
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
static int pp_each_user_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
const ast_string_field provider_name
void ast_var_delete(struct ast_var_t *var)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct user::@476 extensions
static struct http_route * unref_route(struct http_route *route)
#define ao2_callback_data(container, flags, cb_fn, arg, data)
#define ao2_iterator_next(iter)
static struct ast_cli_entry pp_cli[]
#define ao2_alloc(data_size, destructor_fn)
struct ao2_container * users
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
static void provider_destructor(void *obj)
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
char * ast_var_find(const struct varshead *head, const char *name)
struct ast_var_t::@249 entries
#define ast_var_assign(name, value)
static int pp_each_user_read2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
structure to hold phone profiles read from phoneprov.conf
static const char * variable_lookup[]
static void user_destructor(void *obj)
Free all memory associated with a user.
Module has failed to load, may be in an inconsistent state.
int ast_phoneprov_add_extension(char *provider_name, struct varshead *vars)
Adds an extension.
#define ao2_find(container, arg, flags)
structure to hold users read from users.conf
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Structure used to handle boolean flags.
#define MAX_PROVIDER_BUCKETS
struct ast_iostream * stream
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",)
struct varshead * ast_var_list_create(void)
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
const ast_string_field name
Standard Command Line Interface.
struct phone_profile::@475 dynamic_files
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
static int phone_profile_hash_fn(const void *obj, const int flags)
struct ao2_container * http_routes
static struct extension * delete_extension(struct extension *exten)
Definition of a URI handler.
#define MAX_ROUTE_BUCKETS
void ast_phoneprov_provider_unregister(char *provider_name)
Unegisters a config provider from phoneprov and frees its resources.
static int extension_delete_cb(void *obj, void *arg, void *data, int flags)
static struct user * unref_user(struct user *user)
const ast_string_field macaddress
static void delete_users(void)
Delete all users.
static int add_user_extension(struct user *user, struct extension *exten)
Add an extension to a user ordered by index/linenumber.
ast_phoneprov_load_users_cb load_users
Options provided by main asterisk program.
int error(const char *format,...)
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
ast_http_method
HTTP Request methods known by Asterisk.
#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field)
Inserts a list entry before the current entry during a traversal.
structure to hold http routes (valid URIs, and the files they link to)
#define AST_VAR_LIST_TRAVERSE(head, var)
const ast_string_field provider_name
void ast_get_dst_info(const time_t *const timep, int *dst_enabled, time_t *dst_start, time_t *dst_end, int *gmt_off, const char *const zone)
static int pp_each_user_helper(struct ast_channel *chan, char *data, char *buf, struct ast_str **bufstr, int len)
A dialplan function that can be used to print a string for each phoneprov user.
#define ASTERISK_GPL_KEY
The text the key() function should return.
const char * ast_phoneprov_std_variable_lookup(enum ast_phoneprov_std_variables var)
Returns the string respresentation of a phoneprov standard variable.
Asterisk module definitions.
static void delete_file(struct phoneprov_file *file)
static snd_pcm_format_t format
void ast_var_list_destroy(struct varshead *head)
static void AST_VAR_LIST_INSERT_TAIL(struct varshead *head, struct ast_var_t *var)
static struct phone_profile * find_profile(const char *name)
Return a phone profile looked up by name.
static struct prometheus_metrics_provider provider
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ast_custom_function_register(acf)
Register a custom function.
void ast_phoneprov_delete_extension(char *provider_name, char *macaddress)
Deletes an extension.
static struct in_addr __ourip
for use in lookup_iface
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
static int pp_each_extension_read2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
const ast_string_field mime_type
#define AST_APP_ARG(name)
Define an application argument.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
static int phoneprov_callback(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_vars, struct ast_variable *headers)
Callback that is executed everytime an http request is received by this module.
#define ao2_link(container, obj)