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 
  134#define SIMPLE_HASH_FN(fname, stype, field) \ 
  135static int fname(const void *obj, const int flags) \ 
  137    const struct stype *provider = obj; \ 
  139    switch (flags & OBJ_SEARCH_MASK) { \ 
  140    case OBJ_SEARCH_KEY: \ 
  143    case OBJ_SEARCH_OBJECT: \ 
  145        key = provider->field; \ 
  151    return ast_str_hash(key); \ 
   134#define SIMPLE_HASH_FN(fname, stype, field) \ … 
  163#define SIMPLE_CMP_FN(fname, stype, field) \ 
  164static int fname(void *obj, void *arg, int flags) \ 
  166    const struct stype *object_left = obj, *object_right = arg; \ 
  167    const char *right_key = arg; \ 
  169    switch (flags & OBJ_SEARCH_MASK) { \ 
  170    case OBJ_SEARCH_OBJECT: \ 
  171        right_key = object_right->field; \ 
  172    case OBJ_SEARCH_KEY: \ 
  173        cmp = strcmp(object_left->field, right_key); \ 
  175    case OBJ_SEARCH_PARTIAL_KEY: \ 
  176        cmp = strncmp(object_left->field, right_key, strlen(right_key)); \ 
   163#define SIMPLE_CMP_FN(fname, stype, field) \ …   269static struct in_addr 
__ourip = { .s_addr = 0x00000000, };
 
  344#define SIPUSERS_PROVIDER_NAME "sipusers" 
  351    struct sockaddr_in *sin;
 
  353    memset(&ifr, 0, 
sizeof(ifr));
 
  356    mysock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
 
  362    res = ioctl(mysock, SIOCGIFADDR, &ifr);
 
  371        sin = (
struct sockaddr_in *)&ifr.ifr_addr;
 
 
  410    if (!(f = fopen(filename, 
"r"))) {
 
  415    fseek(f, 0, SEEK_END);
 
  417    fseek(f, 0, SEEK_SET);
 
  423    if (
len != fread(*ret, 
sizeof(
char), 
len, f)) {
 
 
  453    ast_get_dst_info(&utc_time, &dstenable, &dststart, &dstend, &tzoffset, zone);
 
  454    snprintf(buffer, 
sizeof(buffer), 
"%d", tzoffset);
 
  463    when.tv_sec = dststart;
 
  466    snprintf(buffer, 
sizeof(buffer), 
"%d", tm_info.
tm_mon+1);
 
  469    snprintf(buffer, 
sizeof(buffer), 
"%d", tm_info.
tm_mday);
 
  472    snprintf(buffer, 
sizeof(buffer), 
"%d", tm_info.
tm_hour);
 
  475    when.tv_sec = dstend;
 
  478    snprintf(buffer, 
sizeof(buffer), 
"%d", tm_info.
tm_mon + 1);
 
  481    snprintf(buffer, 
sizeof(buffer), 
"%d", tm_info.
tm_mday);
 
  484    snprintf(buffer, 
sizeof(buffer), 
"%d", tm_info.
tm_hour);
 
 
  534    route->
file = pp_file;
 
 
  613    for (; v; v = v->
next) {
 
  614        if (!strcasecmp(v->
name, 
"mime_type")) {
 
  616        } 
else if (!strcasecmp(v->
name, 
"setvar")) {
 
  617            char value_copy[strlen(v->
value) + 1];
 
  624            strcpy(value_copy, v->
value); 
 
  635        } 
else if (!strcasecmp(v->
name, 
"staticdir")) {
 
  639            char *file_extension;
 
  640            char value_copy[strlen(v->
value) + 1];
 
  652            if ((file_extension = strrchr(pp_file->
format, 
'.')))
 
  655            strcpy(value_copy, v->
value); 
 
  667            if (!strcasecmp(v->
name, 
"static_file")) {
 
 
  719        sscanf(tmp, 
"%d", &exten->
index);
 
 
  843            } 
else if (exten->
index == exten_iter->
index) {
 
 
  883    char *newserver = 
NULL;
 
  890        ast_http_error(ser, 501, 
"Not Implemented", 
"Attempt to use unimplemented / unsupported method");
 
  902        fd = open(path, O_RDONLY);
 
  907        len = lseek(fd, 0, SEEK_END);
 
  908        lseek(fd, 0, SEEK_SET);
 
  916        ast_str_set(&http_header, 0, 
"Content-type: %s\r\n",
 
  958                struct sockaddr_in sa_in;
 
  960            socklen_t namelen = 
sizeof(
name.sa);
 
  995        ast_str_set(&http_header, 0, 
"Content-type: %s\r\n",
 
 1022    ast_http_error(ser, 500, 
"Internal Error", 
"An internal error has occured.");
 
 
 1044    while ((tmp = strstr(
args.string, 
"%{")))
 
 
 1078    .
name = 
"PP_EACH_USER",
 
 
 1100        ast_log(
LOG_WARNING, 
"PP_EACH_EXTENSION requires both a macaddress and template filename.\n");
 
 
 1156    .
name = 
"PP_EACH_EXTENSION",
 
 
 1161#define FORMATS "%-20.20s %-40.40s  %-30.30s\n" 
 1162#define FORMATD "%-20.20s %-20.20s %-40.40s  %-30.30s\n" 
 1165    int fd = *(
int *)arg;
 
 1168    if (data && route->
user) {
 
 1171    if (!data && !route->
user) {
 
 
 1184        e->
command = 
"phoneprov show routes";
 
 1186            "Usage: phoneprov show routes\n" 
 1187            "       Lists all registered phoneprov http routes.\n";
 
 1195    ast_cli(
a->fd, 
"Static routes\n\n");
 
 1196    ast_cli(
a->fd, 
FORMATS, 
"Profile", 
"Relative URI", 
"Physical location");
 
 1200    ast_cli(
a->fd, 
"\nDynamic routes\n\n");
 
 1201    ast_cli(
a->fd, 
FORMATD, 
"Provider", 
"Profile", 
"Relative URI", 
"Template");
 
 
 1214    .description = 
"Asterisk HTTP Phone Provisioning Tool",
 
 
 1235    if (!(phoneprov_cfg = 
ast_config_load(
"phoneprov.conf", config_flags))
 
 1244        struct in_addr addr;
 
 
 1325        if (strcasecmp(cat, 
"general") && strcasecmp(cat, 
"authentication")) {
 
 
 1374    if (!(phoneprov_cfg = 
ast_config_load(
"phoneprov.conf", config_flags))
 
 1382        if (!strcasecmp(cat, 
"general")) {
 
 1390        ast_log(
LOG_ERROR, 
"There are no provisioning profiles in phoneprov.conf.\n");
 
 
 1437        phone_profile_hash_fn, 
NULL, phone_profile_cmp_fn);
 
 1444        http_route_hash_fn, 
NULL, http_route_cmp_fn);
 
 1456        user_hash_fn, 
NULL, user_cmp_fn);
 
 1471        ast_log(
LOG_WARNING, 
"Unable register users config provider.  Others may succeed.\n");
 
 
 1672        ast_log(
LOG_ERROR, 
"Provider '%s' wasn't found in the registry.\n", provider_name);
 
 1678    if (!profile_name) {
 
 1679        ast_log(
LOG_ERROR, 
"No profile could be found for user '%s' - skipping.\n", username);
 
 1683        ast_log(
LOG_ERROR, 
"Could not look up profile '%s' - skipping.\n", profile_name);
 
 
Access Control of various sorts.
void ast_cli_unregister_multiple(void)
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.
#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.
#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.
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
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::@224 entries
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
structure to hold extensions
struct extension::@483 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
const ast_string_field staticdir
struct phone_profile::@484 static_files
struct phone_profile::@485 dynamic_files
const ast_string_field default_mime_type
const ast_string_field name
structure to hold file data
const ast_string_field mime_type
struct phoneprov_file::@482 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 phoneprov_users.conf
struct user::@486 extensions
const ast_string_field macaddress
struct phone_profile * profile
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.