static int localnet_to_vl(const void *obj, struct ast_variable **fields) { const struct ast_sip_transport *transport = obj; char str[MAX_OBJECT_FIELD]; struct ast_variable *head = NULL; struct ast_ha *ha; RAII_VAR(struct ast_sip_transport_state *, state, find_state_by_transport(transport), ao2_cleanup); if (!state) { return -1; } for (ha = state->localnet; ha; ha = ha->next) { const char *addr = ast_strdupa(ast_sockaddr_stringify_addr(&ha->addr)); snprintf(str, MAX_OBJECT_FIELD, "%s%s/%s", ha->sense == AST_SENSE_ALLOW ? "!" : "", addr, ast_sockaddr_stringify_addr(&ha->netmask)); ast_variable_list_append(&head, ast_variable_new("local_net", str, "")); } if (head) { *fields = head; } return 0; }
int ast_json_to_ast_variables(struct ast_json *json_variables, struct ast_variable **variables) { struct ast_json_iter *it_json_var; *variables = NULL; for (it_json_var = ast_json_object_iter(json_variables); it_json_var; it_json_var = ast_json_object_iter_next(json_variables, it_json_var)) { struct ast_variable *new_var; const char *key = ast_json_object_iter_key(it_json_var); if (ast_strlen_zero(key)) { continue; } new_var = ast_variable_new(key, ast_json_string_get(ast_json_object_iter_value(it_json_var)), ""); if (!new_var) { ast_variables_destroy(*variables); *variables = NULL; return -1; } ast_variable_list_append(variables, new_var); } return 0; }
static int contact_to_var_list(void *object, void *arg, int flags) { struct ast_sip_contact_wrapper *wrapper = object; struct ast_variable **var = arg; ast_variable_list_append(&*var, ast_variable_new("contact", wrapper->contact->uri, "")); return 0; }
/*! * \brief Verifies a user event header/value pair * * \param user_event which user event to check * \param header The header to verify * \param value The value read from the event * * \retval -1 on error or evaluation failure * \retval 0 if match not needed or success */ static int verify_user_event_fields(int user_event, const char *header, const char *value) { struct ast_variable *current; struct ast_variable *expected; regex_t regexbuf; int error; if (user_event >= AST_VECTOR_SIZE(&expected_user_event_fields)) { return -1; } expected = AST_VECTOR_GET(&expected_user_event_fields, user_event); if (!expected) { return -1; } for (current = expected; current; current = current->next) { struct ast_variable *bad_header; if (strcmp(current->name, header)) { continue; } error = regcomp(®exbuf, current->value, REG_EXTENDED | REG_NOSUB); if (error) { char error_buf[128]; regerror(error, ®exbuf, error_buf, sizeof(error_buf)); ast_log(LOG_ERROR, "Failed to compile regex '%s' for header check '%s': %s\n", current->value, current->name, error_buf); return -1; } if (!regexec(®exbuf, value, 0, NULL, 0)) { regfree(®exbuf); return 0; } bad_header = ast_variable_new(header, value, __FILE__); if (bad_header) { struct ast_variable *bad_headers_head = NULL; if (user_event < AST_VECTOR_SIZE(&bad_headers)) { bad_headers_head = AST_VECTOR_GET(&bad_headers, user_event); } ast_variable_list_append(&bad_headers_head, bad_header); AST_VECTOR_INSERT(&bad_headers, user_event, bad_headers_head); } regfree(®exbuf); return -1; } return 0; }
enum ast_json_to_ast_vars_code ast_json_to_ast_variables(struct ast_json *json_variables, struct ast_variable **variables) { struct ast_json_iter *it_json_var; *variables = NULL; for (it_json_var = ast_json_object_iter(json_variables); it_json_var; it_json_var = ast_json_object_iter_next(json_variables, it_json_var)) { struct ast_variable *new_var; const char *key = ast_json_object_iter_key(it_json_var); const char *value; struct ast_json *json_value; if (ast_strlen_zero(key)) { continue; } json_value = ast_json_object_iter_value(it_json_var); if (ast_json_typeof(json_value) != AST_JSON_STRING) { /* Error: Only strings allowed */ ast_variables_destroy(*variables); *variables = NULL; return AST_JSON_TO_AST_VARS_CODE_INVALID_TYPE; } value = ast_json_string_get(json_value); /* Should never be NULL. Otherwise, how could it be a string type? */ ast_assert(value != NULL); if (!value) { /* To be safe. */ continue; } new_var = ast_variable_new(key, value, ""); if (!new_var) { /* Error: OOM */ ast_variables_destroy(*variables); *variables = NULL; return AST_JSON_TO_AST_VARS_CODE_OOM; } ast_variable_list_append(variables, new_var); } return AST_JSON_TO_AST_VARS_CODE_SUCCESS; }
void ast_ari_asterisk_update_object(struct ast_variable *headers, struct ast_ari_asterisk_update_object_args *args, struct ast_ari_response *response) { RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref); RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup); RAII_VAR(void *, sorcery_obj, NULL, ao2_cleanup); struct ast_json *fields; struct ast_variable *update_set = NULL; int created = 0; sorcery = ast_sorcery_retrieve_by_module_name(args->config_class); if (!sorcery) { ast_ari_response_error( response, 404, "Not Found", "configClass '%s' not found", args->config_class); return; } object_type = ast_sorcery_get_object_type(sorcery, args->object_type); if (!object_type) { ast_ari_response_error( response, 404, "Not Found", "objectType '%s' not found", args->object_type); return; } sorcery_obj = ast_sorcery_retrieve_by_id(sorcery, args->object_type, args->id); if (!sorcery_obj) { ast_debug(5, "Sorcery object '%s' does not exist; creating it\n", args->id); sorcery_obj = ast_sorcery_alloc(sorcery, args->object_type, args->id); if (!sorcery_obj) { ast_ari_response_alloc_failed(response); return; } created = 1; } else { void *copy; copy = ast_sorcery_copy(sorcery, sorcery_obj); if (!copy) { ast_ari_response_alloc_failed(response); return; } ao2_ref(sorcery_obj, -1); sorcery_obj = copy; } fields = ast_json_object_get(args->fields, "fields"); if (!fields && !created) { /* Whoops. We need data. */ ast_ari_response_error( response, 400, "Bad request", "Fields must be provided to update object '%s'", args->id); return; } else if (fields) { size_t i; for (i = 0; i < ast_json_array_size(fields); i++) { struct ast_variable *new_var; struct ast_json *json_value = ast_json_array_get(fields, i); if (!json_value) { continue; } new_var = ast_variable_new( ast_json_string_get(ast_json_object_get(json_value, "attribute")), ast_json_string_get(ast_json_object_get(json_value, "value")), ""); if (!new_var) { ast_variables_destroy(update_set); ast_ari_response_alloc_failed(response); return; } ast_variable_list_append(&update_set, new_var); } } /* APPLY! Note that a NULL update_set is fine (and necessary), as it * will force validation on a newly created object. */ if (ast_sorcery_objectset_apply(sorcery, sorcery_obj, update_set)) { ast_variables_destroy(update_set); ast_ari_response_error( response, 400, "Bad request", "%s of object '%s' failed field value validation", created ? "Creation" : "Update", args->id); return; } ast_variables_destroy(update_set); if (created) { if (ast_sorcery_create(sorcery, sorcery_obj)) { ast_ari_response_error( response, 403, "Forbidden", "Cannot create sorcery objects of type '%s'", args->object_type); return; } } else { if (ast_sorcery_update(sorcery, sorcery_obj)) { ast_ari_response_error( response, 403, "Forbidden", "Cannot update sorcery objects of type '%s'", args->object_type); return; } } return_sorcery_object(sorcery, sorcery_obj, response); }