AST-2013-003: Prevent username disclosure in SIP channel driver

When authenticating a SIP request with alwaysauthreject enabled, allowguest
disabled, and autocreatepeer disabled, Asterisk discloses whether a user
exists for INVITE, SUBSCRIBE, and REGISTER transactions in multiple ways. The
information is disclosed when:
 * A "407 Proxy Authentication Required" response is sent instead of a
   "401 Unauthorized" response
 * The presence or absence of additional tags occurs at the end of "403
   Forbidden" (such as "(Bad Auth)")
 * A "401 Unauthorized" response is sent instead of "403 Forbidden" response
   after a retransmission
 * Retransmission are sent when a matching peer did not exist, but not when a
   matching peer did exist.

This patch resolves these various vectors by ensuring that the responses sent
in all scenarios is the same, regardless of the presence of a matching peer.

This issue was reported by Walter Doekes, OSSO B.V. A substantial portion of
the testing and the solution to this problem was done by Walter as well - a
huge thanks to his tireless efforts in finding all the ways in which this
setting didn't work, providing automated tests, and working with Kinsey on
getting this fixed.

(closes issue ASTERISK-21013)
Reported by: wdoekes
Tested by: wdoekes, kmoore
patches:
  AST-2013-003-1.8 uploaded by kmoore, wdoekes (License 6273, 5674)
  AST-2013-003-10 uploaded by kmoore, wdoekes (License 6273, 5674)
  AST-2013-003-11 uploaded by kmoore, wdoekes (License 6273, 5674)
........

Merged revisions 384003 from http://svn.asterisk.org/svn/asterisk/branches/11


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@384019 65c4cc65-6c06-0410-ace0-fbb531ad65f3
changes/78/78/1
Matthew Jordan 13 years ago
parent ec144089ea
commit 0ffce56f1b

