If no resources exist or all are unavailable the device state is considered
to be unavailable.
+Security Events Framework
+-------------------------
+ * Security Event timestamps now use ISO 8601 formatted date/time instead of the
+ "seconds-microseconds" format that it was using previously.
+
Sorcery
------------------
* All future modules which utilize Sorcery for object persistence must have a
#include "asterisk/test.h"
#include "asterisk/data.h"
#include "asterisk/netsock2.h"
+#include "asterisk/security_events.h"
#include "iax2/include/iax2.h"
#include "iax2/include/firmware.h"
static void acl_change_stasis_subscribe(void)
{
if (!acl_change_sub) {
- acl_change_sub = stasis_subscribe(ast_acl_topic(),
+ acl_change_sub = stasis_subscribe(ast_security_topic(),
acl_change_stasis_cb, NULL);
}
}
static int default_maxcallbitrate; /*!< Maximum bitrate for call */
static struct ast_codec_pref default_prefs; /*!< Default codec prefs */
static char default_zone[MAX_TONEZONE_COUNTRY]; /*!< Default tone zone for channels created from the SIP driver */
-static unsigned int default_transports; /*!< Default Transports (enum sip_transport) that are acceptable */
-static unsigned int default_primary_transport; /*!< Default primary Transport (enum sip_transport) for outbound connections to devices */
+static unsigned int default_transports; /*!< Default Transports (enum ast_transport) that are acceptable */
+static unsigned int default_primary_transport; /*!< Default primary Transport (enum ast_transport) for outbound connections to devices */
static struct sip_settings sip_cfg; /*!< SIP configuration data.
\note in the future we could have multiple of these (per domain, per device group etc) */
static const char *sip_get_callid(struct ast_channel *chan);
static int handle_request_do(struct sip_request *req, struct ast_sockaddr *addr);
-static int sip_standard_port(enum sip_transport type, int port);
+static int sip_standard_port(enum ast_transport type, int port);
static int sip_prepare_socket(struct sip_pvt *p);
static int get_address_family_filter(unsigned int transport);
sip_get_transport(tmpl->socket.type), peer->name, get_transport_list(peer->transports) \
); \
ret = 1; \
- } else if (peer->socket.type & SIP_TRANSPORT_TLS) { \
+ } else if (peer->socket.type & AST_TRANSPORT_TLS) { \
ast_log(LOG_WARNING, \
"peer '%s' HAS NOT USED (OR SWITCHED TO) TLS in favor of '%s' (but this was allowed in sip.conf)!\n", \
peer->name, sip_get_transport(tmpl->socket.type) \
}
ao2_t_ref(tcptls_session, +1, "tcptls_session ref for sip_threadinfo object");
th->tcptls_session = tcptls_session;
- th->type = transport ? transport : (tcptls_session->ssl ? SIP_TRANSPORT_TLS: SIP_TRANSPORT_TCP);
+ th->type = transport ? transport : (tcptls_session->ssl ? AST_TRANSPORT_TLS: AST_TRANSPORT_TCP);
ao2_t_link(threadt, th, "Adding new tcptls helper thread");
ao2_t_ref(th, -1, "Decrementing threadinfo ref from alloc, only table ref remains");
return th;
}
req.socket.fd = ast_websocket_fd(session);
- set_socket_transport(&req.socket, ast_websocket_is_secure(session) ? SIP_TRANSPORT_WSS : SIP_TRANSPORT_WS);
+ set_socket_transport(&req.socket, ast_websocket_is_secure(session) ? AST_TRANSPORT_WSS : AST_TRANSPORT_WS);
req.socket.ws_session = session;
handle_request_do(&req, ast_websocket_remote_address(session));
goto cleanup;
}
- if (!(me = sip_threadinfo_create(tcptls_session, tcptls_session->ssl ? SIP_TRANSPORT_TLS : SIP_TRANSPORT_TCP))) {
+ if (!(me = sip_threadinfo_create(tcptls_session, tcptls_session->ssl ? AST_TRANSPORT_TLS : AST_TRANSPORT_TCP))) {
goto cleanup;
}
ao2_t_ref(me, +1, "Adding threadinfo ref for tcp_helper_thread");
memset(buf, 0, sizeof(buf));
if (tcptls_session->ssl) {
- set_socket_transport(&req.socket, SIP_TRANSPORT_TLS);
+ set_socket_transport(&req.socket, AST_TRANSPORT_TLS);
req.socket.port = htons(ourport_tls);
} else {
- set_socket_transport(&req.socket, SIP_TRANSPORT_TCP);
+ set_socket_transport(&req.socket, AST_TRANSPORT_TCP);
req.socket.port = htons(ourport_tcp);
}
req.socket.fd = tcptls_session->fd;
if (!ast_sockaddr_parse(&proxy->ip, proxy->name, 0)) {
/* Ok, not an IP address, then let's check if it's a domain or host */
/* XXX Todo - if we have proxy port, don't do SRV */
- proxy->ip.ss.ss_family = get_address_family_filter(SIP_TRANSPORT_UDP); /* Filter address family */
+ proxy->ip.ss.ss_family = get_address_family_filter(AST_TRANSPORT_UDP); /* Filter address family */
if (ast_get_ip_or_srv(&proxy->ip, proxy->name, sip_cfg.srvlookup ? "_sip._udp" : NULL) < 0) {
ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name);
return FALSE;
}
if (!strcasecmp(transport, "udp")) {
- res |= SIP_TRANSPORT_UDP;
+ res |= AST_TRANSPORT_UDP;
}
if (!strcasecmp(transport, "tcp")) {
- res |= SIP_TRANSPORT_TCP;
+ res |= AST_TRANSPORT_TCP;
}
if (!strcasecmp(transport, "tls")) {
- res |= SIP_TRANSPORT_TLS;
+ res |= AST_TRANSPORT_TLS;
}
if (!strcasecmp(transport, "ws")) {
- res |= SIP_TRANSPORT_WS;
+ res |= AST_TRANSPORT_WS;
}
if (!strcasecmp(transport, "wss")) {
- res |= SIP_TRANSPORT_WSS;
+ res |= AST_TRANSPORT_WSS;
}
return res;
memset(buf, 0, SIP_TRANSPORT_STR_BUFSIZE);
- if (transports & SIP_TRANSPORT_UDP) {
+ if (transports & AST_TRANSPORT_UDP) {
strncat(buf, "UDP,", SIP_TRANSPORT_STR_BUFSIZE - strlen(buf));
}
- if (transports & SIP_TRANSPORT_TCP) {
+ if (transports & AST_TRANSPORT_TCP) {
strncat(buf, "TCP,", SIP_TRANSPORT_STR_BUFSIZE - strlen(buf));
}
- if (transports & SIP_TRANSPORT_TLS) {
+ if (transports & AST_TRANSPORT_TLS) {
strncat(buf, "TLS,", SIP_TRANSPORT_STR_BUFSIZE - strlen(buf));
}
- if (transports & SIP_TRANSPORT_WS) {
+ if (transports & AST_TRANSPORT_WS) {
strncat(buf, "WS,", SIP_TRANSPORT_STR_BUFSIZE - strlen(buf));
}
- if (transports & SIP_TRANSPORT_WSS) {
+ if (transports & AST_TRANSPORT_WSS) {
strncat(buf, "WSS,", SIP_TRANSPORT_STR_BUFSIZE - strlen(buf));
}
}
/*! \brief Return transport as string */
-const char *sip_get_transport(enum sip_transport t)
+const char *sip_get_transport(enum ast_transport t)
{
switch (t) {
- case SIP_TRANSPORT_UDP:
+ case AST_TRANSPORT_UDP:
return "UDP";
- case SIP_TRANSPORT_TCP:
+ case AST_TRANSPORT_TCP:
return "TCP";
- case SIP_TRANSPORT_TLS:
+ case AST_TRANSPORT_TLS:
return "TLS";
- case SIP_TRANSPORT_WS:
- case SIP_TRANSPORT_WSS:
+ case AST_TRANSPORT_WS:
+ case AST_TRANSPORT_WSS:
return "WS";
}
}
/*! \brief Return protocol string for srv dns query */
-static inline const char *get_srv_protocol(enum sip_transport t)
+static inline const char *get_srv_protocol(enum ast_transport t)
{
switch (t) {
- case SIP_TRANSPORT_UDP:
+ case AST_TRANSPORT_UDP:
return "udp";
- case SIP_TRANSPORT_WS:
+ case AST_TRANSPORT_WS:
return "ws";
- case SIP_TRANSPORT_TLS:
- case SIP_TRANSPORT_TCP:
+ case AST_TRANSPORT_TLS:
+ case AST_TRANSPORT_TCP:
return "tcp";
- case SIP_TRANSPORT_WSS:
+ case AST_TRANSPORT_WSS:
return "wss";
}
}
/*! \brief Return service string for srv dns query */
-static inline const char *get_srv_service(enum sip_transport t)
+static inline const char *get_srv_service(enum ast_transport t)
{
switch (t) {
- case SIP_TRANSPORT_TCP:
- case SIP_TRANSPORT_UDP:
- case SIP_TRANSPORT_WS:
+ case AST_TRANSPORT_TCP:
+ case AST_TRANSPORT_UDP:
+ case AST_TRANSPORT_WS:
return "sip";
- case SIP_TRANSPORT_TLS:
- case SIP_TRANSPORT_WSS:
+ case AST_TRANSPORT_TLS:
+ case AST_TRANSPORT_WSS:
return "sips";
}
return "sip";
return XMIT_ERROR;
}
- if (p->socket.type == SIP_TRANSPORT_UDP) {
+ if (p->socket.type == AST_TRANSPORT_UDP) {
res = ast_sendto(p->socket.fd, ast_str_buffer(data), ast_str_strlen(data), 0, dst);
} else if (p->socket.tcptls_session) {
res = sip_tcptls_write(p->socket.tcptls_session, ast_str_buffer(data), ast_str_strlen(data));
if (!ast_sockaddr_isnull(&externaddr)) {
ast_sockaddr_copy(us, &externaddr);
switch (p->socket.type) {
- case SIP_TRANSPORT_TCP:
+ case AST_TRANSPORT_TCP:
if (!externtcpport && ast_sockaddr_port(&externaddr)) {
/* for consistency, default to the externaddr port */
externtcpport = ast_sockaddr_port(&externaddr);
}
ast_sockaddr_set_port(us, externtcpport);
break;
- case SIP_TRANSPORT_TLS:
+ case AST_TRANSPORT_TLS:
ast_sockaddr_set_port(us, externtlsport);
break;
- case SIP_TRANSPORT_UDP:
+ case AST_TRANSPORT_UDP:
if (!ast_sockaddr_port(&externaddr)) {
ast_sockaddr_set_port(us, ast_sockaddr_port(&bindaddr));
}
} else {
/* no remapping, but we bind to a specific address, so use it. */
switch (p->socket.type) {
- case SIP_TRANSPORT_TCP:
+ case AST_TRANSPORT_TCP:
if (!ast_sockaddr_is_any(&sip_tcp_desc.local_address)) {
ast_sockaddr_copy(us,
&sip_tcp_desc.local_address);
ast_sockaddr_port(&sip_tcp_desc.local_address));
}
break;
- case SIP_TRANSPORT_TLS:
+ case AST_TRANSPORT_TLS:
if (!ast_sockaddr_is_any(&sip_tls_desc.local_address)) {
ast_sockaddr_copy(us,
&sip_tls_desc.local_address);
ast_sockaddr_port(&sip_tls_desc.local_address));
}
break;
- case SIP_TRANSPORT_UDP:
+ case AST_TRANSPORT_UDP:
/* fall through on purpose */
default:
if (!ast_sockaddr_is_any(&bindaddr)) {
}
}
}
- ast_debug(3, "Setting SIP_TRANSPORT_%s with address %s\n", sip_get_transport(p->socket.type), ast_sockaddr_stringify(us));
+ ast_debug(3, "Setting AST_TRANSPORT_%s with address %s\n", sip_get_transport(p->socket.type), ast_sockaddr_stringify(us));
}
/*! \brief Append to SIP dialog history with arg list */
/* If the transport is something reliable (TCP or TLS) then don't really send this reliably */
/* I removed the code from retrans_pkt that does the same thing so it doesn't get loaded into the scheduler */
/*! \todo According to the RFC some packets need to be retransmitted even if its TCP, so this needs to get revisited */
- if (!(p->socket.type & SIP_TRANSPORT_UDP)) {
+ if (!(p->socket.type & AST_TRANSPORT_UDP)) {
xmitres = __sip_xmit(p, data); /* Send packet */
if (xmitres == XMIT_ERROR) { /* Serious network trouble, no need to try again */
append_history(p, "XmitErr", "%s", fatal ? "(Critical)" : "(Non-critical)");
if (ast_sockaddr_resolve(&addrs,
tmp->value,
PARSE_PORT_FORBID,
- get_address_family_filter(SIP_TRANSPORT_UDP)) <= 0 ||
+ get_address_family_filter(AST_TRANSPORT_UDP)) <= 0 ||
ast_sockaddr_cmp(&addrs[0], addr)) {
/* No match */
ast_variables_destroy(*var);
copy_route(&dialog->route, peer->path);
if (dialog->route) {
/* Parse SIP URI of first route-set hop and use it as target address */
- __set_address_from_contact(dialog->route->hop, &dialog->sa, dialog->socket.type == SIP_TRANSPORT_TLS ? 1 : 0);
+ __set_address_from_contact(dialog->route->hop, &dialog->sa, dialog->socket.type == AST_TRANSPORT_TLS ? 1 : 0);
}
if (dialog_initialize_rtp(dialog)) {
}
/*! \brief The default sip port for the given transport */
-static inline int default_sip_port(enum sip_transport type)
+static inline int default_sip_port(enum ast_transport type)
{
- return type == SIP_TRANSPORT_TLS ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
+ return type == AST_TRANSPORT_TLS ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
}
/*! \brief create address structure from device name
}
}
- if (ast_sockaddr_resolve_first_transport(&dialog->sa, hostn, 0, dialog->socket.type ? dialog->socket.type : SIP_TRANSPORT_UDP)) {
+ if (ast_sockaddr_resolve_first_transport(&dialog->sa, hostn, 0, dialog->socket.type ? dialog->socket.type : AST_TRANSPORT_UDP)) {
ast_log(LOG_WARNING, "No such host: %s\n", peername);
return -1;
}
}
if (!dialog->socket.type)
- set_socket_transport(&dialog->socket, SIP_TRANSPORT_UDP);
+ set_socket_transport(&dialog->socket, AST_TRANSPORT_UDP);
if (!dialog->socket.port) {
dialog->socket.port = htons(ast_sockaddr_port(&bindaddr));
}
}
/* Check to see if we should try to force encryption */
- if (p->req_secure_signaling && p->socket.type != SIP_TRANSPORT_TLS) {
+ if (p->req_secure_signaling && p->socket.type != AST_TRANSPORT_TLS) {
ast_log(LOG_WARNING, "Encrypted signaling is required\n");
ast_channel_hangupcause_set(ast, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
return -1;
static char *generate_uri(struct sip_pvt *pvt, char *buf, size_t size)
{
struct ast_str *uri = ast_str_alloca(size);
- ast_str_set(&uri, 0, "%s", pvt->socket.type == SIP_TRANSPORT_TLS ? "sips:" : "sip:");
+ ast_str_set(&uri, 0, "%s", pvt->socket.type == AST_TRANSPORT_TLS ? "sips:" : "sip:");
/* Here would be a great place to generate a UUID, but for now we'll
* use the handy random string generation function we already have
*/
/* Later in ast_sip_ouraddrfor we need this to choose the right ip and port for the specific transport */
set_socket_transport(&p->socket, req->socket.type);
} else {
- set_socket_transport(&p->socket, SIP_TRANSPORT_UDP);
+ set_socket_transport(&p->socket, AST_TRANSPORT_UDP);
}
p->socket.fd = -1;
{
struct sip_subscription_mwi *mwi;
int portnum = 0;
- enum sip_transport transport = SIP_TRANSPORT_UDP;
+ enum ast_transport transport = AST_TRANSPORT_UDP;
char buf[256] = "";
char *username = NULL, *hostname = NULL, *secret = NULL, *authuser = NULL, *porta = NULL, *mailbox = NULL;
if (p->route &&
!(sipmethod == SIP_CANCEL ||
(sipmethod == SIP_ACK && (p->invitestate == INV_COMPLETED || p->invitestate == INV_CANCELLED)))) {
- if (p->socket.type != SIP_TRANSPORT_UDP && p->socket.tcptls_session) {
+ if (p->socket.type != AST_TRANSPORT_UDP && p->socket.tcptls_session) {
/* For TCP/TLS sockets that are connected we won't need
* to do any hostname/IP lookups */
} else if (ast_test_flag(&p->flags[0], SIP_NAT_FORCE_RPORT)) {
char tmp[SIPBUFSIZE];
char *user = ast_uri_encode(p->exten, tmp, sizeof(tmp), ast_uri_sip_user);
- if (p->socket.type == SIP_TRANSPORT_UDP) {
+ if (p->socket.type == AST_TRANSPORT_UDP) {
ast_string_field_build(p, our_contact, "<sip:%s%s%s>", user,
ast_strlen_zero(user) ? "" : "@", ast_sockaddr_stringify_remote(&p->ourip));
} else {
domain = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip));
if (!sip_standard_port(p->socket.type, ourport)) {
- if (p->socket.type == SIP_TRANSPORT_UDP) {
+ if (p->socket.type == AST_TRANSPORT_UDP) {
ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d\r\n", exten, domain, ourport);
} else {
ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d;transport=%s\r\n", exten, domain, ourport, sip_get_transport(p->socket.type));
}
} else {
- if (p->socket.type == SIP_TRANSPORT_UDP) {
+ if (p->socket.type == AST_TRANSPORT_UDP) {
ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, domain);
} else {
ast_str_append(&out, 0, "Message-Account: sip:%s@%s;transport=%s\r\n", exten, domain, sip_get_transport(p->socket.type));
/* Set transport and port so the correct contact is built */
set_socket_transport(&p->socket, r->transport);
- if (r->transport == SIP_TRANSPORT_TLS || r->transport == SIP_TRANSPORT_TCP) {
+ if (r->transport == AST_TRANSPORT_TLS || r->transport == AST_TRANSPORT_TCP) {
p->socket.port =
htons(ast_sockaddr_port(&sip_tcp_desc.local_address));
}
if (!ast_sockaddr_port(addr)) {
ast_sockaddr_set_port(addr,
(get_transport_str2enum(transport) ==
- SIP_TRANSPORT_TLS ||
+ AST_TRANSPORT_TLS ||
!strncasecmp(fullcontact, "sips", 4)) ?
STANDARD_TLS_PORT : STANDARD_SIP_PORT);
}
return 0;
}
- return __set_address_from_contact(pvt->fullcontact, &pvt->sa, pvt->socket.type == SIP_TRANSPORT_TLS ? 1 : 0);
+ return __set_address_from_contact(pvt->fullcontact, &pvt->sa, pvt->socket.type == AST_TRANSPORT_TLS ? 1 : 0);
}
/*! \brief Parse contact header and save registration (peer registration) */
ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
}
- if ((transport_type != SIP_TRANSPORT_WS) && (transport_type != SIP_TRANSPORT_WSS) &&
+ if ((transport_type != AST_TRANSPORT_WS) && (transport_type != AST_TRANSPORT_WSS) &&
(!ast_test_flag(&peer->flags[0], SIP_NAT_FORCE_RPORT) && !ast_test_flag(&peer->flags[0], SIP_NAT_RPORT_PRESENT))) {
/* use the data provided in the Contact header for call routing */
ast_debug(1, "Store REGISTER's Contact header for call routing.\n");
static void acl_change_stasis_subscribe(void)
{
if (!acl_change_sub) {
- acl_change_sub = stasis_subscribe(ast_acl_topic(),
+ acl_change_sub = stasis_subscribe(ast_security_topic(),
acl_change_stasis_cb, NULL);
}
struct sip_auth_container *credentials;
if (!ast_strlen_zero(p->domain))
- snprintf(uri, sizeof(uri), "%s:%s", p->socket.type == SIP_TRANSPORT_TLS ? "sips" : "sip", p->domain);
+ snprintf(uri, sizeof(uri), "%s:%s", p->socket.type == AST_TRANSPORT_TLS ? "sips" : "sip", p->domain);
else if (!ast_strlen_zero(p->uri))
ast_copy_string(uri, p->uri, sizeof(uri));
else
- snprintf(uri, sizeof(uri), "%s:%s@%s", p->socket.type == SIP_TRANSPORT_TLS ? "sips" : "sip", p->username, ast_sockaddr_stringify_host_remote(&p->sa));
+ snprintf(uri, sizeof(uri), "%s:%s@%s", p->socket.type == AST_TRANSPORT_TLS ? "sips" : "sip", p->username, ast_sockaddr_stringify_host_remote(&p->sa));
snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
char *contact_number = NULL;
char *separator, *trans;
char *domain;
- enum sip_transport transport = SIP_TRANSPORT_UDP;
+ enum ast_transport transport = AST_TRANSPORT_UDP;
ast_copy_string(contact, sip_get_header(req, "Contact"), sizeof(contact));
if ((separator = strchr(contact, ',')))
*separator = '\0';
if (!strncasecmp(trans, "tcp", 3))
- transport = SIP_TRANSPORT_TCP;
+ transport = AST_TRANSPORT_TCP;
else if (!strncasecmp(trans, "tls", 3))
- transport = SIP_TRANSPORT_TLS;
+ transport = AST_TRANSPORT_TLS;
else {
if (strncasecmp(trans, "udp", 3))
ast_debug(1, "received contact with an invalid transport, '%s'\n", contact_number);
/* This will assume UDP for all unknown transports */
- transport = SIP_TRANSPORT_UDP;
+ transport = AST_TRANSPORT_UDP;
}
}
contact_number = remove_uri_parameters(contact_number);
ast_channel_hangupcause_set(owner, hangup_sip2cause(resp));
}
- if (p->socket.type == SIP_TRANSPORT_UDP) {
+ if (p->socket.type == AST_TRANSPORT_UDP) {
int ack_res = FALSE;
/* Acknowledge whatever it is destined for */
}
req.socket.fd = sipsock;
- set_socket_transport(&req.socket, SIP_TRANSPORT_UDP);
+ set_socket_transport(&req.socket, AST_TRANSPORT_UDP);
req.socket.tcptls_session = NULL;
req.socket.port = htons(ast_sockaddr_port(&bindaddr));
* \param port Port we are checking to see if it's the standard port.
* \note port is expected in host byte order
*/
-static int sip_standard_port(enum sip_transport type, int port)
+static int sip_standard_port(enum ast_transport type, int port)
{
- if (type & SIP_TRANSPORT_TLS)
+ if (type & AST_TRANSPORT_TLS)
return port == STANDARD_TLS_PORT;
else
return port == STANDARD_SIP_PORT;
{
const struct ast_sockaddr *addr = NULL;
- if ((transport == SIP_TRANSPORT_UDP) || !transport) {
+ if ((transport == AST_TRANSPORT_UDP) || !transport) {
addr = &bindaddr;
- } else if (transport == SIP_TRANSPORT_TCP || transport == SIP_TRANSPORT_WS) {
+ } else if (transport == AST_TRANSPORT_TCP || transport == AST_TRANSPORT_WS) {
addr = &sip_tcp_desc.local_address;
- } else if (transport == SIP_TRANSPORT_TLS || transport == SIP_TRANSPORT_WSS) {
+ } else if (transport == AST_TRANSPORT_TLS || transport == AST_TRANSPORT_WSS) {
addr = &sip_tls_desc.local_address;
}
pthread_t launched;
/* check to see if a socket is already active */
- if ((s->fd != -1) && (s->type == SIP_TRANSPORT_UDP)) {
+ if ((s->fd != -1) && (s->type == AST_TRANSPORT_UDP)) {
return s->fd;
}
- if ((s->type & (SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS)) &&
+ if ((s->type & (AST_TRANSPORT_TCP | AST_TRANSPORT_TLS)) &&
(s->tcptls_session) &&
(s->tcptls_session->fd != -1)) {
return s->tcptls_session->fd;
}
- if ((s->type & (SIP_TRANSPORT_WS | SIP_TRANSPORT_WSS))) {
+ if ((s->type & (AST_TRANSPORT_WS | AST_TRANSPORT_WSS))) {
return s->ws_session ? ast_websocket_fd(s->ws_session) : -1;
}
s->type = p->outboundproxy->transport;
}
- if (s->type == SIP_TRANSPORT_UDP) {
+ if (s->type == AST_TRANSPORT_UDP) {
s->fd = sipsock;
return s->fd;
}
ca->accept_fd = -1;
ast_sockaddr_copy(&ca->remote_address,sip_real_dst(p));
/* if type is TLS, we need to create a tls cfg for this session arg */
- if (s->type == SIP_TRANSPORT_TLS) {
+ if (s->type == AST_TRANSPORT_TLS) {
if (!(ca->tls_cfg = ast_calloc(1, sizeof(*ca->tls_cfg)))) {
goto create_tcptls_session_fail;
}
}
/* Send the packet out using the proper method for this peer */
- if ((peer->socket.fd != -1) && (peer->socket.type == SIP_TRANSPORT_UDP)) {
+ if ((peer->socket.fd != -1) && (peer->socket.type == AST_TRANSPORT_UDP)) {
res = ast_sendto(peer->socket.fd, keepalive, sizeof(keepalive), 0, &peer->addr);
- } else if ((peer->socket.type & (SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS)) &&
+ } else if ((peer->socket.type & (AST_TRANSPORT_TCP | AST_TRANSPORT_TLS)) &&
(peer->socket.tcptls_session) &&
(peer->socket.tcptls_session->fd != -1)) {
res = sip_tcptls_write(peer->socket.tcptls_session, keepalive, sizeof(keepalive));
- } else if (peer->socket.type == SIP_TRANSPORT_UDP) {
+ } else if (peer->socket.type == AST_TRANSPORT_UDP) {
res = ast_sendto(sipsock, keepalive, sizeof(keepalive), 0, &peer->addr);
}
copy_route(&p->route, peer->path);
if (p->route) {
/* Parse SIP URI of first route-set hop and use it as target address */
- __set_address_from_contact(p->route->hop, &p->sa, p->socket.type == SIP_TRANSPORT_TLS ? 1 : 0);
+ __set_address_from_contact(p->route->hop, &p->sa, p->socket.type == AST_TRANSPORT_TLS ? 1 : 0);
}
/* Send OPTIONs to peer's fullcontact */
char *trans = NULL;
char dialstring[256];
char *remote_address;
- enum sip_transport transport = 0;
+ enum ast_transport transport = 0;
struct ast_callid *callid;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(peerorhost);
if (trans) {
*trans++ = '\0';
if (!strcasecmp(trans, "tcp"))
- transport = SIP_TRANSPORT_TCP;
+ transport = AST_TRANSPORT_TCP;
else if (!strcasecmp(trans, "tls"))
- transport = SIP_TRANSPORT_TLS;
+ transport = AST_TRANSPORT_TLS;
else {
if (strcasecmp(trans, "udp"))
ast_log(LOG_WARNING, "'%s' is not a valid transport option to Dial() for SIP calls, using udp by default.\n", trans);
- transport = SIP_TRANSPORT_UDP;
+ transport = AST_TRANSPORT_UDP;
}
} else { /* use default */
- transport = SIP_TRANSPORT_UDP;
+ transport = AST_TRANSPORT_UDP;
}
if (!host) {
peer->expire = -1;
peer->pokeexpire = -1;
peer->keepalivesend = -1;
- set_socket_transport(&peer->socket, SIP_TRANSPORT_UDP);
+ set_socket_transport(&peer->socket, AST_TRANSPORT_UDP);
}
peer->type = SIP_TYPE_PEER;
ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
trans = ast_skip_blanks(trans);
if (!strncasecmp(trans, "udp", 3)) {
- peer->transports |= SIP_TRANSPORT_UDP;
+ peer->transports |= AST_TRANSPORT_UDP;
} else if (!strncasecmp(trans, "wss", 3)) {
- peer->transports |= SIP_TRANSPORT_WSS;
+ peer->transports |= AST_TRANSPORT_WSS;
} else if (!strncasecmp(trans, "ws", 2)) {
- peer->transports |= SIP_TRANSPORT_WS;
+ peer->transports |= AST_TRANSPORT_WS;
} else if (sip_cfg.tcp_enabled && !strncasecmp(trans, "tcp", 3)) {
- peer->transports |= SIP_TRANSPORT_TCP;
+ peer->transports |= AST_TRANSPORT_TCP;
} else if (default_tls_cfg.enabled && !strncasecmp(trans, "tls", 3)) {
- peer->transports |= SIP_TRANSPORT_TLS;
+ peer->transports |= AST_TRANSPORT_TLS;
} else if (!strncasecmp(trans, "tcp", 3) || !strncasecmp(trans, "tls", 3)) {
ast_log(LOG_WARNING, "'%.3s' is not a valid transport type when %.3senable=no. If no other is specified, the defaults from general will be used.\n", trans, trans);
} else {
if (ast_sockaddr_port(&peer->addr) == 0) {
ast_sockaddr_set_port(&peer->addr,
- (peer->socket.type & SIP_TRANSPORT_TLS) ?
+ (peer->socket.type & AST_TRANSPORT_TLS) ?
STANDARD_TLS_PORT : STANDARD_SIP_PORT);
}
if (ast_sockaddr_port(&peer->defaddr) == 0) {
ast_sockaddr_set_port(&peer->defaddr,
- (peer->socket.type & SIP_TRANSPORT_TLS) ?
+ (peer->socket.type & AST_TRANSPORT_TLS) ?
STANDARD_TLS_PORT : STANDARD_SIP_PORT);
}
if (!peer->socket.port) {
- peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
+ peer->socket.port = htons(((peer->socket.type & AST_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
}
if (!sip_cfg.ignore_regexpire && peer->host_dynamic && realtime) {
memset(&default_prefs, 0 , sizeof(default_prefs));
memset(&sip_cfg.outboundproxy, 0, sizeof(struct sip_proxy));
sip_cfg.outboundproxy.force = FALSE; /*!< Don't force proxy usage, use route: headers */
- default_transports = SIP_TRANSPORT_UDP;
- default_primary_transport = SIP_TRANSPORT_UDP;
+ default_transports = AST_TRANSPORT_UDP;
+ default_primary_transport = AST_TRANSPORT_UDP;
ourport_tcp = STANDARD_SIP_PORT;
ourport_tls = STANDARD_TLS_PORT;
externtcpport = STANDARD_SIP_PORT;
trans = ast_skip_blanks(trans);
if (!strncasecmp(trans, "udp", 3)) {
- default_transports |= SIP_TRANSPORT_UDP;
+ default_transports |= AST_TRANSPORT_UDP;
} else if (!strncasecmp(trans, "tcp", 3)) {
- default_transports |= SIP_TRANSPORT_TCP;
+ default_transports |= AST_TRANSPORT_TCP;
} else if (!strncasecmp(trans, "tls", 3)) {
- default_transports |= SIP_TRANSPORT_TLS;
+ default_transports |= AST_TRANSPORT_TLS;
} else if (!strncasecmp(trans, "wss", 3)) {
- default_transports |= SIP_TRANSPORT_WSS;
+ default_transports |= AST_TRANSPORT_WSS;
} else if (!strncasecmp(trans, "ws", 2)) {
- default_transports |= SIP_TRANSPORT_WS;
+ default_transports |= AST_TRANSPORT_WS;
} else {
ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans);
}
sip_cfg.allow_external_domains = 1;
}
/* If not or badly configured, set default transports */
- if (!sip_cfg.tcp_enabled && (default_transports & SIP_TRANSPORT_TCP)) {
+ if (!sip_cfg.tcp_enabled && (default_transports & AST_TRANSPORT_TCP)) {
ast_log(LOG_WARNING, "Cannot use 'tcp' transport with tcpenable=no. Removing from available transports.\n");
- default_primary_transport &= ~SIP_TRANSPORT_TCP;
- default_transports &= ~SIP_TRANSPORT_TCP;
+ default_primary_transport &= ~AST_TRANSPORT_TCP;
+ default_transports &= ~AST_TRANSPORT_TCP;
}
- if (!default_tls_cfg.enabled && (default_transports & SIP_TRANSPORT_TLS)) {
+ if (!default_tls_cfg.enabled && (default_transports & AST_TRANSPORT_TLS)) {
ast_log(LOG_WARNING, "Cannot use 'tls' transport with tlsenable=no. Removing from available transports.\n");
- default_primary_transport &= ~SIP_TRANSPORT_TLS;
- default_transports &= ~SIP_TRANSPORT_TLS;
+ default_primary_transport &= ~AST_TRANSPORT_TLS;
+ default_transports &= ~AST_TRANSPORT_TLS;
}
if (!default_transports) {
ast_log(LOG_WARNING, "No valid transports available, falling back to 'udp'.\n");
- default_transports = default_primary_transport = SIP_TRANSPORT_UDP;
+ default_transports = default_primary_transport = AST_TRANSPORT_UDP;
} else if (!default_primary_transport) {
ast_log(LOG_WARNING, "No valid default transport. Selecting 'udp' as default.\n");
- default_primary_transport = SIP_TRANSPORT_UDP;
+ default_primary_transport = AST_TRANSPORT_UDP;
}
/* Build list of authentication to various SIP realms, i.e. service providers */
static int ast_sockaddr_resolve_first(struct ast_sockaddr *addr,
const char* name, int flag)
{
- return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(SIP_TRANSPORT_UDP));
+ return ast_sockaddr_resolve_first_af(addr, name, flag, get_address_family_filter(AST_TRANSPORT_UDP));
}
/*! \brief Return the first entry from ast_sockaddr_resolve filtered by family of binddaddr
}
/* We matched the IP, check to see if we need to match by port as well. */
- if ((peer->transports & peer2->transports) & (SIP_TRANSPORT_TLS | SIP_TRANSPORT_TCP)) {
+ if ((peer->transports & peer2->transports) & (AST_TRANSPORT_TLS | AST_TRANSPORT_TCP)) {
/* peer matching on port is not possible with TCP/TLS */
return CMP_MATCH | CMP_STOP;
} else if (ast_test_flag(&peer2->flags[0], SIP_INSECURE_PORT)) {
{
int portnum = 0;
int domainport = 0;
- enum sip_transport transport = SIP_TRANSPORT_UDP;
+ enum ast_transport transport = AST_TRANSPORT_UDP;
char buf[256] = "";
char *userpart = NULL, *hostpart = NULL;
/* register => [peer?][transport://]user[@domain][:secret[:authuser]]@host[:port][/extension][~expiry] */
/* set transport type */
if (!pre2.transport) {
- transport = SIP_TRANSPORT_UDP;
+ transport = AST_TRANSPORT_UDP;
} else if (!strncasecmp(pre2.transport, "tcp", 3)) {
- transport = SIP_TRANSPORT_TCP;
+ transport = AST_TRANSPORT_TCP;
} else if (!strncasecmp(pre2.transport, "tls", 3)) {
- transport = SIP_TRANSPORT_TLS;
+ transport = AST_TRANSPORT_TLS;
} else if (!strncasecmp(pre2.transport, "udp", 3)) {
- transport = SIP_TRANSPORT_UDP;
+ transport = AST_TRANSPORT_UDP;
} else {
- transport = SIP_TRANSPORT_UDP;
+ transport = AST_TRANSPORT_UDP;
ast_log(LOG_NOTICE, "'%.3s' is not a valid transport type on line %d of sip.conf. defaulting to udp.\n", pre2.transport, lineno);
}
/* if no portnum specified, set default for transport */
if (!portnum) {
- if (transport == SIP_TRANSPORT_TLS) {
+ if (transport == AST_TRANSPORT_TLS) {
portnum = STANDARD_TLS_PORT;
} else {
portnum = STANDARD_SIP_PORT;
strcmp(reg->authuser, "") ||
strcmp(reg->secret, "") ||
strcmp(reg->peername, "") ||
- reg->transport != SIP_TRANSPORT_UDP ||
+ reg->transport != AST_TRANSPORT_UDP ||
reg->timeout != -1 ||
reg->expire != -1 ||
reg->refresh != default_expiry ||
strcmp(reg->authuser, "") ||
strcmp(reg->secret, "pass") ||
strcmp(reg->peername, "") ||
- reg->transport != SIP_TRANSPORT_UDP ||
+ reg->transport != AST_TRANSPORT_UDP ||
reg->timeout != -1 ||
reg->expire != -1 ||
reg->refresh != default_expiry ||
strcmp(reg->authuser, "authuser") ||
strcmp(reg->secret, "pass") ||
strcmp(reg->peername, "") ||
- reg->transport != SIP_TRANSPORT_UDP ||
+ reg->transport != AST_TRANSPORT_UDP ||
reg->timeout != -1 ||
reg->expire != -1 ||
reg->refresh != default_expiry ||
strcmp(reg->authuser, "authuser") ||
strcmp(reg->secret, "pass") ||
strcmp(reg->peername, "") ||
- reg->transport != SIP_TRANSPORT_UDP ||
+ reg->transport != AST_TRANSPORT_UDP ||
reg->timeout != -1 ||
reg->expire != -1 ||
reg->refresh != default_expiry ||
strcmp(reg->authuser, "authuser") ||
strcmp(reg->secret, "pass") ||
strcmp(reg->peername, "") ||
- reg->transport != SIP_TRANSPORT_TCP ||
+ reg->transport != AST_TRANSPORT_TCP ||
reg->timeout != -1 ||
reg->expire != -1 ||
reg->refresh != default_expiry ||
strcmp(reg->authuser, "authuser") ||
strcmp(reg->secret, "pass") ||
strcmp(reg->peername, "") ||
- reg->transport != SIP_TRANSPORT_TLS ||
+ reg->transport != AST_TRANSPORT_TLS ||
reg->timeout != -1 ||
reg->expire != -1 ||
reg->refresh != 111 ||
strcmp(reg->authuser, "authuser") ||
strcmp(reg->secret, "pass") ||
strcmp(reg->peername, "peer") ||
- reg->transport != SIP_TRANSPORT_TCP ||
+ reg->transport != AST_TRANSPORT_TCP ||
reg->timeout != -1 ||
reg->expire != -1 ||
reg->refresh != 111 ||
strcmp(reg->authuser, "authuser") ||
strcmp(reg->secret, "pass") ||
strcmp(reg->peername, "peer") ||
- reg->transport != SIP_TRANSPORT_UDP ||
+ reg->transport != AST_TRANSPORT_UDP ||
reg->timeout != -1 ||
reg->expire != -1 ||
reg->refresh != 111 ||
strcmp(reg->authuser, "authuser") ||
strcmp(reg->secret, "pass") ||
strcmp(reg->peername, "") ||
- reg->transport != SIP_TRANSPORT_UDP ||
+ reg->transport != AST_TRANSPORT_UDP ||
reg->timeout != -1 ||
reg->expire != -1 ||
reg->refresh != default_expiry ||
strcmp(reg->authuser, "") ||
strcmp(reg->secret, "") ||
strcmp(reg->peername, "") ||
- reg->transport != SIP_TRANSPORT_UDP ||
+ reg->transport != AST_TRANSPORT_UDP ||
reg->timeout != -1 ||
reg->expire != -1 ||
reg->refresh != default_expiry ||
return res;
}
-int sip_parse_host(char *line, int lineno, char **hostname, int *portnum, enum sip_transport *transport)
+int sip_parse_host(char *line, int lineno, char **hostname, int *portnum, enum ast_transport *transport)
{
char *port;
*hostname += 3;
if (!strncasecmp(line, "tcp", 3)) {
- *transport = SIP_TRANSPORT_TCP;
+ *transport = AST_TRANSPORT_TCP;
} else if (!strncasecmp(line, "tls", 3)) {
- *transport = SIP_TRANSPORT_TLS;
+ *transport = AST_TRANSPORT_TLS;
} else if (!strncasecmp(line, "udp", 3)) {
- *transport = SIP_TRANSPORT_UDP;
+ *transport = AST_TRANSPORT_UDP;
} else if (lineno) {
ast_log(LOG_NOTICE, "'%.3s' is not a valid transport type on line %d of sip.conf. defaulting to udp.\n", line, lineno);
} else {
}
} else {
*hostname = line;
- *transport = SIP_TRANSPORT_UDP;
+ *transport = AST_TRANSPORT_UDP;
}
if ((line = strrchr(*hostname, '@')))
}
if (!port) {
- if (*transport & SIP_TRANSPORT_TLS) {
+ if (*transport & AST_TRANSPORT_TLS) {
*portnum = STANDARD_TLS_PORT;
} else {
*portnum = STANDARD_SIP_PORT;
int res = AST_TEST_PASS;
char *host;
int port;
- enum sip_transport transport;
+ enum ast_transport transport;
char host1[] = "www.blah.com";
char host2[] = "tcp://www.blah.com";
char host3[] = "tls://10.10.10.10";
sip_parse_host(host1, 1, &host, &port, &transport);
if (port != STANDARD_SIP_PORT ||
ast_strlen_zero(host) || strcmp(host, "www.blah.com") ||
- transport != SIP_TRANSPORT_UDP) {
+ transport != AST_TRANSPORT_UDP) {
ast_test_status_update(test, "Test 1: simple host failed.\n");
res = AST_TEST_FAIL;
}
sip_parse_host(host2, 1, &host, &port, &transport);
if (port != STANDARD_SIP_PORT ||
ast_strlen_zero(host) || strcmp(host, "www.blah.com") ||
- transport != SIP_TRANSPORT_TCP) {
+ transport != AST_TRANSPORT_TCP) {
ast_test_status_update(test, "Test 2: tcp host failed.\n");
res = AST_TEST_FAIL;
}
sip_parse_host(host3, 1, &host, &port, &transport);
if (port != STANDARD_TLS_PORT ||
ast_strlen_zero(host) || strcmp(host, "10.10.10.10") ||
- transport != SIP_TRANSPORT_TLS) {
+ transport != AST_TRANSPORT_TLS) {
ast_test_status_update(test, "Test 3: tls host failed. \n");
res = AST_TEST_FAIL;
}
sip_parse_host(host4, 1, &host, &port, &transport);
if (port != 1234 || ast_strlen_zero(host) ||
strcmp(host, "10.10.10.10") ||
- transport != SIP_TRANSPORT_TLS) {
+ transport != AST_TRANSPORT_TLS) {
ast_test_status_update(test, "Test 4: tls host with custom port failed.\n");
res = AST_TEST_FAIL;
}
sip_parse_host(host5, 1, &host, &port, &transport);
if (port != 1234 || ast_strlen_zero(host) ||
strcmp(host, "10.10.10.10") ||
- transport != SIP_TRANSPORT_UDP) {
+ transport != AST_TRANSPORT_UDP) {
ast_test_status_update(test, "Test 5: simple host with custom port failed.\n");
res = AST_TEST_FAIL;
}
return -1;
}
} else if (!strcasecmp(args.param, "secure_signaling")) {
- snprintf(buf, buflen, "%s", p->socket.type == SIP_TRANSPORT_TLS ? "1" : "");
+ snprintf(buf, buflen, "%s", p->socket.type == AST_TRANSPORT_TLS ? "1" : "");
} else if (!strcasecmp(args.param, "secure_media")) {
snprintf(buf, buflen, "%s", p->srtp ? "1" : "");
} else {
* \retval 0 on success
* \retval -1 on failure
*/
-int sip_parse_host(char *line, int lineno, char **hostname, int *portnum, enum sip_transport *transport);
+int sip_parse_host(char *line, int lineno, char **hostname, int *portnum, enum ast_transport *transport);
/*! \brief Parse the comma-separated nat= option values
* \param value The comma-separated value
#include "asterisk/features.h"
#include "asterisk/http_websocket.h"
#include "asterisk/rtp_engine.h"
+#include "asterisk/netsock2.h"
#ifndef FALSE
#define FALSE 0
SESSION_TIMER_REFRESHER_PARAM_UAS,
};
-/*! \brief Define some implemented SIP transports
- \note Asterisk does not support SCTP or UDP/DTLS
-*/
-enum sip_transport {
- SIP_TRANSPORT_UDP = 1, /*!< Unreliable transport for SIP, needs retransmissions */
- SIP_TRANSPORT_TCP = 1 << 1, /*!< Reliable, but unsecure */
- SIP_TRANSPORT_TLS = 1 << 2, /*!< TCP/TLS - reliable and secure transport for signalling */
- SIP_TRANSPORT_WS = 1 << 3, /*!< WebSocket, unsecure */
- SIP_TRANSPORT_WSS = 1 << 4, /*!< WebSocket, secure */
-};
-
/*! \brief Automatic peer registration behavior
*/
enum autocreatepeer_mode {
struct ast_sockaddr ip; /*!< Currently used IP address and port */
int port;
time_t last_dnsupdate; /*!< When this was resolved */
- enum sip_transport transport;
+ enum ast_transport transport;
int force; /*!< If it's an outbound proxy, Force use of this outbound proxy for all outbound requests */
/* Room for a SRV record chain based on the name */
};
/*! \brief The SIP socket definition */
struct sip_socket {
- enum sip_transport type; /*!< UDP, TCP or TLS */
+ enum ast_transport type; /*!< UDP, TCP or TLS */
int fd; /*!< Filed descriptor, the actual socket */
uint16_t port;
struct ast_tcptls_session_instance *tcptls_session; /* If tcp or tls, a socket manager */
AST_STRING_FIELD(callback); /*!< Callback extension */
);
struct sip_socket socket; /*!< Socket used for this peer */
- enum sip_transport default_outbound_transport; /*!< Peer Registration may change the default outbound transport.
+ enum ast_transport default_outbound_transport; /*!< Peer Registration may change the default outbound transport.
If register expires, default should be reset. to this value */
/* things that don't belong in flags */
- unsigned short transports:5; /*!< Transports (enum sip_transport) that are acceptable for this peer */
+ unsigned short transports:5; /*!< Transports (enum ast_transport) that are acceptable for this peer */
unsigned short is_realtime:1; /*!< this is a 'realtime' peer */
unsigned short rt_fromcontact:1;/*!< copy fromcontact from realtime */
unsigned short host_dynamic:1; /*!< Dynamic Peers register with Asterisk */
AST_STRING_FIELD(callback); /*!< Contact extension */
AST_STRING_FIELD(peername); /*!< Peer registering to */
);
- enum sip_transport transport; /*!< Transport for this registration UDP, TCP or TLS */
+ enum ast_transport transport; /*!< Transport for this registration UDP, TCP or TLS */
int portno; /*!< Optional port override */
int regdomainport; /*!< Port override for domainport */
int expire; /*!< Sched ID of expiration */
int alert_pipe[2]; /*! Used to alert tcptls thread when packet is ready to be written */
pthread_t threadid;
struct ast_tcptls_session_instance *tcptls_session;
- enum sip_transport type; /*!< We keep a copy of the type here so we can display it in the connection list */
+ enum ast_transport type; /*!< We keep a copy of the type here so we can display it in the connection list */
AST_LIST_HEAD_NOLOCK(, tcptls_packet) packet_q;
};
AST_STRING_FIELD(secret); /*!< Password in clear text */
AST_STRING_FIELD(mailbox); /*!< Mailbox store to put MWI into */
);
- enum sip_transport transport; /*!< Transport to use */
+ enum ast_transport transport; /*!< Transport to use */
int portno; /*!< Optional port override */
int resub; /*!< Sched ID of resubscription */
unsigned int subscribed:1; /*!< Whether we are currently subscribed or not */
struct sip_peer *sip_find_peer(const char *peer, struct ast_sockaddr *addr, int realtime, int which_objects, int devstate_only, int transport);
void sip_auth_headers(enum sip_auth_type code, char **header, char **respheader);
const char *sip_get_header(const struct sip_request *req, const char *name);
-const char *sip_get_transport(enum sip_transport t);
+const char *sip_get_transport(enum ast_transport t);
#ifdef REF_DEBUG
#define sip_ref_peer(arg1,arg2) _ref_peer((arg1),(arg2), __FILE__, __LINE__, __PRETTY_FUNCTION__)
/*! \brief Determine transport type used to receive request*/
-static enum ast_security_event_transport_type security_event_get_transport(const struct sip_pvt *p)
+static enum ast_transport security_event_get_transport(const struct sip_pvt *p)
{
- int res = 0;
-
- switch (p->socket.type) {
- case SIP_TRANSPORT_UDP:
- return AST_SECURITY_EVENT_TRANSPORT_UDP;
- case SIP_TRANSPORT_TCP:
- case SIP_TRANSPORT_WS:
- return AST_SECURITY_EVENT_TRANSPORT_TCP;
- case SIP_TRANSPORT_TLS:
- case SIP_TRANSPORT_WSS:
- return AST_SECURITY_EVENT_TRANSPORT_TLS;
- }
-
- return res;
+ return p->socket.type;
}
void sip_report_invalid_peer(const struct sip_pvt *p)
int ast_named_acl_reload(void);
/*!
- * \brief accessor for the ACL stasis topic
+ * \brief a \ref stasis_message_type for changes against a named ACL or the set of all named ACLs
* \since 12
*
- * \retval NULL if the stasis topic hasn't been created or has been disabled
- * \retval a pointer to the ACL stasis topic
- */
-struct stasis_topic *ast_acl_topic(void);
-
-/*!
- * \brief accessor for the named ACL change stasis message type
- * \since 12
+ * \retval NULL on error
+ * \retval \ref stasis_message_type for named ACL changes
*
- * \retval NULL if the ACL change message type hasn't been created or has been canceled
- * \retval a pointer to the ACL change message type
+ * \note Messages of this type should always be issued on and expected from the
+ * \ref ast_security_topic \ref stasis_topic
*/
struct stasis_message_type *ast_named_acl_change_type(void);
#ifndef _ASTERISK_JSON_H
#define _ASTERISK_JSON_H
+#include "asterisk/netsock2.h"
+
/*! \file
*
* \brief Asterisk JSON abstraction layer.
*/
struct ast_json *ast_json_timeval(const struct timeval tv, const char *zone);
+/*!
+ * \brief Construct an IP address as JSON
+ *
+ * XXX some comments describing the need for this here
+ *
+ * \param addr ast_sockaddr to encode
+ * \param transport_type ast_transport to include in the address string if any. Should just be one.
+ * \return JSON string containing the IP address with optional transport information
+ * \return \c NULL on error.
+ */
+struct ast_json *ast_json_ipaddr(const struct ast_sockaddr *addr, enum ast_transport transport_type);
+
/*!
* \brief Construct a context/exten/priority as JSON.
*
AST_AF_INET6 = 10,
};
+enum ast_transport {
+ AST_TRANSPORT_UDP = 1,
+ AST_TRANSPORT_TCP = 1 << 1,
+ AST_TRANSPORT_TLS = 1 << 2,
+ AST_TRANSPORT_WS = 1 << 3,
+ AST_TRANSPORT_WSS = 1 << 4,
+};
+
/*!
* \brief Socket address structure.
*
);
};
-/*!
- * \brief Types of supported transports
- */
-enum ast_sip_transport_type {
- AST_SIP_TRANSPORT_UDP,
- AST_SIP_TRANSPORT_TCP,
- AST_SIP_TRANSPORT_TLS,
- /* XXX Websocket ? */
-};
-
/*! \brief Maximum number of ciphers supported for a TLS transport */
#define SIP_TLS_MAX_CIPHERS 64
AST_STRING_FIELD(domain);
);
/*! Type of transport */
- enum ast_sip_transport_type type;
+ enum ast_transport type;
/*! Address and port to bind to */
pj_sockaddr host;
/*! Number of simultaneous asynchronous operations */
size_t offset;
};
+/*!
+ * \brief A \ref stasis_topic which publishes messages for security related issues.
+ * \since 12
+ *
+ * \retval \ref stasis_topic for security related issues.
+ * \retval NULL on error
+ */
+struct stasis_topic *ast_security_topic(void);
+
+/*!
+ * \brief A \ref stasis_message_type for security events
+ * \since 12
+ *
+ * \retval NULL on error
+ * \retval \ref stasis_message_type for security events
+ *
+ * \note Messages of this type should always be issued on and expected from
+ * the \ref ast_security_topic \ref stasis_topic
+ */
+struct stasis_message_type *ast_security_event_type(void);
+
+/*!
+ * \brief initializes stasis topic/event types for \ref ast_security_topic and \ref ast_security_event_type
+ * \since 12
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_security_stasis_init(void);
+
+/*!
+ * \brief removes stasis topic/event types for \ref ast_security_topic and \ref ast_security_event_type
+ * \since 12
+ */
+void ast_security_stasis_cleanup(void);
+
/*!
* \brief Get the list of required IEs for a given security event sub-type
*
#define __AST_SECURITY_EVENTS_DEFS_H__
#include "asterisk/network.h"
+#include "asterisk/netsock2.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
AST_SECURITY_EVENT_SEVERITY_ERROR = (1 << 1),
};
-/*!
- * \brief Transport types
- */
-enum ast_security_event_transport_type {
- AST_SECURITY_EVENT_TRANSPORT_UDP,
- AST_SECURITY_EVENT_TRANSPORT_TCP,
- AST_SECURITY_EVENT_TRANSPORT_TLS,
-};
-
#define AST_SEC_EVT(e) ((struct ast_security_event_common *) e)
struct ast_security_event_ip_addr {
const struct ast_sockaddr *addr;
- enum ast_security_event_transport_type transport;
+ enum ast_transport transport;
};
/*!
#include "asterisk/sorcery.h"
#include "asterisk/stasis.h"
#include "asterisk/json.h"
+#include "asterisk/security_events.h"
#include "asterisk/stasis_endpoints.h"
#include "../defaults.h"
exit(1);
}
+ if (ast_security_stasis_init()) { /* Initialize Security Stasis Topic and Events */
+ ast_security_stasis_cleanup();
+ printf("%s", term_quit());
+ exit(1);
+ }
+
if (ast_named_acl_init()) { /* Initialize the Named ACL system */
printf("%s", term_quit());
exit(1);
return ast_json_string_create(buf);
}
+struct ast_json *ast_json_ipaddr(const struct ast_sockaddr *addr, enum ast_transport transport_type)
+{
+ struct ast_str *string = ast_str_alloca(64);
+
+ if (!string) {
+ return NULL;
+ }
+
+ ast_str_set(&string, 0, (ast_sockaddr_is_ipv4(addr) ||
+ ast_sockaddr_is_ipv4_mapped(addr)) ? "IPV4/" : "IPV6/");
+
+ if (transport_type) {
+ char *transport_string = NULL;
+
+ /* NOTE: None will be applied if multiple transport types are specified in transport_type */
+ switch(transport_type) {
+ case AST_TRANSPORT_UDP:
+ transport_string = "UDP";
+ break;
+ case AST_TRANSPORT_TCP:
+ transport_string = "TCP";
+ break;
+ case AST_TRANSPORT_TLS:
+ transport_string = "TLS";
+ break;
+ case AST_TRANSPORT_WS:
+ transport_string = "WS";
+ break;
+ case AST_TRANSPORT_WSS:
+ transport_string = "WSS";
+ break;
+ }
+
+ if (transport_string) {
+ ast_str_append(&string, 0, "%s/", transport_string);
+ }
+ }
+
+ ast_str_append(&string, 0, "%s", ast_sockaddr_stringify_addr(addr));
+ ast_str_append(&string, 0, "/%s", ast_sockaddr_stringify_port(addr));
+
+ return ast_json_string_create(ast_str_buffer(string));
+}
+
void ast_json_init(void)
{
/* Setup to use Asterisk custom allocators */
static void acl_change_stasis_subscribe(void)
{
if (!acl_change_sub) {
- acl_change_sub = stasis_subscribe(ast_acl_topic(),
+ acl_change_sub = stasis_subscribe(ast_security_topic(),
acl_change_stasis_cb, NULL);
}
}
return maskint;
}
-static enum ast_security_event_transport_type mansession_get_transport(const struct mansession *s)
+static enum ast_transport mansession_get_transport(const struct mansession *s)
{
- return s->tcptls_session->parent->tls_cfg ? AST_SECURITY_EVENT_TRANSPORT_TLS :
- AST_SECURITY_EVENT_TRANSPORT_TCP;
+ return s->tcptls_session->parent->tls_cfg ? AST_TRANSPORT_TLS :
+ AST_TRANSPORT_TCP;
}
static void report_invalid_user(const struct mansession *s, const char *username)
#include "asterisk/paths.h"
#include "asterisk/stasis.h"
#include "asterisk/json.h"
+#include "asterisk/security_events.h"
#define NACL_CONFIG "acl.conf"
#define ACL_FAMILY "acls"
return ha;
}
-/*! \brief Topic for ACLs */
-static struct stasis_topic *acl_topic;
-
/*! \brief Message type for named ACL changes */
STASIS_MESSAGE_TYPE_DEFN(ast_named_acl_change_type);
static void acl_stasis_shutdown(void)
{
- ao2_cleanup(acl_topic);
- acl_topic = NULL;
STASIS_MESSAGE_TYPE_CLEANUP(ast_named_acl_change_type);
}
static void ast_acl_stasis_init(void)
{
ast_register_atexit(acl_stasis_shutdown);
- acl_topic = stasis_topic_create("ast_acl");
STASIS_MESSAGE_TYPE_INIT(ast_named_acl_change_type);
}
-struct stasis_topic *ast_acl_topic(void)
-{
- return acl_topic;
-}
-
/*!
* \internal
* \brief Sends a stasis message corresponding to a given named ACL that has changed or
* that all ACLs have been updated and old copies must be refreshed. Consumers of
- * named ACLs should subscribe to the ast_acl_topic and respond to messages of the
- * ast_named_acl_change_type stasis message type in order to be able to accomodate
- * changes to named ACLs.
+ * named ACLs should subscribe to the ast_security_topic and respond to messages
+ * of the ast_named_acl_change_type stasis message type in order to be able to
+ * accommodate changes to named ACLs.
*
* \param name Name of the ACL that has changed. May be an empty string (but not NULL)
* If name is an empty string, then all ACLs must be refreshed.
goto publish_failure;
}
- stasis_publish(ast_acl_topic(), msg);
+ stasis_publish(ast_security_topic(), msg);
return 0;
#include "asterisk/network.h"
#include "asterisk/security_events.h"
#include "asterisk/netsock2.h"
+#include "asterisk/stasis.h"
+#include "asterisk/json.h"
+#include "asterisk/astobj2.h"
static const size_t TIMESTAMP_STR_LEN = 32;
+/*! \brief Security Topic */
+static struct stasis_topic *security_topic;
+
+struct stasis_topic *ast_security_topic(void)
+{
+ return security_topic;
+}
+
+/*! \brief Message type for security events */
+STASIS_MESSAGE_TYPE_DEFN(ast_security_event_type);
+
+int ast_security_stasis_init(void)
+{
+ security_topic = stasis_topic_create("ast_security");
+ if (!security_topic) {
+ return -1;
+ }
+
+ if (STASIS_MESSAGE_TYPE_INIT(ast_security_event_type)) {
+ return -1;
+ }
+
+ if (ast_register_atexit(ast_security_stasis_cleanup)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+void ast_security_stasis_cleanup(void)
+{
+ STASIS_MESSAGE_TYPE_CLEANUP(ast_security_event_type);
+
+ ao2_cleanup(security_topic);
+ security_topic = NULL;
+}
+
static const struct {
const char *name;
uint32_t version;
return sec_events[event_type].optional_ies;
}
-static void encode_timestamp(struct ast_str **str, const struct timeval *tv)
-{
- ast_str_set(str, 0, "%u-%u",
- (unsigned int) tv->tv_sec,
- (unsigned int) tv->tv_usec);
-}
-
-static struct ast_event *alloc_event(const struct ast_security_event_common *sec)
-{
- struct ast_str *str = ast_str_alloca(TIMESTAMP_STR_LEN);
- struct timeval tv = ast_tvnow();
- const char *severity_str;
-
- if (check_event_type(sec->event_type)) {
- return NULL;
- }
-
- encode_timestamp(&str, &tv);
-
- severity_str = S_OR(
- ast_security_event_severity_get_name(sec_events[sec->event_type].severity),
- "Unknown"
- );
-
- return ast_event_new(AST_EVENT_SECURITY,
- AST_EVENT_IE_SECURITY_EVENT, AST_EVENT_IE_PLTYPE_UINT, sec->event_type,
- AST_EVENT_IE_EVENT_VERSION, AST_EVENT_IE_PLTYPE_UINT, sec->version,
- AST_EVENT_IE_EVENT_TV, AST_EVENT_IE_PLTYPE_STR, ast_str_buffer(str),
- AST_EVENT_IE_SERVICE, AST_EVENT_IE_PLTYPE_STR, sec->service,
- AST_EVENT_IE_SEVERITY, AST_EVENT_IE_PLTYPE_STR, severity_str,
- AST_EVENT_IE_END);
-}
-
-static int add_timeval_ie(struct ast_event **event, enum ast_event_ie_type ie_type,
- const struct timeval *tv)
-{
- struct ast_str *str = ast_str_alloca(TIMESTAMP_STR_LEN);
-
- encode_timestamp(&str, tv);
-
- return ast_event_append_ie_str(event, ie_type, ast_str_buffer(str));
-}
-
-static int add_ip_ie(struct ast_event **event, enum ast_event_ie_type ie_type,
+static int add_ip_json_object(struct ast_json *json, enum ast_event_ie_type ie_type,
const struct ast_security_event_ip_addr *addr)
{
- struct ast_str *str = ast_str_alloca(64);
+ struct ast_json *json_ip;
- ast_str_set(&str, 0, (ast_sockaddr_is_ipv4(addr->addr) || ast_sockaddr_is_ipv4_mapped(addr->addr)) ? "IPV4/" : "IPV6/");
-
- switch (addr->transport) {
- case AST_SECURITY_EVENT_TRANSPORT_UDP:
- ast_str_append(&str, 0, "UDP/");
- break;
- case AST_SECURITY_EVENT_TRANSPORT_TCP:
- ast_str_append(&str, 0, "TCP/");
- break;
- case AST_SECURITY_EVENT_TRANSPORT_TLS:
- ast_str_append(&str, 0, "TLS/");
- break;
+ json_ip = ast_json_ipaddr(addr->addr, addr->transport);
+ if (!json_ip) {
+ return -1;
}
- ast_str_append(&str, 0, "%s", ast_sockaddr_stringify_addr(addr->addr));
- ast_str_append(&str, 0, "/%s", ast_sockaddr_stringify_port(addr->addr));
-
- return ast_event_append_ie_str(event, ie_type, ast_str_buffer(str));
+ return ast_json_object_set(json, ast_event_get_ie_type_name(ie_type), json_ip);
}
enum ie_required {
REQUIRED
};
-static int add_ie(struct ast_event **event, const struct ast_security_event_common *sec,
+static int add_json_object(struct ast_json *json, const struct ast_security_event_common *sec,
const struct ast_security_event_ie_type *ie_type, enum ie_required req)
{
int res = 0;
case AST_EVENT_IE_ATTEMPTED_TRANSPORT:
{
const char *str;
+ struct ast_json *json_string;
str = *((const char **)(((const char *) sec) + ie_type->offset));
"type '%d' not present\n", ie_type->ie_type,
sec->event_type);
res = -1;
+ break;
}
- if (str) {
- res = ast_event_append_ie_str(event, ie_type->ie_type, str);
+ if (!str) {
+ break;
}
+ json_string = ast_json_string_create(str);
+ if (!json_string) {
+ res = -1;
+ break;
+ }
+
+ res = ast_json_object_set(json, ast_event_get_ie_type_name(ie_type->ie_type), json_string);
break;
}
case AST_EVENT_IE_EVENT_VERSION:
case AST_EVENT_IE_USING_PASSWORD:
{
+ struct ast_json *json_string;
uint32_t val;
val = *((const uint32_t *)(((const char *) sec) + ie_type->offset));
- res = ast_event_append_ie_uint(event, ie_type->ie_type, val);
+
+ json_string = ast_json_stringf("%d", val);
+ if (!json_string) {
+ res = -1;
+ break;
+ }
+
+ res = ast_json_object_set(json, ast_event_get_ie_type_name(ie_type->ie_type), json_string);
break;
}
case AST_EVENT_IE_LOCAL_ADDR:
}
if (addr->addr) {
- res = add_ip_ie(event, ie_type->ie_type, addr);
+ res = add_ip_json_object(json, ie_type->ie_type, addr);
}
+
break;
}
case AST_EVENT_IE_SESSION_TV:
}
if (tval) {
- add_timeval_ie(event, ie_type->ie_type, tval);
+ struct ast_json *json_tval = ast_json_timeval(*tval, NULL);
+ if (!json_tval) {
+ res = -1;
+ break;
+ }
+ res = ast_json_object_set(json, ast_event_get_ie_type_name(ie_type->ie_type), json_tval);
}
break;
return res;
}
+static struct ast_json *alloc_security_event_json_object(const struct ast_security_event_common *sec)
+{
+ struct timeval tv = ast_tvnow();
+ const char *severity_str;
+ struct ast_json *json_temp;
+ RAII_VAR(struct ast_json *, json_object, ast_json_object_create(), ast_json_unref);
+
+ if (!json_object) {
+ return NULL;
+ }
+
+ /* NOTE: Every time ast_json_object_set is used, json_temp becomes a stale pointer since the reference is taken.
+ * This is true even if ast_json_object_set fails.
+ */
+
+ /* AST_EVENT_IE_SECURITY_EVENT */
+ json_temp = ast_json_integer_create(sec->event_type);
+ if (!json_temp || ast_json_object_set(json_object, ast_event_get_ie_type_name(AST_EVENT_IE_SECURITY_EVENT), json_temp)) {
+ return NULL;
+ }
+
+ /* AST_EVENT_IE_EVENT_VERSION */
+ json_temp = ast_json_stringf("%d", sec->version);
+ if (!json_temp || ast_json_object_set(json_object, ast_event_get_ie_type_name(AST_EVENT_IE_EVENT_VERSION), json_temp)) {
+ return NULL;
+ }
+
+ /* AST_EVENT_IE_EVENT_TV */
+ json_temp = ast_json_timeval(tv, NULL);
+ if (!json_temp || ast_json_object_set(json_object, ast_event_get_ie_type_name(AST_EVENT_IE_EVENT_TV), json_temp)) {
+ return NULL;
+ }
+
+ /* AST_EVENT_IE_SERVICE */
+ json_temp = ast_json_string_create(sec->service);
+ if (!json_temp || ast_json_object_set(json_object, ast_event_get_ie_type_name(AST_EVENT_IE_SERVICE), json_temp)) {
+ return NULL;
+ }
+
+ /* AST_EVENT_IE_SEVERITY */
+ severity_str = S_OR(
+ ast_security_event_severity_get_name(sec_events[sec->event_type].severity),
+ "Unknown"
+ );
+
+ json_temp = ast_json_string_create(severity_str);
+ if (!json_temp || ast_json_object_set(json_object, ast_event_get_ie_type_name(AST_EVENT_IE_SEVERITY), json_temp)) {
+ return NULL;
+ }
+
+ return ast_json_ref(json_object);
+}
+
static int handle_security_event(const struct ast_security_event_common *sec)
{
- struct ast_event *event;
+ RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_json_payload *, json_payload, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
+
const struct ast_security_event_ie_type *ies;
unsigned int i;
- if (!(event = alloc_event(sec))) {
+ json_object = alloc_security_event_json_object(sec);
+
+ if (!json_object) {
return -1;
}
for (ies = ast_security_event_get_required_ies(sec->event_type), i = 0;
ies[i].ie_type != AST_EVENT_IE_END;
i++) {
- if (add_ie(&event, sec, ies + i, REQUIRED)) {
+ if (add_json_object(json_object, sec, ies + i, REQUIRED)) {
goto return_error;
}
}
for (ies = ast_security_event_get_optional_ies(sec->event_type), i = 0;
ies[i].ie_type != AST_EVENT_IE_END;
i++) {
- if (add_ie(&event, sec, ies + i, NOT_REQUIRED)) {
+ if (add_json_object(json_object, sec, ies + i, NOT_REQUIRED)) {
goto return_error;
}
}
+ /* The json blob is ready. Throw it in the payload and send it out over stasis. */
+ if (!(json_payload = ast_json_payload_create(json_object))) {
+ goto return_error;
+ }
+
+ msg = stasis_message_create(ast_security_event_type(), json_payload);
- if (ast_event_queue(event)) {
+ if (!msg) {
goto return_error;
}
+ stasis_publish(ast_security_topic(), msg);
+
return 0;
return_error:
- if (event) {
- ast_event_destroy(event);
- }
-
return -1;
}
int ast_security_event_report(const struct ast_security_event_common *sec)
{
- int res;
-
if (sec->event_type < 0 || sec->event_type >= AST_SECURITY_EVENT_NUM_TYPES) {
ast_log(LOG_ERROR, "Invalid security event type\n");
return -1;
return -1;
}
- res = handle_security_event(sec);
+ if (handle_security_event(sec)) {
+ ast_log(LOG_ERROR, "Failed to issue security event of type %s.\n",
+ ast_security_event_get_name(sec->event_type));
+ }
- return res;
+ return 0;
}
#include "asterisk/module.h"
#include "asterisk/logger.h"
-#include "asterisk/event.h"
#include "asterisk/threadstorage.h"
#include "asterisk/strings.h"
#include "asterisk/security_events.h"
+#include "asterisk/stasis.h"
+#include "asterisk/json.h"
static const char LOG_SECURITY_NAME[] = "SECURITY";
static int LOG_SECURITY;
-static struct ast_event_sub *security_event_sub;
+static struct stasis_subscription *security_stasis_sub;
AST_THREADSTORAGE(security_event_buf);
static const size_t SECURITY_EVENT_BUF_INIT_LEN = 256;
REQUIRED
};
-static int ie_is_present(const struct ast_event *event,
- const enum ast_event_ie_type ie_type)
-{
- return (ast_event_get_ie_raw(event, ie_type) != NULL);
-}
-
-static void append_ie(struct ast_str **str, const struct ast_event *event,
+static void append_json_single(struct ast_str **str, struct ast_json *json,
const enum ast_event_ie_type ie_type, enum ie_required required)
{
- if (!required && !ie_is_present(event, ie_type)) {
- /* Optional IE isn't present. Ignore. */
+ const char *ie_type_key = ast_event_get_ie_type_name(ie_type);
+
+ struct ast_json *json_string;
+
+ json_string = ast_json_object_get(json, ie_type_key);
+
+ if (!required && !json_string) {
+ /* Optional IE isn't present. Ignore. */
return;
}
/* At this point, it _better_ be there! */
- ast_assert(ie_is_present(event, ie_type));
-
- switch (ast_event_get_ie_pltype(ie_type)) {
- case AST_EVENT_IE_PLTYPE_UINT:
- ast_str_append(str, 0, ",%s=\"%u\"",
- ast_event_get_ie_type_name(ie_type),
- ast_event_get_ie_uint(event, ie_type));
- break;
- case AST_EVENT_IE_PLTYPE_STR:
- ast_str_append(str, 0, ",%s=\"%s\"",
- ast_event_get_ie_type_name(ie_type),
- ast_event_get_ie_str(event, ie_type));
- break;
- case AST_EVENT_IE_PLTYPE_BITFLAGS:
- ast_str_append(str, 0, ",%s=\"%u\"",
- ast_event_get_ie_type_name(ie_type),
- ast_event_get_ie_bitflags(event, ie_type));
- break;
- case AST_EVENT_IE_PLTYPE_UNKNOWN:
- case AST_EVENT_IE_PLTYPE_EXISTS:
- case AST_EVENT_IE_PLTYPE_RAW:
- ast_log(LOG_WARNING, "Unexpected payload type for IE '%s'\n",
- ast_event_get_ie_type_name(ie_type));
- break;
- }
+ ast_assert(json_string != NULL);
+
+ ast_str_append(str, 0, ",%s=\"%s\"",
+ ie_type_key,
+ ast_json_string_get(json_string));
}
-static void append_ies(struct ast_str **str, const struct ast_event *event,
+static void append_json(struct ast_str **str, struct ast_json *json,
const struct ast_security_event_ie_type *ies, enum ie_required required)
{
unsigned int i;
for (i = 0; ies[i].ie_type != AST_EVENT_IE_END; i++) {
- append_ie(str, event, ies[i].ie_type, required);
+ append_json_single(str, json, ies[i].ie_type, required);
}
}
-static void security_event_cb(const struct ast_event *event, void *data)
+static void security_event_stasis_cb(struct ast_json *json)
{
struct ast_str *str;
+ struct ast_json *event_type_json;
enum ast_security_event_type event_type;
+ event_type_json = ast_json_object_get(json, "SecurityEvent");
+ event_type = ast_json_integer_get(event_type_json);
+
+ ast_assert(event_type >= 0 && event_type < AST_SECURITY_EVENT_NUM_TYPES);
+
if (!(str = ast_str_thread_get(&security_event_buf,
SECURITY_EVENT_BUF_INIT_LEN))) {
return;
}
- /* Note that the event type is guaranteed to be valid here. */
- event_type = ast_event_get_ie_uint(event, AST_EVENT_IE_SECURITY_EVENT);
- ast_assert(event_type >= 0 && event_type < AST_SECURITY_EVENT_NUM_TYPES);
-
ast_str_set(&str, 0, "%s=\"%s\"",
ast_event_get_ie_type_name(AST_EVENT_IE_SECURITY_EVENT),
ast_security_event_get_name(event_type));
- append_ies(&str, event,
+ append_json(&str, json,
ast_security_event_get_required_ies(event_type), REQUIRED);
- append_ies(&str, event,
+ append_json(&str, json,
ast_security_event_get_optional_ies(event_type), NOT_REQUIRED);
ast_log_dynamic_level(LOG_SECURITY, "%s\n", ast_str_buffer(str));
}
+static void security_stasis_cb(void *data, struct stasis_subscription *sub,
+ struct stasis_topic *topic, struct stasis_message *message)
+{
+ struct ast_json_payload *payload = stasis_message_data(message);
+
+ if (stasis_message_type(message) != ast_security_event_type()) {
+ return;
+ }
+
+ if (!payload) {
+ return;
+ }
+
+ security_event_stasis_cb(payload->json);
+}
+
static int load_module(void)
{
if ((LOG_SECURITY = ast_logger_register_level(LOG_SECURITY_NAME)) == -1) {
return AST_MODULE_LOAD_DECLINE;
}
- if (!(security_event_sub = ast_event_subscribe(AST_EVENT_SECURITY,
- security_event_cb, "Security Event Logger",
- NULL, AST_EVENT_IE_END))) {
+ if (!(security_stasis_sub = stasis_subscribe(ast_security_topic(), security_stasis_cb, NULL))) {
ast_logger_unregister_level(LOG_SECURITY_NAME);
LOG_SECURITY = -1;
return AST_MODULE_LOAD_DECLINE;
static int unload_module(void)
{
- if (security_event_sub) {
- security_event_sub = ast_event_unsubscribe(security_event_sub);
+ if (security_stasis_sub) {
+ security_stasis_sub = stasis_unsubscribe(security_stasis_sub);
}
ast_verb(3, "Security Logging Disabled\n");
return -1;
}
- if (transport->type == AST_SIP_TRANSPORT_UDP) {
+ if (transport->type == AST_TRANSPORT_UDP) {
selector->type = PJSIP_TPSELECTOR_TRANSPORT;
selector->u.transport = transport->state->transport;
- } else if (transport->type == AST_SIP_TRANSPORT_TCP || transport->type == AST_SIP_TRANSPORT_TLS) {
+ } else if (transport->type == AST_TRANSPORT_TCP || transport->type == AST_TRANSPORT_TLS) {
selector->type = PJSIP_TPSELECTOR_LISTENER;
selector->u.listener = transport->state->factory;
} else {
/* Set default port if not present */
if (!pj_sockaddr_get_port(&transport->host)) {
- pj_sockaddr_set_port(&transport->host, (transport->type == AST_SIP_TRANSPORT_TLS) ? 5061 : 5060);
+ pj_sockaddr_set_port(&transport->host, (transport->type == AST_TRANSPORT_TLS) ? 5061 : 5060);
}
/* Now that we know what address family we can set up a dnsmgr refresh for the external media address if present */
}
}
- if (transport->type == AST_SIP_TRANSPORT_UDP) {
+ if (transport->type == AST_TRANSPORT_UDP) {
if (transport->host.addr.sa_family == pj_AF_INET()) {
res = pjsip_udp_transport_start(ast_sip_get_pjsip_endpoint(), &transport->host.ipv4, NULL, transport->async_operations, &transport->state->transport);
} else if (transport->host.addr.sa_family == pj_AF_INET6()) {
res = pjsip_udp_transport_start6(ast_sip_get_pjsip_endpoint(), &transport->host.ipv6, NULL, transport->async_operations, &transport->state->transport);
}
- } else if (transport->type == AST_SIP_TRANSPORT_TCP) {
+ } else if (transport->type == AST_TRANSPORT_TCP) {
pjsip_tcp_transport_cfg cfg;
pjsip_tcp_transport_cfg_default(&cfg, transport->host.addr.sa_family);
cfg.async_cnt = transport->async_operations;
res = pjsip_tcp_transport_start3(ast_sip_get_pjsip_endpoint(), &cfg, &transport->state->factory);
- } else if (transport->type == AST_SIP_TRANSPORT_TLS) {
+ } else if (transport->type == AST_TRANSPORT_TLS) {
transport->tls.ca_list_file = pj_str((char*)transport->ca_list_file);
transport->tls.cert_file = pj_str((char*)transport->cert_file);
transport->tls.privkey_file = pj_str((char*)transport->privkey_file);
struct ast_sip_transport *transport = obj;
if (!strcasecmp(var->value, "udp")) {
- transport->type = AST_SIP_TRANSPORT_UDP;
+ transport->type = AST_TRANSPORT_UDP;
} else if (!strcasecmp(var->value, "tcp")) {
- transport->type = AST_SIP_TRANSPORT_TCP;
+ transport->type = AST_TRANSPORT_TCP;
} else if (!strcasecmp(var->value, "tls")) {
- transport->type = AST_SIP_TRANSPORT_TLS;
+ transport->type = AST_TRANSPORT_TLS;
} else {
/* TODO: Implement websockets */
return -1;
/*! \brief Structure which contains information about a transport */
struct request_transport_details {
/*! \brief Type of transport */
- enum ast_sip_transport_type type;
+ enum ast_transport type;
/*! \brief Potential pointer to the transport itself, if UDP */
pjsip_transport *transport;
/*! \brief Potential pointer to the transport factory itself, if TCP/TLS */
details.factory = tdata->tp_sel.u.listener;
} else if (tdata->tp_info.transport->key.type == PJSIP_TRANSPORT_UDP || tdata->tp_info.transport->key.type == PJSIP_TRANSPORT_UDP6) {
/* Connectionless uses the same transport for all requests */
- details.type = AST_SIP_TRANSPORT_UDP;
+ details.type = AST_TRANSPORT_UDP;
details.transport = tdata->tp_info.transport;
} else {
if (tdata->tp_info.transport->key.type == PJSIP_TRANSPORT_TCP) {
- details.type = AST_SIP_TRANSPORT_TCP;
+ details.type = AST_TRANSPORT_TCP;
} else if (tdata->tp_info.transport->key.type == PJSIP_TRANSPORT_TLS) {
- details.type = AST_SIP_TRANSPORT_TLS;
+ details.type = AST_TRANSPORT_TLS;
} else {
/* Unknown transport type, we can't map and thus can't apply NAT changes */
return PJ_SUCCESS;
}
if (!details.local_port) {
- details.local_port = (details.type == AST_SIP_TRANSPORT_TLS) ? 5061 : 5060;
+ details.local_port = (details.type == AST_TRANSPORT_TLS) ? 5061 : 5060;
}
}
return -1;
}
- if (transport->type == AST_SIP_TRANSPORT_UDP) {
+ if (transport->type == AST_TRANSPORT_UDP) {
selector.type = PJSIP_TPSELECTOR_TRANSPORT;
selector.u.transport = transport->state->transport;
- } else if (transport->type == AST_SIP_TRANSPORT_TCP || transport->type == AST_SIP_TRANSPORT_TLS) {
+ } else if (transport->type == AST_TRANSPORT_TCP || transport->type == AST_TRANSPORT_TLS) {
selector.type = PJSIP_TPSELECTOR_LISTENER;
selector.u.listener = transport->state->factory;
} else {
.common.session_tv = &session_tv,
.common.local_addr = {
.addr = &addr_local,
- .transport = AST_SECURITY_EVENT_TRANSPORT_UDP,
+ .transport = AST_TRANSPORT_UDP,
},
.common.remote_addr = {
.addr = &addr_remote,
- .transport = AST_SECURITY_EVENT_TRANSPORT_UDP,
+ .transport = AST_TRANSPORT_UDP,
},
.acl_name = "TEST_ACL",
.common.session_tv = &session_tv,
.common.local_addr = {
.addr = &addr_local,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
.common.remote_addr = {
.addr = &addr_remote,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
};
.common.session_tv = &session_tv,
.common.local_addr = {
.addr = &addr_local,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TLS,
+ .transport = AST_TRANSPORT_TLS,
},
.common.remote_addr = {
.addr = &addr_remote,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TLS,
+ .transport = AST_TRANSPORT_TLS,
},
};
.common.session_tv = &session_tv,
.common.local_addr = {
.addr = &addr_local,
- .transport = AST_SECURITY_EVENT_TRANSPORT_UDP,
+ .transport = AST_TRANSPORT_UDP,
},
.common.remote_addr = {
.addr = &addr_remote,
- .transport = AST_SECURITY_EVENT_TRANSPORT_UDP,
+ .transport = AST_TRANSPORT_UDP,
},
};
.common.session_tv = &session_tv,
.common.local_addr = {
.addr = &addr_local,
- .transport = AST_SECURITY_EVENT_TRANSPORT_UDP,
+ .transport = AST_TRANSPORT_UDP,
},
.common.remote_addr = {
.addr = &addr_remote,
- .transport = AST_SECURITY_EVENT_TRANSPORT_UDP,
+ .transport = AST_TRANSPORT_UDP,
},
};
.common.session_tv = &session_tv,
.common.local_addr = {
.addr = &addr_local,
- .transport = AST_SECURITY_EVENT_TRANSPORT_UDP,
+ .transport = AST_TRANSPORT_UDP,
},
.common.remote_addr = {
.addr = &addr_remote,
- .transport = AST_SECURITY_EVENT_TRANSPORT_UDP,
+ .transport = AST_TRANSPORT_UDP,
},
.request_type = "MakeMeDinner",
.common.session_tv = &session_tv,
.common.local_addr = {
.addr = &addr_local,
- .transport = AST_SECURITY_EVENT_TRANSPORT_UDP,
+ .transport = AST_TRANSPORT_UDP,
},
.common.remote_addr = {
.addr = &addr_remote,
- .transport = AST_SECURITY_EVENT_TRANSPORT_UDP,
+ .transport = AST_TRANSPORT_UDP,
},
.request_type = "MakeMeBreakfast",
.common.session_tv = &session_tv,
.common.local_addr = {
.addr = &addr_local,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
.common.remote_addr = {
.addr = &addr_remote,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
.auth_method = "PlainText"
.common.session_tv = &session_tv,
.common.local_addr = {
.addr = &addr_local,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
.common.remote_addr = {
.addr = &addr_remote,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
.request_type = "CheeseBurger",
.common.session_tv = &session_tv,
.common.local_addr = {
.addr = &addr_local,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
.common.remote_addr = {
.addr = &addr_remote,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
};
.common.session_tv = &session_tv,
.common.local_addr = {
.addr = &addr_local,
- .transport = AST_SECURITY_EVENT_TRANSPORT_UDP,
+ .transport = AST_TRANSPORT_UDP,
},
.common.remote_addr = {
.addr = &addr_remote,
- .transport = AST_SECURITY_EVENT_TRANSPORT_UDP,
+ .transport = AST_TRANSPORT_UDP,
},
.expected_addr = {
.addr = &addr_expected,
- .transport = AST_SECURITY_EVENT_TRANSPORT_UDP,
+ .transport = AST_TRANSPORT_UDP,
},
};
.common.session_tv = &session_tv,
.common.local_addr = {
.addr = &addr_local,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
.common.remote_addr = {
.addr = &addr_remote,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
.challenge = "8adf8a9sd8fas9df23ljk4",
.common.session_tv = &session_tv,
.common.local_addr = {
.addr = &addr_local,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
.common.remote_addr = {
.addr = &addr_remote,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
.challenge = "GoOdChAlLeNgE",
.received_challenge = "BaDcHaLlEnGe",
.common.session_tv = &session_tv,
.common.local_addr = {
.addr = &addr_local,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
.common.remote_addr = {
.addr = &addr_remote,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
.challenge = "IcHaLlEnGeYoU",
};
.common.session_tv = &session_tv,
.common.local_addr = {
.addr = &addr_local,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
.common.remote_addr = {
.addr = &addr_remote,
- .transport = AST_SECURITY_EVENT_TRANSPORT_TCP,
+ .transport = AST_TRANSPORT_TCP,
},
.transport = "UDP",
};