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) \
129static 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) \
158static 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)); \
263static struct in_addr
__ourip = { .s_addr = 0x00000000, };
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;
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);
528 route->
file = pp_file;
607 for (; v; v = v->
next) {
608 if (!strcasecmp(v->
name,
"mime_type")) {
610 }
else if (!strcasecmp(v->
name,
"setvar")) {
611 char value_copy[strlen(v->
value) + 1];
618 strcpy(value_copy, v->
value);
629 }
else if (!strcasecmp(v->
name,
"staticdir")) {
633 char *file_extension;
634 char value_copy[strlen(v->
value) + 1];
646 if ((file_extension = strrchr(pp_file->
format,
'.')))
649 strcpy(value_copy, v->
value);
661 if (!strcasecmp(v->
name,
"static_file")) {
837 }
else if (exten->
index == exten_iter->
index) {
877 char *newserver =
NULL;
884 ast_http_error(ser, 501,
"Not Implemented",
"Attempt to use unimplemented / unsupported method");
896 fd = open(path, O_RDONLY);
901 len = lseek(fd, 0, SEEK_END);
902 lseek(fd, 0, SEEK_SET);
910 ast_str_set(&http_header, 0,
"Content-type: %s\r\n",
952 struct sockaddr_in sa_in;
954 socklen_t namelen =
sizeof(
name.sa);
989 ast_str_set(&http_header, 0,
"Content-type: %s\r\n",
1016 ast_http_error(ser, 500,
"Internal Error",
"An internal error has occured.");
1038 while ((
tmp = strstr(
args.string,
"%{")))
1072 .
name =
"PP_EACH_USER",
1094 ast_log(
LOG_WARNING,
"PP_EACH_EXTENSION requires both a macaddress and template filename.\n");
1150 .
name =
"PP_EACH_EXTENSION",
1155#define FORMATS "%-20.20s %-40.40s %-30.30s\n"
1156#define FORMATD "%-20.20s %-20.20s %-40.40s %-30.30s\n"
1159 int fd = *(
int *)arg;
1162 if (data && route->
user) {
1165 if (!data && !route->
user) {
1178 e->
command =
"phoneprov show routes";
1180 "Usage: phoneprov show routes\n"
1181 " Lists all registered phoneprov http routes.\n";
1189 ast_cli(
a->fd,
"Static routes\n\n");
1190 ast_cli(
a->fd,
FORMATS,
"Profile",
"Relative URI",
"Physical location");
1194 ast_cli(
a->fd,
"\nDynamic routes\n\n");
1195 ast_cli(
a->fd,
FORMATD,
"Provider",
"Profile",
"Relative URI",
"Template");
1208 .description =
"Asterisk HTTP Phone Provisioning Tool",
1229 if (!(phoneprov_cfg =
ast_config_load(
"phoneprov.conf", config_flags))
1238 struct in_addr addr;
1319 if (strcasecmp(cat,
"general") && strcasecmp(cat,
"authentication")) {
1368 if (!(phoneprov_cfg =
ast_config_load(
"phoneprov.conf", config_flags))
1376 if (!strcasecmp(cat,
"general")) {
1384 ast_log(
LOG_ERROR,
"There are no provisioning profiles in phoneprov.conf.\n");
1431 phone_profile_hash_fn,
NULL, phone_profile_cmp_fn);
1438 http_route_hash_fn,
NULL, http_route_cmp_fn);
1450 user_hash_fn,
NULL, user_cmp_fn);
1465 ast_log(
LOG_WARNING,
"Unable register users config provider. Others may succeed.\n");
1666 ast_log(
LOG_ERROR,
"Provider '%s' wasn't found in the registry.\n", provider_name);
1672 if (!profile_name) {
1673 ast_log(
LOG_ERROR,
"No profile could be found for user '%s' - skipping.\n", username);
1677 ast_log(
LOG_ERROR,
"Could not look up profile '%s' - skipping.\n", profile_name);
Access Control of various sorts.
Asterisk version information.
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_malloc(len)
A wrapper for malloc()
#define ao2_iterator_next(iter)
#define ao2_link(container, obj)
Add an object to a container.
@ AO2_ALLOC_OPT_LOCK_MUTEX
#define ao2_callback(c, flags, cb_fn, arg)
ao2_callback() is a generic function that applies cb_fn() to all objects in a container,...
int ao2_container_count(struct ao2_container *c)
Returns the number of elements in a container.
#define ao2_callback_data(container, flags, cb_fn, arg, data)
#define ao2_find(container, arg, flags)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
#define ao2_alloc(data_size, destructor_fn)
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
static struct prometheus_metrics_provider provider
General Asterisk PBX channel definitions.
void ast_var_list_destroy(struct varshead *head)
char * ast_var_find(const struct varshead *head, const char *name)
static void AST_VAR_LIST_INSERT_TAIL(struct varshead *head, struct ast_var_t *var)
const char * ast_var_name(const struct ast_var_t *var)
#define AST_VAR_LIST_TRAVERSE(head, var)
#define ast_var_assign(name, value)
struct varshead * ast_var_list_clone(struct varshead *head)
void ast_var_delete(struct ast_var_t *var)
struct varshead * ast_var_list_create(void)
Standard Command Line Interface.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
#define AST_CLI_DEFINE(fn, txt,...)
void ast_cli(int fd, const char *fmt,...)
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Generic File Format Support. Should be included by clients of the file handling routines....
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Support for Private Asterisk HTTP Servers.
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.
ast_http_method
HTTP Request methods known by Asterisk.
const char * ast_http_ftype2mtype(const char *ftype) attribute_pure
Return mime type based on extension.
void ast_http_uri_unlink(struct ast_http_uri *urihandler)
Unregister a URI handler.
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.
int ast_http_uri_link(struct ast_http_uri *urihandler)
Register a URI handler.
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define AST_APP_ARG(name)
Define an application argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
Configuration File Parser.
#define ast_config_load(filename, flags)
Load a config file.
char * ast_category_browse(struct ast_config *config, const char *prev_name)
Browse categories.
#define CONFIG_STATUS_FILEINVALID
void ast_config_destroy(struct ast_config *cfg)
Destroys a config.
const char * ast_variable_retrieve(struct ast_config *config, const char *category, const char *variable)
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category_name)
int ast_iostream_get_fd(struct ast_iostream *stream)
Get an iostream's file descriptor.
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
#define AST_LIST_INSERT_BEFORE_CURRENT(elm, field)
Inserts a list entry before the current entry during a traversal.
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
struct ast_tm * ast_localtime(const struct timeval *timep, struct ast_tm *p_tm, const char *zone)
Timezone-independent version of localtime_r(3).
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)
Asterisk module definitions.
@ AST_MODFLAG_GLOBAL_SYMBOLS
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODPRI_CHANNEL_DEPEND
@ AST_MODULE_SUPPORT_EXTENDED
#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.
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
Options provided by main asterisk program.
Asterisk file paths, configured in asterisk.conf.
const char * ast_config_AST_DATA_DIR
Core PBX routines and definitions.
void ast_str_substitute_variables_varshead(struct ast_str **buf, ssize_t maxlen, struct varshead *headp, const char *templ)
#define ast_custom_function_register(acf)
Register a custom function.
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
ast_phoneprov_std_variables
@ AST_PHONEPROV_STD_DST_END_MDAY
@ AST_PHONEPROV_STD_SERVER_IFACE
@ AST_PHONEPROV_STD_VAR_LIST_LENGTH
@ AST_PHONEPROV_STD_SERVER_PORT
@ AST_PHONEPROV_STD_DST_START_MDAY
@ AST_PHONEPROV_STD_CALLERID
@ AST_PHONEPROV_STD_DST_START_MONTH
@ AST_PHONEPROV_STD_TZOFFSET
@ AST_PHONEPROV_STD_USERNAME
@ AST_PHONEPROV_STD_DST_END_MONTH
@ AST_PHONEPROV_STD_LINENUMBER
@ AST_PHONEPROV_STD_TIMEZONE
@ AST_PHONEPROV_STD_SERVER
@ AST_PHONEPROV_STD_LABEL
@ AST_PHONEPROV_STD_PROFILE
@ AST_PHONEPROV_STD_EXTENSION_LENGTH
@ AST_PHONEPROV_STD_DST_END_HOUR
@ AST_PHONEPROV_STD_DST_ENABLE
@ AST_PHONEPROV_STD_DISPLAY_NAME
@ AST_PHONEPROV_STD_SECRET
@ AST_PHONEPROV_STD_DST_START_HOUR
@ AST_PHONEPROV_STD_VOICEMAIL_EXTEN
@ AST_PHONEPROV_STD_LINEKEYS
int(* ast_phoneprov_load_users_cb)(void)
Causes the provider to load its users.
static int load_file(const char *filename, char **ret)
Read a TEXT file into a string and return the length.
static void profile_destructor(void *obj)
#define MAX_ROUTE_BUCKETS
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 MAX_PROFILE_BUCKETS
static void delete_providers(void)
Delete all providers.
static struct in_addr __ourip
for use in lookup_iface
static void provider_destructor(void *obj)
#define MAX_PROVIDER_BUCKETS
void ast_phoneprov_delete_extensions(char *provider_name)
Deletes all extensions for this provider.
void ast_phoneprov_provider_unregister(char *provider_name)
Unegisters a config provider from phoneprov and frees its resources.
static int pp_each_extension_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static struct ast_custom_function pp_each_extension_function
static struct user * find_user(const char *macaddress)
Return a user looked up by name.
static int load_common(void)
const char * ast_phoneprov_std_variable_lookup(enum ast_phoneprov_std_variables var)
Returns the string respresentation of a phoneprov standard variable.
static struct ast_cli_entry pp_cli[]
static struct phone_profile * find_profile(const char *name)
Return a phone profile looked up by name.
static struct ast_custom_function pp_each_user_function
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)
#define SIMPLE_CMP_FN(fname, stype, field)
Creates a compare function for a structure string field.
int ast_phoneprov_add_extension(char *provider_name, struct varshead *vars)
Adds an extension.
static struct phoneprov_provider * find_provider(char *name)
static int build_user_routes(struct user *user)
Add an http route for dynamic files attached to the profile of the user.
static int pp_each_user_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static const char * pp_general_lookup[]
static void user_destructor(void *obj)
Free all memory associated with a user.
static int route_list_cb(void *obj, void *arg, void *data, int flags)
static int pp_each_extension_read2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
static int routes_delete_cb(void *obj, void *arg, int flags)
static int extensions_delete_cb(void *obj, void *arg, int flags)
struct ao2_container * users
static const char * pp_user_lookup[]
static struct phone_profile * unref_profile(struct phone_profile *prof)
struct ao2_container * http_routes
static int lookup_iface(const char *iface, struct in_addr *address)
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.
static const char * variable_lookup[]
static void delete_profiles(void)
Delete all phone profiles, freeing their memory.
static struct user * unref_user(struct user *user)
#define SIMPLE_HASH_FN(fname, stype, field)
Creates a hash function for a structure string field.
static void delete_file(struct phoneprov_file *file)
static struct extension * delete_extension(struct extension *exten)
static struct ast_http_uri phoneprovuri
struct ao2_container * profiles
static void delete_routes(void)
Delete all http routes, freeing their memory.
static int pp_each_user_read2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
static int extension_delete_cb(void *obj, void *arg, void *data, int flags)
static struct varshead * get_defaults(void)
void ast_phoneprov_delete_extension(char *provider_name, char *macaddress)
Deletes an extension.
static int load_module(void)
Load the module.
static void delete_users(void)
Delete all users.
static int load_users(void)
#define SIPUSERS_PROVIDER_NAME
static int unload_module(void)
static int add_user_extension(struct user *user, struct extension *exten)
Add an extension to a user ordered by index/linenumber.
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.
struct ao2_container * providers
static struct extension * build_extension(const char *name, struct varshead *vars)
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.
static void route_destructor(void *obj)
static struct http_route * unref_route(struct http_route *route)
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.
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.
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.
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
#define ast_calloc_with_stringfields(n, type, size)
Allocate a structure with embedded stringfields in a single allocation.
#define AST_STRING_FIELD(name)
Declare a string field.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
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.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true"....
static force_inline int attribute_pure ast_strlen_zero(const char *s)
int ast_build_string(char **buffer, size_t *space, const char *fmt,...)
Build a string in a buffer, designed to be called repeatedly.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Main Channel structure associated with a channel.
descriptor for a cli entry.
Data structure associated with a custom dialplan function.
Structure used to handle boolean flags.
Definition of a URI handler.
ast_http_callback callback
Support for dynamic strings.
describes a server instance
struct ast_iostream * stream
struct ast_var_t::@211 entries
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
structure to hold extensions
struct extension::@446 entry
const ast_string_field name
structure to hold http routes (valid URIs, and the files they link to)
const ast_string_field uri
struct phone_profile * profile
struct phoneprov_file * file
structure to hold phone profiles read from phoneprov.conf
struct phone_profile::@448 dynamic_files
const ast_string_field staticdir
const ast_string_field default_mime_type
const ast_string_field name
struct phone_profile::@447 static_files
structure to hold file data
const ast_string_field mime_type
struct phoneprov_file::@445 entry
const ast_string_field template
const ast_string_field format
structure to hold config providers
ast_phoneprov_load_users_cb load_users
const ast_string_field provider_name
structure to hold users read from users.conf
const ast_string_field macaddress
struct phone_profile * profile
struct user::@449 extensions
const ast_string_field provider_name
list of users found in the config file
int error(const char *format,...)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.