@ -1009,6 +1009,11 @@ static struct ao2_container *threadt;
static struct ao2_container *peers; static struct ao2_container *peers;
static struct ao2_container *peers_by_ip; static struct ao2_container *peers_by_ip;
/*! \brief A bogus peer, to be used when authentication should fail */
static struct sip_peer *bogus_peer;
/*! \brief We can recognise the bogus peer by this invalid MD5 hash */
#define BOGUS_PEER_MD5SECRET "intentionally_invalid_md5_string"
/*! \brief The register list: Other SIP proxies we register with and receive calls from */ /*! \brief The register list: Other SIP proxies we register with and receive calls from */
static struct ast_register_list { static struct ast_register_list {
ASTOBJ_CONTAINER_COMPONENTS(struct sip_registry); ASTOBJ_CONTAINER_COMPONENTS(struct sip_registry);
@ -1157,7 +1162,7 @@ static int transmit_response_with_unsupported(struct sip_pvt *p, const char *msg
static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *rand, enum xmittype reliable, const char *header, int stale); static int transmit_response_with_auth(struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *rand, enum xmittype reliable, const char *header, int stale);
static int transmit_provisional_response(struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp); static int transmit_provisional_response(struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp);
static int transmit_response_with_allow(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable); static int transmit_response_with_allow(struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable);
static void transmit_fake_auth_response(struct sip_pvt *p, int sipmethod, struct sip_request *req, enum xmittype reliable); static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable);
static int transmit_request(struct sip_pvt *p, int sipmethod, uint32_t seqno, enum xmittype reliable, int newbranch); static int transmit_request(struct sip_pvt *p, int sipmethod, uint32_t seqno, enum xmittype reliable, int newbranch);
static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, uint32_t seqno, enum xmittype reliable, int newbranch); static int transmit_request_with_auth(struct sip_pvt *p, int sipmethod, uint32_t seqno, enum xmittype reliable, int newbranch);
static int transmit_publish(struct sip_epa_entry *epa_entry, enum sip_publish_type publish_type, const char * const explicit_uri); static int transmit_publish(struct sip_epa_entry *epa_entry, enum sip_publish_type publish_type, const char * const explicit_uri);
@ -16479,6 +16484,7 @@ static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request *
char a1_hash[256]; char a1_hash[256];
char resp_hash[256]=""; char resp_hash[256]="";
char *c; char *c;
int is_bogus_peer = 0;
int wrongnonce = FALSE; int wrongnonce = FALSE;
int good_response; int good_response;
const char *usednonce = p->nonce; const char *usednonce = p->nonce;
@ -16550,8 +16556,14 @@ static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request *
sip_digest_parser(c, keys); sip_digest_parser(c, keys);
/* We cannot rely on the bogus_peer having a bad md5 value. Someone could
* use it to construct valid auth. */
if (md5secret && strcmp(md5secret, BOGUS_PEER_MD5SECRET) == 0) {
is_bogus_peer = 1;
}
/* Verify that digest username matches the username we auth as */ /* Verify that digest username matches the username we auth as */
if (strcmp(username, keys[K_USER].s)) { if (strcmp(username, keys[K_USER].s) && !is_bogus_peer) {
ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n", ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
username, keys[K_USER].s); username, keys[K_USER].s);
/* Oops, we're trying something here */ /* Oops, we're trying something here */
@ -16590,7 +16602,8 @@ static enum check_auth_result check_auth(struct sip_pvt *p, struct sip_request *
} }
good_response = keys[K_RESP].s && good_response = keys[K_RESP].s &&
!strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)); !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash)) &&
!is_bogus_peer; /* lastly, check that the peer isn't the fake peer */
if (wrongnonce) { if (wrongnonce) {
if (good_response) { if (good_response) {
if (sipdebug) if (sipdebug)
@ -16821,13 +16834,13 @@ static int cb_extensionstate(char *context, char *exten, struct ast_state_cb_inf
/*! \brief Send a fake 401 Unauthorized response when the administrator /*! \brief Send a fake 401 Unauthorized response when the administrator
wants to hide the names of local devices from fishers wants to hide the names of local devices from fishers
*/ */
static void transmit_fake_auth_response(struct sip_pvt *p, int sipmethod, struct sip_request *req, enum xmittype reliable) static void transmit_fake_auth_response(struct sip_pvt *p, struct sip_request *req, enum xmittype reliable)
{ {
/* We have to emulate EXACTLY what we'd get with a good peer /* We have to emulate EXACTLY what we'd get with a good peer
* and a bad password, or else we leak information. */ * and a bad password, or else we leak information. */
const char *response = "407 Proxy Authentication Required"; const char *response = "401 Unauthorized";
const char *reqheader = "Proxy-Authorization"; const char *reqheader = "Authorization";
const char *respheader = "Proxy-Authenticate"; const char *respheader = "WWW-Authenticate";
const char *authtoken; const char *authtoken;
struct ast_str *buf; struct ast_str *buf;
char *c; char *c;
@ -16842,36 +16855,31 @@ static void transmit_fake_auth_response(struct sip_pvt *p, int sipmethod, struct
[K_LAST] = { NULL, NULL} [K_LAST] = { NULL, NULL}
}; };
if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
response = "401 Unauthorized";
reqheader = "Authorization";
respheader = "WWW-Authenticate";
}
authtoken = sip_get_header(req, reqheader); authtoken = sip_get_header(req, reqheader);
if (req->ignore && !ast_strlen_zero(p->nonce) && ast_strlen_zero(authtoken)) { if (req->ignore && !ast_strlen_zero(p->nonce) && ast_strlen_zero(authtoken)) {
/* This is a retransmitted invite/register/etc, don't reconstruct authentication /* This is a retransmitted invite/register/etc, don't reconstruct authentication
* information */ * information */
transmit_response_with_auth(p, response, req, p->nonce, 0, respheader, 0); transmit_response_with_auth(p, response, req, p->nonce, reliable, respheader, 0);
/* Schedule auto destroy in 32 seconds (according to RFC 3261) */ /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
return; return;
} else if (ast_strlen_zero(p->nonce) || ast_strlen_zero(authtoken)) { } else if (ast_strlen_zero(p->nonce) || ast_strlen_zero(authtoken)) {
/* We have no auth, so issue challenge and request authentication */ /* We have no auth, so issue challenge and request authentication */
build_nonce(p, 1); build_nonce(p, 1);
transmit_response_with_auth(p, response, req, p->nonce, 0, respheader, 0); transmit_response_with_auth(p, response, req, p->nonce, reliable, respheader, 0);
/* Schedule auto destroy in 32 seconds */ /* Schedule auto destroy in 32 seconds */
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
return; return;
} }
if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) { if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
return; return;
} }
/* Make a copy of the response and parse it */ /* Make a copy of the response and parse it */
if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) { if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) {
transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
return; return;
} }
@ -16909,7 +16917,7 @@ static void transmit_fake_auth_response(struct sip_pvt *p, int sipmethod, struct
/* Schedule auto destroy in 32 seconds */ /* Schedule auto destroy in 32 seconds */
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
} else { } else {
transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); __transmit_response(p, "403 Forbidden", &p->initreq, reliable);
} }
} }
@ -17019,7 +17027,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock
if (!AST_LIST_EMPTY(&domain_list)) { if (!AST_LIST_EMPTY(&domain_list)) {
if (!check_sip_domain(domain, NULL, 0)) { if (!check_sip_domain(domain, NULL, 0)) {
if (sip_cfg.alwaysauthreject) { if (sip_cfg.alwaysauthreject) {
transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE); transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE);
} else { } else {
transmit_response(p, "404 Not found (unknown domain)", &p->initreq); transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
} }
@ -17046,6 +17054,13 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock
} }
peer = sip_find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0); peer = sip_find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0);
/* If we don't want username disclosure, use the bogus_peer when a user
* is not found. */
if (!peer && sip_cfg.alwaysauthreject && sip_cfg.autocreatepeer == AUTOPEERS_DISABLED) {
peer = bogus_peer;
sip_ref_peer(peer, "register_verify: ref the bogus_peer");
}
if (!(peer && ast_apply_acl(peer->acl, addr, "SIP Peer ACL: "))) { if (!(peer && ast_apply_acl(peer->acl, addr, "SIP Peer ACL: "))) {
/* Peer fails ACL check */ /* Peer fails ACL check */
if (peer) { if (peer) {
@ -17137,7 +17152,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock
switch (parse_register_contact(p, peer, req)) { switch (parse_register_contact(p, peer, req)) {
case PARSE_REGISTER_DENIED: case PARSE_REGISTER_DENIED:
ast_log(LOG_WARNING, "Registration denied because of contact ACL\n"); ast_log(LOG_WARNING, "Registration denied because of contact ACL\n");
transmit_response_with_date(p, "403 Forbidden (ACL)", req); transmit_response_with_date(p, "403 Forbidden", req);
res = 0; res = 0;
break; break;
case PARSE_REGISTER_FAILED: case PARSE_REGISTER_FAILED:
@ -17177,7 +17192,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock
switch (res) { switch (res) {
case AUTH_SECRET_FAILED: case AUTH_SECRET_FAILED:
/* Wrong password in authentication. Go away, don't try again until you fixed it */ /* Wrong password in authentication. Go away, don't try again until you fixed it */
transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq); transmit_response(p, "403 Forbidden", &p->initreq);
if (global_authfailureevents) { if (global_authfailureevents) {
const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
@ -17200,7 +17215,7 @@ static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sock
case AUTH_PEER_NOT_DYNAMIC: case AUTH_PEER_NOT_DYNAMIC:
case AUTH_ACL_FAILED: case AUTH_ACL_FAILED:
if (sip_cfg.alwaysauthreject) { if (sip_cfg.alwaysauthreject) {
transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE); transmit_fake_auth_response(p, &p->initreq, XMIT_UNRELIABLE);
if (global_authfailureevents) { if (global_authfailureevents) {
const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr)); const char *peer_addr = ast_strdupa(ast_sockaddr_stringify_addr(addr));
const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr)); const char *peer_port = ast_strdupa(ast_sockaddr_stringify_port(addr));
@ -18239,9 +18254,21 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
ast_verbose("No matching peer for '%s' from '%s'\n", ast_verbose("No matching peer for '%s' from '%s'\n",
of, ast_sockaddr_stringify(&p->recv)); of, ast_sockaddr_stringify(&p->recv));
} }
/* If you don't mind, we can return 404s for devices that do
* not exist: username disclosure. If we allow guests, there
* is no way around that. */
if (sip_cfg.allowguest || !sip_cfg.alwaysauthreject) {
return AUTH_DONT_KNOW; return AUTH_DONT_KNOW;
} }
/* If you do mind, we use a peer that will never authenticate.
* This ensures that we follow the same code path as regular
* auth: less chance for username disclosure. */
peer = bogus_peer;
sip_ref_peer(peer, "sip_ref_peer: check_peer_ok: must ref bogus_peer so unreffing it does not fail");
}
/* build_peer, called through sip_find_peer, is not able to check the /* build_peer, called through sip_find_peer, is not able to check the
* sip_pvt->natdetected flag in order to determine if the peer is behind * sip_pvt->natdetected flag in order to determine if the peer is behind
* NAT or not when SIP_PAGE3_NAT_AUTO_RPORT or SIP_PAGE3_NAT_AUTO_COMEDIA * NAT or not when SIP_PAGE3_NAT_AUTO_RPORT or SIP_PAGE3_NAT_AUTO_COMEDIA
@ -18262,9 +18289,10 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
sip_unref_peer(peer, "sip_unref_peer: check_peer_ok: from sip_find_peer call, early return of AUTH_ACL_FAILED"); sip_unref_peer(peer, "sip_unref_peer: check_peer_ok: from sip_find_peer call, early return of AUTH_ACL_FAILED");
return AUTH_ACL_FAILED; return AUTH_ACL_FAILED;
} }
if (debug) if (debug && peer != bogus_peer) {
ast_verbose("Found peer '%s' for '%s' from %s\n", ast_verbose("Found peer '%s' for '%s' from %s\n",
peer->name, of, ast_sockaddr_stringify(&p->recv)); peer->name, of, ast_sockaddr_stringify(&p->recv));
}
/* XXX what about p->prefs = peer->prefs; ? */ /* XXX what about p->prefs = peer->prefs; ? */
/* Set Frame packetization */ /* Set Frame packetization */
@ -18547,8 +18575,6 @@ static enum check_auth_result check_user_full(struct sip_pvt *p, struct sip_requ
} else { } else {
res = AUTH_RTP_FAILED; res = AUTH_RTP_FAILED;
} }
} else if (sip_cfg.alwaysauthreject) {
res = AUTH_FAKE_AUTH; /* reject with fake authorization request */
} else { } else {
res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */ res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
} }
@ -18683,13 +18709,8 @@ static void receive_message(struct sip_pvt *p, struct sip_request *req, struct a
return; return;
} }
if (res < 0) { /* Something failed in authentication */ if (res < 0) { /* Something failed in authentication */
if (res == AUTH_FAKE_AUTH) {
ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", sip_get_header(req, "From"));
transmit_fake_auth_response(p, SIP_MESSAGE, req, XMIT_UNRELIABLE);
} else {
ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", sip_get_header(req, "From")); ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", sip_get_header(req, "From"));
transmit_response(p, "403 Forbidden", req); transmit_response(p, "403 Forbidden", req);
}
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
return; return;
} }
@ -24847,13 +24868,8 @@ static int handle_request_options(struct sip_pvt *p, struct sip_request *req, st
return 0; return 0;
} }
if (res < 0) { /* Something failed in authentication */ if (res < 0) { /* Something failed in authentication */
if (res == AUTH_FAKE_AUTH) {
ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", sip_get_header(req, "From"));
transmit_fake_auth_response(p, SIP_OPTIONS, req, XMIT_UNRELIABLE);
} else {
ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", sip_get_header(req, "From")); ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", sip_get_header(req, "From"));
transmit_response(p, "403 Forbidden", req); transmit_response(p, "403 Forbidden", req);
}
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
return 0; return 0;
} }
@ -25498,13 +25514,8 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str
goto request_invite_cleanup; goto request_invite_cleanup;
} }
if (res < 0) { /* Something failed in authentication */ if (res < 0) { /* Something failed in authentication */
if (res == AUTH_FAKE_AUTH) {
ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", sip_get_header(req, "From"));
transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE);
} else {
ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", sip_get_header(req, "From")); ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", sip_get_header(req, "From"));
transmit_response_reliable(p, "403 Forbidden", req); transmit_response_reliable(p, "403 Forbidden", req);
}
p->invitestate = INV_COMPLETED; p->invitestate = INV_COMPLETED;
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
goto request_invite_cleanup; goto request_invite_cleanup;
@ -27547,18 +27558,13 @@ static int handle_request_publish(struct sip_pvt *p, struct sip_request *req, st
return -1; return -1;
} }
auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_RELIABLE, addr); auth_result = check_user(p, req, SIP_PUBLISH, uri, XMIT_UNRELIABLE, addr);
if (auth_result == AUTH_CHALLENGE_SENT) { if (auth_result == AUTH_CHALLENGE_SENT) {
p->lastinvite = seqno; p->lastinvite = seqno;
return 0; return 0;
} else if (auth_result < 0) { } else if (auth_result < 0) {
if (auth_result == AUTH_FAKE_AUTH) {
ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", sip_get_header(req, "From"));
transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE);
} else {
ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", sip_get_header(req, "From")); ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", sip_get_header(req, "From"));
transmit_response_reliable(p, "403 Forbidden", req); transmit_response(p, "403 Forbidden", req);
}
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
ast_string_field_set(p, theirtag, NULL); ast_string_field_set(p, theirtag, NULL);
return 0; return 0;
@ -27770,19 +27776,14 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req,
* use if !req->ignore, because then we'll end up sending * use if !req->ignore, because then we'll end up sending
* a 200 OK if someone retransmits without sending auth */ * a 200 OK if someone retransmits without sending auth */
if (p->subscribed == NONE || resubscribe) { if (p->subscribed == NONE || resubscribe) {
res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, addr, &authpeer); res = check_user_full(p, req, SIP_SUBSCRIBE, e, XMIT_UNRELIABLE, addr, &authpeer);
/* if an authentication response was sent, we are done here */ /* if an authentication response was sent, we are done here */
if (res == AUTH_CHALLENGE_SENT) /* authpeer = NULL here */ if (res == AUTH_CHALLENGE_SENT) /* authpeer = NULL here */
return 0; return 0;
if (res != AUTH_SUCCESSFUL) { if (res != AUTH_SUCCESSFUL) {
if (res == AUTH_FAKE_AUTH) {
ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", sip_get_header(req, "From"));
transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE);
} else {
ast_log(LOG_NOTICE, "Failed to authenticate device %s for SUBSCRIBE\n", sip_get_header(req, "From")); ast_log(LOG_NOTICE, "Failed to authenticate device %s for SUBSCRIBE\n", sip_get_header(req, "From"));
transmit_response_reliable(p, "403 Forbidden", req); transmit_response(p, "403 Forbidden", req);
}
pvt_set_needdestroy(p, "authentication failed"); pvt_set_needdestroy(p, "authentication failed");
return 0; return 0;
@ -33315,6 +33316,7 @@ static int sip_do_reload(enum channelreloadreason reason)
/*! \brief Force reload of module from cli */ /*! \brief Force reload of module from cli */
static char *sip_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) static char *sip_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{ {
static struct sip_peer *tmp_peer, *new_peer;
switch (cmd) { switch (cmd) {
case CLI_INIT: case CLI_INIT:
@ -33337,6 +33339,18 @@ static char *sip_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a
ast_mutex_unlock(&sip_reload_lock); ast_mutex_unlock(&sip_reload_lock);
restart_monitor(); restart_monitor();
tmp_peer = bogus_peer;
/* Create new bogus peer possibly with new global settings. */
if ((new_peer = temp_peer("(bogus_peer)"))) {
ast_string_field_set(new_peer, md5secret, BOGUS_PEER_MD5SECRET);
ast_clear_flag(&new_peer->flags[0], SIP_INSECURE);
bogus_peer = new_peer;
ao2_t_ref(tmp_peer, -1, "unref the old bogus_peer during reload");
} else {
ast_log(LOG_ERROR, "Could not update the fake authentication peer.\n");
/* You probably have bigger (memory?) issues to worry about though.. */
}
return CLI_SUCCESS; return CLI_SUCCESS;
} }
@ -34564,6 +34578,17 @@ static int load_module(void)
return AST_MODULE_LOAD_DECLINE; return AST_MODULE_LOAD_DECLINE;
} }
/* Initialize bogus peer. Can be done first after reload_config() */
if (!(bogus_peer = temp_peer("(bogus_peer)"))) {
ast_log(LOG_ERROR, "Unable to create bogus_peer for authentication\n");
io_context_destroy(io);
ast_sched_context_destroy(sched);
return AST_MODULE_LOAD_FAILURE;
}
/* Make sure the auth will always fail. */
ast_string_field_set(bogus_peer, md5secret, BOGUS_PEER_MD5SECRET);
ast_clear_flag(&bogus_peer->flags[0], SIP_INSECURE);
/* Prepare the version that does not require DTMF BEGIN frames. /* Prepare the version that does not require DTMF BEGIN frames.
* We need to use tricks such as memcpy and casts because the variable * We need to use tricks such as memcpy and casts because the variable
* has const fields. * has const fields.
@ -34579,6 +34604,7 @@ static int load_module(void)
/* Make sure we can register our sip channel type */ /* Make sure we can register our sip channel type */
if (ast_channel_register(&sip_tech)) { if (ast_channel_register(&sip_tech)) {
ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n"); ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
ao2_t_ref(bogus_peer, -1, "unref the bogus_peer");
io_context_destroy(io); io_context_destroy(io);
ast_sched_context_destroy(sched); ast_sched_context_destroy(sched);
return AST_MODULE_LOAD_FAILURE; return AST_MODULE_LOAD_FAILURE;
@ -34841,6 +34867,8 @@ static int unload_module(void)
ast_debug(2, "TCP/TLS thread container did not become empty :(\n"); ast_debug(2, "TCP/TLS thread container did not become empty :(\n");
} }
ao2_t_ref(bogus_peer, -1, "unref the bogus_peer");
ao2_t_ref(peers, -1, "unref the peers table"); ao2_t_ref(peers, -1, "unref the peers table");
ao2_t_ref(peers_by_ip, -1, "unref the peers_by_ip table"); ao2_t_ref(peers_by_ip, -1, "unref the peers_by_ip table");
ao2_t_ref(dialogs, -1, "unref the dialogs table"); ao2_t_ref(dialogs, -1, "unref the dialogs table");

@ -507,7 +507,6 @@ enum check_auth_result {
AUTH_SECRET_FAILED = -1, AUTH_SECRET_FAILED = -1,
AUTH_USERNAME_MISMATCH = -2, AUTH_USERNAME_MISMATCH = -2,
AUTH_NOT_FOUND = -3, /*!< returned by register_verify */ AUTH_NOT_FOUND = -3, /*!< returned by register_verify */
AUTH_FAKE_AUTH = -4,
AUTH_UNKNOWN_DOMAIN = -5, AUTH_UNKNOWN_DOMAIN = -5,
AUTH_PEER_NOT_DYNAMIC = -6, AUTH_PEER_NOT_DYNAMIC = -6,
AUTH_ACL_FAILED = -7, AUTH_ACL_FAILED = -7,

@ -342,9 +342,6 @@ int sip_report_security_event(const struct sip_pvt *p, const struct sip_request
/* with sip_cfg.alwaysauthreject on, generates 2 events */ /* with sip_cfg.alwaysauthreject on, generates 2 events */
sip_report_invalid_peer(p); sip_report_invalid_peer(p);
break; break;
case AUTH_FAKE_AUTH:
sip_report_invalid_peer(p);
break;
case AUTH_UNKNOWN_DOMAIN: case AUTH_UNKNOWN_DOMAIN:
snprintf(aclname, sizeof(aclname), "domain_must_match"); snprintf(aclname, sizeof(aclname), "domain_must_match");
sip_report_failed_acl(p, aclname); sip_report_failed_acl(p, aclname);

Loading…
Cancel
Save