mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-22 20:56:39 +00:00
AST-2022-002 - res_stir_shaken/curl: Add ACL checks for Identity header.
Adds a new configuration option, stir_shaken_profile, in pjsip.conf that can be specified on a per endpoint basis. This option will reference a stir_shaken_profile that can be configured in stir_shaken.conf. The type of this option must be 'profile'. The stir_shaken option can be specified on this object with the same values as before (attest, verify, on), but it cannot be off since having the profile itself implies wanting STIR/SHAKEN support. You can also specify an ACL from acl.conf (along with permit and deny lines in the object itself) that will be used to limit what interfaces Asterisk will attempt to retrieve information from when reading the Identity header. ASTERISK-29476 Change-Id: I87fa61f78a9ea0cd42530691a30da3c781842406
This commit is contained in:
@@ -21,9 +21,12 @@
|
||||
#include "asterisk/utils.h"
|
||||
#include "asterisk/logger.h"
|
||||
#include "asterisk/file.h"
|
||||
#include "asterisk/acl.h"
|
||||
|
||||
#include "curl.h"
|
||||
#include "general.h"
|
||||
#include "stir_shaken.h"
|
||||
#include "profile.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <sys/stat.h>
|
||||
@@ -52,6 +55,11 @@ struct curl_cb_write_buf {
|
||||
const char *url;
|
||||
};
|
||||
|
||||
struct curl_cb_open_socket {
|
||||
const struct ast_acl_list *acl;
|
||||
curl_socket_t *sockfd;
|
||||
};
|
||||
|
||||
struct curl_cb_data *curl_cb_data_create(void)
|
||||
{
|
||||
struct curl_cb_data *data;
|
||||
@@ -73,6 +81,18 @@ void curl_cb_data_free(struct curl_cb_data *data)
|
||||
ast_free(data);
|
||||
}
|
||||
|
||||
static void curl_cb_open_socket_free(struct curl_cb_open_socket *data)
|
||||
{
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
|
||||
close(*data->sockfd);
|
||||
|
||||
/* We don't need to free the ACL since we just use a reference */
|
||||
ast_free(data);
|
||||
}
|
||||
|
||||
char *curl_cb_data_get_cache_control(const struct curl_cb_data *data)
|
||||
{
|
||||
if (!data) {
|
||||
@@ -200,7 +220,26 @@ static size_t curl_write_cb(void *curl_data, size_t size, size_t actual_size, vo
|
||||
return real_size;
|
||||
}
|
||||
|
||||
char *curl_public_key(const char *public_cert_url, const char *path, struct curl_cb_data *data)
|
||||
static curl_socket_t stir_shaken_curl_open_socket_callback(void *our_data, curlsocktype purpose, struct curl_sockaddr *address)
|
||||
{
|
||||
struct curl_cb_open_socket *data = our_data;
|
||||
|
||||
if (!ast_acl_list_is_empty((struct ast_acl_list *)data->acl)) {
|
||||
struct ast_sockaddr ast_address = { {0,} };
|
||||
|
||||
ast_sockaddr_copy_sockaddr(&ast_address, &address->addr, address->addrlen);
|
||||
|
||||
if (ast_apply_acl((struct ast_acl_list *)data->acl, &ast_address, NULL) != AST_SENSE_ALLOW) {
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
}
|
||||
|
||||
*data->sockfd = socket(address->family, address->socktype, address->protocol);
|
||||
|
||||
return *data->sockfd;
|
||||
}
|
||||
|
||||
char *curl_public_key(const char *public_cert_url, const char *path, struct curl_cb_data *data, const struct ast_acl_list *acl)
|
||||
{
|
||||
FILE *public_key_file;
|
||||
char *filename;
|
||||
@@ -209,13 +248,25 @@ char *curl_public_key(const char *public_cert_url, const char *path, struct curl
|
||||
CURL *curl;
|
||||
char curl_errbuf[CURL_ERROR_SIZE + 1];
|
||||
struct curl_cb_write_buf *buf;
|
||||
struct curl_cb_open_socket *open_socket_data;
|
||||
curl_socket_t sockfd;
|
||||
|
||||
buf = ast_calloc(1, sizeof(*buf));
|
||||
curl_errbuf[CURL_ERROR_SIZE] = '\0';
|
||||
|
||||
buf = ast_calloc(1, sizeof(*buf));
|
||||
if (!buf) {
|
||||
ast_log(LOG_ERROR, "Failed to allocate memory for CURL write buffer for %s\n", public_cert_url);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
open_socket_data = ast_calloc(1, sizeof(*open_socket_data));
|
||||
if (!open_socket_data) {
|
||||
ast_log(LOG_ERROR, "Failed to allocate memory for open socket callback\n");
|
||||
return NULL;
|
||||
}
|
||||
open_socket_data->acl = acl;
|
||||
open_socket_data->sockfd = &sockfd;
|
||||
|
||||
buf->url = public_cert_url;
|
||||
curl_errbuf[CURL_ERROR_SIZE] = '\0';
|
||||
|
||||
@@ -231,14 +282,19 @@ char *curl_public_key(const char *public_cert_url, const char *path, struct curl
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, buf);
|
||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf);
|
||||
curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, MAX_BUF_SIZE_PER_WRITE);
|
||||
curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, stir_shaken_curl_open_socket_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, open_socket_data);
|
||||
|
||||
if (curl_easy_perform(curl)) {
|
||||
ast_log(LOG_ERROR, "%s\n", curl_errbuf);
|
||||
curl_easy_cleanup(curl);
|
||||
ast_free(buf);
|
||||
curl_cb_open_socket_free(open_socket_data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
curl_cb_open_socket_free(open_socket_data);
|
||||
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
|
Reference in New Issue
Block a user