35 #include <sys/ioctl.h>
36 #include <sys/socket.h>
39 #include <sys/sockio.h>
43 #include "asterisk/channel.h"
61 #define MAX_PROFILE_BUCKETS 1
62 #define MAX_ROUTE_BUCKETS 1
63 #define MAX_USER_BUCKETS 1
65 #define MAX_PROFILE_BUCKETS 17
66 #define MAX_ROUTE_BUCKETS 563
67 #define MAX_USER_BUCKETS 563
70 #define VAR_BUF_SIZE 4096
104 static struct in_addr
__ourip = { .s_addr = 0x00000000, };
175 struct phone_profile *profile;
202 static int lookup_iface(
const char *iface,
struct in_addr *address)
206 struct sockaddr_in *sin;
208 memset(&ifr, 0,
sizeof(ifr));
211 mysock = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
217 res = ioctl(mysock, SIOCGIFADDR, &ifr);
223 memcpy(address, &__ourip,
sizeof(__ourip));
226 sin = (
struct sockaddr_in *)&ifr.ifr_addr;
227 memcpy(address, &sin->sin_addr,
sizeof(*address));
232 static struct phone_profile *
unref_profile(
struct phone_profile *prof)
242 struct phone_profile tmp = {
251 const struct phone_profile *profile = obj;
258 const struct phone_profile *profile1 = obj, *profile2 = arg;
271 struct phone_profile *profile = obj;
304 const struct http_route *route1 = obj, *route2 = arg;
317 static int load_file(
const char *filename,
char **ret)
322 if (!(f = fopen(filename,
"r"))) {
327 fseek(f, 0, SEEK_END);
329 fseek(f, 0, SEEK_SET);
333 if (len != fread(*ret,
sizeof(
char), len, f)) {
363 ast_get_dst_info(&utc_time, &dstenable, &dststart, &dstend, &tzoffset, zone);
364 snprintf(buffer,
sizeof(buffer),
"%d", tzoffset);
375 when.tv_sec = dststart;
378 snprintf(buffer,
sizeof(buffer),
"%d", tm_info.
tm_mon+1);
382 snprintf(buffer,
sizeof(buffer),
"%d", tm_info.
tm_mday);
386 snprintf(buffer,
sizeof(buffer),
"%d", tm_info.
tm_hour);
390 when.tv_sec = dstend;
393 snprintf(buffer,
sizeof(buffer),
"%d", tm_info.
tm_mon + 1);
397 snprintf(buffer,
sizeof(buffer),
"%d", tm_info.
tm_mday);
401 snprintf(buffer,
sizeof(buffer),
"%d", tm_info.
tm_hour);
421 ast_http_error(ser, 501,
"Not Implemented",
"Attempt to use unimplemented / unsupported method");
433 fd = open(path, O_RDONLY);
438 len = lseek(fd, 0, SEEK_END);
439 lseek(fd, 0, SEEK_SET);
447 ast_str_set(&http_header, 0,
"Content-type: %s\r\n",
450 ast_http_send(ser, method, 200, NULL, http_header, NULL, fd, 0);
485 struct sockaddr_in sa_in;
487 socklen_t namelen =
sizeof(
name.sa);
490 if ((res = getsockname(ser->
fd, &
name.sa, &namelen))) {
494 struct extension *exten_iter;
511 ast_str_set(&http_header, 0,
"Content-type: %s\r\n",
524 ast_http_send(ser, method, 200, NULL, http_header, result, 0, 0);
535 ast_http_error(ser, 404,
"Not Found",
"Nothing to see here. Move along.");
540 ast_http_error(ser, 500,
"Internal Error",
"An internal error has occured.");
565 route->
file = pp_file;
578 struct phone_profile *profile;
599 for (; v; v = v->
next) {
600 if (!strcasecmp(v->
name,
"mime_type")) {
602 }
else if (!strcasecmp(v->
name,
"setvar")) {
622 }
else if (!strcasecmp(v->
name,
"staticdir")) {
626 char *file_extension;
639 if ((file_extension = strrchr(pp_file->
format,
'.')))
653 if (!strcasecmp(v->
name,
"static_file")) {
700 struct extension *
exten;
733 exten->
index = atoi(tmp);
758 static struct user *
unref_user(
struct user *user)
777 const struct user *user = obj;
782 static int users_cmp_fn(
void *obj,
void *arg,
int flags)
784 const struct user *user1 = obj, *user2 = arg;
792 struct user *user = obj;
793 struct extension *
exten;
821 static struct user *
build_user(
const char *mac,
struct phone_profile *profile)
868 struct extension *exten_iter;
873 }
else if (exten->
index == exten_iter->
index) {
928 if (!strcasecmp(v->
name,
"vmexten")) {
935 if (!strcasecmp(v->
name,
"localextenlength")) {
951 if (!strcasecmp(cat,
"general")) {
953 if (!strcasecmp(v->
name,
"serveraddr"))
955 else if (!strcasecmp(v->
name,
"serveriface")) {
959 }
else if (!strcasecmp(v->
name,
"serverport"))
961 else if (!strcasecmp(v->
name,
"default_profile"))
972 const char *tmp, *mac;
974 struct phone_profile *profile;
975 struct extension *
exten;
977 if (!strcasecmp(cat,
"general")) {
981 if (!strcasecmp(cat,
"authentication"))
994 ast_log(
LOG_WARNING,
"No profile for user [%s] with mac '%s' - skipping\n", cat, mac);
1071 struct phone_profile *profile;
1099 while ((tmp = strstr(
args.string,
"%{")))
1142 struct extension *
exten;
1143 char path[PATH_MAX];
1155 ast_log(
LOG_WARNING,
"PP_EACH_EXTENSION requries both a macaddress and template filename.\n");
1219 #define FORMAT "%-40.40s %-30.30s\n"
1225 e->
command =
"phoneprov show routes";
1227 "Usage: phoneprov show routes\n"
1228 " Lists all registered phoneprov http routes.\n";
1266 .description =
"Asterisk HTTP Phone Provisioning Tool",
const ast_string_field staticdir
static void route_destructor(void *obj)
struct phoneprov_file::@339 entry
static char exten[AST_MAX_EXTENSION]
Main Channel structure associated with a channel.
static char global_server[80]
#define AST_CLI_DEFINE(fn, txt,...)
static struct user * build_user(const char *mac, struct phone_profile *profile)
Build and return a user structure based on gathered config data.
Asterisk main include file. File version handling, generic pbx functions.
#define ao2_link(arg1, arg2)
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
static void build_profile(const char *name, struct ast_variable *v)
Build a phone profile and add it to the list of phone profiles.
static struct pp_variable_lookup pp_variable_list[]
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
String manipulation functions.
Asterisk version information.
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
struct ast_var_t * ast_var_assign(const char *name, const char *value)
#define ao2_iterator_next(arg1)
const ast_string_field format
descriptor for a cli entry.
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
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.
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).
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
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 users_hash_fn(const void *obj, const int flags)
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
const char *const template_var
static struct ao2_container * profiles
void ast_http_uri_unlink(struct ast_http_uri *urihandler)
Unregister a URI handler.
Configuration File Parser.
#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_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
struct ast_str * ast_str_create(size_t init_len)
Create a malloc'ed dynamic length string.
#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.
#define ast_mutex_lock(a)
static int routes_hash_fn(const void *obj, const int flags)
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags)
Create an iterator for a container.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
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.
struct phoneprov_file * file
structure to hold file data
void ast_cli(int fd, const char *fmt,...)
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
void ast_var_delete(struct ast_var_t *var)
static struct user * find_user(const char *macaddress)
Return a user looked up by name.
void ast_config_destroy(struct ast_config *config)
Destroys a config.
const ast_string_field default_mime_type
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom 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)
String fields in structures.
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, const int fd, unsigned int static_content)
Generic function for sending http/1.1 response.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Support for Private Asterisk HTTP Servers.
#define MAX_PROFILE_BUCKETS
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)
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)
static int unload_module(void)
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_config_load(filename, flags)
Load a config file.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Data structure associated with a custom dialplan function.
Access Control of various sorts.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
#define AST_STRING_FIELD(name)
Declare a string field.
char * ast_category_browse(struct ast_config *config, const char *prev)
Goes through categories.
#define ao2_ref(o, delta)
static int set_config(void)
static void profile_destructor(void *obj)
Lookup table to translate between users.conf property names and variables for use in phoneprov templa...
struct phone_profile * profile
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
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.
const char * ast_config_AST_DATA_DIR
#define AST_LIST_HEAD_NOLOCK(name, type)
Defines a structure to be used to hold a list of specified type (with no lock).
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.
#define ast_strdupa(s)
duplicate a string in memory from the stack
static int profile_hash_fn(const void *obj, const int flags)
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
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 users_cmp_fn(void *obj, void *arg, int flags)
static int pp_each_user_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
static int routes_cmp_fn(void *obj, void *arg, int flags)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static struct http_route * unref_route(struct http_route *route)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
static struct ast_cli_entry pp_cli[]
#define ao2_alloc(data_size, destructor_fn)
static 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.
#define ao2_find(arg1, arg2, arg3)
struct ast_var_t::@158 entries
const char * ast_inet_ntoa(struct in_addr ia)
thread-safe replacement for inet_ntoa().
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 struct extension * build_extension(struct ast_config *cfg, const char *name)
static void user_destructor(void *obj)
Free all memory associated with a user.
static struct ast_custom_function pp_each_extension_function
structure to hold users read from users.conf
void ao2_iterator_destroy(struct ao2_iterator *i)
Destroy a container iterator.
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Structure used to handle boolean flags.
static int profile_cmp_fn(void *obj, void *arg, int flags)
#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.
static char global_default_profile[80]
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
#define ao2_container_alloc(arg1, arg2, arg3)
const char *const user_var
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
static struct ao2_container * http_routes
static struct extension * delete_extension(struct extension *exten)
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition of a URI handler.
#define MAX_ROUTE_BUCKETS
static struct ast_http_uri phoneprovuri
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
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.
Options provided by main asterisk program.
struct phone_profile::@340 static_files
#define AST_APP_ARG(name)
Define an application argument.
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
struct ast_variable * next
#define ast_mutex_init(pmutex)
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define CONFIG_STATUS_FILEINVALID
ast_http_method
HTTP Request methods known by Asterisk.
#define ast_mutex_destroy(a)
#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_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
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 void build_route(struct phoneprov_file *pp_file, struct user *user, char *uri)
Build a route structure and add it to the list of available http routes.
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.
Asterisk module definitions.
struct phone_profile::@341 dynamic_files
static void delete_file(struct phoneprov_file *file)
static struct phone_profile * find_profile(const char *name)
Return a phone profile looked up by name.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
static ast_mutex_t globals_lock
static struct varshead global_variables
List of global variables currently available: VOICEMAIL_EXTEN struct ast_string_field_mgr __field_mgr...
#define ao2_unlink(arg1, arg2)
#define ast_custom_function_register(acf)
Register a custom function.
struct user::@343 extensions
Structure for mutex and tracking information.
static force_inline int attribute_pure ast_str_case_hash(const char *str)
Compute a hash value on a case-insensitive string.
static struct in_addr __ourip
for use in lookup_iface
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
#define ast_mutex_unlock(a)
static int pp_each_extension_read2(struct ast_channel *chan, const char *cmd, char *data, struct ast_str **buf, ssize_t len)
static char global_serverport[6]
const ast_string_field mime_type
#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.